156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Protocol Buffers - Google's data interchange format
256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Copyright 2008 Google Inc.  All rights reserved.
356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// http://code.google.com/p/protobuf/
456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Redistribution and use in source and binary forms, with or without
656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// modification, are permitted provided that the following conditions are
756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// met:
856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//     * Redistributions of source code must retain the above copyright
1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// notice, this list of conditions and the following disclaimer.
1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//     * Redistributions in binary form must reproduce the above
1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// copyright notice, this list of conditions and the following disclaimer
1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// in the documentation and/or other materials provided with the
1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// distribution.
1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//     * Neither the name of Google Inc. nor the names of its
1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// contributors may be used to endorse or promote products derived from
1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// this software without specific prior written permission.
1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Author: kenton@google.com (Kenton Varda)
3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//  Based on original Protocol Buffers design by
3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//  Sanjay Ghemawat, Jeff Dean, and others.
3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// This file contains common implementations of the interfaces defined in
3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// zero_copy_stream.h which are only included in the full (non-lite)
3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// protobuf library.  These implementations include Unix file descriptors
3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// and C++ iostreams.  See also:  zero_copy_stream_impl_lite.h
3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <string>
4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <iosfwd>
4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <google/protobuf/io/zero_copy_stream.h>
4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <google/protobuf/stubs/common.h>
4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonnamespace google {
5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonnamespace protobuf {
5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonnamespace io {
5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyInputStream which reads from a file descriptor.
5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// FileInputStream is preferred over using an ifstream with IstreamInputStream.
6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// The latter will introduce an extra layer of buffering, harming performance.
6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Also, it's conceivable that FileInputStream could someday be enhanced
6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// to use zero-copy file descriptors on OSs which support them.
6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Creates a stream that reads from the given Unix file descriptor.
6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If a block_size is given, it specifies the number of bytes that
6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // should be read and returned with each call to Next().  Otherwise,
6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // a reasonable default is used.
6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  explicit FileInputStream(int file_descriptor, int block_size = -1);
7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~FileInputStream();
7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Flushes any buffers and closes the underlying file.  Returns false if
7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // an error occurs during the process; use GetErrno() to examine the error.
7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Even if an error occurs, the file descriptor is closed when this returns.
7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Close();
7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // By default, the file descriptor is not closed when the stream is
7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // This leaves no way for the caller to detect if close() fails.  If
8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // detecting close() errors is important to you, you should arrange
8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // to close the descriptor yourself.
8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If an I/O error has occurred on this file descriptor, this is the
8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // errno from that error.  Otherwise, this is zero.  Once an error
8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // occurs, the stream is broken and all subsequent operations will
8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // fail.
8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int GetErrno() { return copying_input_.GetErrno(); }
8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyInputStream ----------------------------------
9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(const void** data, int* size);
9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Skip(int count);
9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   public:
9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    CopyingFileInputStream(int file_descriptor);
10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    ~CopyingFileInputStream();
10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool Close();
10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int GetErrno() { return errno_; }
10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // implements CopyingInputStream ---------------------------------
10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int Read(void* buffer, int size);
10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int Skip(int count);
10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   private:
11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The file descriptor.
11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    const int file_;
11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool close_on_delete_;
11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool is_closed_;
11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The errno of the I/O error, if one has occurred.  Otherwise, zero.
11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int errno_;
11856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
11956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // Did we try to seek once and fail?  If so, we assume this file descriptor
12056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // doesn't support seeking and won't try again.
12156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool previous_seek_failed_;
12256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
12356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
12456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  };
12556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
12656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingFileInputStream copying_input_;
12756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingInputStreamAdaptor impl_;
12856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
12956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
13056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
13156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
13256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
13356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
13456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyOutputStream which writes to a file descriptor.
13556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
13656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// FileOutputStream is preferred over using an ofstream with
13756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// OstreamOutputStream.  The latter will introduce an extra layer of buffering,
13856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// harming performance.  Also, it's conceivable that FileOutputStream could
13956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// someday be enhanced to use zero-copy file descriptors on OSs which
14056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// support them.
14156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
14256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
14356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Creates a stream that writes to the given Unix file descriptor.
14456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If a block_size is given, it specifies the size of the buffers
14556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // that should be returned by Next().  Otherwise, a reasonable default
14656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // is used.
14756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  explicit FileOutputStream(int file_descriptor, int block_size = -1);
14856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~FileOutputStream();
14956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
15056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Flushes any buffers and closes the underlying file.  Returns false if
15156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // an error occurs during the process; use GetErrno() to examine the error.
15256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Even if an error occurs, the file descriptor is closed when this returns.
15356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Close();
15456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
15556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Flushes FileOutputStream's buffers but does not close the
15656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // underlying file. No special measures are taken to ensure that
15756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // underlying operating system file object is synchronized to disk.
15856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Flush();
15956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
16056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // By default, the file descriptor is not closed when the stream is
16156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
16256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // This leaves no way for the caller to detect if close() fails.  If
16356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // detecting close() errors is important to you, you should arrange
16456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // to close the descriptor yourself.
16556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
16656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
16756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If an I/O error has occurred on this file descriptor, this is the
16856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // errno from that error.  Otherwise, this is zero.  Once an error
16956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // occurs, the stream is broken and all subsequent operations will
17056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // fail.
17156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int GetErrno() { return copying_output_.GetErrno(); }
17256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
17356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyOutputStream ---------------------------------
17456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(void** data, int* size);
17556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
17656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
17756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
17856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
17956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
18056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   public:
18156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    CopyingFileOutputStream(int file_descriptor);
18256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    ~CopyingFileOutputStream();
18356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
18456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool Close();
18556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
18656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int GetErrno() { return errno_; }
18756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
18856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // implements CopyingOutputStream --------------------------------
18956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool Write(const void* buffer, int size);
19056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
19156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   private:
19256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The file descriptor.
19356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    const int file_;
19456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool close_on_delete_;
19556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool is_closed_;
19656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
19756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The errno of the I/O error, if one has occurred.  Otherwise, zero.
19856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int errno_;
19956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
20056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
20156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  };
20256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
20356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingFileOutputStream copying_output_;
20456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingOutputStreamAdaptor impl_;
20556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
20656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
20756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
20856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
20956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
21056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
21156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyInputStream which reads from a C++ istream.
21256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
21356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Note that for reading files (or anything represented by a file descriptor),
21456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// FileInputStream is more efficient.
21556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
21656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
21756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Creates a stream that reads from the given C++ istream.
21856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If a block_size is given, it specifies the number of bytes that
21956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // should be read and returned with each call to Next().  Otherwise,
22056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // a reasonable default is used.
22156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  explicit IstreamInputStream(istream* stream, int block_size = -1);
22256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~IstreamInputStream();
22356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
22456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyInputStream ----------------------------------
22556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(const void** data, int* size);
22656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
22756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Skip(int count);
22856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
22956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
23056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
23156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
23256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   public:
23356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    CopyingIstreamInputStream(istream* input);
23456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    ~CopyingIstreamInputStream();
23556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
23656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // implements CopyingInputStream ---------------------------------
23756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int Read(void* buffer, int size);
23856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // (We use the default implementation of Skip().)
23956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
24056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   private:
24156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The stream.
24256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    istream* input_;
24356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
24456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
24556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  };
24656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
24756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingIstreamInputStream copying_input_;
24856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingInputStreamAdaptor impl_;
24956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
25056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
25156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
25256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
25356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
25456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
25556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyOutputStream which writes to a C++ ostream.
25656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//
25756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// Note that for writing files (or anything represented by a file descriptor),
25856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// FileOutputStream is more efficient.
25956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
26056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
26156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // Creates a stream that writes to the given C++ ostream.
26256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // If a block_size is given, it specifies the size of the buffers
26356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // that should be returned by Next().  Otherwise, a reasonable default
26456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // is used.
26556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  explicit OstreamOutputStream(ostream* stream, int block_size = -1);
26656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~OstreamOutputStream();
26756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
26856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyOutputStream ---------------------------------
26956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(void** data, int* size);
27056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
27156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
27256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
27456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
27556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   public:
27656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    CopyingOstreamOutputStream(ostream* output);
27756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    ~CopyingOstreamOutputStream();
27856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // implements CopyingOutputStream --------------------------------
28056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    bool Write(const void* buffer, int size);
28156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
28256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   private:
28356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // The stream.
28456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    ostream* output_;
28556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
28656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
28756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  };
28856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
28956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingOstreamOutputStream copying_output_;
29056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  CopyingOutputStreamAdaptor impl_;
29156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
29256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
29356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
29456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
29556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
29656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
29756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyInputStream which reads from several other streams in sequence.
29856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ConcatenatingInputStream is unable to distinguish between end-of-stream
29956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// and read errors in the underlying streams, so it assumes any errors mean
30056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// end-of-stream.  So, if the underlying streams fail for any other reason,
30156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ConcatenatingInputStream may do odd things.  It is suggested that you do
30256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// not use ConcatenatingInputStream on streams that might produce read errors
30356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// other than end-of-stream.
30456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
30556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
30656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // All streams passed in as well as the array itself must remain valid
30756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // until the ConcatenatingInputStream is destroyed.
30856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
30956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~ConcatenatingInputStream();
31056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
31156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyInputStream ----------------------------------
31256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(const void** data, int* size);
31356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
31456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Skip(int count);
31556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
31656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
31756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
31856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
31956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // As streams are retired, streams_ is incremented and count_ is
32056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // decremented.
32156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ZeroCopyInputStream* const* streams_;
32256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int stream_count_;
32356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 bytes_retired_;  // Bytes read from previous streams.
32456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
32556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
32656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
32756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
32856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
32956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
33056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// A ZeroCopyInputStream which wraps some other stream and limits it to
33156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// a particular byte count.
33256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
33356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public:
33456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
33556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ~LimitingInputStream();
33656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
33756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // implements ZeroCopyInputStream ----------------------------------
33856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Next(const void** data, int* size);
33956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  void BackUp(int count);
34056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  bool Skip(int count);
34156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 ByteCount() const;
34256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
34356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
34456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private:
34556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  ZeroCopyInputStream* input_;
34656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  int64 limit_;  // Decreases as we go, becomes negative if we overshoot.
34756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
34856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
34956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson};
35056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
35156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// ===================================================================
35256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
35356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson}  // namespace io
35456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson}  // namespace protobuf
35556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
35656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson}  // namespace google
35756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
35856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson