// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_CONTAINERS_BUFFER_ITERATOR_H_ #define BASE_CONTAINERS_BUFFER_ITERATOR_H_ #include <string.h> #include <concepts> #include <optional> #include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/memory/raw_span.h" #include "base/numerics/checked_math.h" namespace base { // BufferIterator is a bounds-checked container utility to access variable- // length, heterogeneous structures contained within a buffer. If the data are // homogeneous, use base::span<> instead. // // After being created with a weakly-owned buffer, BufferIterator returns // pointers to structured data within the buffer. After each method call that // returns data in the buffer, the iterator position is advanced by the byte // size of the object (or span of objects) returned. If there are not enough // bytes remaining in the buffer to return the requested object(s), a nullptr // or empty span is returned. // // This class is similar to base::Pickle, which should be preferred for // serializing to disk. Pickle versions its header and does not support writing // structures, which are problematic for serialization due to struct padding and // version shear concerns. // // Example usage: // // std::vector<uint8_t> buffer(4096); // if (!ReadSomeData(&buffer, buffer.size())) { // LOG(ERROR) << "Failed to read data."; // return false; // } // // BufferIterator<uint8_t> iterator(buffer); // uint32_t* num_items = iterator.Object<uint32_t>(); // if (!num_items) { // LOG(ERROR) << "No num_items field." // return false; // } // // base::span<const item_struct> items = // iterator.Span<item_struct>(*num_items); // if (items.size() != *num_items) { // LOG(ERROR) << "Not enough items."; // return false; // } // // // ... validate the objects in |items|. template <typename B> class BufferIterator { … }; } // namespace base #endif // BASE_CONTAINERS_BUFFER_ITERATOR_H_