123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- // Author: kenton@google.com (Kenton Varda)
- // Based on original Protocol Buffers design by
- // Sanjay Ghemawat, Jeff Dean, and others.
- //
- // This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
- // interfaces, which represent abstract I/O streams to and from which
- // protocol buffers can be read and written. For a few simple
- // implementations of these interfaces, see zero_copy_stream_impl.h.
- //
- // These interfaces are different from classic I/O streams in that they
- // try to minimize the amount of data copying that needs to be done.
- // To accomplish this, responsibility for allocating buffers is moved to
- // the stream object, rather than being the responsibility of the caller.
- // So, the stream can return a buffer which actually points directly into
- // the final data structure where the bytes are to be stored, and the caller
- // can interact directly with that buffer, eliminating an intermediate copy
- // operation.
- //
- // As an example, consider the common case in which you are reading bytes
- // from an array that is already in memory (or perhaps an mmap()ed file).
- // With classic I/O streams, you would do something like:
- // char buffer[BUFFER_SIZE];
- // input->Read(buffer, BUFFER_SIZE);
- // DoSomething(buffer, BUFFER_SIZE);
- // Then, the stream basically just calls memcpy() to copy the data from
- // the array into your buffer. With a ZeroCopyInputStream, you would do
- // this instead:
- // const void* buffer;
- // int size;
- // input->Next(&buffer, &size);
- // DoSomething(buffer, size);
- // Here, no copy is performed. The input stream returns a pointer directly
- // into the backing array, and the caller ends up reading directly from it.
- //
- // If you want to be able to read the old-fashion way, you can create
- // a CodedInputStream or CodedOutputStream wrapping these objects and use
- // their ReadRaw()/WriteRaw() methods. These will, of course, add a copy
- // step, but Coded*Stream will handle buffering so at least it will be
- // reasonably efficient.
- //
- // ZeroCopyInputStream example:
- // // Read in a file and print its contents to stdout.
- // int fd = open("myfile", O_RDONLY);
- // ZeroCopyInputStream* input = new FileInputStream(fd);
- //
- // const void* buffer;
- // int size;
- // while (input->Next(&buffer, &size)) {
- // cout.write(buffer, size);
- // }
- //
- // delete input;
- // close(fd);
- //
- // ZeroCopyOutputStream example:
- // // Copy the contents of "infile" to "outfile", using plain read() for
- // // "infile" but a ZeroCopyOutputStream for "outfile".
- // int infd = open("infile", O_RDONLY);
- // int outfd = open("outfile", O_WRONLY);
- // ZeroCopyOutputStream* output = new FileOutputStream(outfd);
- //
- // void* buffer;
- // int size;
- // while (output->Next(&buffer, &size)) {
- // int bytes = read(infd, buffer, size);
- // if (bytes < size) {
- // // Reached EOF.
- // output->BackUp(size - bytes);
- // break;
- // }
- // }
- //
- // delete output;
- // close(infd);
- // close(outfd);
- #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
- #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
- #include <string>
- #include <google/protobuf/stubs/common.h>
- #include <google/protobuf/port_def.inc>
- namespace google {
- namespace protobuf {
- namespace io {
- // Defined in this file.
- class ZeroCopyInputStream;
- class ZeroCopyOutputStream;
- // Abstract interface similar to an input stream but designed to minimize
- // copying.
- class PROTOBUF_EXPORT ZeroCopyInputStream {
- public:
- ZeroCopyInputStream() {}
- virtual ~ZeroCopyInputStream() {}
- // Obtains a chunk of data from the stream.
- //
- // Preconditions:
- // * "size" and "data" are not NULL.
- //
- // Postconditions:
- // * If the returned value is false, there is no more data to return or
- // an error occurred. All errors are permanent.
- // * Otherwise, "size" points to the actual number of bytes read and "data"
- // points to a pointer to a buffer containing these bytes.
- // * Ownership of this buffer remains with the stream, and the buffer
- // remains valid only until some other method of the stream is called
- // or the stream is destroyed.
- // * It is legal for the returned buffer to have zero size, as long
- // as repeatedly calling Next() eventually yields a buffer with non-zero
- // size.
- virtual bool Next(const void** data, int* size) = 0;
- // Backs up a number of bytes, so that the next call to Next() returns
- // data again that was already returned by the last call to Next(). This
- // is useful when writing procedures that are only supposed to read up
- // to a certain point in the input, then return. If Next() returns a
- // buffer that goes beyond what you wanted to read, you can use BackUp()
- // to return to the point where you intended to finish.
- //
- // Preconditions:
- // * The last method called must have been Next().
- // * count must be less than or equal to the size of the last buffer
- // returned by Next().
- //
- // Postconditions:
- // * The last "count" bytes of the last buffer returned by Next() will be
- // pushed back into the stream. Subsequent calls to Next() will return
- // the same data again before producing new data.
- virtual void BackUp(int count) = 0;
- // Skips a number of bytes. Returns false if the end of the stream is
- // reached or some input error occurred. In the end-of-stream case, the
- // stream is advanced to the end of the stream (so ByteCount() will return
- // the total size of the stream).
- virtual bool Skip(int count) = 0;
- // Returns the total number of bytes read since this object was created.
- virtual int64_t ByteCount() const = 0;
- private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
- };
- // Abstract interface similar to an output stream but designed to minimize
- // copying.
- class PROTOBUF_EXPORT ZeroCopyOutputStream {
- public:
- ZeroCopyOutputStream() {}
- virtual ~ZeroCopyOutputStream() {}
- // Obtains a buffer into which data can be written. Any data written
- // into this buffer will eventually (maybe instantly, maybe later on)
- // be written to the output.
- //
- // Preconditions:
- // * "size" and "data" are not NULL.
- //
- // Postconditions:
- // * If the returned value is false, an error occurred. All errors are
- // permanent.
- // * Otherwise, "size" points to the actual number of bytes in the buffer
- // and "data" points to the buffer.
- // * Ownership of this buffer remains with the stream, and the buffer
- // remains valid only until some other method of the stream is called
- // or the stream is destroyed.
- // * Any data which the caller stores in this buffer will eventually be
- // written to the output (unless BackUp() is called).
- // * It is legal for the returned buffer to have zero size, as long
- // as repeatedly calling Next() eventually yields a buffer with non-zero
- // size.
- virtual bool Next(void** data, int* size) = 0;
- // Backs up a number of bytes, so that the end of the last buffer returned
- // by Next() is not actually written. This is needed when you finish
- // writing all the data you want to write, but the last buffer was bigger
- // than you needed. You don't want to write a bunch of garbage after the
- // end of your data, so you use BackUp() to back up.
- //
- // Preconditions:
- // * The last method called must have been Next().
- // * count must be less than or equal to the size of the last buffer
- // returned by Next().
- // * The caller must not have written anything to the last "count" bytes
- // of that buffer.
- //
- // Postconditions:
- // * The last "count" bytes of the last buffer returned by Next() will be
- // ignored.
- virtual void BackUp(int count) = 0;
- // Returns the total number of bytes written since this object was created.
- virtual int64_t ByteCount() const = 0;
- // Write a given chunk of data to the output. Some output streams may
- // implement this in a way that avoids copying. Check AllowsAliasing() before
- // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
- // called on a stream that does not allow aliasing.
- //
- // NOTE: It is caller's responsibility to ensure that the chunk of memory
- // remains live until all of the data has been consumed from the stream.
- virtual bool WriteAliasedRaw(const void* data, int size);
- virtual bool AllowsAliasing() const { return false; }
- private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
- };
- } // namespace io
- } // namespace protobuf
- } // namespace google
- #include <google/protobuf/port_undef.inc>
- #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
|