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