zero_copy_stream_impl.h 13 KB

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