~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

Viewing changes to src/google/protobuf/io/zero_copy_stream_impl_lite.h

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2010-02-11 11:13:19 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100211111319-zdn8hmw0gh8s4cf8
Tags: 2.2.0a-0.1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Don't use python2.4.
* Ubuntu changes dropped:
  - Disable death tests on Itanium, fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Protocol Buffers - Google's data interchange format
 
2
// Copyright 2008 Google Inc.  All rights reserved.
 
3
// http://code.google.com/p/protobuf/
 
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
 
 
31
// Author: kenton@google.com (Kenton Varda)
 
32
//  Based on original Protocol Buffers design by
 
33
//  Sanjay Ghemawat, Jeff Dean, and others.
 
34
//
 
35
// This file contains common implementations of the interfaces defined in
 
36
// zero_copy_stream.h which are included in the "lite" protobuf library.
 
37
// These implementations cover I/O on raw arrays and strings, as well as
 
38
// adaptors which make it easy to implement streams based on traditional
 
39
// streams.  Of course, many users will probably want to write their own
 
40
// implementations of these interfaces specific to the particular I/O
 
41
// abstractions they prefer to use, but these should cover the most common
 
42
// cases.
 
43
 
 
44
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
 
45
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
 
46
 
 
47
#include <string>
 
48
#include <iosfwd>
 
49
#include <google/protobuf/io/zero_copy_stream.h>
 
50
#include <google/protobuf/stubs/common.h>
 
51
 
 
52
 
 
53
namespace google {
 
54
namespace protobuf {
 
55
namespace io {
 
56
 
 
57
// ===================================================================
 
58
 
 
59
// A ZeroCopyInputStream backed by an in-memory array of bytes.
 
60
class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
 
61
 public:
 
62
  // Create an InputStream that returns the bytes pointed to by "data".
 
63
  // "data" remains the property of the caller but must remain valid until
 
64
  // the stream is destroyed.  If a block_size is given, calls to Next()
 
65
  // will return data blocks no larger than the given size.  Otherwise, the
 
66
  // first call to Next() returns the entire array.  block_size is mainly
 
67
  // useful for testing; in production you would probably never want to set
 
68
  // it.
 
69
  ArrayInputStream(const void* data, int size, int block_size = -1);
 
70
  ~ArrayInputStream();
 
71
 
 
72
  // implements ZeroCopyInputStream ----------------------------------
 
73
  bool Next(const void** data, int* size);
 
74
  void BackUp(int count);
 
75
  bool Skip(int count);
 
76
  int64 ByteCount() const;
 
77
 
 
78
 
 
79
 private:
 
80
  const uint8* const data_;  // The byte array.
 
81
  const int size_;           // Total size of the array.
 
82
  const int block_size_;     // How many bytes to return at a time.
 
83
 
 
84
  int position_;
 
85
  int last_returned_size_;   // How many bytes we returned last time Next()
 
86
                             // was called (used for error checking only).
 
87
 
 
88
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
 
89
};
 
90
 
 
91
// ===================================================================
 
92
 
 
93
// A ZeroCopyOutputStream backed by an in-memory array of bytes.
 
94
class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
 
95
 public:
 
96
  // Create an OutputStream that writes to the bytes pointed to by "data".
 
97
  // "data" remains the property of the caller but must remain valid until
 
98
  // the stream is destroyed.  If a block_size is given, calls to Next()
 
99
  // will return data blocks no larger than the given size.  Otherwise, the
 
100
  // first call to Next() returns the entire array.  block_size is mainly
 
101
  // useful for testing; in production you would probably never want to set
 
102
  // it.
 
103
  ArrayOutputStream(void* data, int size, int block_size = -1);
 
104
  ~ArrayOutputStream();
 
105
 
 
106
  // implements ZeroCopyOutputStream ---------------------------------
 
107
  bool Next(void** data, int* size);
 
108
  void BackUp(int count);
 
109
  int64 ByteCount() const;
 
110
 
 
111
 private:
 
112
  uint8* const data_;        // The byte array.
 
113
  const int size_;           // Total size of the array.
 
114
  const int block_size_;     // How many bytes to return at a time.
 
115
 
 
116
  int position_;
 
117
  int last_returned_size_;   // How many bytes we returned last time Next()
 
118
                             // was called (used for error checking only).
 
119
 
 
120
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
 
121
};
 
122
 
 
123
// ===================================================================
 
124
 
 
125
// A ZeroCopyOutputStream which appends bytes to a string.
 
126
class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
 
127
 public:
 
128
  // Create a StringOutputStream which appends bytes to the given string.
 
129
  // The string remains property of the caller, but it MUST NOT be accessed
 
130
  // in any way until the stream is destroyed.
 
131
  //
 
132
  // Hint:  If you call target->reserve(n) before creating the stream,
 
133
  //   the first call to Next() will return at least n bytes of buffer
 
134
  //   space.
 
135
  explicit StringOutputStream(string* target);
 
136
  ~StringOutputStream();
 
137
 
 
138
  // implements ZeroCopyOutputStream ---------------------------------
 
139
  bool Next(void** data, int* size);
 
140
  void BackUp(int count);
 
141
  int64 ByteCount() const;
 
142
 
 
143
 private:
 
144
  static const int kMinimumSize = 16;
 
145
 
 
146
  string* target_;
 
147
 
 
148
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
 
149
};
 
