zero_copy_stream_impl.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // This file contains common implementations of the interfaces defined in
  35. // zero_copy_stream.h which are only included in the full (non-lite)
  36. // protobuf library. These implementations include Unix file descriptors
  37. // and C++ iostreams. See also: zero_copy_stream_impl_lite.h
  38. #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
  39. #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
  40. #include <iosfwd>
  41. #include <string>
  42. #include <google/protobuf/stubs/common.h>
  43. #include <google/protobuf/io/zero_copy_stream.h>
  44. #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
  45. #include <google/protobuf/port_def.inc>
  46. namespace google {
  47. namespace protobuf {
  48. namespace io {
  49. // ===================================================================
  50. // A ZeroCopyInputStream which reads from a file descriptor.
  51. //
  52. // FileInputStream is preferred over using an ifstream with IstreamInputStream.
  53. // The latter will introduce an extra layer of buffering, harming performance.
  54. // Also, it's conceivable that FileInputStream could someday be enhanced
  55. // to use zero-copy file descriptors on OSs which support them.
  56. class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
  57. public:
  58. // Creates a stream that reads from the given Unix file descriptor.
  59. // If a block_size is given, it specifies the number of bytes that
  60. // should be read and returned with each call to Next(). Otherwise,
  61. // a reasonable default is used.
  62. explicit FileInputStream(int file_descriptor, int block_size = -1);
  63. // Flushes any buffers and closes the underlying file. Returns false if
  64. // an error occurs during the process; use GetErrno() to examine the error.
  65. // Even if an error occurs, the file descriptor is closed when this returns.
  66. bool Close();
  67. // By default, the file descriptor is not closed when the stream is
  68. // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
  69. // This leaves no way for the caller to detect if close() fails. If
  70. // detecting close() errors is important to you, you should arrange
  71. // to close the descriptor yourself.
  72. void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
  73. // If an I/O error has occurred on this file descriptor, this is the
  74. // errno from that error. Otherwise, this is zero. Once an error
  75. // occurs, the stream is broken and all subsequent operations will
  76. // fail.
  77. int GetErrno() const { return copying_input_.GetErrno(); }
  78. // implements ZeroCopyInputStream ----------------------------------
  79. bool Next(const void** data, int* size) override;
  80. void BackUp(int count) override;
  81. bool Skip(int count) override;
  82. int64_t ByteCount() const override;
  83. private:
  84. class PROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
  85. public:
  86. CopyingFileInputStream(int file_descriptor);
  87. ~CopyingFileInputStream() override;
  88. bool Close();
  89. void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
  90. int GetErrno() const { return errno_; }
  91. // implements CopyingInputStream ---------------------------------
  92. int Read(void* buffer, int size) override;
  93. int Skip(int count) override;
  94. private:
  95. // The file descriptor.
  96. const int file_;
  97. bool close_on_delete_;
  98. bool is_closed_;
  99. // The errno of the I/O error, if one has occurred. Otherwise, zero.
  100. int errno_;
  101. // Did we try to seek once and fail? If so, we assume this file descriptor
  102. // doesn't support seeking and won't try again.
  103. bool previous_seek_failed_;
  104. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
  105. };
  106. CopyingFileInputStream copying_input_;
  107. CopyingInputStreamAdaptor impl_;
  108. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
  109. };
  110. // ===================================================================
  111. // A ZeroCopyOutputStream which writes to a file descriptor.
  112. //
  113. // FileOutputStream is preferred over using an ofstream with
  114. // OstreamOutputStream. The latter will introduce an extra layer of buffering,
  115. // harming performance. Also, it's conceivable that FileOutputStream could
  116. // someday be enhanced to use zero-copy file descriptors on OSs which
  117. // support them.
  118. class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor {
  119. public:
  120. // Creates a stream that writes to the given Unix file descriptor.
  121. // If a block_size is given, it specifies the size of the buffers
  122. // that should be returned by Next(). Otherwise, a reasonable default
  123. // is used.
  124. explicit FileOutputStream(int file_descriptor, int block_size = -1);
  125. ~FileOutputStream() override;
  126. // Flushes any buffers and closes the underlying file. Returns false if
  127. // an error occurs during the process; use GetErrno() to examine the error.
  128. // Even if an error occurs, the file descriptor is closed when this returns.
  129. bool Close();
  130. // By default, the file descriptor is not closed when the stream is
  131. // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
  132. // This leaves no way for the caller to detect if close() fails. If
  133. // detecting close() errors is important to you, you should arrange
  134. // to close the descriptor yourself.
  135. void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
  136. // If an I/O error has occurred on this file descriptor, this is the
  137. // errno from that error. Otherwise, this is zero. Once an error
  138. // occurs, the stream is broken and all subsequent operations will
  139. // fail.
  140. int GetErrno() const { return copying_output_.GetErrno(); }
  141. private:
  142. class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
  143. public:
  144. CopyingFileOutputStream(int file_descriptor);
  145. ~CopyingFileOutputStream() override;
  146. bool Close();
  147. void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
  148. int GetErrno() const { return errno_; }
  149. // implements CopyingOutputStream --------------------------------
  150. bool Write(const void* buffer, int size) override;
  151. private:
  152. // The file descriptor.
  153. const int file_;
  154. bool close_on_delete_;
  155. bool is_closed_;
  156. // The errno of the I/O error, if one has occurred. Otherwise, zero.
  157. int errno_;
  158. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
  159. };
  160. CopyingFileOutputStream copying_output_;
  161. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
  162. };
  163. // ===================================================================
  164. // A ZeroCopyInputStream which reads from a C++ istream.
  165. //
  166. // Note that for reading files (or anything represented by a file descriptor),
  167. // FileInputStream is more efficient.
  168. class PROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
  169. public:
  170. // Creates a stream that reads from the given C++ istream.
  171. // If a block_size is given, it specifies the number of bytes that
  172. // should be read and returned with each call to Next(). Otherwise,
  173. // a reasonable default is used.
  174. explicit IstreamInputStream(std::istream* stream, int block_size = -1);
  175. // implements ZeroCopyInputStream ----------------------------------
  176. bool Next(const void** data, int* size) override;
  177. void BackUp(int count) override;
  178. bool Skip(int count) override;
  179. int64_t ByteCount() const override;
  180. private:
  181. class PROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
  182. public:
  183. CopyingIstreamInputStream(std::istream* input);
  184. ~CopyingIstreamInputStream() override;
  185. // implements CopyingInputStream ---------------------------------
  186. int Read(void* buffer, int size) override;
  187. // (We use the default implementation of Skip().)
  188. private:
  189. // The stream.
  190. std::istream* input_;
  191. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
  192. };
  193. CopyingIstreamInputStream copying_input_;
  194. CopyingInputStreamAdaptor impl_;
  195. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
  196. };
  197. // ===================================================================
  198. // A ZeroCopyOutputStream which writes to a C++ ostream.
  199. //
  200. // Note that for writing files (or anything represented by a file descriptor),
  201. // FileOutputStream is more efficient.
  202. class PROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
  203. public:
  204. // Creates a stream that writes to the given C++ ostream.
  205. // If a block_size is given, it specifies the size of the buffers
  206. // that should be returned by Next(). Otherwise, a reasonable default
  207. // is used.
  208. explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
  209. ~OstreamOutputStream() override;
  210. // implements ZeroCopyOutputStream ---------------------------------
  211. bool Next(void** data, int* size) override;
  212. void BackUp(int count) override;
  213. int64_t ByteCount() const override;
  214. private:
  215. class PROTOBUF_EXPORT CopyingOstreamOutputStream
  216. : public CopyingOutputStream {
  217. public:
  218. CopyingOstreamOutputStream(std::ostream* output);
  219. ~CopyingOstreamOutputStream() override;
  220. // implements CopyingOutputStream --------------------------------
  221. bool Write(const void* buffer, int size) override;
  222. private:
  223. // The stream.
  224. std::ostream* output_;
  225. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
  226. };
  227. CopyingOstreamOutputStream copying_output_;
  228. CopyingOutputStreamAdaptor impl_;
  229. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
  230. };
  231. // ===================================================================
  232. // A ZeroCopyInputStream which reads from several other streams in sequence.
  233. // ConcatenatingInputStream is unable to distinguish between end-of-stream
  234. // and read errors in the underlying streams, so it assumes any errors mean
  235. // end-of-stream. So, if the underlying streams fail for any other reason,
  236. // ConcatenatingInputStream may do odd things. It is suggested that you do
  237. // not use ConcatenatingInputStream on streams that might produce read errors
  238. // other than end-of-stream.
  239. class PROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
  240. public:
  241. // All streams passed in as well as the array itself must remain valid
  242. // until the ConcatenatingInputStream is destroyed.
  243. ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
  244. ~ConcatenatingInputStream() override = default;
  245. // implements ZeroCopyInputStream ----------------------------------
  246. bool Next(const void** data, int* size) override;
  247. void BackUp(int count) override;
  248. bool Skip(int count) override;
  249. int64_t ByteCount() const override;
  250. private:
  251. // As streams are retired, streams_ is incremented and count_ is
  252. // decremented.
  253. ZeroCopyInputStream* const* streams_;
  254. int stream_count_;
  255. int64_t bytes_retired_; // Bytes read from previous streams.
  256. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
  257. };
  258. // ===================================================================
  259. } // namespace io
  260. } // namespace protobuf
  261. } // namespace google
  262. #include <google/protobuf/port_undef.inc>
  263. #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__