15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/io/zero_copy_stream_impl_lite.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h> 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/stl_util.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <algorithm> 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default block size for Copying{In,Out}putStreamAdaptor. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultBlockSize = 8192; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayInputStream::ArrayInputStream(const void* data, int size, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int block_size) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_(reinterpret_cast<const uint8*>(data)), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_(size), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_size_(block_size > 0 ? block_size : size), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_(0), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_(0) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayInputStream::~ArrayInputStream() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ArrayInputStream::Next(const void** data, int* size) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position_ < size_) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = min(block_size_, size_ - position_); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = data_ + position_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = last_returned_size_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += last_returned_size_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're at the end of the array. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = 0; // Don't let caller back up. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ArrayInputStream::BackUp(int count) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GT(last_returned_size_, 0) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "BackUp() can only be called after a successful Next()."; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_LE(count, last_returned_size_); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ -= count; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = 0; // Don't let caller back up further. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ArrayInputStream::Skip(int count) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = 0; // Don't let caller back up. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count > size_ - position_) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ = size_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += count; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 ArrayInputStream::ByteCount() const { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return position_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_(reinterpret_cast<uint8*>(data)), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_(size), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_size_(block_size > 0 ? block_size : size), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_(0), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_(0) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayOutputStream::~ArrayOutputStream() { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ArrayOutputStream::Next(void** data, int* size) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position_ < size_) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = min(block_size_, size_ - position_); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = data_ + position_; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = last_returned_size_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += last_returned_size_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're at the end of the array. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = 0; // Don't let caller back up. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ArrayOutputStream::BackUp(int count) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GT(last_returned_size_, 0) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "BackUp() can only be called after a successful Next()."; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_LE(count, last_returned_size_); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ -= count; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_returned_size_ = 0; // Don't let caller back up further. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 ArrayOutputStream::ByteCount() const { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return position_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringOutputStream::StringOutputStream(string* target) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : target_(target) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringOutputStream::~StringOutputStream() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StringOutputStream::Next(void** data, int* size) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_size = target_->size(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Grow the string. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_size < target_->capacity()) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resize the string to match its capacity, since we can get away 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without a memory allocation this way. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLStringResizeUninitialized(target_, target_->capacity()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Size has reached capacity, so double the size. Also make sure 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that the new size is at least kMinimumSize. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLStringResizeUninitialized( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max(old_size * 2, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = string_as_array(target_) + old_size; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = target_->size() - old_size; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StringOutputStream::BackUp(int count) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_LE(count, target_->size()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_->resize(target_->size() - count); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 StringOutputStream::ByteCount() const { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_->size(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingInputStream::~CopyingInputStream() {} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CopyingInputStream::Skip(int count) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char junk[4096]; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int skipped = 0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (skipped < count) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes = Read(junk, min(count - skipped, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<int>(sizeof(junk)))); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes <= 0) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EOF or read error. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skipped; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skipped += bytes; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skipped; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyingInputStream* copying_stream, int block_size) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : copying_stream_(copying_stream), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owns_copying_stream_(false), 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_(false), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_(0), 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_(0), 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backup_bytes_(0) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (owns_copying_stream_) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete copying_stream_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already failed on a previous read. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateBufferIfNeeded(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (backup_bytes_ > 0) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have data left over from a previous BackUp(), so just return that. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = buffer_.get() + buffer_used_ - backup_bytes_; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = backup_bytes_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backup_bytes_ = 0; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read new data into the buffer. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_used_ <= 0) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EOF or read error. We don't need the buffer anymore. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_used_ < 0) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read error (not EOF). 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_ = true; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeBuffer(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += buffer_used_; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = buffer_used_; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = buffer_.get(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingInputStreamAdaptor::BackUp(int count) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " BackUp() can only be called after Next()."; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_LE(count, buffer_used_) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Can't back up over more bytes than were returned by the last call" 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " to Next()."; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Parameter to BackUp() can't be negative."; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backup_bytes_ = count; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CopyingInputStreamAdaptor::Skip(int count) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already failed on a previous read. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First skip any bytes left over from a previous BackUp(). 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (backup_bytes_ >= count) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have more data left over than we're trying to skip. Just chop it. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backup_bytes_ -= count; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count -= backup_bytes_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backup_bytes_ = 0; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int skipped = copying_stream_->Skip(count); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += skipped; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return skipped == count; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 CopyingInputStreamAdaptor::ByteCount() const { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return position_ - backup_bytes_; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_.get() == NULL) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(new uint8[buffer_size_]); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingInputStreamAdaptor::FreeBuffer() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_EQ(backup_bytes_, 0); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ = 0; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingOutputStream::~CopyingOutputStream() {} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyingOutputStream* copying_stream, int block_size) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : copying_stream_(copying_stream), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owns_copying_stream_(false), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_(false), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_(0), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_(0) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteBuffer(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (owns_copying_stream_) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete copying_stream_; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CopyingOutputStreamAdaptor::Flush() { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBuffer(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_used_ == buffer_size_) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteBuffer()) return false; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateBufferIfNeeded(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = buffer_.get() + buffer_used_; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = buffer_size_ - buffer_used_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ = buffer_size_; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingOutputStreamAdaptor::BackUp(int count) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(count, 0); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " BackUp() can only be called after Next()."; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_LE(count, buffer_used_) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Can't back up over more bytes than were returned by the last call" 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " to Next()."; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ -= count; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 CopyingOutputStreamAdaptor::ByteCount() const { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return position_ + buffer_used_; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CopyingOutputStreamAdaptor::WriteBuffer() { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already failed on a previous write. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_used_ == 0) return true; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copying_stream_->Write(buffer_.get(), buffer_used_)) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) position_ += buffer_used_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ = 0; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_ = true; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeBuffer(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_ == NULL) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(new uint8[buffer_size_]); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyingOutputStreamAdaptor::FreeBuffer() { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_used_ = 0; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace io 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 396