git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / pzstd / utils / Buffer.h
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
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
31   static void delete_buffer(unsigned char* buffer) {
32     delete[] buffer;
33   }
34
35  public:
36   /// Construct an empty buffer that owns no data.
37   explicit Buffer() {}
38
39   /// Construct a `Buffer` that owns a new underlying buffer of size `size`.
40   explicit Buffer(std::size_t size)
41       : buffer_(new unsigned char[size], delete_buffer),
42         range_(buffer_.get(), buffer_.get() + size) {}
43
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    */
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).
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).
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.
75   ByteRange range() const {
76     return range_;
77   }
78   /// Returns a mutable `Range` pointing to the `Buffer`s data.
79   MutableByteRange range() {
80     return range_;
81   }
82
83   const unsigned char* data() const {
84     return range_.data();
85   }
86
87   unsigned char* data() {
88     return range_.data();
89   }
90
91   std::size_t size() const {
92     return range_.size();
93   }
94
95   bool empty() const {
96     return range_.empty();
97   }
98 };
99 }