/* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "packet/iterator.h" #include "os/log.h" namespace bluetooth { namespace packet { template Iterator::Iterator(const std::forward_list& data, size_t offset) { data_ = data; index_ = offset; begin_ = 0; end_ = 0; for (auto& view : data) { end_ += view.size(); } } template Iterator Iterator::operator+(int offset) { auto itr(*this); return itr += offset; } template Iterator& Iterator::operator+=(int offset) { index_ += offset; return *this; } template Iterator& Iterator::operator++() { index_++; return *this; } template Iterator Iterator::operator-(int offset) { auto itr(*this); return itr -= offset; } template int Iterator::operator-(Iterator& itr) { return index_ - itr.index_; } template Iterator& Iterator::operator-=(int offset) { index_ -= offset; return *this; } template Iterator& Iterator::operator--() { if (index_ != 0) index_--; return *this; } template Iterator& Iterator::operator=(const Iterator& itr) { if (this == &itr) return *this; this->data_ = itr.data_; this->begin_ = itr.begin_; this->end_ = itr.end_; this->index_ = itr.index_; return *this; } template bool Iterator::operator==(const Iterator& itr) const { return index_ == itr.index_; } template bool Iterator::operator!=(const Iterator& itr) const { return !(*this == itr); } template bool Iterator::operator<(const Iterator& itr) const { return index_ < itr.index_; } template bool Iterator::operator>(const Iterator& itr) const { return index_ > itr.index_; } template bool Iterator::operator<=(const Iterator& itr) const { return index_ <= itr.index_; } template bool Iterator::operator>=(const Iterator& itr) const { return index_ >= itr.index_; } template uint8_t Iterator::operator*() const { ASSERT_LOG(index_ < end_ && !(begin_ > index_), "Index %zu out of bounds: [%zu,%zu)", index_, begin_, end_); size_t index = index_; for (auto view : data_) { if (index < view.size()) { return view[index]; } index -= view.size(); } ASSERT_LOG(false, "Out of fragments searching for index %zu", index_); return 0; } template size_t Iterator::NumBytesRemaining() const { if (end_ > index_ && !(begin_ > index_)) { return end_ - index_; } else { return 0; } } template Iterator Iterator::Subrange(size_t index, size_t length) const { Iterator to_return(*this); if (to_return.NumBytesRemaining() > index) { to_return.index_ = to_return.index_ + index; to_return.begin_ = to_return.index_; if (to_return.NumBytesRemaining() >= length) { to_return.end_ = to_return.index_ + length; } } else { to_return.end_ = 0; } return to_return; } // Explicit instantiations for both types of Iterators. template class Iterator; template class Iterator; } // namespace packet } // namespace bluetooth