150
 
 
151
// Note:  There is no StringInputStream.  Instead, just create an
 
152
// ArrayInputStream as follows:
 
153
//   ArrayInputStream input(str.data(), str.size());
 
154
 
 
155
// ===================================================================
 
156
 
 
157
// A generic traditional input stream interface.
 
158
//
 
159
// Lots of traditional input streams (e.g. file descriptors, C stdio
 
160
// streams, and C++ iostreams) expose an interface where every read
 
161
// involves copying bytes into a buffer.  If you want to take such an
 
162
// interface and make a ZeroCopyInputStream based on it, simply implement
 
163
// CopyingInputStream and then use CopyingInputStreamAdaptor.
 
164
//
 
165
// CopyingInputStream implementations should avoid buffering if possible.
 
166
// CopyingInputStreamAdaptor does its own buffering and will read data
 
167
// in large blocks.
 
168
class LIBPROTOBUF_EXPORT CopyingInputStream {
 
169
 public:
 
170
  virtual ~CopyingInputStream();
 
171
 
 
172
  // Reads up to "size" bytes into the given buffer.  Returns the number of
 
173
  // bytes read.  Read() waits until at least one byte is available, or
 
174
  // returns zero if no bytes will ever become available (EOF), or -1 if a
 
175
  // permanent read error occurred.
 
176
  virtual int Read(void* buffer, int size) = 0;
 
177
 
 
178
  // Skips the next "count" bytes of input.  Returns the number of bytes
 
179
  // actually skipped.  This will always be exactly equal to "count" unless
 
180
  // EOF was reached or a permanent read error occurred.
 
181
  //
 
182
  // The default implementation just repeatedly calls Read() into a scratch
 
183
  // buffer.
 
184
  virtual int Skip(int count);
 
185
};
 
186
 
 
187
// A ZeroCopyInputStream which reads from a CopyingInputStream.  This is
 
188
// useful for implementing ZeroCopyInputStreams that read from traditional
 
189
// streams.  Note that this class is not really zero-copy.
 
190
//
 
191
// If you want to read from file descriptors or C++ istreams, this is
 
192
// already implemented for you:  use FileInputStream or IstreamInputStream
 
193
// respectively.
 
194
class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
 
195
 public:
 
196
  // Creates a stream that reads from the given CopyingInputStream.
 
197
  // If a block_size is given, it specifies the number of bytes that
 
198
  // should be read and returned with each call to Next().  Otherwise,
 
199
  // a reasonable default is used.  The caller retains ownership of
 
200
  // copying_stream unless SetOwnsCopyingStream(true) is called.
 
201
  explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
 
202
                                     int block_size = -1);
 
203
  ~CopyingInputStreamAdaptor();
 
204
 
 
205
  // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
 
206
  // delete the underlying CopyingInputStream when it is destroyed.
 
207
  void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
 
208
 
 
209
  // implements ZeroCopyInputStream ----------------------------------
 
210
  bool Next(const void** data, int* size);
 
211
  void BackUp(int count);
 
212
  bool Skip(int count);
 
213
  int64 ByteCount() const;
 
214
 
 
215
 private:
 
216
  // Insures that buffer_ is not NULL.
 
217
  void AllocateBufferIfNeeded();
 
218
  // Frees the buffer and resets buffer_used_.
 
219
  void FreeBuffer();
 
220
 
 
221
  // The underlying copying stream.
 
222
  CopyingInputStream* copying_stream_;
 
223
  bool owns_copying_stream_;
 
224
 
 
225
  // True if we have seen a permenant error from the underlying stream.
 
226
  bool failed_;
 
227
 
 
228
  // The current position of copying_stream_, relative to the point where
 
229
  // we started reading.
 
230
  int64 position_;
 
231
 
 
232
  // Data is read into this buffer.  It may be NULL if no buffer is currently
 
