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)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interfaces, which represent abstract I/O streams to and from which
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// protocol buffers can be read and written.  For a few simple
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementations of these interfaces, see zero_copy_stream_impl.h.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These interfaces are different from classic I/O streams in that they
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// try to minimize the amount of data copying that needs to be done.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To accomplish this, responsibility for allocating buffers is moved to
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the stream object, rather than being the responsibility of the caller.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// So, the stream can return a buffer which actually points directly into
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the final data structure where the bytes are to be stored, and the caller
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can interact directly with that buffer, eliminating an intermediate copy
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As an example, consider the common case in which you are reading bytes
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from an array that is already in memory (or perhaps an mmap()ed file).
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With classic I/O streams, you would do something like:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   char buffer[BUFFER_SIZE];
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   input->Read(buffer, BUFFER_SIZE);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DoSomething(buffer, BUFFER_SIZE);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then, the stream basically just calls memcpy() to copy the data from
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the array into your buffer.  With a ZeroCopyInputStream, you would do
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this instead:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   const void* buffer;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int size;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   input->Next(&buffer, &size);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DoSomething(buffer, size);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here, no copy is performed.  The input stream returns a pointer directly
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into the backing array, and the caller ends up reading directly from it.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you want to be able to read the old-fashion way, you can create
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a CodedInputStream or CodedOutputStream wrapping these objects and use
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// their ReadRaw()/WriteRaw() methods.  These will, of course, add a copy
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// step, but Coded*Stream will handle buffering so at least it will be
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reasonably efficient.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ZeroCopyInputStream example:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // Read in a file and print its contents to stdout.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int fd = open("myfile", O_RDONLY);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   ZeroCopyInputStream* input = new FileInputStream(fd);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   const void* buffer;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int size;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   while (input->Next(&buffer, &size)) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     cout.write(buffer, size);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   delete input;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   close(fd);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ZeroCopyOutputStream example:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // Copy the contents of "infile" to "outfile", using plain read() for
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // "infile" but a ZeroCopyOutputStream for "outfile".
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int infd = open("infile", O_RDONLY);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int outfd = open("outfile", O_WRONLY);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   ZeroCopyOutputStream* output = new FileOutputStream(outfd);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void* buffer;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   int size;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   while (output->Next(&buffer, &size)) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     int bytes = read(infd, buffer, size);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     if (bytes < size) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       // Reached EOF.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       output->BackUp(size - bytes);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       break;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   delete output;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   close(infd);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   close(outfd);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in this file.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ZeroCopyInputStream;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ZeroCopyOutputStream;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Abstract interface similar to an input stream but designed to minimize
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copying.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline ZeroCopyInputStream() {}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ZeroCopyInputStream();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtains a chunk of data from the stream.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preconditions:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * "size" and "data" are not NULL.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Postconditions:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * If the returned value is false, there is no more data to return or
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   an error occurred.  All errors are permanent.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * Otherwise, "size" points to the actual number of bytes read and "data"
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   points to a pointer to a buffer containing these bytes.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * Ownership of this buffer remains with the stream, and the buffer
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   remains valid only until some other method of the stream is called
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   or the stream is destroyed.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * It is legal for the returned buffer to have zero size, as long
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   as repeatedly calling Next() eventually yields a buffer with non-zero
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   size.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Next(const void** data, int* size) = 0;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Backs up a number of bytes, so that the next call to Next() returns
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // data again that was already returned by the last call to Next().  This
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is useful when writing procedures that are only supposed to read up
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a certain point in the input, then return.  If Next() returns a
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffer that goes beyond what you wanted to read, you can use BackUp()
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to return to the point where you intended to finish.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preconditions:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * The last method called must have been Next().
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * count must be less than or equal to the size of the last buffer
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   returned by Next().
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Postconditions:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * The last "count" bytes of the last buffer returned by Next() will be
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   pushed back into the stream.  Subsequent calls to Next() will return
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   the same data again before producing new data.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BackUp(int count) = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skips a number of bytes.  Returns false if the end of the stream is
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reached or some input error occurred.  In the end-of-stream case, the
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream is advanced to the end of the stream (so ByteCount() will return
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the total size of the stream).
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Skip(int count) = 0;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the total number of bytes read since this object was created.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int64 ByteCount() const = 0;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Abstract interface similar to an output stream but designed to minimize
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copying.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline ZeroCopyOutputStream() {}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ZeroCopyOutputStream();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtains a buffer into which data can be written.  Any data written
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into this buffer will eventually (maybe instantly, maybe later on)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be written to the output.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preconditions:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * "size" and "data" are not NULL.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Postconditions:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * If the returned value is false, an error occurred.  All errors are
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   permanent.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * Otherwise, "size" points to the actual number of bytes in the buffer
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   and "data" points to the buffer.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * Ownership of this buffer remains with the stream, and the buffer
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   remains valid only until some other method of the stream is called
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   or the stream is destroyed.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * Any data which the caller stores in this buffer will eventually be
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   written to the output (unless BackUp() is called).
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * It is legal for the returned buffer to have zero size, as long
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   as repeatedly calling Next() eventually yields a buffer with non-zero
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   size.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Next(void** data, int* size) = 0;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Backs up a number of bytes, so that the end of the last buffer returned
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by Next() is not actually written.  This is needed when you finish
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // writing all the data you want to write, but the last buffer was bigger
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than you needed.  You don't want to write a bunch of garbage after the
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // end of your data, so you use BackUp() to back up.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preconditions:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * The last method called must have been Next().
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * count must be less than or equal to the size of the last buffer
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   returned by Next().
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * The caller must not have written anything to the last "count" bytes
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   of that buffer.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Postconditions:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // * The last "count" bytes of the last buffer returned by Next() will be
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   ignored.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BackUp(int count) = 0;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the total number of bytes written since this object was created.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int64 ByteCount() const = 0;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace io
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
239