xref: /aosp_15_r20/external/libbrillo/brillo/streams/memory_containers.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
7*1a96fba6SXin Li 
8*1a96fba6SXin Li #include <string>
9*1a96fba6SXin Li #include <utility>
10*1a96fba6SXin Li #include <vector>
11*1a96fba6SXin Li 
12*1a96fba6SXin Li #include <brillo/brillo_export.h>
13*1a96fba6SXin Li #include <brillo/errors/error.h>
14*1a96fba6SXin Li #include <brillo/streams/stream.h>
15*1a96fba6SXin Li 
16*1a96fba6SXin Li namespace brillo {
17*1a96fba6SXin Li namespace data_container {
18*1a96fba6SXin Li 
19*1a96fba6SXin Li // MemoryStream class relies on helper classes defined below to support data
20*1a96fba6SXin Li // storage in various types of containers.
21*1a96fba6SXin Li // A particular implementation of container type (e.g. based on raw memory
22*1a96fba6SXin Li // buffers, std::vector, std::string or others) need to implement the container
23*1a96fba6SXin Li // interface provided by data_container::DataContainerInterface.
24*1a96fba6SXin Li // Low-level functionality such as reading data from and writing data to the
25*1a96fba6SXin Li // container, getting and changing the buffer size, and so on, must be provided.
26*1a96fba6SXin Li // Not all methods must be provided. For example, for read-only containers, only
27*1a96fba6SXin Li // read operations can be provided.
28*1a96fba6SXin Li class BRILLO_EXPORT DataContainerInterface {
29*1a96fba6SXin Li  public:
30*1a96fba6SXin Li   DataContainerInterface() = default;
31*1a96fba6SXin Li   virtual ~DataContainerInterface() = default;
32*1a96fba6SXin Li 
33*1a96fba6SXin Li   // Read the data from the container into |buffer|. Up to |size_to_read| bytes
34*1a96fba6SXin Li   // must be read at a time. The container can return fewer bytes. The actual
35*1a96fba6SXin Li   // size of data read is provided in |size_read|.
36*1a96fba6SXin Li   // If the read operation fails, the function must return false and provide
37*1a96fba6SXin Li   // additional information about the error in |error| object.
38*1a96fba6SXin Li   virtual bool Read(void* buffer,
39*1a96fba6SXin Li                     size_t size_to_read,
40*1a96fba6SXin Li                     size_t offset,
41*1a96fba6SXin Li                     size_t* size_read,
42*1a96fba6SXin Li                     ErrorPtr* error) = 0;
43*1a96fba6SXin Li 
44*1a96fba6SXin Li   // Writes |size_to_write| bytes of data from |buffer| into the container.
45*1a96fba6SXin Li   // The container may accept fewer bytes of data. The actual size of data
46*1a96fba6SXin Li   // written is provided in |size_written|.
47*1a96fba6SXin Li   // If the read operation fails, the function must return false and provide
48*1a96fba6SXin Li   // additional information about the error in |error| object.
49*1a96fba6SXin Li   virtual bool Write(const void* buffer,
50*1a96fba6SXin Li                      size_t size_to_write,
51*1a96fba6SXin Li                      size_t offset,
52*1a96fba6SXin Li                      size_t* size_written,
53*1a96fba6SXin Li                      ErrorPtr* error) = 0;
54*1a96fba6SXin Li   // Resizes the container to the new size specified in |new_size|.
55*1a96fba6SXin Li   virtual bool Resize(size_t new_size, ErrorPtr* error) = 0;
56*1a96fba6SXin Li   // Returns the current size of the container.
57*1a96fba6SXin Li   virtual size_t GetSize() const = 0;
58*1a96fba6SXin Li   // Returns true if the container is read-only.
59*1a96fba6SXin Li   virtual bool IsReadOnly() const = 0;
60*1a96fba6SXin Li 
61*1a96fba6SXin Li  private:
62*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(DataContainerInterface);
63*1a96fba6SXin Li };
64*1a96fba6SXin Li 
65*1a96fba6SXin Li // ContiguousBufferBase is a helper base class for memory containers that
66*1a96fba6SXin Li // employ contiguous memory for all of their data. This class provides the
67*1a96fba6SXin Li // default implementation for Read() and Write() functions and requires the
68*1a96fba6SXin Li // implementations to provide GetBuffer() and/or ReadOnlyBuffer() functions.
69*1a96fba6SXin Li class BRILLO_EXPORT ContiguousBufferBase : public DataContainerInterface {
70*1a96fba6SXin Li  public:
71*1a96fba6SXin Li   ContiguousBufferBase() = default;
72*1a96fba6SXin Li   // Implementation of DataContainerInterface::Read().
73*1a96fba6SXin Li   bool Read(void* buffer,
74*1a96fba6SXin Li             size_t size_to_read,
75*1a96fba6SXin Li             size_t offset,
76*1a96fba6SXin Li             size_t* size_read,
77*1a96fba6SXin Li             ErrorPtr* error) override;
78*1a96fba6SXin Li   // Implementation of DataContainerInterface::Write().
79*1a96fba6SXin Li   bool Write(const void* buffer,
80*1a96fba6SXin Li              size_t size_to_write,
81*1a96fba6SXin Li              size_t offset,
82*1a96fba6SXin Li              size_t* size_written,
83*1a96fba6SXin Li              ErrorPtr* error) override;
84*1a96fba6SXin Li 
85*1a96fba6SXin Li   // Overload to provide the pointer to the read-only data for the container at
86*1a96fba6SXin Li   // the specified |offset|. In case of an error, this function must return
87*1a96fba6SXin Li   // nullptr and provide error details in |error| object if provided.
88*1a96fba6SXin Li   virtual const void* GetReadOnlyBuffer(size_t offset,
89*1a96fba6SXin Li                                         ErrorPtr* error) const = 0;
90*1a96fba6SXin Li   // Overload to provide the pointer to the read/write data for the container at
91*1a96fba6SXin Li   // the specified |offset|. In case of an error, this function must return
92*1a96fba6SXin Li   // nullptr and provide error details in |error| object if provided.
93*1a96fba6SXin Li   virtual void* GetBuffer(size_t offset, ErrorPtr* error) = 0;
94*1a96fba6SXin Li 
95*1a96fba6SXin Li  protected:
96*1a96fba6SXin Li   // Wrapper around memcpy which can be mocked out in tests.
97*1a96fba6SXin Li   virtual void CopyMemoryBlock(void* dest, const void* src, size_t size) const;
98*1a96fba6SXin Li 
99*1a96fba6SXin Li  private:
100*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ContiguousBufferBase);
101*1a96fba6SXin Li };
102*1a96fba6SXin Li 
103*1a96fba6SXin Li // ContiguousReadOnlyBufferBase is a specialization of ContiguousBufferBase for
104*1a96fba6SXin Li // read-only containers.
105*1a96fba6SXin Li class BRILLO_EXPORT ContiguousReadOnlyBufferBase : public ContiguousBufferBase {
106*1a96fba6SXin Li  public:
107*1a96fba6SXin Li   ContiguousReadOnlyBufferBase() = default;
108*1a96fba6SXin Li   // Fails with an error "operation_not_supported" (Stream is read-only) error.
109*1a96fba6SXin Li   bool Write(const void* buffer,
110*1a96fba6SXin Li              size_t size_to_write,
111*1a96fba6SXin Li              size_t offset,
112*1a96fba6SXin Li              size_t* size_written,
113*1a96fba6SXin Li              ErrorPtr* error) override;
114*1a96fba6SXin Li   // Fails with an error "operation_not_supported" (Stream is read-only) error.
115*1a96fba6SXin Li   bool Resize(size_t new_size, ErrorPtr* error) override;
116*1a96fba6SXin Li   // Fails with an error "operation_not_supported" (Stream is read-only) error.
IsReadOnly()117*1a96fba6SXin Li   bool IsReadOnly() const override { return true; }
118*1a96fba6SXin Li   // Fails with an error "operation_not_supported" (Stream is read-only) error.
119*1a96fba6SXin Li   void* GetBuffer(size_t offset, ErrorPtr* error) override;
120*1a96fba6SXin Li 
121*1a96fba6SXin Li  private:
122*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ContiguousReadOnlyBufferBase);
123*1a96fba6SXin Li };
124*1a96fba6SXin Li 
125*1a96fba6SXin Li // ReadOnlyBuffer implements a read-only container based on raw memory block.
126*1a96fba6SXin Li class BRILLO_EXPORT ReadOnlyBuffer : public ContiguousReadOnlyBufferBase {
127*1a96fba6SXin Li  public:
128*1a96fba6SXin Li   // Constructs the container based at the pointer to memory |buffer| and its
129*1a96fba6SXin Li   // |size|. The pointer to the memory must be valid throughout life-time of
130*1a96fba6SXin Li   // the stream using this container.
ReadOnlyBuffer(const void * buffer,size_t size)131*1a96fba6SXin Li   ReadOnlyBuffer(const void* buffer, size_t size)
132*1a96fba6SXin Li       : buffer_(buffer), size_(size) {}
133*1a96fba6SXin Li 
134*1a96fba6SXin Li   // Returns the pointer to data at |offset|.
GetReadOnlyBuffer(size_t offset,ErrorPtr *)135*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset,
136*1a96fba6SXin Li                                 ErrorPtr* /* error */) const override {
137*1a96fba6SXin Li     return reinterpret_cast<const uint8_t*>(buffer_) + offset;
138*1a96fba6SXin Li   }
139*1a96fba6SXin Li   // Returns the size of the container.
GetSize()140*1a96fba6SXin Li   size_t GetSize() const override { return size_; }
141*1a96fba6SXin Li 
142*1a96fba6SXin Li  private:
143*1a96fba6SXin Li   // Raw memory pointer to the data block and its size.
144*1a96fba6SXin Li   const void* buffer_;
145*1a96fba6SXin Li   size_t size_;
146*1a96fba6SXin Li 
147*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ReadOnlyBuffer);
148*1a96fba6SXin Li };
149*1a96fba6SXin Li 
150*1a96fba6SXin Li // VectorPtr<T> is a read/write container based on a vector<T> pointer.
151*1a96fba6SXin Li // This is a template class to allow usage of both vector<char> and
152*1a96fba6SXin Li // vector<uint8_t> without duplicating the implementation.
153*1a96fba6SXin Li template<typename T>
154*1a96fba6SXin Li class VectorPtr : public ContiguousBufferBase {
155*1a96fba6SXin Li  public:
156*1a96fba6SXin Li   static_assert(sizeof(T) == 1, "Only char/byte is supported");
VectorPtr(std::vector<T> * vector)157*1a96fba6SXin Li   explicit VectorPtr(std::vector<T>* vector) : vector_ptr_(vector) {}
158*1a96fba6SXin Li 
Resize(size_t new_size,ErrorPtr *)159*1a96fba6SXin Li   bool Resize(size_t new_size, ErrorPtr* /* error */) override {
160*1a96fba6SXin Li     vector_ptr_->resize(new_size);
161*1a96fba6SXin Li     return true;
162*1a96fba6SXin Li   }
GetSize()163*1a96fba6SXin Li   size_t GetSize() const override { return vector_ptr_->size(); }
IsReadOnly()164*1a96fba6SXin Li   bool IsReadOnly() const override { return false; }
GetReadOnlyBuffer(size_t offset,ErrorPtr *)165*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset,
166*1a96fba6SXin Li                                 ErrorPtr* /* error */) const override {
167*1a96fba6SXin Li     return reinterpret_cast<const uint8_t*>(vector_ptr_->data()) + offset;
168*1a96fba6SXin Li   }
GetBuffer(size_t offset,ErrorPtr *)169*1a96fba6SXin Li   void* GetBuffer(size_t offset, ErrorPtr* /* error */) override {
170*1a96fba6SXin Li     return reinterpret_cast<uint8_t*>(vector_ptr_->data()) + offset;
171*1a96fba6SXin Li   }
172*1a96fba6SXin Li 
173*1a96fba6SXin Li  protected:
174*1a96fba6SXin Li   std::vector<T>* vector_ptr_;
175*1a96fba6SXin Li 
176*1a96fba6SXin Li  private:
177*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(VectorPtr);
178*1a96fba6SXin Li };
179*1a96fba6SXin Li 
180*1a96fba6SXin Li // ReadOnlyVectorRef<T> is a read-only container based on a vector<T> reference.
181*1a96fba6SXin Li // This is a template class to allow usage of both vector<char> and
182*1a96fba6SXin Li // vector<uint8_t> without duplicating the implementation.
183*1a96fba6SXin Li template<typename T>
184*1a96fba6SXin Li class ReadOnlyVectorRef : public ContiguousReadOnlyBufferBase {
185*1a96fba6SXin Li  public:
186*1a96fba6SXin Li   static_assert(sizeof(T) == 1, "Only char/byte is supported");
ReadOnlyVectorRef(const std::vector<T> & vector)187*1a96fba6SXin Li   explicit ReadOnlyVectorRef(const std::vector<T>& vector)
188*1a96fba6SXin Li       : vector_ref_(vector) {}
189*1a96fba6SXin Li 
GetReadOnlyBuffer(size_t offset,ErrorPtr *)190*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset,
191*1a96fba6SXin Li                                 ErrorPtr* /* error */) const override {
192*1a96fba6SXin Li     return reinterpret_cast<const uint8_t*>(vector_ref_.data()) + offset;
193*1a96fba6SXin Li   }
GetSize()194*1a96fba6SXin Li   size_t GetSize() const override { return vector_ref_.size(); }
195*1a96fba6SXin Li 
196*1a96fba6SXin Li  protected:
197*1a96fba6SXin Li   const std::vector<T>& vector_ref_;
198*1a96fba6SXin Li 
199*1a96fba6SXin Li  private:
200*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ReadOnlyVectorRef);
201*1a96fba6SXin Li };
202*1a96fba6SXin Li 
203*1a96fba6SXin Li // ReadOnlyVectorCopy<T> is a read-only container based on a copy of vector<T>.
204*1a96fba6SXin Li // This container actually owns the data stored in the vector.
205*1a96fba6SXin Li // This is a template class to allow usage of both vector<char> and
206*1a96fba6SXin Li // vector<uint8_t> without duplicating the implementation.
207*1a96fba6SXin Li template<typename T>
208*1a96fba6SXin Li class ReadOnlyVectorCopy : public ContiguousReadOnlyBufferBase {
209*1a96fba6SXin Li  public:
210*1a96fba6SXin Li   static_assert(sizeof(T) == 1, "Only char/byte is supported");
ReadOnlyVectorCopy(std::vector<T> vector)211*1a96fba6SXin Li   explicit ReadOnlyVectorCopy(std::vector<T> vector)
212*1a96fba6SXin Li       : vector_copy_(std::move(vector)) {}
213*1a96fba6SXin Li 
ReadOnlyVectorCopy(const T * buffer,size_t size)214*1a96fba6SXin Li   ReadOnlyVectorCopy(const T* buffer, size_t size)
215*1a96fba6SXin Li       : vector_copy_(buffer, buffer + size) {}
216*1a96fba6SXin Li 
GetReadOnlyBuffer(size_t offset,ErrorPtr *)217*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset,
218*1a96fba6SXin Li                                 ErrorPtr* /* error */) const override {
219*1a96fba6SXin Li     return reinterpret_cast<const uint8_t*>(vector_copy_.data()) + offset;
220*1a96fba6SXin Li   }
GetSize()221*1a96fba6SXin Li   size_t GetSize() const override { return vector_copy_.size(); }
222*1a96fba6SXin Li 
223*1a96fba6SXin Li  protected:
224*1a96fba6SXin Li   std::vector<T> vector_copy_;
225*1a96fba6SXin Li 
226*1a96fba6SXin Li  private:
227*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ReadOnlyVectorCopy);
228*1a96fba6SXin Li };
229*1a96fba6SXin Li 
230*1a96fba6SXin Li // ByteBuffer is a read/write container that manages the data and underlying
231*1a96fba6SXin Li // storage.
232*1a96fba6SXin Li class BRILLO_EXPORT ByteBuffer : public VectorPtr<uint8_t> {
233*1a96fba6SXin Li  public:
234*1a96fba6SXin Li   explicit ByteBuffer(size_t reserve_size);
235*1a96fba6SXin Li   ~ByteBuffer() override;
236*1a96fba6SXin Li 
237*1a96fba6SXin Li  private:
238*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
239*1a96fba6SXin Li };
240*1a96fba6SXin Li 
241*1a96fba6SXin Li // StringPtr is a read/write container based on external std::string storage.
242*1a96fba6SXin Li class BRILLO_EXPORT StringPtr : public ContiguousBufferBase {
243*1a96fba6SXin Li  public:
244*1a96fba6SXin Li   explicit StringPtr(std::string* string);
245*1a96fba6SXin Li 
246*1a96fba6SXin Li   bool Resize(size_t new_size, ErrorPtr* error) override;
GetSize()247*1a96fba6SXin Li   size_t GetSize() const override { return string_ptr_->size(); }
IsReadOnly()248*1a96fba6SXin Li   bool IsReadOnly() const override { return false; }
249*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset, ErrorPtr* error) const override;
250*1a96fba6SXin Li   void* GetBuffer(size_t offset, ErrorPtr* error) override;
251*1a96fba6SXin Li 
252*1a96fba6SXin Li  protected:
253*1a96fba6SXin Li   std::string* string_ptr_;
254*1a96fba6SXin Li 
255*1a96fba6SXin Li  private:
256*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(StringPtr);
257*1a96fba6SXin Li };
258*1a96fba6SXin Li 
259*1a96fba6SXin Li // ReadOnlyStringRef is a read-only container based on external std::string.
260*1a96fba6SXin Li class BRILLO_EXPORT ReadOnlyStringRef : public ContiguousReadOnlyBufferBase {
261*1a96fba6SXin Li  public:
262*1a96fba6SXin Li   explicit ReadOnlyStringRef(const std::string& string);
263*1a96fba6SXin Li   const void* GetReadOnlyBuffer(size_t offset, ErrorPtr* error) const override;
GetSize()264*1a96fba6SXin Li   size_t GetSize() const override { return string_ref_.size(); }
265*1a96fba6SXin Li 
266*1a96fba6SXin Li  protected:
267*1a96fba6SXin Li   const std::string& string_ref_;
268*1a96fba6SXin Li 
269*1a96fba6SXin Li  private:
270*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ReadOnlyStringRef);
271*1a96fba6SXin Li };
272*1a96fba6SXin Li 
273*1a96fba6SXin Li // ReadOnlyStringCopy is a read-only container based on a copy of a std::string.
274*1a96fba6SXin Li // This container actually owns the data stored in the string.
275*1a96fba6SXin Li class BRILLO_EXPORT ReadOnlyStringCopy : public ReadOnlyStringRef {
276*1a96fba6SXin Li  public:
277*1a96fba6SXin Li   explicit ReadOnlyStringCopy(std::string string);
278*1a96fba6SXin Li 
279*1a96fba6SXin Li  protected:
280*1a96fba6SXin Li   std::string string_copy_;
281*1a96fba6SXin Li 
282*1a96fba6SXin Li  private:
283*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ReadOnlyStringCopy);
284*1a96fba6SXin Li };
285*1a96fba6SXin Li 
286*1a96fba6SXin Li }  // namespace data_container
287*1a96fba6SXin Li }  // namespace brillo
288*1a96fba6SXin Li 
289*1a96fba6SXin Li #endif  // LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
290