LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf/io - zero_copy_stream_impl_lite.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 205 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 43 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13