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 "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 |