PageRenderTime 42ms CodeModel.GetById 23ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 340 lines | 113 code | 57 blank | 170 comment | 0 complexity | e618771e139938cf70862e0776700455 MD5 | raw file
  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
 53namespace google {
 54namespace protobuf {
 55namespace io {
 56
 57// ===================================================================
 58
 59// A ZeroCopyInputStream backed by an in-memory array of bytes.
 60class 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.
 94class 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.
126class 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.
168class 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.
194class 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.
262class 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.
278class 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__