/* * 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 <bool little_endian> Iterator<little_endian>::Iterator(std::forward_list<View> data, size_t offset) { data_ = data; index_ = offset; length_ = 0; for (auto& view : data) { length_ += view.size(); } } template <bool little_endian> Iterator<little_endian> Iterator<little_endian>::operator+(int offset) { auto itr(*this); return itr += offset; } template <bool little_endian> Iterator<little_endian>& Iterator<little_endian>::operator+=(int offset) { index_ += offset; return *this; } template <bool little_endian> Iterator<little_endian> Iterator<little_endian>::operator++(int) { auto itr(*this); index_++; return itr; } template <bool little_endian> Iterator<little_endian>& Iterator<little_endian>::operator++() { index_++; return *this; } template <bool little_endian> Iterator<little_endian> Iterator<little_endian>::operator-(int offset) { auto itr(*this); return itr -= offset; } template <bool little_endian> int Iterator<little_endian>::operator-(Iterator<little_endian>& itr) { return index_ - itr.index_; } template <bool little_endian> Iterator<little_endian>& Iterator<little_endian>::operator-=(int offset) { index_ -= offset; return *this; } template <bool little_endian> Iterator<little_endian> Iterator<little_endian>::operator--(int) { auto itr(*this); if (index_ != 0) index_--; return itr; } template <bool little_endian> Iterator<little_endian>& Iterator<little_endian>::operator--() { if (index_ != 0) index_--; return *this; } template <bool little_endian> Iterator<little_endian>& Iterator<little_endian>::operator=(const Iterator<little_endian>& itr) { data_ = itr.data_; index_ = itr.index_; return *this; } template <bool little_endian> bool Iterator<little_endian>::operator==(const Iterator<little_endian>& itr) const { return index_ == itr.index_; } template <bool little_endian> bool Iterator<little_endian>::operator!=(const Iterator<little_endian>& itr) const { return !(*this == itr); } template <bool little_endian> bool Iterator<little_endian>::operator<(const Iterator<little_endian>& itr) const { return index_ < itr.index_; } template <bool little_endian> bool Iterator<little_endian>::operator>(const Iterator<little_endian>& itr) const { return index_ > itr.index_; } template <bool little_endian> bool Iterator<little_endian>::operator<=(const Iterator<little_endian>& itr) const { return index_ <= itr.index_; } template <bool little_endian> bool Iterator<little_endian>::operator>=(const Iterator<little_endian>& itr) const { return index_ >= itr.index_; } template <bool little_endian> uint8_t Iterator<little_endian>::operator*() const { ASSERT_LOG(index_ < length_, "Index %zu out of bounds: %zu", index_, length_); 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 <bool little_endian> size_t Iterator<little_endian>::NumBytesRemaining() const { if (length_ > index_) { return length_ - index_; } else { return 0; } } // Explicit instantiations for both types of Iterators. template class Iterator<true>; template class Iterator<false>; } // namespace packet } // namespace bluetooth