Initial import of v2.0.0beta
[protobuf.git] / src / google / protobuf / io / zero_copy_stream_impl.h
blobbd73afb7cff08ed1b197d6ca4e5250f27669e947
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
4 //
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
8 //
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__
31 #include <string>
32 #include <iosfwd>
33 #include <google/protobuf/io/zero_copy_stream.h>
34 #include <google/protobuf/stubs/common.h>
37 namespace google {
38 namespace protobuf {
39 namespace io {
41 // ===================================================================
43 // A ZeroCopyInputStream backed by an in-memory array of bytes.
44 class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
45 public:
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
52 // it.
53 ArrayInputStream(const void* data, int size, int block_size = -1);
54 ~ArrayInputStream();
56 // implements ZeroCopyInputStream ----------------------------------
57 bool Next(const void** data, int* size);
58 void BackUp(int count);
59 bool Skip(int count);
60 int64 ByteCount() const;
63 private:
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.
68 int position_;
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 {
79 public:
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
86 // it.
87 ArrayOutputStream(void* data, int size, int block_size = -1);
88 ~ArrayOutputStream();
90 // implements ZeroCopyOutputStream ---------------------------------
91 bool Next(void** data, int* size);
92 void BackUp(int count);
93 int64 ByteCount() const;
95 private:
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.
100 int position_;
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 {
111 public:
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
118 // space.
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;
127 private:
128 static const int kMinimumSize = 16;
130 string* target_;
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
154 // in large blocks.
155 class LIBPROTOBUF_EXPORT CopyingInputStream {
156 public:
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
170 // buffer.
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
180 // respectively.
181 class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
182 public:
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;
202 private:
203 // Insures that buffer_ is not NULL.
204 void AllocateBufferIfNeeded();
205 // Frees the buffer and resets buffer_used_.
206 void FreeBuffer();
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.
213 bool failed_;
215 // The current position of copying_stream_, relative to the point where
216 // we started reading.
217 int64 position_;
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_.
226 int buffer_used_;
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_
231 int backup_bytes_;
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
248 // in large blocks.
249 class LIBPROTOBUF_EXPORT CopyingOutputStream {
250 public:
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
264 // respectively.
265 class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
266 public:
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
270 // is used.
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.)
278 bool Flush();
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;
289 private:
290 // Write the current buffer, if it is present.
291 bool WriteBuffer();
292 // Insures that buffer_ is not NULL.
293 void AllocateBufferIfNeeded();
294 // Frees the buffer.
295 void FreeBuffer();
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.
302 bool failed_;
304 // The current position of copying_stream_, relative to the point where
305 // we started writing.
306 int64 position_;
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_.
316 int buffer_used_;
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 {
330 public:
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);
336 ~FileInputStream();
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.
341 bool Close();
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
353 // fail.
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;
362 private:
363 class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
364 public:
365 CopyingFileInputStream(int file_descriptor);
366 ~CopyingFileInputStream();
368 bool Close();
369 void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
370 int GetErrno() { return errno_; }
372 // implements CopyingInputStream ---------------------------------
373 int Read(void* buffer, int size);
374 int Skip(int count);
376 private:
377 // The file descriptor.
378 const int file_;
379 bool close_on_delete_;
380 bool is_closed_;
382 // The errno of the I/O error, if one has occurred. Otherwise, zero.
383 int errno_;
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 {
407 public:
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
411 // is used.
412 explicit FileOutputStream(int file_descriptor, int block_size = -1);
413 ~FileOutputStream();
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.
418 bool Close();
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
430 // fail.
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;
438 private:
439 class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
440 public:
441 CopyingFileOutputStream(int file_descriptor);
442 ~CopyingFileOutputStream();
444 bool Close();
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);
451 private:
452 // The file descriptor.
453 const int file_;
454 bool close_on_delete_;
455 bool is_closed_;
457 // The errno of the I/O error, if one has occurred. Otherwise, zero.
458 int errno_;
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 {
476 public:
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;
490 private:
491 class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
492 public:
493 CopyingIstreamInputStream(istream* input);
494 ~CopyingIstreamInputStream();
496 // implements CopyingInputStream ---------------------------------
497 int Read(void* buffer, int size);
498 // (We use the default implementation of Skip().)
500 private:
501 // The stream.
502 istream* input_;
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 {
520 public:
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
524 // is used.
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;
533 private:
534 class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
535 public:
536 CopyingOstreamOutputStream(ostream* output);
537 ~CopyingOstreamOutputStream();
539 // implements CopyingOutputStream --------------------------------
540 bool Write(const void* buffer, int size);
542 private:
543 // The stream.
544 ostream* output_;
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 {
565 public:
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;
578 private:
579 // As streams are retired, streams_ is incremented and count_ is
580 // decremented.
581 ZeroCopyInputStream* const* streams_;
582 int stream_count_;
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 {
593 public:
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;
604 private:
605 ZeroCopyInputStream* input_;
606 int64 limit_; // Decreases as we go, becomes negative if we overshoot.
608 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
611 // ===================================================================
613 } // namespace io
614 } // namespace protobuf
616 } // namespace google
617 #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__