OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium 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 // Streams classes. | |
6 // | |
7 // These memory-resident streams are used for serialzing 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 achive the memory | |
12 // layout A1 A2 B1 B2 by writing 'A's to one stream and 'B's to another. | |
13 #ifndef COURGETTE_STREAMS_H_ | |
14 #define COURGETTE_STREAMS_H_ | |
15 | |
16 #include <stdio.h> // for FILE* | |
17 #include <string> | |
18 | |
19 #include "base/basictypes.h" | |
20 | |
21 #include "third_party/courgette/region.h" | |
22 | |
23 namespace courgette { | |
24 | |
25 class SourceStream; | |
26 class SinkStream; | |
27 | |
28 // Maximum number of streams in a stream set. | |
29 static const unsigned int kMaxStreams = 10; | |
30 | |
31 // A SourceStream allows a region of memory to be scanned by a sequence of Read | |
32 // operations. The stream does not own the memory. | |
33 class SourceStream { | |
34 public: | |
35 SourceStream() : start_(NULL), end_(NULL), current_(NULL) {} | |
36 | |
37 // Initializes the SourceStream to yield the bytes at |pointer|. The caller | |
38 // still owns the memory at |pointer| and should free the memory only after | |
39 // the last use of the stream. | |
40 void Init(const void* pointer, size_t length) { | |
41 start_ = static_cast<const uint8*>(pointer); | |
42 end_ = start_ + length; | |
43 current_ = start_; | |
44 } | |
45 | |
46 // Initializes the SourceStream to yield the bytes in |region|. The caller | |
47 // still owns the memory at |region| and should free the memory only after | |
48 // the last use of the stream. | |
49 void Init(const Region& region) { Init(region.start(), region.length()); } | |
50 | |
51 // Initializes the SourceStream to yield the bytes in |string|. The caller | |
52 // still owns the memory at |string| and should free the memory only after | |
53 // the last use of the stream. | |
54 void Init(const std::string& string) { Init(string.c_str(), string.size()); } | |
55 | |
56 // Initializes the SourceStream to yield the bytes written to |sink|. |sink| | |
57 // still owns the memory, so needs to outlive |this|. |sink| should not be | |
58 // written to after |this| is initialized. | |
59 void Init(const SinkStream& sink); | |
60 | |
61 // Returns number of bytes remaining to be read from stream. | |
62 size_t Remaining() const { return end_ - current_; } | |
63 | |
64 // Returns initial length of stream before any data consumed by reading. | |
65 size_t OriginalLength() const { return end_ - start_; } | |
66 | |
67 const uint8* Buffer() const { return current_; } | |
68 bool Empty() const { return current_ == end_; } | |
69 | |
70 // Copies bytes from stream to memory at |destination|. Returns 'false' if | |
71 // insufficient data to satisfy request. | |
72 bool Read(void* destination, size_t byte_count); | |
73 | |
74 // Reads a varint formatted unsigned integer from stream. Returns 'false' if | |
75 // the read failed due to insufficient data or malformed Varint32. | |
76 bool ReadVarint32(uint32* output_value); | |
77 | |
78 // Reads a varint formatted signed integer from stream. Returns 'false' if | |
79 // the read failed due to insufficient data or malformed Varint32. | |
80 bool ReadVarint32Signed(int32* output_value); | |
81 | |
82 // Initializes |substream| to yield |length| bytes from |this| stream, | |
83 // starting at |offset| bytes from the current position. Returns 'false' if | |
84 // there are insufficient bytes in |this| stream. | |
85 bool ShareSubstream(size_t offset, size_t length, SourceStream* substream); | |
86 | |
87 // Initializes |substream| to yield |length| bytes from |this| stream, | |
88 // starting at the current position. Returns 'false' if there are | |
89 // insufficient bytes in |this| stream. | |
90 bool ShareSubstream(size_t length, SourceStream* substream) { | |
91 return ShareSubstream(0, length, substream); | |
92 } | |
93 | |
94 // Reads |length| bytes from |this| stream. Initializes |substream| to yield | |
95 // the bytes. Returns 'false' if there are insufficient bytes in |this| | |
96 // stream. | |
97 bool ReadSubstream(size_t length, SourceStream* substream); | |
98 | |
99 // Skips over bytes. Returns 'false' if insufficient data to satisfy request. | |
100 bool Skip(size_t byte_count); | |
101 | |
102 private: | |
103 const uint8* start_; // Points to start of buffer. | |
104 const uint8* end_; // Points to first location after buffer. | |
105 const uint8* current_; // Points into buffer at current read location. | |
106 | |
107 DISALLOW_COPY_AND_ASSIGN(SourceStream); | |
108 }; | |
109 | |
110 // A SinkStream accumulates writes into a buffer that it owns. The stream is | |
111 // initialy in an 'accumulating' state where writes are permitted. Accessing | |
112 // the buffer moves the stream into a 'locked' state where no more writes are | |
113 // permitted. The stream may also be in a 'retired' state where the buffer | |
114 // contents are no longer available. | |
115 class SinkStream { | |
116 public: | |
117 SinkStream() {} | |
118 ~SinkStream() {} | |
119 | |
120 // Appends |byte_count| bytes from |data| to the stream. | |
121 void Write(const void* data, size_t byte_count); | |
122 | |
123 // Appends the 'varint32' encoding of |value| to the stream. | |
124 void WriteVarint32(uint32 value); | |
125 | |
126 // Appends the 'varint32' encoding of |value| to the stream. | |
127 void WriteVarint32Signed(int32 value); | |
128 | |
129 // Contents of |other| are appended to |this| stream. The |other| stream | |
130 // becomes retired. | |
131 void Append(SinkStream* other); | |
132 | |
133 // Returns the number of bytes in this SinkStream | |
134 size_t Length() const { return buffer_.size(); } | |
135 | |
136 // Returns a pointer to contiguously allocated Length() bytes in the stream. | |
137 // Writing to the stream invalidates the pointer. The SinkStream continues to | |
138 // own the memory. | |
139 const uint8* Buffer() const { | |
140 return reinterpret_cast<const uint8*>(buffer_.c_str()); | |
141 } | |
142 | |
143 // Hints that the stream will grow by an additional |length| bytes. | |
144 void Reserve(size_t length) { buffer_.reserve(length + buffer_.length()); } | |
145 | |
146 private: | |
147 std::string buffer_; // Use a string to manage the stream's memory. | |
148 | |
149 DISALLOW_COPY_AND_ASSIGN(SinkStream); | |
150 }; | |
151 | |
152 // A SourceStreamSet is a set of SourceStreams. | |
153 class SourceStreamSet { | |
154 public: | |
155 SourceStreamSet(); | |
156 ~SourceStreamSet(); | |
157 | |
158 // Initializes the SourceStreamSet with the stream data in memory at |source|. | |
159 // The caller continues to own the memory and should not modify or free the | |
160 // memory until the SourceStreamSet destructor has been called. | |
161 // | |
162 // The layout of the streams are as written by SinkStreamSet::CopyTo. | |
163 // Init returns 'false' if the layout is inconsistent with |byte_count|. | |
164 bool Init(const void* source, size_t byte_count); | |
165 | |
166 // Initializes |this| from |source|. The caller continues to own the memory | |
167 // because it continues to be owned by |source|. | |
168 bool Init(SourceStream* source); | |
169 | |
170 // Returns a pointer to one of the sub-streams. | |
171 SourceStream* stream(size_t id) { return id < count_ ? &streams_[id] : NULL; } | |
172 | |
173 // Initialize |set| from |this|. | |
174 bool ReadSet(SourceStreamSet* set); | |
175 | |
176 // Returns 'true' if all streams are completely consumed. | |
177 bool Empty() const; | |
178 | |
179 private: | |
180 size_t count_; | |
181 SourceStream streams_[kMaxStreams]; | |
182 | |
183 DISALLOW_COPY_AND_ASSIGN(SourceStreamSet); | |
184 }; | |
185 | |
186 class SinkStreamSet { | |
187 public: | |
188 SinkStreamSet(); | |
189 ~SinkStreamSet(); | |
190 | |
191 // Initializes the SinkStreamSet to have |stream_index_limit| streams. Must | |
192 // be <= kMaxStreams. If Init is not called the default is has kMaxStream. | |
193 void Init(size_t stream_index_limit); | |
194 | |
195 // Returns a pointer to a substream. | |
196 SinkStream* stream(size_t id) { return id < count_ ? &streams_[id] : NULL; } | |
197 | |
198 // CopyTo serializes the streams in the SinkStreamSet into a single target | |
199 // stream or file. The serialized format may be re-read by initializing a | |
200 // SourceStreamSet with a buffer containing the data. | |
201 bool CopyTo(SinkStream* combined_stream); | |
202 bool CopyToFile(FILE* file); | |
203 bool CopyToFileDescriptor(int file_descriptor); | |
204 | |
205 // Writes the streams of |set| into the corresponding streams of |this|. | |
206 // Stream zero first has some metadata written to it. |set| becomes retired. | |
207 // Partner to SourceStreamSet::ReadSet. | |
208 bool WriteSet(SinkStreamSet* set); | |
209 | |
210 private: | |
211 void CopyHeaderTo(SinkStream* stream); | |
212 | |
213 size_t count_; | |
214 SinkStream streams_[kMaxStreams]; | |
215 | |
216 DISALLOW_COPY_AND_ASSIGN(SinkStreamSet); | |
217 }; | |
218 | |
219 } // namespace | |
220 #endif // COURGETTE_STREAMS_H_ | |
OLD | NEW |