123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- // 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 common implementations of the interfaces defined in
- // zero_copy_stream.h which are only included in the full (non-lite)
- // protobuf library. These implementations include Unix file descriptors
- // and C++ iostreams. See also: zero_copy_stream_impl_lite.h
- #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
- #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
- #include <iosfwd>
- #include <string>
- #include <google/protobuf/stubs/common.h>
- #include <google/protobuf/io/zero_copy_stream.h>
- #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
- #include <google/protobuf/port_def.inc>
- namespace google {
- namespace protobuf {
- namespace io {
- // ===================================================================
- // A ZeroCopyInputStream which reads from a file descriptor.
- //
- // FileInputStream is preferred over using an ifstream with IstreamInputStream.
- // The latter will introduce an extra layer of buffering, harming performance.
- // Also, it's conceivable that FileInputStream could someday be enhanced
- // to use zero-copy file descriptors on OSs which support them.
- class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
- public:
- // Creates a stream that reads from the given Unix file descriptor.
- // If a block_size is given, it specifies the number of bytes that
- // should be read and returned with each call to Next(). Otherwise,
- // a reasonable default is used.
- explicit FileInputStream(int file_descriptor, int block_size = -1);
- // Flushes any buffers and closes the underlying file. Returns false if
- // an error occurs during the process; use GetErrno() to examine the error.
- // Even if an error occurs, the file descriptor is closed when this returns.
- bool Close();
- // By default, the file descriptor is not closed when the stream is
- // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
- // This leaves no way for the caller to detect if close() fails. If
- // detecting close() errors is important to you, you should arrange
- // to close the descriptor yourself.
- void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
- // If an I/O error has occurred on this file descriptor, this is the
- // errno from that error. Otherwise, this is zero. Once an error
- // occurs, the stream is broken and all subsequent operations will
- // fail.
- int GetErrno() const { return copying_input_.GetErrno(); }
- // implements ZeroCopyInputStream ----------------------------------
- bool Next(const void** data, int* size) override;
- void BackUp(int count) override;
- bool Skip(int count) override;
- int64_t ByteCount() const override;
- private:
- class PROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
- public:
- CopyingFileInputStream(int file_descriptor);
- ~CopyingFileInputStream() override;
- bool Close();
- void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
- int GetErrno() const { return errno_; }
- // implements CopyingInputStream ---------------------------------
- int Read(void* buffer, int size) override;
- int Skip(int count) override;
- private:
- // The file descriptor.
- const int file_;
- bool close_on_delete_;
- bool is_closed_;
- // The errno of the I/O error, if one has occurred. Otherwise, zero.
- int errno_;
- // Did we try to seek once and fail? If so, we assume this file descriptor
- // doesn't support seeking and won't try again.
- bool previous_seek_failed_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
- };
- CopyingFileInputStream copying_input_;
- CopyingInputStreamAdaptor impl_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
- };
- // ===================================================================
- // A ZeroCopyOutputStream which writes to a file descriptor.
- //
- // FileOutputStream is preferred over using an ofstream with
- // OstreamOutputStream. The latter will introduce an extra layer of buffering,
- // harming performance. Also, it's conceivable that FileOutputStream could
- // someday be enhanced to use zero-copy file descriptors on OSs which
- // support them.
- class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor {
- public:
- // Creates a stream that writes to the given Unix file descriptor.
- // If a block_size is given, it specifies the size of the buffers
- // that should be returned by Next(). Otherwise, a reasonable default
- // is used.
- explicit FileOutputStream(int file_descriptor, int block_size = -1);
- ~FileOutputStream() override;
- // Flushes any buffers and closes the underlying file. Returns false if
- // an error occurs during the process; use GetErrno() to examine the error.
- // Even if an error occurs, the file descriptor is closed when this returns.
- bool Close();
- // By default, the file descriptor is not closed when the stream is
- // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
- // This leaves no way for the caller to detect if close() fails. If
- // detecting close() errors is important to you, you should arrange
- // to close the descriptor yourself.
- void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
- // If an I/O error has occurred on this file descriptor, this is the
- // errno from that error. Otherwise, this is zero. Once an error
- // occurs, the stream is broken and all subsequent operations will
- // fail.
- int GetErrno() const { return copying_output_.GetErrno(); }
- private:
- class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
- public:
- CopyingFileOutputStream(int file_descriptor);
- ~CopyingFileOutputStream() override;
- bool Close();
- void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
- int GetErrno() const { return errno_; }
- // implements CopyingOutputStream --------------------------------
- bool Write(const void* buffer, int size) override;
- private:
- // The file descriptor.
- const int file_;
- bool close_on_delete_;
- bool is_closed_;
- // The errno of the I/O error, if one has occurred. Otherwise, zero.
- int errno_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
- };
- CopyingFileOutputStream copying_output_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
- };
- // ===================================================================
- // A ZeroCopyInputStream which reads from a C++ istream.
- //
- // Note that for reading files (or anything represented by a file descriptor),
- // FileInputStream is more efficient.
- class PROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
- public:
- // Creates a stream that reads from the given C++ istream.
- // If a block_size is given, it specifies the number of bytes that
- // should be read and returned with each call to Next(). Otherwise,
- // a reasonable default is used.
- explicit IstreamInputStream(std::istream* stream, int block_size = -1);
- // implements ZeroCopyInputStream ----------------------------------
- bool Next(const void** data, int* size) override;
- void BackUp(int count) override;
- bool Skip(int count) override;
- int64_t ByteCount() const override;
- private:
- class PROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
- public:
- CopyingIstreamInputStream(std::istream* input);
- ~CopyingIstreamInputStream() override;
- // implements CopyingInputStream ---------------------------------
- int Read(void* buffer, int size) override;
- // (We use the default implementation of Skip().)
- private:
- // The stream.
- std::istream* input_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
- };
- CopyingIstreamInputStream copying_input_;
- CopyingInputStreamAdaptor impl_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
- };
- // ===================================================================
- // A ZeroCopyOutputStream which writes to a C++ ostream.
- //
- // Note that for writing files (or anything represented by a file descriptor),
- // FileOutputStream is more efficient.
- class PROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
- public:
- // Creates a stream that writes to the given C++ ostream.
- // If a block_size is given, it specifies the size of the buffers
- // that should be returned by Next(). Otherwise, a reasonable default
- // is used.
- explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
- ~OstreamOutputStream() override;
- // implements ZeroCopyOutputStream ---------------------------------
- bool Next(void** data, int* size) override;
- void BackUp(int count) override;
- int64_t ByteCount() const override;
- private:
- class PROTOBUF_EXPORT CopyingOstreamOutputStream
- : public CopyingOutputStream {
- public:
- CopyingOstreamOutputStream(std::ostream* output);
- ~CopyingOstreamOutputStream() override;
- // implements CopyingOutputStream --------------------------------
- bool Write(const void* buffer, int size) override;
- private:
- // The stream.
- std::ostream* output_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
- };
- CopyingOstreamOutputStream copying_output_;
- CopyingOutputStreamAdaptor impl_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
- };
- // ===================================================================
- // A ZeroCopyInputStream which reads from several other streams in sequence.
- // ConcatenatingInputStream is unable to distinguish between end-of-stream
- // and read errors in the underlying streams, so it assumes any errors mean
- // end-of-stream. So, if the underlying streams fail for any other reason,
- // ConcatenatingInputStream may do odd things. It is suggested that you do
- // not use ConcatenatingInputStream on streams that might produce read errors
- // other than end-of-stream.
- class PROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
- public:
- // All streams passed in as well as the array itself must remain valid
- // until the ConcatenatingInputStream is destroyed.
- ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
- ~ConcatenatingInputStream() override = default;
- // implements ZeroCopyInputStream ----------------------------------
- bool Next(const void** data, int* size) override;
- void BackUp(int count) override;
- bool Skip(int count) override;
- int64_t ByteCount() const override;
- private:
- // As streams are retired, streams_ is incremented and count_ is
- // decremented.
- ZeroCopyInputStream* const* streams_;
- int stream_count_;
- int64_t bytes_retired_; // Bytes read from previous streams.
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
- };
- // ===================================================================
- } // namespace io
- } // namespace protobuf
- } // namespace google
- #include <google/protobuf/port_undef.inc>
- #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
|