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#ifdef _MSC_VER 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <io.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <unistd.h> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/types.h> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/stat.h> 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <fcntl.h> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <errno.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <iostream> 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <algorithm> 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h> 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/stl_util-inl.h> 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace io { 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// return value is undefined. We re-define it to always produce an error. 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define lseek(fd, offset, origin) ((off_t)-1) 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// EINTR sucks. 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint close_no_eintr(int fd) { 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result; 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = close(fd); 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (result < 0 && errno == EINTR); 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileInputStream::FileInputStream(int file_descriptor, int block_size) 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : copying_input_(file_descriptor), 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_(©ing_input_, block_size) { 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileInputStream::~FileInputStream() {} 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileInputStream::Close() { 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return copying_input_.Close(); 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileInputStream::Next(const void** data, int* size) { 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Next(data, size); 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileInputStream::BackUp(int count) { 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.BackUp(count); 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileInputStream::Skip(int count) { 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Skip(count); 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 FileInputStream::ByteCount() const { 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.ByteCount(); 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileInputStream::CopyingFileInputStream::CopyingFileInputStream( 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int file_descriptor) 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : file_(file_descriptor), 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close_on_delete_(false), 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is_closed_(false), 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_(0), 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville previous_seek_failed_(false) { 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (close_on_delete_) { 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Close()) { 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileInputStream::CopyingFileInputStream::Close() { 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!is_closed_); 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is_closed_ = true; 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (close_no_eintr(file_) != 0) { 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The docs on close() do not specify whether a file descriptor is still 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // open after close() fails with EIO. However, the glibc source code 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // seems to indicate that it is not. 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_ = errno; 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) { 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!is_closed_); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result; 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = read(file_, buffer, size); 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (result < 0 && errno == EINTR); 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result < 0) { 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Read error (not EOF). 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_ = errno; 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint FileInputStream::CopyingFileInputStream::Skip(int count) { 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!is_closed_); 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!previous_seek_failed_ && 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville lseek(file_, count, SEEK_CUR) != (off_t)-1) { 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Seek succeeded. 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return count; 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Failed to seek. 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note to self: Don't seek again. This file descriptor doesn't 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // support it. 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville previous_seek_failed_ = true; 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Use the default implementation. 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return CopyingInputStream::Skip(count); 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileOutputStream::FileOutputStream(int file_descriptor, int block_size) 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : copying_output_(file_descriptor), 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_(©ing_output_, block_size) { 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileOutputStream::~FileOutputStream() { 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.Flush(); 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileOutputStream::Close() { 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool flush_succeeded = impl_.Flush(); 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return copying_output_.Close() && flush_succeeded; 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileOutputStream::Flush() { 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Flush(); 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileOutputStream::Next(void** data, int* size) { 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Next(data, size); 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileOutputStream::BackUp(int count) { 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.BackUp(count); 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 FileOutputStream::ByteCount() const { 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.ByteCount(); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int file_descriptor) 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : file_(file_descriptor), 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close_on_delete_(false), 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is_closed_(false), 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_(0) { 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (close_on_delete_) { 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Close()) { 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileOutputStream::CopyingFileOutputStream::Close() { 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!is_closed_); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is_closed_ = true; 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (close_no_eintr(file_) != 0) { 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The docs on close() do not specify whether a file descriptor is still 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // open after close() fails with EIO. However, the glibc source code 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // seems to indicate that it is not. 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_ = errno; 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileOutputStream::CopyingFileOutputStream::Write( 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* buffer, int size) { 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!is_closed_); 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int total_written = 0; 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer); 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (total_written < size) { 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int bytes; 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes = write(file_, buffer_base + total_written, size - total_written); 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (bytes < 0 && errno == EINTR); 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (bytes <= 0) { 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Write error. 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FIXME(kenton): According to the man page, if write() returns zero, 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // there was no error; write() simply did not write anything. It's 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // unclear under what circumstances this might happen, but presumably 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // errno won't be set in this case. I am confused as to how such an 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // event should be handled. For now I'm treating it as an error, since 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // retrying seems like it could lead to an infinite loop. I suspect 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this never actually happens anyway. 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (bytes < 0) { 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno_ = errno; 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_written += bytes; 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIstreamInputStream::IstreamInputStream(istream* input, int block_size) 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : copying_input_(input), 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_(©ing_input_, block_size) { 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIstreamInputStream::~IstreamInputStream() {} 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool IstreamInputStream::Next(const void** data, int* size) { 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Next(data, size); 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid IstreamInputStream::BackUp(int count) { 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.BackUp(count); 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool IstreamInputStream::Skip(int count) { 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Skip(count); 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 IstreamInputStream::ByteCount() const { 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.ByteCount(); 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream( 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville istream* input) 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : input_(input) { 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {} 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint IstreamInputStream::CopyingIstreamInputStream::Read( 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* buffer, int size) { 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->read(reinterpret_cast<char*>(buffer), size); 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = input_->gcount(); 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == 0 && input_->fail() && !input_->eof()) { 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return -1; 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleOstreamOutputStream::OstreamOutputStream(ostream* output, int block_size) 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : copying_output_(output), 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_(©ing_output_, block_size) { 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleOstreamOutputStream::~OstreamOutputStream() { 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.Flush(); 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool OstreamOutputStream::Next(void** data, int* size) { 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.Next(data, size); 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid OstreamOutputStream::BackUp(int count) { 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville impl_.BackUp(count); 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 OstreamOutputStream::ByteCount() const { 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return impl_.ByteCount(); 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleOstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream( 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ostream* output) 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : output_(output) { 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleOstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() { 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool OstreamOutputStream::CopyingOstreamOutputStream::Write( 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* buffer, int size) { 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output_->write(reinterpret_cast<const char*>(buffer), size); 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return output_->good(); 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleConcatenatingInputStream::ConcatenatingInputStream( 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ZeroCopyInputStream* const streams[], int count) 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : streams_(streams), stream_count_(count), bytes_retired_(0) { 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleConcatenatingInputStream::~ConcatenatingInputStream() { 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ConcatenatingInputStream::Next(const void** data, int* size) { 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (stream_count_ > 0) { 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (streams_[0]->Next(data, size)) return true; 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // That stream is done. Advance to the next one. 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes_retired_ += streams_[0]->ByteCount(); 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++streams_; 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --stream_count_; 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // No more streams. 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ConcatenatingInputStream::BackUp(int count) { 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (stream_count_ > 0) { 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville streams_[0]->BackUp(count); 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next()."; 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ConcatenatingInputStream::Skip(int count) { 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (stream_count_ > 0) { 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Assume that ByteCount() can be used to find out how much we actually 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // skipped when Skip() fails. 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int64 target_byte_count = streams_[0]->ByteCount() + count; 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (streams_[0]->Skip(count)) return true; 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Hit the end of the stream. Figure out how many more bytes we still have 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to skip. 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int64 final_byte_count = streams_[0]->ByteCount(); 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville count = target_byte_count - final_byte_count; 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // That stream is done. Advance to the next one. 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes_retired_ += final_byte_count; 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++streams_; 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --stream_count_; 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 ConcatenatingInputStream::ByteCount() const { 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (stream_count_ == 0) { 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return bytes_retired_; 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return bytes_retired_ + streams_[0]->ByteCount(); 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int64 limit) 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : input_(input), limit_(limit) {} 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLimitingInputStream::~LimitingInputStream() { 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we overshot the limit, back up. 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ < 0) input_->BackUp(-limit_); 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool LimitingInputStream::Next(const void** data, int* size) { 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ <= 0) return false; 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!input_->Next(data, size)) return false; 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville limit_ -= *size; 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ < 0) { 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We overshot the limit. Reduce *size to hide the rest of the buffer. 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *size += limit_; 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid LimitingInputStream::BackUp(int count) { 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ < 0) { 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->BackUp(count - limit_); 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville limit_ = count; 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->BackUp(count); 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville limit_ += count; 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool LimitingInputStream::Skip(int count) { 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (count > limit_) { 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ < 0) return false; 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->Skip(limit_); 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville limit_ = 0; 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!input_->Skip(count)) return false; 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville limit_ -= count; 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint64 LimitingInputStream::ByteCount() const { 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (limit_ < 0) { 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return input_->ByteCount() + limit_; 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return input_->ByteCount(); 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace io 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 471