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