1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc. All rights reserved.
3
// http://code.google.com/p/protobuf/
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
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
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.
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.
31
// Author: kenton@google.com (Kenton Varda)
32
// Based on original Protocol Buffers design by
33
// Sanjay Ghemawat, Jeff Dean, and others.
35
// This file contains common implementations of the interfaces defined in
36
// zero_copy_stream.h which are only included in the full (non-lite)
37
// protobuf library. These implementations include Unix file descriptors
38
// and C++ iostreams. See also: zero_copy_stream_impl_lite.h
40
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
41
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
45
#include <google/protobuf/io/zero_copy_stream.h>
46
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
47
#include <google/protobuf/stubs/common.h>
55
// ===================================================================
57
// A ZeroCopyInputStream which reads from a file descriptor.
59
// FileInputStream is preferred over using an ifstream with IstreamInputStream.
60
// The latter will introduce an extra layer of buffering, harming performance.
61
// Also, it's conceivable that FileInputStream could someday be enhanced
62
// to use zero-copy file descriptors on OSs which support them.
63
class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
65
// Creates a stream that reads from the given Unix file descriptor.
66
// If a block_size is given, it specifies the number of bytes that
67
// should be read and returned with each call to Next(). Otherwise,
68
// a reasonable default is used.
69
explicit FileInputStream(int file_descriptor, int block_size = -1);
72
// Flushes any buffers and closes the underlying file. Returns false if
73
// an error occurs during the process; use GetErrno() to examine the error.
74
// Even if an error occurs, the file descriptor is closed when this returns.
77
// By default, the file descriptor is not closed when the stream is
78
// destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
79
// This leaves no way for the caller to detect if close() fails. If
80
// detecting close() errors is important to you, you should arrange
81
// to close the descriptor yourself.
82
void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
84
// If an I/O error has occurred on this file descriptor, this is the
85
// errno from that error. Otherwise, this is zero. Once an error
86
// occurs, the stream is broken and all subsequent operations will
88
int GetErrno() { return copying_input_.GetErrno(); }
90
// implements ZeroCopyInputStream ----------------------------------
91
bool Next(const void** data, int* size);
92
void BackUp(int count);
94
int64 ByteCount() const;
97
class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
99
CopyingFileInputStream(int file_descriptor);
100
~CopyingFileInputStream();
103
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
104
int GetErrno() { return errno_; }
106
// implements CopyingInputStream ---------------------------------
107
int Read(void* buffer, int size);
111
// The file descriptor.
113
bool close_on_delete_;
116
// The errno of the I/O error, if one has occurred. Otherwise, zero.
119
// Did we try to seek once and fail? If so, we assume this file descriptor
120
// doesn't support seeking and won't try again.
121
bool previous_seek_failed_;
123
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
126
CopyingFileInputStream copying_input_;
127
CopyingInputStreamAdaptor impl_;
129
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
132
// ===================================================================
134
// A ZeroCopyOutputStream which writes to a file descriptor.
136
// FileOutputStream is preferred over using an ofstream with
137
// OstreamOutputStream. The latter will introduce an extra layer of buffering,
138
// harming performance. Also, it's conceivable that FileOutputStream could
139
// someday be enhanced to use zero-copy file descriptors on OSs which
141
class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
143
// Creates a stream that writes to the given Unix file descriptor.
144
// If a block_size is given, it specifies the size of the buffers
145
// that should be returned by Next(). Otherwise, a reasonable default
147
explicit FileOutputStream(int file_descriptor, int block_size = -1);
150
// Flushes any buffers and closes the underlying file. Returns false if
151
// an error occurs during the process; use GetErrno() to examine the error.
152
// Even if an error occurs, the file descriptor is closed when this returns.
155
// Flushes FileOutputStream's buffers but does not close the
156
// underlying file. No special measures are taken to ensure that
157
// underlying operating system file object is synchronized to disk.
160
// By default, the file descriptor is not closed when the stream is
161
// destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
162
// This leaves no way for the caller to detect if close() fails. If
163
// detecting close() errors is important to you, you should arrange
164
// to close the descriptor yourself.
165
void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
167
// If an I/O error has occurred on this file descriptor, this is the
168
// errno from that error. Otherwise, this is zero. Once an error
169
// occurs, the stream is broken and all subsequent operations will
171
int GetErrno() { return copying_output_.GetErrno(); }
173
// implements ZeroCopyOutputStream ---------------------------------
174
bool Next(void** data, int* size);
175
void BackUp(int count);
176
int64 ByteCount() const;
179
class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
181
CopyingFileOutputStream(int file_descriptor);
182
~CopyingFileOutputStream();
185
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
186
int GetErrno() { return errno_; }
188
// implements CopyingOutputStream --------------------------------
189
bool Write(const void* buffer, int size);
192
// The file descriptor.
194
bool close_on_delete_;
197
// The errno of the I/O error, if one has occurred. Otherwise, zero.
200
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
203
CopyingFileOutputStream copying_output_;
204
CopyingOutputStreamAdaptor impl_;
206
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
209
// ===================================================================
211
// A ZeroCopyInputStream which reads from a C++ istream.
213
// Note that for reading files (or anything represented by a file descriptor),
214
// FileInputStream is more efficient.
215
class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
217
// Creates a stream that reads from the given C++ istream.
218
// If a block_size is given, it specifies the number of bytes that
219
// should be read and returned with each call to Next(). Otherwise,
220
// a reasonable default is used.
221
explicit IstreamInputStream(istream* stream, int block_size = -1);
222
~IstreamInputStream();
224
// implements ZeroCopyInputStream ----------------------------------
225
bool Next(const void** data, int* size);
226
void BackUp(int count);
227
bool Skip(int count);
228
int64 ByteCount() const;
231
class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
233
CopyingIstreamInputStream(istream* input);
234
~CopyingIstreamInputStream();
236
// implements CopyingInputStream ---------------------------------
237
int Read(void* buffer, int size);
238
// (We use the default implementation of Skip().)
244
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
247
CopyingIstreamInputStream copying_input_;
248
CopyingInputStreamAdaptor impl_;
250
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
253
// ===================================================================
255
// A ZeroCopyOutputStream which writes to a C++ ostream.
257
// Note that for writing files (or anything represented by a file descriptor),
258
// FileOutputStream is more efficient.
259
class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
261
// Creates a stream that writes to the given C++ ostream.
262
// If a block_size is given, it specifies the size of the buffers
263
// that should be returned by Next(). Otherwise, a reasonable default
265
explicit OstreamOutputStream(ostream* stream, int block_size = -1);
266
~OstreamOutputStream();
268
// implements ZeroCopyOutputStream ---------------------------------
269
bool Next(void** data, int* size);
270
void BackUp(int count);
271
int64 ByteCount() const;
274
class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
276
CopyingOstreamOutputStream(ostream* output);
277
~CopyingOstreamOutputStream();
279
// implements CopyingOutputStream --------------------------------
280
bool Write(const void* buffer, int size);
286
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
289
CopyingOstreamOutputStream copying_output_;
290
CopyingOutputStreamAdaptor impl_;
292
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
295
// ===================================================================
297
// A ZeroCopyInputStream which reads from several other streams in sequence.
298
// ConcatenatingInputStream is unable to distinguish between end-of-stream
299
// and read errors in the underlying streams, so it assumes any errors mean
300
// end-of-stream. So, if the underlying streams fail for any other reason,
301
// ConcatenatingInputStream may do odd things. It is suggested that you do
302
// not use ConcatenatingInputStream on streams that might produce read errors
303
// other than end-of-stream.
304
class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
306
// All streams passed in as well as the array itself must remain valid
307
// until the ConcatenatingInputStream is destroyed.
308
ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
309
~ConcatenatingInputStream();
311
// implements ZeroCopyInputStream ----------------------------------
312
bool Next(const void** data, int* size);
313
void BackUp(int count);
314
bool Skip(int count);
315
int64 ByteCount() const;
319
// As streams are retired, streams_ is incremented and count_ is
321
ZeroCopyInputStream* const* streams_;
323
int64 bytes_retired_; // Bytes read from previous streams.
325
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
328
// ===================================================================
330
// A ZeroCopyInputStream which wraps some other stream and limits it to
331
// a particular byte count.
332
class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
334
LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
335
~LimitingInputStream();
337
// implements ZeroCopyInputStream ----------------------------------
338
bool Next(const void** data, int* size);
339
void BackUp(int count);
340
bool Skip(int count);
341
int64 ByteCount() const;
345
ZeroCopyInputStream* input_;
346
int64 limit_; // Decreases as we go, becomes negative if we overshoot.
348
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
351
// ===================================================================
354
} // namespace protobuf
356
} // namespace google
357
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__