[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / streams.h
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Streams classes.
6 //
7 // These memory-resident streams are used for serializing data into a sequential
8 // region of memory.
9 // Streams are divided into SourceStreams for reading and SinkStreams for
10 // writing.  Streams are aggregated into Sets which allows several streams to be
11 // used at once.  Example: we can write A1, B1, A2, B2 but achieve the memory
12 // layout A1 A2 B1 B2 by writing 'A's to one stream and 'B's to another.
13
14 #ifndef COURGETTE_STREAMS_H_
15 #define COURGETTE_STREAMS_H_
16
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <stdio.h>  // for FILE*
20 #include <string>
21
22 #include "courgette/memory_allocator.h"
23 #include "courgette/region.h"
24
25
26 namespace courgette {
27
28 class SourceStream;
29 class SinkStream;
30
31 // Maximum number of streams in a stream set.
32 static const unsigned int kMaxStreams = 10;
33
34 // A simple interface for reading binary data.
35 class BasicBuffer {
36  public:
37   BasicBuffer() {}
38   virtual ~BasicBuffer() {}
39   virtual const uint8_t* data() const = 0;
40   virtual size_t length() const = 0;
41 };
42
43 // A SourceStream allows a region of memory to be scanned by a sequence of Read
44 // operations.  The stream does not own the memory.
45 class SourceStream {
46  public:
47   SourceStream() : start_(nullptr), end_(nullptr), current_(nullptr) {}
48
49   SourceStream(const SourceStream&) = delete;
50   SourceStream& operator=(const SourceStream&) = delete;
51
52   // Initializes the SourceStream to yield the bytes at |pointer|.  The caller
53   // still owns the memory at |pointer| and should free the memory only after
54   // the last use of the stream.
55   void Init(const void* pointer, size_t length) {
56     start_ = static_cast<const uint8_t*>(pointer);
57     end_ = start_ + length;
58     current_ = start_;
59   }
60
61   // Initializes the SourceStream to yield the bytes in |region|.  The caller
62   // still owns the memory at |region| and should free the memory only after
63   // the last use of the stream.
64   void Init(const Region& region) { Init(region.start(), region.length()); }
65
66   // Initializes the SourceStream to yield the bytes in |string|.  The caller
67   // still owns the memory at |string| and should free the memory only after
68   // the last use of the stream.
69   void Init(const std::string& string) { Init(string.c_str(), string.size()); }
70
71   // Initializes the SourceStream to yield the bytes written to |sink|. |sink|
72   // still owns the memory, so needs to outlive |this|.  |sink| should not be
73   // written to after |this| is initialized.
74   void Init(const SinkStream& sink);
75
76   // Returns number of bytes remaining to be read from stream.
77   size_t Remaining() const { return end_ - current_; }
78
79   // Returns initial length of stream before any data consumed by reading.
80   size_t OriginalLength() const { return end_ - start_; }
81
82   const uint8_t* Buffer() const { return current_; }
83   bool Empty() const { return current_ == end_; }
84
85   // Copies bytes from stream to memory at |destination|.  Returns 'false' if
86   // insufficient data to satisfy request.
87   bool Read(void* destination, size_t byte_count);
88
89   // Reads a varint formatted unsigned integer from stream.  Returns 'false' if
90   // the read failed due to insufficient data or malformed Varint32.
91   bool ReadVarint32(uint32_t* output_value);
92
93   // Reads a varint formatted signed integer from stream.  Returns 'false' if
94   // the read failed due to insufficient data or malformed Varint32.
95   bool ReadVarint32Signed(int32_t* output_value);
96
97   // Initializes |substream| to yield |length| bytes from |this| stream,
98   // starting at |offset| bytes from the current position.  Returns 'false' if
99   // there are insufficient bytes in |this| stream.
100   bool ShareSubstream(size_t offset, size_t length, SourceStream* substream);
101
102   // Initializes |substream| to yield |length| bytes from |this| stream,
103   // starting at the current position.  Returns 'false' if there are
104   // insufficient bytes in |this| stream.
105   bool ShareSubstream(size_t length, SourceStream* substream) {
106     return ShareSubstream(0, length, substream);
107   }
108
109   // Reads |length| bytes from |this| stream.  Initializes |substream| to yield
110   // the bytes.  Returns 'false' if there are insufficient bytes in |this|
111   // stream.
112   bool ReadSubstream(size_t length, SourceStream* substream);
113
114   // Skips over bytes.  Returns 'false' if insufficient data to satisfy request.
115   bool Skip(size_t byte_count);
116
117  private:
118   const uint8_t* start_;    // Points to start of buffer.
119   const uint8_t* end_;      // Points to first location after buffer.
120   const uint8_t* current_;  // Points into buffer at current read location.
121 };
122
123 // A SinkStream accumulates writes into a buffer that it owns.  The stream is
124 // initially in an 'accumulating' state where writes are permitted.  Accessing
125 // the buffer moves the stream into a 'locked' state where no more writes are
126 // permitted.  The stream may also be in a 'retired' state where the buffer
127 // contents are no longer available.
128 class SinkStream {
129  public:
130   SinkStream() {}
131
132   SinkStream(const SinkStream&) = delete;
133   SinkStream& operator=(const SinkStream&) = delete;
134
135   ~SinkStream() {}
136
137   // Appends |byte_count| bytes from |data| to the stream.
138   [[nodiscard]] CheckBool Write(const void* data, size_t byte_count);
139
140   // Appends the 'varint32' encoding of |value| to the stream.
141   [[nodiscard]] CheckBool WriteVarint32(uint32_t value);
142
143   // Appends the 'varint32' encoding of |value| to the stream.
144   [[nodiscard]] CheckBool WriteVarint32Signed(int32_t value);
145
146   // Appends the 'varint32' encoding of |value| to the stream.
147   // On platforms where sizeof(size_t) != sizeof(int32_t), do a safety check.
148   [[nodiscard]] CheckBool WriteSizeVarint32(size_t value);
149
150   // Contents of |other| are appended to |this| stream.  The |other| stream
151   // becomes retired.
152   [[nodiscard]] CheckBool Append(SinkStream* other);
153
154   // Returns the number of bytes in this SinkStream
155   size_t Length() const { return buffer_.size(); }
156
157   // Returns a pointer to contiguously allocated Length() bytes in the stream.
158   // Writing to the stream invalidates the pointer.  The SinkStream continues to
159   // own the memory.
160   const uint8_t* Buffer() const {
161     return reinterpret_cast<const uint8_t*>(buffer_.data());
162   }
163
164   // Hints that the stream will grow by an additional |length| bytes.
165   // Caller must be prepared to handle memory allocation problems.
166   [[nodiscard]] CheckBool Reserve(size_t length) {
167     return buffer_.reserve(length + buffer_.size());
168   }
169
170   // Finished with this stream and any storage it has.
171   void Retire();
172
173  private:
174   NoThrowBuffer<char> buffer_;
175 };
176
177 // A SourceStreamSet is a set of SourceStreams.
178 class SourceStreamSet {
179  public:
180   SourceStreamSet();
181
182   SourceStreamSet(const SourceStreamSet&) = delete;
183   SourceStreamSet& operator=(const SourceStreamSet&) = delete;
184
185   ~SourceStreamSet();
186
187   // Initializes the SourceStreamSet with the stream data in memory at |source|.
188   // The caller continues to own the memory and should not modify or free the
189   // memory until the SourceStreamSet destructor has been called.
190   //
191   // The layout of the streams are as written by SinkStreamSet::CopyTo.
192   // Init returns 'false' if the layout is inconsistent with |byte_count|.
193   bool Init(const void* source, size_t byte_count);
194
195   // Initializes |this| from |source|.  The caller continues to own the memory
196   // because it continues to be owned by |source|.
197   bool Init(SourceStream* source);
198
199   // Returns a pointer to one of the sub-streams.
200   SourceStream* stream(size_t id) {
201     return id < count_ ? &streams_[id] : nullptr;
202   }
203
204   // Initialize |set| from |this|.
205   bool ReadSet(SourceStreamSet* set);
206
207   // Returns 'true' if all streams are completely consumed.
208   bool Empty() const;
209
210  private:
211   size_t count_;
212   SourceStream streams_[kMaxStreams];
213 };
214
215 // A SinkStreamSet is a set of SinkStreams.  Data is collected by writing to the
216 // component streams.  When data collection is complete, it is destructively
217 // transferred, either by flattening into one stream (CopyTo), or transfering
218 // data pairwise into another SinkStreamSet by calling that SinkStreamSet's
219 // WriteSet method.
220 class SinkStreamSet {
221  public:
222   SinkStreamSet();
223
224   SinkStreamSet(const SinkStreamSet&) = delete;
225   SinkStreamSet& operator=(const SinkStreamSet&) = delete;
226
227   ~SinkStreamSet();
228
229   // Initializes the SinkStreamSet to have |stream_index_limit| streams.  Must
230   // be <= kMaxStreams.  If Init is not called the default is has kMaxStream.
231   void Init(size_t stream_index_limit);
232
233   // Returns a pointer to a substream.
234   SinkStream* stream(size_t id) {
235     return id < count_ ? &streams_[id] : nullptr;
236   }
237
238   // CopyTo serializes the streams in this SinkStreamSet into a single target
239   // stream.  The serialized format may be re-read by initializing a
240   // SourceStreamSet with a buffer containing the data.
241   [[nodiscard]] CheckBool CopyTo(SinkStream* combined_stream);
242
243   // Writes the streams of |set| into the corresponding streams of |this|.
244   // Stream zero first has some metadata written to it.  |set| becomes retired.
245   // Partner to SourceStreamSet::ReadSet.
246   [[nodiscard]] CheckBool WriteSet(SinkStreamSet* set);
247
248  private:
249   [[nodiscard]] CheckBool CopyHeaderTo(SinkStream* stream);
250
251   size_t count_;
252   SinkStream streams_[kMaxStreams];
253 };
254
255 }  // namespace courgette
256
257 #endif  // COURGETTE_STREAMS_H_