1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Copyright 2004--2010, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifndef TALK_BASE_STREAM_H__
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define TALK_BASE_STREAM_H__
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/basictypes.h"
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/criticalsection.h"
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h"
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/messagehandler.h"
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/scoped_ptr.h"
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/sigslot.h"
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base {
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamInterface is a generic asynchronous stream interface, supporting read,
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// write, and close operations, and asynchronous signalling of state changes.
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// The interface is designed with file, memory, and socket implementations in
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// mind.  Some implementations offer extended operations, such as seeking.
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// The following enumerations are declared outside of the StreamInterface
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// class for brevity in use.
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// The SS_OPENING state indicates that the stream will signal open or closed
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// in the future.
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum StreamState { SS_CLOSED, SS_OPENING, SS_OPEN };
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Stream read/write methods return this value to indicate various success
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// and failure conditions described below.
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS };
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamEvents are used to asynchronously signal state transitionss.  The flags
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// may be combined.
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  SE_OPEN: The stream has transitioned to the SS_OPEN state
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  SE_CLOSE: The stream has transitioned to the SS_CLOSED state
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  SE_READ: Data is available, so Read is likely to not return SR_BLOCK
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//  SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 };
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Thread;
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StreamInterface : public MessageHandler {
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~StreamInterface();
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const = 0;
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Read attempts to fill buffer of size buffer_len.  Write attempts to send
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // data_len bytes stored in data.  The variables read and write are set only
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // on SR_SUCCESS (see below).  Likewise, error is only set on SR_ERROR.
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Read and Write return a value indicating:
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  SR_ERROR: an error occurred, which is returned in a non-null error
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //    argument.  Interpretation of the error requires knowledge of the
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //    stream's concrete type, which limits its usefulness.
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  SR_SUCCESS: some number of bytes were successfully written, which is
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //    returned in a non-null read/write argument.
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  SR_BLOCK: the stream is in non-blocking mode, and the operation would
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //    block, or the stream is in SS_OPENING state.
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  SR_EOS: the end-of-stream has been reached, or the stream is in the
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //    SS_CLOSED state.
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error) = 0;
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error) = 0;
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Attempt to transition to the SS_CLOSED state.  SE_CLOSE will not be
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // signalled as a result of this call.
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close() = 0;
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Streams may signal one or more StreamEvents to indicate state changes.
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The first argument identifies the stream on which the state change occured.
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The second argument is a bit-wise combination of StreamEvents.
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If SE_CLOSE is signalled, then the third argument is the associated error
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // code.  Otherwise, the value is undefined.
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Note: Not all streams will support asynchronous event signalling.  However,
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // SS_OPENING and SR_BLOCK returned from stream member functions imply that
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // certain events will be raised in the future.
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  sigslot::signal3<StreamInterface*, int, int> SignalEvent;
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Like calling SignalEvent, but posts a message to the specified thread,
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // which will call SignalEvent.  This helps unroll the stack and prevent
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // re-entrancy.
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void PostEvent(Thread* t, int events, int err);
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Like the aforementioned method, but posts to the current thread.
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void PostEvent(int events, int err);
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // OPTIONAL OPERATIONS
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Not all implementations will support the following operations.  In general,
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // a stream will only support an operation if it reasonably efficient to do
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // so.  For example, while a socket could buffer incoming data to support
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // seeking, it will not do so.  Instead, a buffering stream adapter should
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // be used.
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Even though several of these operations are related, you should
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // always use whichever operation is most relevant.  For example, you may
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // be tempted to use GetSize() and GetPosition() to deduce the result of
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // GetAvailable().  However, a stream which is read-once may support the
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // latter operation but not the former.
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The following four methods are used to avoid coping data multiple times.
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // GetReadData returns a pointer to a buffer which is owned by the stream.
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The buffer contains data_len bytes.  NULL is returned if no data is
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // available, or if the method fails.  If the caller processes the data, it
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // must call ConsumeReadData with the number of processed bytes.  GetReadData
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // does not require a matching call to ConsumeReadData if the data is not
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // processed.  Read and ConsumeReadData invalidate the buffer returned by
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // GetReadData.
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual const void* GetReadData(size_t* data_len) { return NULL; }
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeReadData(size_t used) {}
139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // GetWriteBuffer returns a pointer to a buffer which is owned by the stream.
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The buffer has a capacity of buf_len bytes.  NULL is returned if there is
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // no buffer available, or if the method fails.  The call may write data to
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // the buffer, and then call ConsumeWriteBuffer with the number of bytes
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // written.  GetWriteBuffer does not require a matching call to
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ConsumeWriteData if no data is written.  Write, ForceWrite, and
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer.
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // TODO: Allow the caller to specify a minimum buffer size.  If the specified
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // amount of buffer is not yet available, return NULL and Signal SE_WRITE
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // when it is available.  If the requested amount is too large, return an
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // error.
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void* GetWriteBuffer(size_t* buf_len) { return NULL; }
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeWriteBuffer(size_t used) {}
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Write data_len bytes found in data, circumventing any throttling which
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // would could cause SR_BLOCK to be returned.  Returns true if all the data
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // was written.  Otherwise, the method is unsupported, or an unrecoverable
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // error occurred, and the error value is set.  This method should be used
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // sparingly to write critical data which should not be throttled.  A stream
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // which cannot circumvent its blocking constraints should not implement this
160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // method.
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // NOTE: This interface is being considered experimentally at the moment.  It
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // would be used by JUDP and BandwidthStream as a way to circumvent certain
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // soft limits in writing.
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  if (error) *error = -1;
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  return false;
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //}
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Seek to a byte offset from the beginning of the stream.  Returns false if
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // the stream does not support seeking, or cannot seek to the specified
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // position.
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position) { return false; }
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Get the byte offset of the current position from the start of the stream.
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns false if the position is not known.
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const { return false; }
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Get the byte length of the entire stream.  Returns false if the length
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // is not known.
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const { return false; }
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Return the number of Read()-able bytes remaining before end-of-stream.
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns false if not known.
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const { return false; }
185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Return the number of Write()-able bytes remaining before end-of-stream.
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns false if not known.
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetWriteRemaining(size_t* size) const { return false; }
189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Communicates the amount of data which will be written to the stream.  The
191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // stream may choose to preallocate memory to accomodate this data.  The
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // stream may return false to indicate that there is not enough room (ie,
193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Write will return SR_EOS/SR_ERROR at some point).  Note that calling this
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // function should not affect the existing state of data in the stream.
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ReserveSize(size_t size) { return true; }
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // CONVENIENCE METHODS
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // These methods are implemented in terms of other methods, for convenience.
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Seek to the start of the stream.
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  inline bool Rewind() { return SetPosition(0); }
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // WriteAll is a helper function which repeatedly calls Write until all the
207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // data is written, or something other than SR_SUCCESS is returned.  Note that
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // unlike Write, the argument 'written' is always set, and may be non-zero
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // on results other than SR_SUCCESS.  The remaining arguments have the
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // same semantics as Write.
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamResult WriteAll(const void* data, size_t data_len,
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                        size_t* written, int* error);
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Similar to ReadAll.  Calls Read until buffer_len bytes have been read, or
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // until a non-SR_SUCCESS result is returned.  'read' is always set.
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamResult ReadAll(void* buffer, size_t buffer_len,
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                       size_t* read, int* error);
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ReadLine is a helper function which repeatedly calls Read until it hits
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // the end-of-line character, or something other than SR_SUCCESS.
221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // TODO: this is too inefficient to keep here.  Break this out into a buffered
222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // readline object or adapter
223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamResult ReadLine(std::string *line);
224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  StreamInterface();
227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // MessageHandler Interface
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void OnMessage(Message* msg);
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(StreamInterface);
233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamAdapterInterface is a convenient base-class for adapting a stream.
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// By default, all operations are pass-through.  Override the methods that you
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// require adaptation.  Streams should really be upgraded to reference-counted.
239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// In the meantime, use the owned flag to indicate whether the adapter should
240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// own the adapted stream.
241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StreamAdapterInterface : public StreamInterface,
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                               public sigslot::has_slots<> {
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit StreamAdapterInterface(StreamInterface* stream, bool owned = true);
247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Core Stream Interface
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const {
250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetState();
251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error) {
254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->Read(buffer, buffer_len, read, error);
255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error) {
258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->Write(data, data_len, written, error);
259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close() {
261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    stream_->Close();
262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Optional Stream Interface
265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  /*  Note: Many stream adapters were implemented prior to this Read/Write
266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      interface.  Therefore, a simple pass through of data in those cases may
267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      be broken.  At a later time, we should do a once-over pass of all
268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      adapters, and make them compliant with these interfaces, after which this
269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      code can be uncommented.
270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual const void* GetReadData(size_t* data_len) {
271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetReadData(data_len);
272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeReadData(size_t used) {
274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    stream_->ConsumeReadData(used);
275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void* GetWriteBuffer(size_t* buf_len) {
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetWriteBuffer(buf_len);
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeWriteBuffer(size_t used) {
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    stream_->ConsumeWriteBuffer(used);
282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  */
284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  /*  Note: This interface is currently undergoing evaluation.
286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->ForceWrite(data, data_len, error);
288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  */
290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position) {
292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->SetPosition(position);
293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const {
295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetPosition(position);
296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const {
298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetSize(size);
299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const {
301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetAvailable(size);
302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetWriteRemaining(size_t* size) const {
304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->GetWriteRemaining(size);
305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ReserveSize(size_t size) {
307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return stream_->ReserveSize(size);
308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void Attach(StreamInterface* stream, bool owned = true);
3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  StreamInterface* Detach();
312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~StreamAdapterInterface();
3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Note that the adapter presents itself as the origin of the stream events,
317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // since users of the adapter may not recognize the adapted object.
318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void OnEvent(StreamInterface* stream, int events, int err) {
319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    SignalEvent(this, events, err);
320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamInterface* stream() { return stream_; }
322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamInterface* stream_;
325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool owned_;
326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(StreamAdapterInterface);
327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamTap is a non-modifying, pass-through adapter, which copies all data
331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// in either direction to the tap.  Note that errors or blocking on writing to
332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// the tap will prevent further tap writes from occurring.
333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StreamTap : public StreamAdapterInterface {
336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit StreamTap(StreamInterface* stream, StreamInterface* tap);
338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void AttachTap(StreamInterface* tap);
340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamInterface* DetachTap();
341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamResult GetTapResult(int* error);
342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // StreamAdapterInterface Interface
344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error);
348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  scoped_ptr<StreamInterface> tap_;
351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamResult tap_result_;
352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int tap_error_;
353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(StreamTap);
354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamSegment adapts a read stream, to expose a subset of the adapted
358f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// stream's data.  This is useful for cases where a stream contains multiple
359f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// documents concatenated together.  StreamSegment can expose a subset of
360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// the data as an independent stream, including support for rewinding and
361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// seeking.
362f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StreamSegment : public StreamAdapterInterface {
365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The current position of the adapted stream becomes the beginning of the
367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // segment.  If a length is specified, it bounds the length of the segment.
368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit StreamSegment(StreamInterface* stream);
369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit StreamSegment(StreamInterface* stream, size_t length);
370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // StreamAdapterInterface Interface
372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position);
375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const;
376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const;
377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const;
378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t start_, pos_, length_;
381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(StreamSegment);
382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// NullStream gives errors on read, and silently discards all written data.
386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass NullStream : public StreamInterface {
389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  NullStream();
391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~NullStream();
392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // StreamInterface Interface
394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const;
395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error);
399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// FileStream is a simple implementation of a StreamInterface, which does not
404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// support asynchronous notification.
405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass FileStream : public StreamInterface {
408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FileStream();
410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~FileStream();
411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The semantics of filename and mode are the same as stdio's fopen
413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool Open(const std::string& filename, const char* mode);
414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool OpenShare(const std::string& filename, const char* mode,
415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         int shflag);
416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // By default, reads and writes are buffered for efficiency.  Disabling
418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // buffering causes writes to block until the bytes on disk are updated.
419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool DisableBuffering();
420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const;
422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error);
426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position);
428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const;
429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const;
430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const;
431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ReserveSize(size_t size);
432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool Flush();
434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if defined(POSIX)
436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Tries to aquire an exclusive lock on the file.
437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Use OpenShare(...) on win32 to get similar functionality.
438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool TryLock();
439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool Unlock();
440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Note: Deprecated in favor of Filesystem::GetFileSize().
443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static bool GetSize(const std::string& filename, size_t* size);
444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void DoClose();
447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FILE* file_;
449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(FileStream);
452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// A FileStream that is actually not a file, but the output or input of a
456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// sub-command. See "man 3 popen" for documentation of the underlying OS popen()
457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// function.
458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass POpenStream : public FileStream {
459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  POpenStream() : wait_status_(-1) {}
461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~POpenStream();
462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool Open(const std::string& subcommand, const char* mode);
464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Same as Open(). shflag is ignored.
465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool OpenShare(const std::string& subcommand, const char* mode,
466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         int shflag);
467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns the wait status from the last Close() of an Open()'ed stream, or
469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // -1 if no Open()+Close() has been done on this object. Meaning of the number
470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // is documented in "man 2 wait".
471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int GetWaitStatus() const { return wait_status_; }
472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void DoClose();
475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int wait_status_;
478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // POSIX
480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// MemoryStream is a simple implementation of a StreamInterface over in-memory
483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// data.  Data is read and written at the current seek position.  Reads return
484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// end-of-stream when they reach the end of data.  Writes actually extend the
485f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// end of data mark.
486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass MemoryStreamBase : public StreamInterface {
489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const;
491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t bytes, size_t* bytes_read,
492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            int* error);
493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* buffer, size_t bytes,
494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* bytes_written, int* error);
495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position);
497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const;
498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const;
499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const;
500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ReserveSize(size_t size);
501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char* GetBuffer() { return buffer_; }
503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* GetBuffer() const { return buffer_; }
504f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
505f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
506f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MemoryStreamBase();
507f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
508f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult DoReserve(size_t size, int* error);
509f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_
511f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char* buffer_;
512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t buffer_length_;
513f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t data_length_;
514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t seek_position_;
515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(MemoryStreamBase);
518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// MemoryStream dynamically resizes to accomodate written data.
521f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
522f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass MemoryStream : public MemoryStreamBase {
523f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
524f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MemoryStream();
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit MemoryStream(const char* data);  // Calls SetData(data, strlen(data))
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MemoryStream(const void* data, size_t length);  // Calls SetData(data, length)
527f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~MemoryStream();
528f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
529f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void SetData(const void* data, size_t length);
530f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
531f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
532f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult DoReserve(size_t size, int* error);
533dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Memory Streams are aligned for efficiency.
534dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static const int kAlignment = 16;
535dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  char* buffer_alloc_;
536f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
537f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
538f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// ExternalMemoryStream adapts an external memory buffer, so writes which would
539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// extend past the end of the buffer will return end-of-stream.
540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
541f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass ExternalMemoryStream : public MemoryStreamBase {
542f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
543f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ExternalMemoryStream();
544f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ExternalMemoryStream(void* data, size_t length);
5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~ExternalMemoryStream();
546f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
547f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void SetData(void* data, size_t length);
548f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
549f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
550f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// FifoBuffer allows for efficient, thread-safe buffering of data between
551f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// writer and reader. As the data can wrap around the end of the buffer,
552f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// MemoryStreamBase can't help us here.
553f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
554f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass FifoBuffer : public StreamInterface {
555f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
556f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Creates a FIFO buffer with the specified capacity.
557f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit FifoBuffer(size_t length);
558f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~FifoBuffer();
559f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Gets the amount of data currently readable from the buffer.
560f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool GetBuffered(size_t* data_len) const;
561f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Resizes the buffer to the specified capacity. Fails if data_length_ > size
562f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool SetCapacity(size_t length);
563f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
564f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // StreamInterface methods
565f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const;
566f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t bytes,
567f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* bytes_read, int* error);
568f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* buffer, size_t bytes,
569f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* bytes_written, int* error);
570f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
571f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual const void* GetReadData(size_t* data_len);
572f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeReadData(size_t used);
573f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void* GetWriteBuffer(size_t *buf_len);
574f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ConsumeWriteBuffer(size_t used);
575f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
576f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
577f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamState state_;  // keeps the opened/closed state of the stream
578f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  scoped_array<char> buffer_;  // the allocated buffer
579f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t buffer_length_;  // size of the allocated buffer
580f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t data_length_;  // amount of readable data in the buffer
581f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t read_position_;  // offset to the readable data
582f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Thread* owner_;  // stream callbacks are dispatched on this thread
583f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  mutable CriticalSection crit_;  // object lock
584f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(FifoBuffer);
585f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
586f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
587f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
588f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
589f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass LoggingAdapter : public StreamAdapterInterface {
5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
591f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  LoggingAdapter(StreamInterface* stream, LoggingSeverity level,
592f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                 const std::string& label, bool hex_mode = false);
593f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
594f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void set_label(const std::string& label);
595f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
596f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
597f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
598f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
599f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error);
600f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
601f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
602f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch protected:
603f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void OnEvent(StreamInterface* stream, int events, int err);
604f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
605f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
606f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  LoggingSeverity level_;
607f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string label_;
608f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool hex_mode_;
609f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  LogMultilineState lms_;
610f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
611f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(LoggingAdapter);
612f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
613f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
614f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
615f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StringStream - Reads/Writes to an external std::string
616f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
617f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
618f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StringStream : public StreamInterface {
6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit StringStream(std::string& str);
6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit StringStream(const std::string& str);
622f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
623f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamState GetState() const;
624f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Read(void* buffer, size_t buffer_len,
625f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            size_t* read, int* error);
626f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual StreamResult Write(const void* data, size_t data_len,
627f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             size_t* written, int* error);
628f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Close();
629f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool SetPosition(size_t position);
630f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetPosition(size_t* position) const;
631f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetSize(size_t* size) const;
632f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool GetAvailable(size_t* size) const;
633f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual bool ReserveSize(size_t size);
634f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
636f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string& str_;
637f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t read_pos_;
638f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool read_only_;
639f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
640f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
641f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
642f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// StreamReference - A reference counting stream adapter
643f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
644f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
645f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Keep in mind that the streams and adapters defined in this file are
646f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// not thread-safe, so this has limited uses.
647f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
648f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// A StreamRefCount holds the reference count and a pointer to the
649f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// wrapped stream. It deletes the wrapped stream when there are no
650f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// more references. We can then have multiple StreamReference
651f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// instances pointing to one StreamRefCount, all wrapping the same
652f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// stream.
653f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
654f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass StreamReference : public StreamAdapterInterface {
655f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  class StreamRefCount;
656f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
657f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Constructor for the first reference to a stream
658f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Note: get more references through NewReference(). Use this
659f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // constructor only once on a given stream.
6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit StreamReference(StreamInterface* stream);
661f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamInterface* GetStream() { return stream(); }
6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  StreamInterface* NewReference();
6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~StreamReference();
664f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
665f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
666f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  class StreamRefCount {
667f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch   public:
668f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    explicit StreamRefCount(StreamInterface* stream)
669f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        : stream_(stream), ref_count_(1) {
670f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
671f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    void AddReference() {
672f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      CritScope lock(&cs_);
673f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      ++ref_count_;
674f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
675f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    void Release() {
676f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      int ref_count;
677f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      {  // Atomic ops would have been a better fit here.
678f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        CritScope lock(&cs_);
679f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        ref_count = --ref_count_;
680f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
681f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (ref_count == 0) {
682f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        delete stream_;
683f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        delete this;
684f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
685f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
686f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch   private:
687f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    StreamInterface* stream_;
688f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    int ref_count_;
689f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    CriticalSection cs_;
690f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DISALLOW_EVIL_CONSTRUCTORS(StreamRefCount);
691f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  };
692f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
693f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Constructor for adding references
694f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit StreamReference(StreamRefCount* stream_ref_count,
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           StreamInterface* stream);
6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
697f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  StreamRefCount* stream_ref_count_;
698f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(StreamReference);
699f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
700f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
701f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
702f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
703f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Flow attempts to move bytes from source to sink via buffer of size
704f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// buffer_len.  The function returns SR_SUCCESS when source reaches
705f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// end-of-stream (returns SR_EOS), and all the data has been written successful
706f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// to sink.  Alternately, if source returns SR_BLOCK or SR_ERROR, or if sink
707f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// returns SR_BLOCK, SR_ERROR, or SR_EOS, then the function immediately returns
708f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// with the unexpected StreamResult value.
709f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// data_len is the length of the valid data in buffer. in case of error
710f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// this is the data that read from source but can't move to destination.
711f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// as a pass in parameter, it indicates data in buffer that should move to sink
712f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStreamResult Flow(StreamInterface* source,
713f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                  char* buffer, size_t buffer_len,
714f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                  StreamInterface* sink, size_t* data_len = NULL);
715f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
716f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
717f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace talk_base
719f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
720f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // TALK_BASE_STREAM_H__
721