buffer_sink.h 2.3 KB

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