233
  // in use.  Otherwise, it points to an array of size buffer_size_.
 
234
  scoped_array<uint8> buffer_;
 
235
  const int buffer_size_;
 
236
 
 
237
  // Number of valid bytes currently in the buffer (i.e. the size last
 
238
  // returned by Next()).  0 <= buffer_used_ <= buffer_size_.
 
239
  int buffer_used_;
 
240
 
 
241
  // Number of bytes in the buffer which were backed up over by a call to
 
242
  // BackUp().  These need to be returned again.
 
243
  // 0 <= backup_bytes_ <= buffer_used_
 
244
  int backup_bytes_;
 
245
 
 
246
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor);
 
247
};
 
248
 
 
249
// ===================================================================
 
250
 
 
251
// A generic traditional output stream interface.
 
252
//
 
253
// Lots of traditional output streams (e.g. file descriptors, C stdio
 
254
// streams, and C++ iostreams) expose an interface where every write
 
255
// involves copying bytes from a buffer.  If you want to take such an
 
256
// interface and make a ZeroCopyOutputStream based on it, simply implement
 
257
// CopyingOutputStream and then use CopyingOutputStreamAdaptor.
 
258
//
 
259
// CopyingOutputStream implementations should avoid buffering if possible.
 
260
// CopyingOutputStreamAdaptor does its own buffering and will write data
 
261
// in large blocks.
 
262
class LIBPROTOBUF_EXPORT CopyingOutputStream {
 
263
 public:
 
264
  virtual ~CopyingOutputStream();
 
265
 
 
266
  // Writes "size" bytes from the given buffer to the output.  Returns true
 
267
  // if successful, false on a write error.
 
268
  virtual bool Write(const void* buffer, int size) = 0;
 
269
};
 
270
 
 
271
// A ZeroCopyOutputStream which writes to a CopyingOutputStream.  This is
 
272
// useful for implementing ZeroCopyOutputStreams that write to traditional
 
273
// streams.  Note that this class is not really zero-copy.
 
274
//
 
275
// If you want to write to file descriptors or C++ ostreams, this is
 
276
// already implemented for you:  use FileOutputStream or OstreamOutputStream
 
277
// respectively.
 
278
class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
 
279
 public:
 
280
  // Creates a stream that writes to the given Unix file descriptor.
 
281
  // If a block_size is given, it specifies the size of the buffers
 
282
  // that should be returned by Next().  Otherwise, a reasonable default
 
283
  // is used.
 
284
  explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
 
285
                                      int block_size = -1);
 
286
  ~CopyingOutputStreamAdaptor();
 
287
 
 
288
  // Writes all pending data to the underlying stream.  Returns false if a
 
289
  // write error occurred on the underlying stream.  (The underlying
 
290
  // stream itself is not necessarily flushed.)
 
291
  bool Flush();
 
292
 
 
293
  // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
 
294
  // delete the underlying CopyingOutputStream when it is destroyed.
 
295
  void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
 
296
 
 
297
  // implements ZeroCopyOutputStream ---------------------------------
 
298
  bool Next(void** data, int* size);
 
299
  void BackUp(int count);
 
300
  int64 ByteCount() const;
 
301
 
 
302
 private:
 
303
  // Write the current buffer, if it is present.
 
304
  bool WriteBuffer();
 
305
  // Insures that buffer_ is not NULL.
 
306
  void AllocateBufferIfNeeded();
 
307
  // Frees the buffer.
 
308
  void FreeBuffer();
 
309
 
 
310
  // The underlying copying stream.
 
311
  CopyingOutputStream* copying_stream_;
 
312
  bool owns_copying_stream_;
 
313
 
 
314
  // True if we have seen a permenant error from the underlying stream.
 
315
  bool failed_;
 
316
 
 
317
  // The current position of copying_stream_, relative to the point where
 
318
  // we started writing.
 
319
  int64 position_;
 
320
 
 
321
  // Data is written from this buffer.  It may be NULL if no buffer is
 
322
  // currently in use.  Otherwise, it points to an array of size buffer_size_.
 
323
  scoped_array<uint8> buffer_;
 
324
  const int buffer_size_;
 
325
 
 
326
  // Number of valid bytes currently in the buffer (i.e. the size last
 
327
  // returned by Next()).  When BackUp() is called, we just reduce this.
 
328
  // 0 <= buffer_used_ <= buffer_size_.
 
329
  int buffer_used_;
 
330
 
 
331
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
 
332
};
 
333
 
 
334
// ===================================================================
 
335
 
 
336
}  // namespace io
 
337
}  // namespace protobuf
 
338
 
 
339
}  // namespace google
 
340
#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__