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