• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #include "utils/Range.h"
12 
13 #include <array>
14 #include <cstddef>
15 #include <memory>
16 
17 namespace pzstd {
18 
19 /**
20  * A `Buffer` has a pointer to a shared buffer, and a range of the buffer that
21  * it owns.
22  * The idea is that you can allocate one buffer, and write chunks into it
23  * and break off those chunks.
24  * The underlying buffer is reference counted, and will be destroyed when all
25  * `Buffer`s that reference it are destroyed.
26  */
27 class Buffer {
28   std::shared_ptr<unsigned char> buffer_;
29   MutableByteRange range_;
30 
delete_buffer(unsigned char * buffer)31   static void delete_buffer(unsigned char* buffer) {
32     delete[] buffer;
33   }
34 
35  public:
36   /// Construct an empty buffer that owns no data.
Buffer()37   explicit Buffer() {}
38 
39   /// Construct a `Buffer` that owns a new underlying buffer of size `size`.
Buffer(std::size_t size)40   explicit Buffer(std::size_t size)
41       : buffer_(new unsigned char[size], delete_buffer),
42         range_(buffer_.get(), buffer_.get() + size) {}
43 
Buffer(std::shared_ptr<unsigned char> buffer,MutableByteRange data)44   explicit Buffer(std::shared_ptr<unsigned char> buffer, MutableByteRange data)
45       : buffer_(buffer), range_(data) {}
46 
47   Buffer(Buffer&&) = default;
48   Buffer& operator=(Buffer&&) & = default;
49 
50   /**
51    * Splits the data into two pieces: [begin, begin + n), [begin + n, end).
52    * Their data both points into the same underlying buffer.
53    * Modifies the original `Buffer` to point to only [begin + n, end).
54    *
55    * @param n  The offset to split at.
56    * @returns  A buffer that owns the data [begin, begin + n).
57    */
splitAt(std::size_t n)58   Buffer splitAt(std::size_t n) {
59     auto firstPiece = range_.subpiece(0, n);
60     range_.advance(n);
61     return Buffer(buffer_, firstPiece);
62   }
63 
64   /// Modifies the buffer to point to the range [begin + n, end).
advance(std::size_t n)65   void advance(std::size_t n) {
66     range_.advance(n);
67   }
68 
69   /// Modifies the buffer to point to the range [begin, end - n).
subtract(std::size_t n)70   void subtract(std::size_t n) {
71     range_.subtract(n);
72   }
73 
74   /// Returns a read only `Range` pointing to the `Buffer`s data.
range()75   ByteRange range() const {
76     return range_;
77   }
78   /// Returns a mutable `Range` pointing to the `Buffer`s data.
range()79   MutableByteRange range() {
80     return range_;
81   }
82 
data()83   const unsigned char* data() const {
84     return range_.data();
85   }
86 
data()87   unsigned char* data() {
88     return range_.data();
89   }
90 
size()91   std::size_t size() const {
92     return range_.size();
93   }
94 
empty()95   bool empty() const {
96     return range_.empty();
97   }
98 };
99 }
100