Buffer.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Copyright (c) 2016-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. */
  9. #pragma once
  10. #include "utils/Range.h"
  11. #include <array>
  12. #include <cstddef>
  13. #include <memory>
  14. namespace pzstd {
  15. /**
  16. * A `Buffer` has a pointer to a shared buffer, and a range of the buffer that
  17. * it owns.
  18. * The idea is that you can allocate one buffer, and write chunks into it
  19. * and break off those chunks.
  20. * The underlying buffer is reference counted, and will be destroyed when all
  21. * `Buffer`s that reference it are destroyed.
  22. */
  23. class Buffer {
  24. std::shared_ptr<unsigned char> buffer_;
  25. MutableByteRange range_;
  26. static void delete_buffer(unsigned char* buffer) {
  27. delete[] buffer;
  28. }
  29. public:
  30. /// Construct an empty buffer that owns no data.
  31. explicit Buffer() {}
  32. /// Construct a `Buffer` that owns a new underlying buffer of size `size`.
  33. explicit Buffer(std::size_t size)
  34. : buffer_(new unsigned char[size], delete_buffer),
  35. range_(buffer_.get(), buffer_.get() + size) {}
  36. explicit Buffer(std::shared_ptr<unsigned char> buffer, MutableByteRange data)
  37. : buffer_(buffer), range_(data) {}
  38. Buffer(Buffer&&) = default;
  39. Buffer& operator=(Buffer&&) = default;
  40. /**
  41. * Splits the data into two pieces: [begin, begin + n), [begin + n, end).
  42. * Their data both points into the same underlying buffer.
  43. * Modifies the original `Buffer` to point to only [begin + n, end).
  44. *
  45. * @param n The offset to split at.
  46. * @returns A buffer that owns the data [begin, begin + n).
  47. */
  48. Buffer splitAt(std::size_t n) {
  49. auto firstPiece = range_.subpiece(0, n);
  50. range_.advance(n);
  51. return Buffer(buffer_, firstPiece);
  52. }
  53. /// Modifies the buffer to point to the range [begin + n, end).
  54. void advance(std::size_t n) {
  55. range_.advance(n);
  56. }
  57. /// Modifies the buffer to point to the range [begin, end - n).
  58. void subtract(std::size_t n) {
  59. range_.subtract(n);
  60. }
  61. /// Returns a read only `Range` pointing to the `Buffer`s data.
  62. ByteRange range() const {
  63. return range_;
  64. }
  65. /// Returns a mutable `Range` pointing to the `Buffer`s data.
  66. MutableByteRange range() {
  67. return range_;
  68. }
  69. const unsigned char* data() const {
  70. return range_.data();
  71. }
  72. unsigned char* data() {
  73. return range_.data();
  74. }
  75. std::size_t size() const {
  76. return range_.size();
  77. }
  78. bool empty() const {
  79. return range_.empty();
  80. }
  81. };
  82. }