1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/stl_util-inl.h>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace io {
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Default block size for Copying{In,Out}putStreamAdaptor.
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kDefaultBlockSize = 8192;
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleArrayInputStream::ArrayInputStream(const void* data, int size,
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                   int block_size)
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : data_(reinterpret_cast<const uint8*>(data)),
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    size_(size),
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    block_size_(block_size > 0 ? block_size : size),
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_(0),
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_(0) {
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleArrayInputStream::~ArrayInputStream() {
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ArrayInputStream::Next(const void** data, int* size) {
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (position_ < size_) {
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_ = min(block_size_, size_ - position_);
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *data = data_ + position_;
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *size = last_returned_size_;
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_ += last_returned_size_;
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We're at the end of the array.
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_ = 0;   // Don't let caller back up.
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ArrayInputStream::BackUp(int count) {
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GT(last_returned_size_, 0)
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      << "BackUp() can only be called after a successful Next().";
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_LE(count, last_returned_size_);
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  position_ -= count;
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  last_returned_size_ = 0;  // Don't let caller back up further.
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ArrayInputStream::Skip(int count) {
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  last_returned_size_ = 0;   // Don't let caller back up.
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (count > size_ - position_) {
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_ = size_;
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_ += count;
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 ArrayInputStream::ByteCount() const {
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return position_;
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : data_(reinterpret_cast<uint8*>(data)),
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    size_(size),
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    block_size_(block_size > 0 ? block_size : size),
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_(0),
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_(0) {
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleArrayOutputStream::~ArrayOutputStream() {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ArrayOutputStream::Next(void** data, int* size) {
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (position_ < size_) {
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_ = min(block_size_, size_ - position_);
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *data = data_ + position_;
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *size = last_returned_size_;
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_ += last_returned_size_;
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We're at the end of the array.
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_returned_size_ = 0;   // Don't let caller back up.
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ArrayOutputStream::BackUp(int count) {
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GT(last_returned_size_, 0)
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      << "BackUp() can only be called after a successful Next().";
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_LE(count, last_returned_size_);
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  position_ -= count;
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  last_returned_size_ = 0;  // Don't let caller back up further.
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 ArrayOutputStream::ByteCount() const {
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return position_;
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleStringOutputStream::StringOutputStream(string* target)
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : target_(target) {
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleStringOutputStream::~StringOutputStream() {
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool StringOutputStream::Next(void** data, int* size) {
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int old_size = target_->size();
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Grow the string.
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (old_size < target_->capacity()) {
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Resize the string to match its capacity, since we can get away
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // without a memory allocation this way.
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    STLStringResizeUninitialized(target_, target_->capacity());
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Size has reached capacity, so double the size.  Also make sure
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // that the new size is at least kMinimumSize.
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    STLStringResizeUninitialized(
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      target_,
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      max(old_size * 2,
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *data = string_as_array(target_) + old_size;
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *size = target_->size() - old_size;
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid StringOutputStream::BackUp(int count) {
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_LE(count, target_->size());
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  target_->resize(target_->size() - count);
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 StringOutputStream::ByteCount() const {
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return target_->size();
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingInputStream::~CopyingInputStream() {}
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CopyingInputStream::Skip(int count) {
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  char junk[4096];
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int skipped = 0;
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (skipped < count) {
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int bytes = Read(junk, min(count - skipped,
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                               implicit_cast<int>(sizeof(junk))));
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bytes <= 0) {
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // EOF or read error.
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return skipped;
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    skipped += bytes;
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return skipped;
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    CopyingInputStream* copying_stream, int block_size)
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : copying_stream_(copying_stream),
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    owns_copying_stream_(false),
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    failed_(false),
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_(0),
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_used_(0),
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    backup_bytes_(0) {
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (owns_copying_stream_) {
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    delete copying_stream_;
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (failed_) {
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Already failed on a previous read.
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  AllocateBufferIfNeeded();
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (backup_bytes_ > 0) {
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We have data left over from a previous BackUp(), so just return that.
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *data = buffer_.get() + buffer_used_ - backup_bytes_;
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *size = backup_bytes_;
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    backup_bytes_ = 0;
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Read new data into the buffer.
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_used_ <= 0) {
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // EOF or read error.  We don't need the buffer anymore.
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (buffer_used_ < 0) {
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Read error (not EOF).
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      failed_ = true;
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FreeBuffer();
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  position_ += buffer_used_;
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *size = buffer_used_;
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *data = buffer_.get();
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingInputStreamAdaptor::BackUp(int count) {
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    << " BackUp() can only be called after Next().";
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_LE(count, buffer_used_)
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    << " Can't back up over more bytes than were returned by the last call"
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       " to Next().";
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0)
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    << " Parameter to BackUp() can't be negative.";
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  backup_bytes_ = count;
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CopyingInputStreamAdaptor::Skip(int count) {
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (failed_) {
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Already failed on a previous read.
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // First skip any bytes left over from a previous BackUp().
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (backup_bytes_ >= count) {
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We have more data left over than we're trying to skip.  Just chop it.
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    backup_bytes_ -= count;
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  count -= backup_bytes_;
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  backup_bytes_ = 0;
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int skipped = copying_stream_->Skip(count);
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  position_ += skipped;
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return skipped == count;
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 CopyingInputStreamAdaptor::ByteCount() const {
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return position_ - backup_bytes_;
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_.get() == NULL) {
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_.reset(new uint8[buffer_size_]);
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingInputStreamAdaptor::FreeBuffer() {
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_EQ(backup_bytes_, 0);
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_used_ = 0;
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_.reset();
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingOutputStream::~CopyingOutputStream() {}
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    CopyingOutputStream* copying_stream, int block_size)
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : copying_stream_(copying_stream),
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    owns_copying_stream_(false),
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    failed_(false),
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_(0),
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_used_(0) {
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  WriteBuffer();
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (owns_copying_stream_) {
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    delete copying_stream_;
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CopyingOutputStreamAdaptor::Flush() {
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return WriteBuffer();
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_used_ == buffer_size_) {
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!WriteBuffer()) return false;
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  AllocateBufferIfNeeded();
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *data = buffer_.get() + buffer_used_;
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *size = buffer_size_ - buffer_used_;
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_used_ = buffer_size_;
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingOutputStreamAdaptor::BackUp(int count) {
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_GE(count, 0);
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    << " BackUp() can only be called after Next().";
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_LE(count, buffer_used_)
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    << " Can't back up over more bytes than were returned by the last call"
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       " to Next().";
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_used_ -= count;
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 CopyingOutputStreamAdaptor::ByteCount() const {
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return position_ + buffer_used_;
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CopyingOutputStreamAdaptor::WriteBuffer() {
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (failed_) {
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Already failed on a previous write.
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_used_ == 0) return true;
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    position_ += buffer_used_;
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_used_ = 0;
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    failed_ = true;
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FreeBuffer();
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_ == NULL) {
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_.reset(new uint8[buffer_size_]);
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CopyingOutputStreamAdaptor::FreeBuffer() {
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_used_ = 0;
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_.reset();
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace io
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
394