1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
21 // This file contains common implementations of the interfaces defined in
22 // zero_copy_stream.h. These implementations cover I/O on raw arrays,
23 // strings, and file descriptors. Of course, many users will probably
24 // want to write their own implementations of these interfaces specific
25 // to the particular I/O abstractions they prefer to use, but these
26 // should cover the most common cases.
28 #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
29 #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
33 #include <google/protobuf/io/zero_copy_stream.h>
34 #include <google/protobuf/stubs/common.h>
41 // ===================================================================
43 // A ZeroCopyInputStream backed by an in-memory array of bytes.
44 class LIBPROTOBUF_EXPORT ArrayInputStream
: public ZeroCopyInputStream
{
46 // Create an InputStream that returns the bytes pointed to by "data".
47 // "data" remains the property of the caller but must remain valid until
48 // the stream is destroyed. If a block_size is given, calls to Next()
49 // will return data blocks no larger than the given size. Otherwise, the
50 // first call to Next() returns the entire array. block_size is mainly
51 // useful for testing; in production you would probably never want to set
53 ArrayInputStream(const void* data
, int size
, int block_size
= -1);
56 // implements ZeroCopyInputStream ----------------------------------
57 bool Next(const void** data
, int* size
);
58 void BackUp(int count
);
60 int64
ByteCount() const;
64 const uint8
* const data_
; // The byte array.
65 const int size_
; // Total size of the array.
66 const int block_size_
; // How many bytes to return at a time.
69 int last_returned_size_
; // How many bytes we returned last time Next()
70 // was called (used for error checking only).
72 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream
);
75 // ===================================================================
77 // A ZeroCopyOutputStream backed by an in-memory array of bytes.
78 class LIBPROTOBUF_EXPORT ArrayOutputStream
: public ZeroCopyOutputStream
{
80 // Create an OutputStream that writes to the bytes pointed to by "data".
81 // "data" remains the property of the caller but must remain valid until
82 // the stream is destroyed. If a block_size is given, calls to Next()
83 // will return data blocks no larger than the given size. Otherwise, the
84 // first call to Next() returns the entire array. block_size is mainly
85 // useful for testing; in production you would probably never want to set
87 ArrayOutputStream(void* data
, int size
, int block_size
= -1);
90 // implements ZeroCopyOutputStream ---------------------------------
91 bool Next(void** data
, int* size
);
92 void BackUp(int count
);
93 int64
ByteCount() const;
96 uint8
* const data_
; // The byte array.
97 const int size_
; // Total size of the array.
98 const int block_size_
; // How many bytes to return at a time.
101 int last_returned_size_
; // How many bytes we returned last time Next()
102 // was called (used for error checking only).
104 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream
);
107 // ===================================================================
109 // A ZeroCopyOutputStream which appends bytes to a string.
110 class LIBPROTOBUF_EXPORT StringOutputStream
: public ZeroCopyOutputStream
{
112 // Create a StringOutputStream which appends bytes to the given string.
113 // The string remains property of the caller, but it MUST NOT be accessed
114 // in any way until the stream is destroyed.
116 // Hint: If you call target->reserve(n) before creating the stream,
117 // the first call to Next() will return at least n bytes of buffer
119 explicit StringOutputStream(string
* target
);
120 ~StringOutputStream();
122 // implements ZeroCopyOutputStream ---------------------------------
123 bool Next(void** data
, int* size
);
124 void BackUp(int count
);
125 int64
ByteCount() const;
128 static const int kMinimumSize
= 16;
132 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream
);
135 // Note: There is no StringInputStream. Instead, just create an
136 // ArrayInputStream as follows:
137 // ArrayInputStream input(str.data(), str.size());
139 // ===================================================================
142 // ===================================================================
144 // A generic traditional input stream interface.
146 // Lots of traditional input streams (e.g. file descriptors, C stdio
147 // streams, and C++ iostreams) expose an interface where every read
148 // involves copying bytes into a buffer. If you want to take such an
149 // interface and make a ZeroCopyInputStream based on it, simply implement
150 // CopyingInputStream and then use CopyingInputStreamAdaptor.
152 // CopyingInputStream implementations should avoid buffering if possible.
153 // CopyingInputStreamAdaptor does its own buffering and will read data
155 class LIBPROTOBUF_EXPORT CopyingInputStream
{
157 virtual ~CopyingInputStream();
159 // Reads up to "size" bytes into the given buffer. Returns the number of
160 // bytes read. Read() waits until at least one byte is available, or
161 // returns zero if no bytes will ever become available (EOF), or -1 if a
162 // permanent read error occurred.
163 virtual int Read(void* buffer
, int size
) = 0;
165 // Skips the next "count" bytes of input. Returns the number of bytes
166 // actually skipped. This will always be exactly equal to "count" unless
167 // EOF was reached or a permanent read error occurred.
169 // The default implementation just repeatedly calls Read() into a scratch
171 virtual int Skip(int count
);
174 // A ZeroCopyInputStream which reads from a CopyingInputStream. This is
175 // useful for implementing ZeroCopyInputStreams that read from traditional
176 // streams. Note that this class is not really zero-copy.
178 // If you want to read from file descriptors or C++ istreams, this is
179 // already implemented for you: use FileInputStream or IstreamInputStream
181 class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor
: public ZeroCopyInputStream
{
183 // Creates a stream that reads from the given CopyingInputStream.
184 // If a block_size is given, it specifies the number of bytes that
185 // should be read and returned with each call to Next(). Otherwise,
186 // a reasonable default is used. The caller retains ownership of
187 // copying_stream unless SetOwnsCopyingStream(true) is called.
188 explicit CopyingInputStreamAdaptor(CopyingInputStream
* copying_stream
,
189 int block_size
= -1);
190 ~CopyingInputStreamAdaptor();
192 // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
193 // delete the underlying CopyingInputStream when it is destroyed.
194 void SetOwnsCopyingStream(bool value
) { owns_copying_stream_
= value
; }
196 // implements ZeroCopyInputStream ----------------------------------
197 bool Next(const void** data
, int* size
);
198 void BackUp(int count
);
199 bool Skip(int count
);
200 int64
ByteCount() const;
203 // Insures that buffer_ is not NULL.
204 void AllocateBufferIfNeeded();
205 // Frees the buffer and resets buffer_used_.
208 // The underlying copying stream.
209 CopyingInputStream
* copying_stream_
;
210 bool owns_copying_stream_
;
212 // True if we have seen a permenant error from the underlying stream.
215 // The current position of copying_stream_, relative to the point where
216 // we started reading.
219 // Data is read into this buffer. It may be NULL if no buffer is currently
220 // in use. Otherwise, it points to an array of size buffer_size_.
221 scoped_array
<uint8
> buffer_
;
222 const int buffer_size_
;
224 // Number of valid bytes currently in the buffer (i.e. the size last
225 // returned by Next()). 0 <= buffer_used_ <= buffer_size_.
228 // Number of bytes in the buffer which were backed up over by a call to
229 // BackUp(). These need to be returned again.
230 // 0 <= backup_bytes_ <= buffer_used_
233 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor
);
236 // ===================================================================
238 // A generic traditional output stream interface.
240 // Lots of traditional output streams (e.g. file descriptors, C stdio
241 // streams, and C++ iostreams) expose an interface where every write
242 // involves copying bytes from a buffer. If you want to take such an
243 // interface and make a ZeroCopyOutputStream based on it, simply implement
244 // CopyingOutputStream and then use CopyingOutputStreamAdaptor.
246 // CopyingOutputStream implementations should avoid buffering if possible.
247 // CopyingOutputStreamAdaptor does its own buffering and will write data
249 class LIBPROTOBUF_EXPORT CopyingOutputStream
{
251 virtual ~CopyingOutputStream();
253 // Writes "size" bytes from the given buffer to the output. Returns true
254 // if successful, false on a write error.
255 virtual bool Write(const void* buffer
, int size
) = 0;
258 // A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is
259 // useful for implementing ZeroCopyOutputStreams that write to traditional
260 // streams. Note that this class is not really zero-copy.
262 // If you want to write to file descriptors or C++ ostreams, this is
263 // already implemented for you: use FileOutputStream or OstreamOutputStream
265 class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor
: public ZeroCopyOutputStream
{
267 // Creates a stream that writes to the given Unix file descriptor.
268 // If a block_size is given, it specifies the size of the buffers
269 // that should be returned by Next(). Otherwise, a reasonable default
271 explicit CopyingOutputStreamAdaptor(CopyingOutputStream
* copying_stream
,
272 int block_size
= -1);
273 ~CopyingOutputStreamAdaptor();
275 // Writes all pending data to the underlying stream. Returns false if a
276 // write error occurred on the underlying stream. (The underlying
277 // stream itself is not necessarily flushed.)
280 // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
281 // delete the underlying CopyingOutputStream when it is destroyed.
282 void SetOwnsCopyingStream(bool value
) { owns_copying_stream_
= value
; }
284 // implements ZeroCopyOutputStream ---------------------------------
285 bool Next(void** data
, int* size
);
286 void BackUp(int count
);
287 int64
ByteCount() const;
290 // Write the current buffer, if it is present.
292 // Insures that buffer_ is not NULL.
293 void AllocateBufferIfNeeded();
297 // The underlying copying stream.
298 CopyingOutputStream
* copying_stream_
;
299 bool owns_copying_stream_
;
301 // True if we have seen a permenant error from the underlying stream.
304 // The current position of copying_stream_, relative to the point where
305 // we started writing.
308 // Data is written from this buffer. It may be NULL if no buffer is
309 // currently in use. Otherwise, it points to an array of size buffer_size_.
310 scoped_array
<uint8
> buffer_
;
311 const int buffer_size_
;
313 // Number of valid bytes currently in the buffer (i.e. the size last
314 // returned by Next()). When BackUp() is called, we just reduce this.
315 // 0 <= buffer_used_ <= buffer_size_.
318 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor
);
321 // ===================================================================
323 // A ZeroCopyInputStream which reads from a file descriptor.
325 // FileInputStream is preferred over using an ifstream with IstreamInputStream.
326 // The latter will introduce an extra layer of buffering, harming performance.
327 // Also, it's conceivable that FileInputStream could someday be enhanced
328 // to use zero-copy file descriptors on OSs which support them.
329 class LIBPROTOBUF_EXPORT FileInputStream
: public ZeroCopyInputStream
{
331 // Creates a stream that reads from the given Unix file descriptor.
332 // If a block_size is given, it specifies the number of bytes that
333 // should be read and returned with each call to Next(). Otherwise,
334 // a reasonable default is used.
335 explicit FileInputStream(int file_descriptor
, int block_size
= -1);
338 // Flushes any buffers and closes the underlying file. Returns false if
339 // an error occurs during the process; use GetErrno() to examine the error.
340 // Even if an error occurs, the file descriptor is closed when this returns.
343 // By default, the file descriptor is not closed when the stream is
344 // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
345 // This leaves no way for the caller to detect if close() fails. If
346 // detecting close() errors is important to you, you should arrange
347 // to close the descriptor yourself.
348 void SetCloseOnDelete(bool value
) { copying_input_
.SetCloseOnDelete(value
); }
350 // If an I/O error has occurred on this file descriptor, this is the
351 // errno from that error. Otherwise, this is zero. Once an error
352 // occurs, the stream is broken and all subsequent operations will
354 int GetErrno() { return copying_input_
.GetErrno(); }
356 // implements ZeroCopyInputStream ----------------------------------
357 bool Next(const void** data
, int* size
);
358 void BackUp(int count
);
359 bool Skip(int count
);
360 int64
ByteCount() const;
363 class LIBPROTOBUF_EXPORT CopyingFileInputStream
: public CopyingInputStream
{
365 CopyingFileInputStream(int file_descriptor
);
366 ~CopyingFileInputStream();
369 void SetCloseOnDelete(bool value
) { close_on_delete_
= value
; }
370 int GetErrno() { return errno_
; }
372 // implements CopyingInputStream ---------------------------------
373 int Read(void* buffer
, int size
);
377 // The file descriptor.
379 bool close_on_delete_
;
382 // The errno of the I/O error, if one has occurred. Otherwise, zero.
385 // Did we try to seek once and fail? If so, we assume this file descriptor
386 // doesn't support seeking and won't try again.
387 bool previous_seek_failed_
;
389 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream
);
392 CopyingFileInputStream copying_input_
;
393 CopyingInputStreamAdaptor impl_
;
395 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream
);
398 // ===================================================================
400 // A ZeroCopyOutputStream which writes to a file descriptor.
402 // FileInputStream is preferred over using an ofstream with OstreamOutputStream.
403 // The latter will introduce an extra layer of buffering, harming performance.
404 // Also, it's conceivable that FileInputStream could someday be enhanced
405 // to use zero-copy file descriptors on OSs which support them.
406 class LIBPROTOBUF_EXPORT FileOutputStream
: public ZeroCopyOutputStream
{
408 // Creates a stream that writes to the given Unix file descriptor.
409 // If a block_size is given, it specifies the size of the buffers
410 // that should be returned by Next(). Otherwise, a reasonable default
412 explicit FileOutputStream(int file_descriptor
, int block_size
= -1);
415 // Flushes any buffers and closes the underlying file. Returns false if
416 // an error occurs during the process; use GetErrno() to examine the error.
417 // Even if an error occurs, the file descriptor is closed when this returns.
420 // By default, the file descriptor is not closed when the stream is
421 // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
422 // This leaves no way for the caller to detect if close() fails. If
423 // detecting close() errors is important to you, you should arrange
424 // to close the descriptor yourself.
425 void SetCloseOnDelete(bool value
) { copying_output_
.SetCloseOnDelete(value
); }
427 // If an I/O error has occurred on this file descriptor, this is the
428 // errno from that error. Otherwise, this is zero. Once an error
429 // occurs, the stream is broken and all subsequent operations will
431 int GetErrno() { return copying_output_
.GetErrno(); }
433 // implements ZeroCopyOutputStream ---------------------------------
434 bool Next(void** data
, int* size
);
435 void BackUp(int count
);
436 int64
ByteCount() const;
439 class LIBPROTOBUF_EXPORT CopyingFileOutputStream
: public CopyingOutputStream
{
441 CopyingFileOutputStream(int file_descriptor
);
442 ~CopyingFileOutputStream();
445 void SetCloseOnDelete(bool value
) { close_on_delete_
= value
; }
446 int GetErrno() { return errno_
; }
448 // implements CopyingOutputStream --------------------------------
449 bool Write(const void* buffer
, int size
);
452 // The file descriptor.
454 bool close_on_delete_
;
457 // The errno of the I/O error, if one has occurred. Otherwise, zero.
460 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream
);
463 CopyingFileOutputStream copying_output_
;
464 CopyingOutputStreamAdaptor impl_
;
466 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream
);
469 // ===================================================================
471 // A ZeroCopyInputStream which reads from a C++ istream.
473 // Note that for reading files (or anything represented by a file descriptor),
474 // FileInputStream is more efficient.
475 class LIBPROTOBUF_EXPORT IstreamInputStream
: public ZeroCopyInputStream
{
477 // Creates a stream that reads from the given C++ istream.
478 // If a block_size is given, it specifies the number of bytes that
479 // should be read and returned with each call to Next(). Otherwise,
480 // a reasonable default is used.
481 explicit IstreamInputStream(istream
* stream
, int block_size
= -1);
482 ~IstreamInputStream();
484 // implements ZeroCopyInputStream ----------------------------------
485 bool Next(const void** data
, int* size
);
486 void BackUp(int count
);
487 bool Skip(int count
);
488 int64
ByteCount() const;
491 class LIBPROTOBUF_EXPORT CopyingIstreamInputStream
: public CopyingInputStream
{
493 CopyingIstreamInputStream(istream
* input
);
494 ~CopyingIstreamInputStream();
496 // implements CopyingInputStream ---------------------------------
497 int Read(void* buffer
, int size
);
498 // (We use the default implementation of Skip().)
504 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream
);
507 CopyingIstreamInputStream copying_input_
;
508 CopyingInputStreamAdaptor impl_
;
510 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream
);
513 // ===================================================================
515 // A ZeroCopyOutputStream which writes to a C++ ostream.
517 // Note that for writing files (or anything represented by a file descriptor),
518 // FileOutputStream is more efficient.
519 class LIBPROTOBUF_EXPORT OstreamOutputStream
: public ZeroCopyOutputStream
{
521 // Creates a stream that writes to the given C++ ostream.
522 // If a block_size is given, it specifies the size of the buffers
523 // that should be returned by Next(). Otherwise, a reasonable default
525 explicit OstreamOutputStream(ostream
* stream
, int block_size
= -1);
526 ~OstreamOutputStream();
528 // implements ZeroCopyOutputStream ---------------------------------
529 bool Next(void** data
, int* size
);
530 void BackUp(int count
);
531 int64
ByteCount() const;
534 class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream
: public CopyingOutputStream
{
536 CopyingOstreamOutputStream(ostream
* output
);
537 ~CopyingOstreamOutputStream();
539 // implements CopyingOutputStream --------------------------------
540 bool Write(const void* buffer
, int size
);
546 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream
);
549 CopyingOstreamOutputStream copying_output_
;
550 CopyingOutputStreamAdaptor impl_
;
552 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream
);
555 // ===================================================================
557 // A ZeroCopyInputStream which reads from several other streams in sequence.
558 // ConcatenatingInputStream is unable to distinguish between end-of-stream
559 // and read errors in the underlying streams, so it assumes any errors mean
560 // end-of-stream. So, if the underlying streams fail for any other reason,
561 // ConcatenatingInputStream may do odd things. It is suggested that you do
562 // not use ConcatenatingInputStream on streams that might produce read errors
563 // other than end-of-stream.
564 class LIBPROTOBUF_EXPORT ConcatenatingInputStream
: public ZeroCopyInputStream
{
566 // All streams passed in as well as the array itself must remain valid
567 // until the ConcatenatingInputStream is destroyed.
568 ConcatenatingInputStream(ZeroCopyInputStream
* const streams
[], int count
);
569 ~ConcatenatingInputStream();
571 // implements ZeroCopyInputStream ----------------------------------
572 bool Next(const void** data
, int* size
);
573 void BackUp(int count
);
574 bool Skip(int count
);
575 int64
ByteCount() const;
579 // As streams are retired, streams_ is incremented and count_ is
581 ZeroCopyInputStream
* const* streams_
;
583 int64 bytes_retired_
; // Bytes read from previous streams.
585 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream
);
588 // ===================================================================
590 // A ZeroCopyInputStream which wraps some other stream and limits it to
591 // a particular byte count.
592 class LIBPROTOBUF_EXPORT LimitingInputStream
: public ZeroCopyInputStream
{
594 LimitingInputStream(ZeroCopyInputStream
* input
, int64 limit
);
595 ~LimitingInputStream();
597 // implements ZeroCopyInputStream ----------------------------------
598 bool Next(const void** data
, int* size
);
599 void BackUp(int count
);
600 bool Skip(int count
);
601 int64
ByteCount() const;
605 ZeroCopyInputStream
* input_
;
606 int64 limit_
; // Decreases as we go, becomes negative if we overshoot.
608 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream
);
611 // ===================================================================
614 } // namespace protobuf
616 } // namespace google
617 #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__