Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:02

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // This file contains common implementations of the interfaces defined in
0013 // zero_copy_stream.h which are only included in the full (non-lite)
0014 // protobuf library.  These implementations include Unix file descriptors
0015 // and C++ iostreams.  See also:  zero_copy_stream_impl_lite.h
0016 
0017 #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
0018 #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
0019 
0020 #include <iosfwd>
0021 #include <string>
0022 
0023 #include "google/protobuf/stubs/common.h"
0024 #include "google/protobuf/io/zero_copy_stream.h"
0025 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
0026 
0027 // Must be included last.
0028 #include "google/protobuf/port_def.inc"
0029 
0030 namespace google {
0031 namespace protobuf {
0032 namespace io {
0033 
0034 // ===================================================================
0035 
0036 // A ZeroCopyInputStream which reads from a file descriptor.
0037 //
0038 // FileInputStream is preferred over using an ifstream with IstreamInputStream.
0039 // The latter will introduce an extra layer of buffering, harming performance.
0040 // Also, it's conceivable that FileInputStream could someday be enhanced
0041 // to use zero-copy file descriptors on OSs which support them.
0042 class PROTOBUF_EXPORT FileInputStream final : public ZeroCopyInputStream {
0043  public:
0044   // Creates a stream that reads from the given Unix file descriptor.
0045   // If a block_size is given, it specifies the number of bytes that
0046   // should be read and returned with each call to Next().  Otherwise,
0047   // a reasonable default is used.
0048   explicit FileInputStream(int file_descriptor, int block_size = -1);
0049   FileInputStream(const FileInputStream&) = delete;
0050   FileInputStream& operator=(const FileInputStream&) = delete;
0051 
0052   // Flushes any buffers and closes the underlying file.  Returns false if
0053   // an error occurs during the process; use GetErrno() to examine the error.
0054   // Even if an error occurs, the file descriptor is closed when this returns.
0055   bool Close();
0056 
0057   // By default, the file descriptor is not closed when the stream is
0058   // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
0059   // This leaves no way for the caller to detect if close() fails.  If
0060   // detecting close() errors is important to you, you should arrange
0061   // to close the descriptor yourself.
0062   void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
0063 
0064   // If an I/O error has occurred on this file descriptor, this is the
0065   // errno from that error.  Otherwise, this is zero.  Once an error
0066   // occurs, the stream is broken and all subsequent operations will
0067   // fail.
0068   int GetErrno() const { return copying_input_.GetErrno(); }
0069 
0070   // implements ZeroCopyInputStream ----------------------------------
0071   bool Next(const void** data, int* size) override;
0072   void BackUp(int count) override;
0073   bool Skip(int count) override;
0074   int64_t ByteCount() const override;
0075 
0076  private:
0077   class PROTOBUF_EXPORT CopyingFileInputStream final
0078       : public CopyingInputStream {
0079    public:
0080     CopyingFileInputStream(int file_descriptor);
0081     CopyingFileInputStream(const CopyingFileInputStream&) = delete;
0082     CopyingFileInputStream& operator=(const CopyingFileInputStream&) = delete;
0083     ~CopyingFileInputStream() override;
0084 
0085     bool Close();
0086     void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
0087     int GetErrno() const { return errno_; }
0088 
0089     // implements CopyingInputStream ---------------------------------
0090     int Read(void* buffer, int size) override;
0091     int Skip(int count) override;
0092 
0093    private:
0094     // The file descriptor.
0095     const int file_;
0096     bool close_on_delete_;
0097     bool is_closed_;
0098 
0099     // The errno of the I/O error, if one has occurred.  Otherwise, zero.
0100     int errno_;
0101 
0102     // Did we try to seek once and fail?  If so, we assume this file descriptor
0103     // doesn't support seeking and won't try again.
0104     bool previous_seek_failed_;
0105   };
0106 
0107   CopyingFileInputStream copying_input_;
0108   CopyingInputStreamAdaptor impl_;
0109 };
0110 
0111 // ===================================================================
0112 
0113 // A ZeroCopyOutputStream which writes to a file descriptor.
0114 //
0115 // FileOutputStream is preferred over using an ofstream with
0116 // OstreamOutputStream.  The latter will introduce an extra layer of buffering,
0117 // harming performance.  Also, it's conceivable that FileOutputStream could
0118 // someday be enhanced to use zero-copy file descriptors on OSs which
0119 // support them.
0120 class PROTOBUF_EXPORT FileOutputStream final
0121     : public CopyingOutputStreamAdaptor {
0122  public:
0123   // Creates a stream that writes to the given Unix file descriptor.
0124   // If a block_size is given, it specifies the size of the buffers
0125   // that should be returned by Next().  Otherwise, a reasonable default
0126   // is used.
0127   explicit FileOutputStream(int file_descriptor, int block_size = -1);
0128   FileOutputStream(const FileOutputStream&) = delete;
0129   FileOutputStream& operator=(const FileOutputStream&) = delete;
0130 
0131   ~FileOutputStream() override;
0132 
0133   // Flushes any buffers and closes the underlying file.  Returns false if
0134   // an error occurs during the process; use GetErrno() to examine the error.
0135   // Even if an error occurs, the file descriptor is closed when this returns.
0136   bool Close();
0137 
0138   // By default, the file descriptor is not closed when the stream is
0139   // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
0140   // This leaves no way for the caller to detect if close() fails.  If
0141   // detecting close() errors is important to you, you should arrange
0142   // to close the descriptor yourself.
0143   void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
0144 
0145   // If an I/O error has occurred on this file descriptor, this is the
0146   // errno from that error.  Otherwise, this is zero.  Once an error
0147   // occurs, the stream is broken and all subsequent operations will
0148   // fail.
0149   int GetErrno() const { return copying_output_.GetErrno(); }
0150 
0151  private:
0152   class PROTOBUF_EXPORT CopyingFileOutputStream final
0153       : public CopyingOutputStream {
0154    public:
0155     CopyingFileOutputStream(int file_descriptor);
0156     CopyingFileOutputStream(const CopyingFileOutputStream&) = delete;
0157     CopyingFileOutputStream& operator=(const CopyingFileOutputStream&) = delete;
0158     ~CopyingFileOutputStream() override;
0159 
0160     bool Close();
0161     void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
0162     int GetErrno() const { return errno_; }
0163 
0164     // implements CopyingOutputStream --------------------------------
0165     bool Write(const void* buffer, int size) override;
0166 
0167    private:
0168     // The file descriptor.
0169     const int file_;
0170     bool close_on_delete_;
0171     bool is_closed_;
0172 
0173     // The errno of the I/O error, if one has occurred.  Otherwise, zero.
0174     int errno_;
0175   };
0176 
0177   CopyingFileOutputStream copying_output_;
0178 };
0179 
0180 // ===================================================================
0181 
0182 // A ZeroCopyInputStream which reads from a C++ istream.
0183 //
0184 // Note that for reading files (or anything represented by a file descriptor),
0185 // FileInputStream is more efficient.
0186 class PROTOBUF_EXPORT IstreamInputStream final : public ZeroCopyInputStream {
0187  public:
0188   // Creates a stream that reads from the given C++ istream.
0189   // If a block_size is given, it specifies the number of bytes that
0190   // should be read and returned with each call to Next().  Otherwise,
0191   // a reasonable default is used.
0192   explicit IstreamInputStream(std::istream* stream, int block_size = -1);
0193   IstreamInputStream(const IstreamInputStream&) = delete;
0194   IstreamInputStream& operator=(const IstreamInputStream&) = delete;
0195 
0196   // implements ZeroCopyInputStream ----------------------------------
0197   bool Next(const void** data, int* size) override;
0198   void BackUp(int count) override;
0199   bool Skip(int count) override;
0200   int64_t ByteCount() const override;
0201 
0202  private:
0203   class PROTOBUF_EXPORT CopyingIstreamInputStream final
0204       : public CopyingInputStream {
0205    public:
0206     CopyingIstreamInputStream(std::istream* input);
0207     CopyingIstreamInputStream(const CopyingIstreamInputStream&) = delete;
0208     CopyingIstreamInputStream& operator=(const CopyingIstreamInputStream&) =
0209         delete;
0210     ~CopyingIstreamInputStream() override;
0211 
0212     // implements CopyingInputStream ---------------------------------
0213     int Read(void* buffer, int size) override;
0214     // (We use the default implementation of Skip().)
0215 
0216    private:
0217     // The stream.
0218     std::istream* input_;
0219   };
0220 
0221   CopyingIstreamInputStream copying_input_;
0222   CopyingInputStreamAdaptor impl_;
0223 };
0224 
0225 // ===================================================================
0226 
0227 // A ZeroCopyOutputStream which writes to a C++ ostream.
0228 //
0229 // Note that for writing files (or anything represented by a file descriptor),
0230 // FileOutputStream is more efficient.
0231 class PROTOBUF_EXPORT OstreamOutputStream final : public ZeroCopyOutputStream {
0232  public:
0233   // Creates a stream that writes to the given C++ ostream.
0234   // If a block_size is given, it specifies the size of the buffers
0235   // that should be returned by Next().  Otherwise, a reasonable default
0236   // is used.
0237   explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
0238   OstreamOutputStream(const OstreamOutputStream&) = delete;
0239   OstreamOutputStream& operator=(const OstreamOutputStream&) = delete;
0240   ~OstreamOutputStream() override;
0241 
0242   // implements ZeroCopyOutputStream ---------------------------------
0243   bool Next(void** data, int* size) override;
0244   void BackUp(int count) override;
0245   int64_t ByteCount() const override;
0246 
0247  private:
0248   class PROTOBUF_EXPORT CopyingOstreamOutputStream final
0249       : public CopyingOutputStream {
0250    public:
0251     CopyingOstreamOutputStream(std::ostream* output);
0252     CopyingOstreamOutputStream(const CopyingOstreamOutputStream&) = delete;
0253     CopyingOstreamOutputStream& operator=(const CopyingOstreamOutputStream&) =
0254         delete;
0255     ~CopyingOstreamOutputStream() override;
0256 
0257     // implements CopyingOutputStream --------------------------------
0258     bool Write(const void* buffer, int size) override;
0259 
0260    private:
0261     // The stream.
0262     std::ostream* output_;
0263   };
0264 
0265   CopyingOstreamOutputStream copying_output_;
0266   CopyingOutputStreamAdaptor impl_;
0267 };
0268 
0269 // ===================================================================
0270 
0271 // A ZeroCopyInputStream which reads from several other streams in sequence.
0272 // ConcatenatingInputStream is unable to distinguish between end-of-stream
0273 // and read errors in the underlying streams, so it assumes any errors mean
0274 // end-of-stream.  So, if the underlying streams fail for any other reason,
0275 // ConcatenatingInputStream may do odd things.  It is suggested that you do
0276 // not use ConcatenatingInputStream on streams that might produce read errors
0277 // other than end-of-stream.
0278 class PROTOBUF_EXPORT ConcatenatingInputStream final
0279     : public ZeroCopyInputStream {
0280  public:
0281   // All streams passed in as well as the array itself must remain valid
0282   // until the ConcatenatingInputStream is destroyed.
0283   ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
0284   ConcatenatingInputStream(const ConcatenatingInputStream&) = delete;
0285   ConcatenatingInputStream& operator=(const ConcatenatingInputStream&) = delete;
0286   ~ConcatenatingInputStream() override = default;
0287 
0288   // implements ZeroCopyInputStream ----------------------------------
0289   bool Next(const void** data, int* size) override;
0290   void BackUp(int count) override;
0291   bool Skip(int count) override;
0292   int64_t ByteCount() const override;
0293 
0294 
0295  private:
0296   // As streams are retired, streams_ is incremented and count_ is
0297   // decremented.
0298   ZeroCopyInputStream* const* streams_;
0299   int stream_count_;
0300   int64_t bytes_retired_;  // Bytes read from previous streams.
0301 };
0302 
0303 // ===================================================================
0304 
0305 }  // namespace io
0306 }  // namespace protobuf
0307 }  // namespace google
0308 
0309 #include "google/protobuf/port_undef.inc"
0310 
0311 #endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__