1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved. 2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be 3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file. 4*a03ca8b9SKrzysztof Kosiński 5*a03ca8b9SKrzysztof Kosiński #ifndef COMPONENTS_ZUCCHINI_BUFFER_SINK_H_ 6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_BUFFER_SINK_H_ 7*a03ca8b9SKrzysztof Kosiński 8*a03ca8b9SKrzysztof Kosiński #include <stdint.h> 9*a03ca8b9SKrzysztof Kosiński 10*a03ca8b9SKrzysztof Kosiński #include <algorithm> 11*a03ca8b9SKrzysztof Kosiński #include <iterator> 12*a03ca8b9SKrzysztof Kosiński 13*a03ca8b9SKrzysztof Kosiński #include "base/check_op.h" 14*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/buffer_view.h" 15*a03ca8b9SKrzysztof Kosiński 16*a03ca8b9SKrzysztof Kosiński namespace zucchini { 17*a03ca8b9SKrzysztof Kosiński 18*a03ca8b9SKrzysztof Kosiński // BufferSink acts like an output stream with convenience methods to serialize 19*a03ca8b9SKrzysztof Kosiński // data into a contiguous sequence of raw data. The underlying MutableBufferView 20*a03ca8b9SKrzysztof Kosiński // emulates a cursor to track current write position, and guards against buffer 21*a03ca8b9SKrzysztof Kosiński // overrun. Where applicable, BufferSink should be passed by pointer to maintain 22*a03ca8b9SKrzysztof Kosiński // cursor progress across writes. 23*a03ca8b9SKrzysztof Kosiński class BufferSink : public MutableBufferView { 24*a03ca8b9SKrzysztof Kosiński public: 25*a03ca8b9SKrzysztof Kosiński using iterator = MutableBufferView::iterator; 26*a03ca8b9SKrzysztof Kosiński 27*a03ca8b9SKrzysztof Kosiński using MutableBufferView::MutableBufferView; 28*a03ca8b9SKrzysztof Kosiński BufferSink() = default; 29*a03ca8b9SKrzysztof Kosiński explicit BufferSink(MutableBufferView buffer); 30*a03ca8b9SKrzysztof Kosiński BufferSink(const BufferSink&) = default; 31*a03ca8b9SKrzysztof Kosiński BufferSink& operator=(BufferSink&&) = default; 32*a03ca8b9SKrzysztof Kosiński 33*a03ca8b9SKrzysztof Kosiński // If sufficient space is available, writes the binary representation of 34*a03ca8b9SKrzysztof Kosiński // |value| starting at the cursor, while advancing the cursor beyond the 35*a03ca8b9SKrzysztof Kosiński // written region, and returns true. Otherwise returns false. 36*a03ca8b9SKrzysztof Kosiński template <class T> PutValue(const T & value)37*a03ca8b9SKrzysztof Kosiński bool PutValue(const T& value) { 38*a03ca8b9SKrzysztof Kosiński DCHECK_NE(begin(), nullptr); 39*a03ca8b9SKrzysztof Kosiński if (Remaining() < sizeof(T)) 40*a03ca8b9SKrzysztof Kosiński return false; 41*a03ca8b9SKrzysztof Kosiński *reinterpret_cast<T*>(begin()) = value; 42*a03ca8b9SKrzysztof Kosiński remove_prefix(sizeof(T)); 43*a03ca8b9SKrzysztof Kosiński return true; 44*a03ca8b9SKrzysztof Kosiński } 45*a03ca8b9SKrzysztof Kosiński 46*a03ca8b9SKrzysztof Kosiński // If sufficient space is available, writes the raw bytes [|first|, |last|) 47*a03ca8b9SKrzysztof Kosiński // starting at the cursor, while advancing the cursor beyond the written 48*a03ca8b9SKrzysztof Kosiński // region, and returns true. Otherwise returns false. 49*a03ca8b9SKrzysztof Kosiński template <class It> PutRange(It first,It last)50*a03ca8b9SKrzysztof Kosiński bool PutRange(It first, It last) { 51*a03ca8b9SKrzysztof Kosiński static_assert(sizeof(typename std::iterator_traits<It>::value_type) == 52*a03ca8b9SKrzysztof Kosiński sizeof(uint8_t), 53*a03ca8b9SKrzysztof Kosiński "value_type should fit in uint8_t"); 54*a03ca8b9SKrzysztof Kosiński DCHECK_NE(begin(), nullptr); 55*a03ca8b9SKrzysztof Kosiński DCHECK(last >= first); 56*a03ca8b9SKrzysztof Kosiński if (Remaining() < size_type(last - first)) 57*a03ca8b9SKrzysztof Kosiński return false; 58*a03ca8b9SKrzysztof Kosiński std::copy(first, last, begin()); 59*a03ca8b9SKrzysztof Kosiński remove_prefix(last - first); 60*a03ca8b9SKrzysztof Kosiński return true; 61*a03ca8b9SKrzysztof Kosiński } 62*a03ca8b9SKrzysztof Kosiński Remaining()63*a03ca8b9SKrzysztof Kosiński size_type Remaining() const { return size(); } 64*a03ca8b9SKrzysztof Kosiński }; 65*a03ca8b9SKrzysztof Kosiński 66*a03ca8b9SKrzysztof Kosiński } // namespace zucchini 67*a03ca8b9SKrzysztof Kosiński 68*a03ca8b9SKrzysztof Kosiński #endif // COMPONENTS_ZUCCHINI_BUFFER_SINK_H_ 69