1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_ZUCCHINI_BUFFER_SINK_H_
- #define COMPONENTS_ZUCCHINI_BUFFER_SINK_H_
- #include <stdint.h>
- #include <algorithm>
- #include <iterator>
- #include "base/check_op.h"
- #include "components/zucchini/buffer_view.h"
- namespace zucchini {
- // BufferSink acts like an output stream with convenience methods to serialize
- // data into a contiguous sequence of raw data. The underlying MutableBufferView
- // emulates a cursor to track current write position, and guards against buffer
- // overrun. Where applicable, BufferSink should be passed by pointer to maintain
- // cursor progress across writes.
- class BufferSink : public MutableBufferView {
- public:
- using iterator = MutableBufferView::iterator;
- using MutableBufferView::MutableBufferView;
- BufferSink() = default;
- explicit BufferSink(MutableBufferView buffer);
- BufferSink(const BufferSink&) = default;
- BufferSink& operator=(BufferSink&&) = default;
- // If sufficient space is available, writes the binary representation of
- // |value| starting at the cursor, while advancing the cursor beyond the
- // written region, and returns true. Otherwise returns false.
- template <class T>
- bool PutValue(const T& value) {
- DCHECK_NE(begin(), nullptr);
- if (Remaining() < sizeof(T))
- return false;
- *reinterpret_cast<T*>(begin()) = value;
- remove_prefix(sizeof(T));
- return true;
- }
- // If sufficient space is available, writes the raw bytes [|first|, |last|)
- // starting at the cursor, while advancing the cursor beyond the written
- // region, and returns true. Otherwise returns false.
- template <class It>
- bool PutRange(It first, It last) {
- static_assert(sizeof(typename std::iterator_traits<It>::value_type) ==
- sizeof(uint8_t),
- "value_type should fit in uint8_t");
- DCHECK_NE(begin(), nullptr);
- DCHECK(last >= first);
- if (Remaining() < size_type(last - first))
- return false;
- std::copy(first, last, begin());
- remove_prefix(last - first);
- return true;
- }
- size_type Remaining() const { return size(); }
- };
- } // namespace zucchini
- #endif // COMPONENTS_ZUCCHINI_BUFFER_SINK_H_
|