73
// Default block size for Copying{In,Out}putStreamAdaptor.
74
static const int kDefaultBlockSize = 8192;
78
// ===================================================================
80
ArrayInputStream::ArrayInputStream(const void* data, int size,
82
: data_(reinterpret_cast<const uint8*>(data)),
84
block_size_(block_size > 0 ? block_size : size),
86
last_returned_size_(0) {
89
ArrayInputStream::~ArrayInputStream() {
92
bool ArrayInputStream::Next(const void** data, int* size) {
93
if (position_ < size_) {
94
last_returned_size_ = min(block_size_, size_ - position_);
95
*data = data_ + position_;
96
*size = last_returned_size_;
97
position_ += last_returned_size_;
100
// We're at the end of the array.
101
last_returned_size_ = 0; // Don't let caller back up.
106
void ArrayInputStream::BackUp(int count) {
107
GOOGLE_CHECK_GT(last_returned_size_, 0)
108
<< "BackUp() can only be called after a successful Next().";
109
GOOGLE_CHECK_LE(count, last_returned_size_);
110
GOOGLE_CHECK_GE(count, 0);
112
last_returned_size_ = 0; // Don't let caller back up further.
115
bool ArrayInputStream::Skip(int count) {
116
GOOGLE_CHECK_GE(count, 0);
117
last_returned_size_ = 0; // Don't let caller back up.
118
if (count > size_ - position_) {
127
int64 ArrayInputStream::ByteCount() const {
132
// ===================================================================
134
ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
135
: data_(reinterpret_cast<uint8*>(data)),
137
block_size_(block_size > 0 ? block_size : size),
139
last_returned_size_(0) {
142
ArrayOutputStream::~ArrayOutputStream() {
145
bool ArrayOutputStream::Next(void** data, int* size) {
146
if (position_ < size_) {
147
last_returned_size_ = min(block_size_, size_ - position_);
148
*data = data_ + position_;
149
*size = last_returned_size_;
150
position_ += last_returned_size_;
153
// We're at the end of the array.
154
last_returned_size_ = 0; // Don't let caller back up.
159
void ArrayOutputStream::BackUp(int count) {
160
GOOGLE_CHECK_GT(last_returned_size_, 0)
161
<< "BackUp() can only be called after a successful Next().";
162
GOOGLE_CHECK_LE(count, last_returned_size_);
163
GOOGLE_CHECK_GE(count, 0);
165
last_returned_size_ = 0; // Don't let caller back up further.
168
int64 ArrayOutputStream::ByteCount() const {
172
// ===================================================================
174
StringOutputStream::StringOutputStream(string* target)
178
StringOutputStream::~StringOutputStream() {
181
bool StringOutputStream::Next(void** data, int* size) {
182
int old_size = target_->size();
185
if (old_size < target_->capacity()) {
186
// Resize the string to match its capacity, since we can get away
187
// without a memory allocation this way.
188
STLStringResizeUninitialized(target_, target_->capacity());
190
// Size has reached capacity, so double the size. Also make sure
191
// that the new size is at least kMinimumSize.
192
STLStringResizeUninitialized(
195
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
198
*data = string_as_array(target_) + old_size;
199
*size = target_->size() - old_size;
203
void StringOutputStream::BackUp(int count) {
204
GOOGLE_CHECK_GE(count, 0);
205
GOOGLE_CHECK_LE(count, target_->size());
206
target_->resize(target_->size() - count);
209
int64 StringOutputStream::ByteCount() const {
210
return target_->size();
213
// ===================================================================
216
// ===================================================================
218
CopyingInputStream::~CopyingInputStream() {}
220
int CopyingInputStream::Skip(int count) {
223
while (skipped < count) {
224
int bytes = Read(junk, min(count - skipped,
225
implicit_cast<int>(sizeof(junk))));
227
// EOF or read error.
235
CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
236
CopyingInputStream* copying_stream, int block_size)
237
: copying_stream_(copying_stream),
238
owns_copying_stream_(false),
241
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
246
CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
247
if (owns_copying_stream_) {
248
delete copying_stream_;
252
bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
254
// Already failed on a previous read.
258
AllocateBufferIfNeeded();
260
if (backup_bytes_ > 0) {
261
// We have data left over from a previous BackUp(), so just return that.
262
*data = buffer_.get() + buffer_used_ - backup_bytes_;
263
*size = backup_bytes_;
268
// Read new data into the buffer.
269
buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
270
if (buffer_used_ <= 0) {
271
// EOF or read error. We don't need the buffer anymore.
272
if (buffer_used_ < 0) {
273
// Read error (not EOF).
279
position_ += buffer_used_;
281
*size = buffer_used_;
282
*data = buffer_.get();
286
void CopyingInputStreamAdaptor::BackUp(int count) {
287
GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
288
<< " BackUp() can only be called after Next().";
289
GOOGLE_CHECK_LE(count, buffer_used_)
290
<< " Can't back up over more bytes than were returned by the last call"
292
GOOGLE_CHECK_GE(count, 0)
293
<< " Parameter to BackUp() can't be negative.";
295
backup_bytes_ = count;
298
bool CopyingInputStreamAdaptor::Skip(int count) {
299
GOOGLE_CHECK_GE(count, 0);
302
// Already failed on a previous read.
306
// First skip any bytes left over from a previous BackUp().
307
if (backup_bytes_ >= count) {
308
// We have more data left over than we're trying to skip. Just chop it.
309
backup_bytes_ -= count;
313
count -= backup_bytes_;
316
int skipped = copying_stream_->Skip(count);
317
position_ += skipped;
318
return skipped == count;
321
int64 CopyingInputStreamAdaptor::ByteCount() const {
322
return position_ - backup_bytes_;
325
void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
326
if (buffer_.get() == NULL) {
327
buffer_.reset(new uint8[buffer_size_]);
331
void CopyingInputStreamAdaptor::FreeBuffer() {
332
GOOGLE_CHECK_EQ(backup_bytes_, 0);
337
// ===================================================================
339
CopyingOutputStream::~CopyingOutputStream() {}
341
CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
342
CopyingOutputStream* copying_stream, int block_size)
343
: copying_stream_(copying_stream),
344
owns_copying_stream_(false),
347
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
351
CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
353
if (owns_copying_stream_) {
354
delete copying_stream_;
358
bool CopyingOutputStreamAdaptor::Flush() {
359
return WriteBuffer();
362
bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
363
if (buffer_used_ == buffer_size_) {
364
if (!WriteBuffer()) return false;
367
AllocateBufferIfNeeded();
369
*data = buffer_.get() + buffer_used_;
370
*size = buffer_size_ - buffer_used_;
371
buffer_used_ = buffer_size_;
375
void CopyingOutputStreamAdaptor::BackUp(int count) {
376
GOOGLE_CHECK_GE(count, 0);
377
GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
378
<< " BackUp() can only be called after Next().";
379
GOOGLE_CHECK_LE(count, buffer_used_)
380
<< " Can't back up over more bytes than were returned by the last call"
383
buffer_used_ -= count;
386
int64 CopyingOutputStreamAdaptor::ByteCount() const {
387
return position_ + buffer_used_;
390
bool CopyingOutputStreamAdaptor::WriteBuffer() {
392
// Already failed on a previous write.
396
if (buffer_used_ == 0) return true;
398
if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
399
position_ += buffer_used_;
409
void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
410
if (buffer_ == NULL) {
411
buffer_.reset(new uint8[buffer_size_]);
415
void CopyingOutputStreamAdaptor::FreeBuffer() {
420
75
// ===================================================================