• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIBBRILLO_BRILLO_STREAMS_MEMORY_STREAM_H_
6 #define LIBBRILLO_BRILLO_STREAMS_MEMORY_STREAM_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include <base/macros.h>
14 #include <base/memory/weak_ptr.h>
15 #include <brillo/brillo_export.h>
16 #include <brillo/streams/memory_containers.h>
17 #include <brillo/streams/stream.h>
18 
19 namespace brillo {
20 
21 // MemoryStream is a brillo::Stream implementation for memory buffer. A number
22 // of memory containers are supported, such as raw memory pointers, data stored
23 // in std::vector and std::string.
24 // MemoryStream offers support for constant read-only memory buffers as well as
25 // for writable buffers that can grow when needed.
26 // A memory stream is created by using the OpenNNN and CreateNNN factory methods
27 // to construct a read-only and writable streams respectively.
28 // The following factory methods overloads are provided:
29 //  - OpenRef    - overloads for constructing the stream on a constant read-only
30 //                 memory buffer that is not owned by the stream. The buffer
31 //                 pointer/reference must remain valid throughout the lifetime
32 //                 of the constructed stream object. The benefit of this is that
33 //                 no data copying is performed and the underlying container can
34 //                 be manipulated outside of the stream.
35 //  - OpenCopyOf - overloads to construct a stream that copies the data from the
36 //                 memory buffer and maintains the copied data until the stream
37 //                 is closed or destroyed. This makes it possible to construct
38 //                 a read-only streams on transient data or for cases where
39 //                 it is not possible or necessary to maintain the lifetime of
40 //                 the underlying memory buffer.
41 //  - Create     - creates a new internal memory buffer that can be written to
42 //                 or read from using the stream I/O interface.
43 //  - CreateRef  - constructs a read/write stream on a reference of data
44 //                 container such as std::vector or std::string which must
45 //                 remain valid throughout the lifetime of the memory stream.
46 //                 The data already stored in the container is maintained,
47 //                 however the stream pointer is set to the beginning of the
48 //                 data when the stream is created.
49 //  - CreateRefForAppend - similar to CreateRef except that it automatically
50 //                 positions the stream seek pointer at the end of the data,
51 //                 which makes it possible to append more data to the existing
52 //                 container.
53 class BRILLO_EXPORT MemoryStream : public Stream {
54  public:
55   // == Construction ==========================================================
56 
57   // Constructs a read-only stream on a generic memory buffer. The data
58   // pointed to by |buffer| will be copied and owned by the stream object.
59   static StreamPtr OpenCopyOf(const void* buffer, size_t size, ErrorPtr* error);
60   static StreamPtr OpenCopyOf(std::string buffer, ErrorPtr* error);
61   static StreamPtr OpenCopyOf(const char* buffer, ErrorPtr* error);
62   // Only vectors of char and uint8_t are supported.
63   template<typename T>
OpenCopyOf(std::vector<T> buffer,ErrorPtr * error)64   inline static StreamPtr OpenCopyOf(std::vector<T> buffer, ErrorPtr* error) {
65     std::unique_ptr<data_container::ReadOnlyVectorCopy<T>> container{
66         new data_container::ReadOnlyVectorCopy<T>{std::move(buffer)}};
67     return CreateEx(std::move(container), 0, error);
68   }
69 
70   // Constructs a read-only stream on a generic memory buffer which is owned
71   // by the caller.
72   // ***WARNING***: The |buffer| pointer must be valid for as long as the stream
73   // object is alive. The stream does not do any additional lifetime management
74   // for the data pointed to by |buffer| and destroying that buffer before
75   // the stream is closed will lead to unexpected behavior.
76   static StreamPtr OpenRef(const void* buffer, size_t size, ErrorPtr* error);
77   static StreamPtr OpenRef(const std::string& buffer, ErrorPtr* error);
78   static StreamPtr OpenRef(const char* buffer, ErrorPtr* error);
79   // Only vectors of char and uint8_t are supported.
80   template<typename T>
OpenRef(const std::vector<T> & buffer,ErrorPtr * error)81   inline static StreamPtr OpenRef(const std::vector<T>& buffer,
82                                   ErrorPtr* error) {
83     std::unique_ptr<data_container::ReadOnlyVectorRef<T>> container{
84         new data_container::ReadOnlyVectorRef<T>{buffer}};
85     return CreateEx(std::move(container), 0, error);
86   }
87 
88   ///------------------------------------------------------------------------
89   // Creates new stream for reading/writing. This method creates an internal
90   // memory buffer and maintains it until the stream is closed. |reserve_size|
91   // parameter is a hint of the buffer size to pre-allocate. This does not
92   // affect the memory buffer reported size. The buffer can grow past that
93   // amount if needed.
94   static StreamPtr Create(size_t reserve_size, ErrorPtr* error);
95 
Create(ErrorPtr * error)96   inline static StreamPtr Create(ErrorPtr* error) { return Create(0, error); }
97 
98   // Creates new stream for reading/writing stored in a string. The string
99   // |buffer| must remain valid during the lifetime of the stream.
100   // The stream pointer will be at the beginning of the string and the string's
101   // content is preserved.
102   static StreamPtr CreateRef(std::string* buffer, ErrorPtr* error);
103 
104   // Creates new stream for reading/writing stored in a vector. The vector
105   // |buffer| must remain valid during the lifetime of the stream.
106   // The stream pointer will be at the beginning of the data and the vector's
107   // content is preserved.
108   // Only vectors of char and uint8_t are supported.
109   template<typename T>
CreateRef(std::vector<T> * buffer,ErrorPtr * error)110   static StreamPtr CreateRef(std::vector<T>* buffer, ErrorPtr* error) {
111     std::unique_ptr<data_container::VectorPtr<T>> container{
112         new data_container::VectorPtr<T>{buffer}};
113     return CreateEx(std::move(container), 0, error);
114   }
115 
116   // Creates new stream for reading/writing stored in a string. The string
117   // |buffer| must remain valid during the lifetime of the stream.
118   // The stream pointer will be at the end of the string and the string's
119   // content is preserved.
120   static StreamPtr CreateRefForAppend(std::string* buffer, ErrorPtr* error);
121 
122   // Creates new stream for reading/writing stored in a vector. The vector
123   // |buffer| must remain valid during the lifetime of the stream.
124   // The stream pointer will be at the end of the data and the vector's
125   // content is preserved.
126   // Only vectors of char and uint8_t are supported.
127   template<typename T>
CreateRefForAppend(std::vector<T> * buffer,ErrorPtr * error)128   static StreamPtr CreateRefForAppend(std::vector<T>* buffer, ErrorPtr* error) {
129     std::unique_ptr<data_container::VectorPtr<T>> container{
130         new data_container::VectorPtr<T>{buffer}};
131     return CreateEx(std::move(container), buffer->size() * sizeof(T), error);
132   }
133 
134   ///------------------------------------------------------------------------
135   // Generic stream creation on a data container. Takes an arbitrary |container|
136   // and constructs a stream using it. The container determines the traits of
137   // the stream (e.g. whether it is read-only, what operations are supported
138   // and so on). |stream_position| is the current stream pointer position at
139   // creation time.
140   static StreamPtr CreateEx(
141       std::unique_ptr<data_container::DataContainerInterface> container,
142       size_t stream_position,
143       ErrorPtr* error);
144 
145   // == Stream capabilities ===================================================
146   bool IsOpen() const override;
147   bool CanRead() const override;
148   bool CanWrite() const override;
149   bool CanSeek() const override;
150   bool CanGetSize() const override;
151 
152   // == Stream size operations ================================================
153   uint64_t GetSize() const override;
154   bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override;
155   uint64_t GetRemainingSize() const override;
156 
157   // == Seek operations =======================================================
158   uint64_t GetPosition() const override;
159   bool Seek(int64_t offset,
160             Whence whence,
161             uint64_t* new_position,
162             ErrorPtr* error) override;
163 
164   // == Read operations =======================================================
165   bool ReadNonBlocking(void* buffer,
166                        size_t size_to_read,
167                        size_t* size_read,
168                        bool* end_of_stream,
169                        ErrorPtr* error) override;
170 
171   // == Write operations ======================================================
172   bool WriteNonBlocking(const void* buffer,
173                         size_t size_to_write,
174                         size_t* size_written,
175                         ErrorPtr* error) override;
176 
177   // == Finalizing/closing streams  ===========================================
178   bool FlushBlocking(ErrorPtr* error) override;
179   bool CloseBlocking(ErrorPtr* error) override;
180 
181   // == Data availability monitoring ==========================================
182   bool WaitForData(AccessMode mode,
183                    const base::Callback<void(AccessMode)>& callback,
184                    ErrorPtr* error) override;
185 
186   bool WaitForDataBlocking(AccessMode in_mode,
187                            base::TimeDelta timeout,
188                            AccessMode* out_mode,
189                            ErrorPtr* error) override;
190 
191  private:
192   friend class MemoryStreamTest;
193 
194   // Private constructor used by MemoryStream::OpenNNNN() and
195   // MemoryStream::CreateNNNN() factory methods.
196   MemoryStream(
197       std::unique_ptr<data_container::DataContainerInterface> container,
198       size_t stream_position);
199 
200   // Checks if the stream has a valid container.
201   bool CheckContainer(ErrorPtr* error) const;
202 
203   // Data container the stream is using to write and/or read data.
204   std::unique_ptr<data_container::DataContainerInterface> container_;
205 
206   // The current stream pointer position.
207   size_t stream_position_{0};
208 
209   DISALLOW_COPY_AND_ASSIGN(MemoryStream);
210 };
211 
212 }  // namespace brillo
213 
214 #endif  // LIBBRILLO_BRILLO_STREAMS_MEMORY_STREAM_H_
215