1 // Copyright (c) 2011 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.
7 // These memory-resident streams are used for serializing data into a sequential
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 #ifndef COURGETTE_STREAMS_H_
14 #define COURGETTE_STREAMS_H_
16 #include <stdio.h> // for FILE*
19 #include "base/basictypes.h"
20 #include "base/compiler_specific.h"
22 #include "courgette/memory_allocator.h"
23 #include "courgette/region.h"
31 // Maximum number of streams in a stream set.
32 static const unsigned int kMaxStreams
= 10;
34 // A SourceStream allows a region of memory to be scanned by a sequence of Read
35 // operations. The stream does not own the memory.
38 SourceStream() : start_(NULL
), end_(NULL
), current_(NULL
) {}
40 // Initializes the SourceStream to yield the bytes at |pointer|. The caller
41 // still owns the memory at |pointer| and should free the memory only after
42 // the last use of the stream.
43 void Init(const void* pointer
, size_t length
) {
44 start_
= static_cast<const uint8
*>(pointer
);
45 end_
= start_
+ length
;
49 // Initializes the SourceStream to yield the bytes in |region|. The caller
50 // still owns the memory at |region| and should free the memory only after
51 // the last use of the stream.
52 void Init(const Region
& region
) { Init(region
.start(), region
.length()); }
54 // Initializes the SourceStream to yield the bytes in |string|. The caller
55 // still owns the memory at |string| and should free the memory only after
56 // the last use of the stream.
57 void Init(const std::string
& string
) { Init(string
.c_str(), string
.size()); }
59 // Initializes the SourceStream to yield the bytes written to |sink|. |sink|
60 // still owns the memory, so needs to outlive |this|. |sink| should not be
61 // written to after |this| is initialized.
62 void Init(const SinkStream
& sink
);
64 // Returns number of bytes remaining to be read from stream.
65 size_t Remaining() const { return end_
- current_
; }
67 // Returns initial length of stream before any data consumed by reading.
68 size_t OriginalLength() const { return end_
- start_
; }
70 const uint8
* Buffer() const { return current_
; }
71 bool Empty() const { return current_
== end_
; }
73 // Copies bytes from stream to memory at |destination|. Returns 'false' if
74 // insufficient data to satisfy request.
75 bool Read(void* destination
, size_t byte_count
);
77 // Reads a varint formatted unsigned integer from stream. Returns 'false' if
78 // the read failed due to insufficient data or malformed Varint32.
79 bool ReadVarint32(uint32
* output_value
);
81 // Reads a varint formatted signed integer from stream. Returns 'false' if
82 // the read failed due to insufficient data or malformed Varint32.
83 bool ReadVarint32Signed(int32
* output_value
);
85 // Initializes |substream| to yield |length| bytes from |this| stream,
86 // starting at |offset| bytes from the current position. Returns 'false' if
87 // there are insufficient bytes in |this| stream.
88 bool ShareSubstream(size_t offset
, size_t length
, SourceStream
* substream
);
90 // Initializes |substream| to yield |length| bytes from |this| stream,
91 // starting at the current position. Returns 'false' if there are
92 // insufficient bytes in |this| stream.
93 bool ShareSubstream(size_t length
, SourceStream
* substream
) {
94 return ShareSubstream(0, length
, substream
);
97 // Reads |length| bytes from |this| stream. Initializes |substream| to yield
98 // the bytes. Returns 'false' if there are insufficient bytes in |this|
100 bool ReadSubstream(size_t length
, SourceStream
* substream
);
102 // Skips over bytes. Returns 'false' if insufficient data to satisfy request.
103 bool Skip(size_t byte_count
);
106 const uint8
* start_
; // Points to start of buffer.
107 const uint8
* end_
; // Points to first location after buffer.
108 const uint8
* current_
; // Points into buffer at current read location.
110 DISALLOW_COPY_AND_ASSIGN(SourceStream
);
113 // A SinkStream accumulates writes into a buffer that it owns. The stream is
114 // initially in an 'accumulating' state where writes are permitted. Accessing
115 // the buffer moves the stream into a 'locked' state where no more writes are
116 // permitted. The stream may also be in a 'retired' state where the buffer
117 // contents are no longer available.
123 // Appends |byte_count| bytes from |data| to the stream.
124 CheckBool
Write(const void* data
, size_t byte_count
) WARN_UNUSED_RESULT
;
126 // Appends the 'varint32' encoding of |value| to the stream.
127 CheckBool
WriteVarint32(uint32 value
) WARN_UNUSED_RESULT
;
129 // Appends the 'varint32' encoding of |value| to the stream.
130 CheckBool
WriteVarint32Signed(int32 value
) WARN_UNUSED_RESULT
;
132 // Appends the 'varint32' encoding of |value| to the stream.
133 // On platforms where sizeof(size_t) != sizeof(int32), do a safety check.
134 CheckBool
WriteSizeVarint32(size_t value
) WARN_UNUSED_RESULT
;
136 // Contents of |other| are appended to |this| stream. The |other| stream
138 CheckBool
Append(SinkStream
* other
) WARN_UNUSED_RESULT
;
140 // Returns the number of bytes in this SinkStream
141 size_t Length() const { return buffer_
.size(); }
143 // Returns a pointer to contiguously allocated Length() bytes in the stream.
144 // Writing to the stream invalidates the pointer. The SinkStream continues to
146 const uint8
* Buffer() const {
147 return reinterpret_cast<const uint8
*>(buffer_
.data());
150 // Hints that the stream will grow by an additional |length| bytes.
151 // Caller must be prepared to handle memory allocation problems.
152 CheckBool
Reserve(size_t length
) WARN_UNUSED_RESULT
{
153 return buffer_
.reserve(length
+ buffer_
.size());
156 // Finished with this stream and any storage it has.
160 NoThrowBuffer
<char> buffer_
;
162 DISALLOW_COPY_AND_ASSIGN(SinkStream
);
165 // A SourceStreamSet is a set of SourceStreams.
166 class SourceStreamSet
{
171 // Initializes the SourceStreamSet with the stream data in memory at |source|.
172 // The caller continues to own the memory and should not modify or free the
173 // memory until the SourceStreamSet destructor has been called.
175 // The layout of the streams are as written by SinkStreamSet::CopyTo.
176 // Init returns 'false' if the layout is inconsistent with |byte_count|.
177 bool Init(const void* source
, size_t byte_count
);
179 // Initializes |this| from |source|. The caller continues to own the memory
180 // because it continues to be owned by |source|.
181 bool Init(SourceStream
* source
);
183 // Returns a pointer to one of the sub-streams.
184 SourceStream
* stream(size_t id
) { return id
< count_
? &streams_
[id
] : NULL
; }
186 // Initialize |set| from |this|.
187 bool ReadSet(SourceStreamSet
* set
);
189 // Returns 'true' if all streams are completely consumed.
194 SourceStream streams_
[kMaxStreams
];
196 DISALLOW_COPY_AND_ASSIGN(SourceStreamSet
);
199 // A SinkStreamSet is a set of SinkStreams. Data is collected by writing to the
200 // component streams. When data collection is complete, it is destructively
201 // transferred, either by flattening into one stream (CopyTo), or transfering
202 // data pairwise into another SinkStreamSet by calling that SinkStreamSet's
204 class SinkStreamSet
{
209 // Initializes the SinkStreamSet to have |stream_index_limit| streams. Must
210 // be <= kMaxStreams. If Init is not called the default is has kMaxStream.
211 void Init(size_t stream_index_limit
);
213 // Returns a pointer to a substream.
214 SinkStream
* stream(size_t id
) { return id
< count_
? &streams_
[id
] : NULL
; }
216 // CopyTo serializes the streams in this SinkStreamSet into a single target
217 // stream. The serialized format may be re-read by initializing a
218 // SourceStreamSet with a buffer containing the data.
219 CheckBool
CopyTo(SinkStream
* combined_stream
) WARN_UNUSED_RESULT
;
221 // Writes the streams of |set| into the corresponding streams of |this|.
222 // Stream zero first has some metadata written to it. |set| becomes retired.
223 // Partner to SourceStreamSet::ReadSet.
224 CheckBool
WriteSet(SinkStreamSet
* set
) WARN_UNUSED_RESULT
;
227 CheckBool
CopyHeaderTo(SinkStream
* stream
) WARN_UNUSED_RESULT
;
230 SinkStream streams_
[kMaxStreams
];
232 DISALLOW_COPY_AND_ASSIGN(SinkStreamSet
);
236 #endif // COURGETTE_STREAMS_H_