PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/google/protobuf/io/zero_copy_stream_impl.h

https://gitlab.com/github-cloud-corporation/protobuf
C Header | 358 lines | 149 code | 69 blank | 140 comment | 0 complexity | 2629f05f27ece1f94c7cbac9cc8b02e4 MD5 | raw file
  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. ~FileInputStream();
  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() { return copying_input_.GetErrno(); }
  78. // implements ZeroCopyInputStream ----------------------------------
  79. bool Next(const void** data, int* size);
  80. void BackUp(int count);
  81. bool Skip(int count);
  82. int64 ByteCount() const;
  83. private:
  84. class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
  85. public:
  86. CopyingFileInputStream(int file_descriptor);
  87. ~CopyingFileInputStream();
  88. bool Close();
  89. void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
  90. int GetErrno() { return errno_; }
  91. // implements CopyingInputStream ---------------------------------
  92. int Read(void* buffer, int size);
  93. int Skip(int count);
  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 LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
  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();
  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. // Flushes FileOutputStream's buffers but does not close the
  131. // underlying file. No special measures are taken to ensure that
  132. // underlying operating system file object is synchronized to disk.
  133. bool Flush();
  134. // By default, the file descriptor is not closed when the stream is
  135. // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
  136. // This leaves no way for the caller to detect if close() fails. If
  137. // detecting close() errors is important to you, you should arrange
  138. // to close the descriptor yourself.
  139. void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
  140. // If an I/O error has occurred on this file descriptor, this is the
  141. // errno from that error. Otherwise, this is zero. Once an error
  142. // occurs, the stream is broken and all subsequent operations will
  143. // fail.
  144. int GetErrno() { return copying_output_.GetErrno(); }
  145. // implements ZeroCopyOutputStream ---------------------------------
  146. bool Next(void** data, int* size);
  147. void BackUp(int count);
  148. int64 ByteCount() const;
  149. private:
  150. class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
  151. public:
  152. CopyingFileOutputStream(int file_descriptor);
  153. ~CopyingFileOutputStream();
  154. bool Close();
  155. void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
  156. int GetErrno() { return errno_; }
  157. // implements CopyingOutputStream --------------------------------
  158. bool Write(const void* buffer, int size);
  159. private:
  160. // The file descriptor.
  161. const int file_;
  162. bool close_on_delete_;
  163. bool is_closed_;
  164. // The errno of the I/O error, if one has occurred. Otherwise, zero.
  165. int errno_;
  166. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
  167. };
  168. CopyingFileOutputStream copying_output_;
  169. CopyingOutputStreamAdaptor impl_;
  170. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
  171. };
  172. // ===================================================================
  173. // A ZeroCopyInputStream which reads from a C++ istream.
  174. //
  175. // Note that for reading files (or anything represented by a file descriptor),
  176. // FileInputStream is more efficient.
  177. class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
  178. public:
  179. // Creates a stream that reads from the given C++ istream.
  180. // If a block_size is given, it specifies the number of bytes that
  181. // should be read and returned with each call to Next(). Otherwise,
  182. // a reasonable default is used.
  183. explicit IstreamInputStream(istream* stream, int block_size = -1);
  184. ~IstreamInputStream();
  185. // implements ZeroCopyInputStream ----------------------------------
  186. bool Next(const void** data, int* size);
  187. void BackUp(int count);
  188. bool Skip(int count);
  189. int64 ByteCount() const;
  190. private:
  191. class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
  192. public:
  193. CopyingIstreamInputStream(istream* input);
  194. ~CopyingIstreamInputStream();
  195. // implements CopyingInputStream ---------------------------------
  196. int Read(void* buffer, int size);
  197. // (We use the default implementation of Skip().)
  198. private:
  199. // The stream.
  200. istream* input_;
  201. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
  202. };
  203. CopyingIstreamInputStream copying_input_;
  204. CopyingInputStreamAdaptor impl_;
  205. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
  206. };
  207. // ===================================================================
  208. // A ZeroCopyOutputStream which writes to a C++ ostream.
  209. //
  210. // Note that for writing files (or anything represented by a file descriptor),
  211. // FileOutputStream is more efficient.
  212. class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
  213. public:
  214. // Creates a stream that writes to the given C++ ostream.
  215. // If a block_size is given, it specifies the size of the buffers
  216. // that should be returned by Next(). Otherwise, a reasonable default
  217. // is used.
  218. explicit OstreamOutputStream(ostream* stream, int block_size = -1);
  219. ~OstreamOutputStream();
  220. // implements ZeroCopyOutputStream ---------------------------------
  221. bool Next(void** data, int* size);
  222. void BackUp(int count);
  223. int64 ByteCount() const;
  224. private:
  225. class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
  226. public:
  227. CopyingOstreamOutputStream(ostream* output);
  228. ~CopyingOstreamOutputStream();
  229. // implements CopyingOutputStream --------------------------------
  230. bool Write(const void* buffer, int size);
  231. private:
  232. // The stream.
  233. ostream* output_;
  234. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
  235. };
  236. CopyingOstreamOutputStream copying_output_;
  237. CopyingOutputStreamAdaptor impl_;
  238. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
  239. };
  240. // ===================================================================
  241. // A ZeroCopyInputStream which reads from several other streams in sequence.
  242. // ConcatenatingInputStream is unable to distinguish between end-of-stream
  243. // and read errors in the underlying streams, so it assumes any errors mean
  244. // end-of-stream. So, if the underlying streams fail for any other reason,
  245. // ConcatenatingInputStream may do odd things. It is suggested that you do
  246. // not use ConcatenatingInputStream on streams that might produce read errors
  247. // other than end-of-stream.
  248. class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
  249. public:
  250. // All streams passed in as well as the array itself must remain valid
  251. // until the ConcatenatingInputStream is destroyed.
  252. ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
  253. ~ConcatenatingInputStream();
  254. // implements ZeroCopyInputStream ----------------------------------
  255. bool Next(const void** data, int* size);
  256. void BackUp(int count);
  257. bool Skip(int count);
  258. int64 ByteCount() const;
  259. private:
  260. // As streams are retired, streams_ is incremented and count_ is
  261. // decremented.
  262. ZeroCopyInputStream* const* streams_;
  263. int stream_count_;
  264. int64 bytes_retired_; // Bytes read from previous streams.
  265. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
  266. };
  267. // ===================================================================
  268. // A ZeroCopyInputStream which wraps some other stream and limits it to
  269. // a particular byte count.
  270. class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
  271. public:
  272. LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
  273. ~LimitingInputStream();
  274. // implements ZeroCopyInputStream ----------------------------------
  275. bool Next(const void** data, int* size);
  276. void BackUp(int count);
  277. bool Skip(int count);
  278. int64 ByteCount() const;
  279. private:
  280. ZeroCopyInputStream* input_;
  281. int64 limit_; // Decreases as we go, becomes negative if we overshoot.
  282. int64 prior_bytes_read_; // Bytes read on underlying stream at construction
  283. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
  284. };
  285. // ===================================================================
  286. } // namespace io
  287. } // namespace protobuf
  288. } // namespace google
  289. #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__