ACE  6.1.0
Public Member Functions | Protected Member Functions | Protected Attributes
ACE_Streambuf Class Reference

Create your custom streambuf by providing and ACE_*_Stream object to this template. I have tested it with ACE_SOCK_Stream and it should work fine for others as well. More...

#include <IOStream.h>

Inheritance diagram for ACE_Streambuf:
Inheritance graph
[legend]
Collaboration diagram for ACE_Streambuf:
Collaboration graph
[legend]

List of all members.

Public Member Functions

virtual ~ACE_Streambuf (void)
ACE_Time_Valuerecv_timeout (ACE_Time_Value *tv=0)
 Get the current Time_Value pointer and provide a new one.
char * reset_put_buffer (char *newBuffer=0, u_int _streambuf_size=0, u_int _pptr=0)
u_int put_avail (void)
char * reset_get_buffer (char *newBuffer=0, u_int _streambuf_size=0, u_int _gptr=0, u_int _egptr=0)
u_int get_waiting (void)
u_int get_avail (void)
u_int streambuf_size (void)
 Query the streambuf for the size of its buffers.
u_char timeout (void)

Protected Member Functions

 ACE_Streambuf (u_int streambuf_size, int io_mode)
virtual int sync (void)
virtual int underflow (void)
virtual int overflow (int c=EOF)
void reset_base (void)
int syncin (void)
int syncout (void)
int flushbuf (void)
int fillbuf (void)
virtual int get_one_byte (void)
virtual ssize_t send (char *buf, ssize_t len)=0
virtual ssize_t recv (char *buf, ssize_t len, ACE_Time_Value *tv=0)=0
virtual ssize_t recv (char *buf, ssize_t len, int flags, ACE_Time_Value *tv=0)=0
virtual ssize_t recv_n (char *buf, ssize_t len, int flags=0, ACE_Time_Value *tv=0)=0
virtual ACE_HANDLE get_handle (void)

Protected Attributes

char * eback_saved_
char * gptr_saved_
char * egptr_saved_
char * pbase_saved_
char * pptr_saved_
char * epptr_saved_
u_char cur_mode_
const u_char get_mode_
const u_char put_mode_
int mode_
const u_int streambuf_size_
u_char timeout_
 Did we take an error because of an IO operation timeout?
ACE_Time_Value recv_timeout_value_
ACE_Time_Valuerecv_timeout_

Detailed Description

Create your custom streambuf by providing and ACE_*_Stream object to this template. I have tested it with ACE_SOCK_Stream and it should work fine for others as well.

For any iostream object, the real work is done by the underlying streambuf class. That is what we create here. A streambuf has an internal buffer area into which data is read and written as the iostream requests and provides data. At some point during the read process, the iostream will realize that the streambuf has no more data. The underflow function of the streambuf is then called. Likewise, during the write process, the iostream will eventually notice that the streabuf's buffer has become full and will invoke the overflow function. The empty/full state of the read/write "buffers" are controled by two sets pointers. One set is dedicated to read, the other to write. These pointers, in turn, reference a common buffer that is to be shared by both read and write operations. It is this common buffer to which data is written and from which it is read. The common buffer is used by functions of the streambuf as well as the iostream. Because of this and the fact that it is "shared" by both read and write operators, there is a danger of data corruption if read and write operations are allowed to take place "at the same time". To prevent data corruption, we manipulate the read and write pointer sets so that the streambuf is in either a read-mode or write-mode at all times and can never be in both modes at the same time. In the constructor: set the read and write sets to NULL This causes the underflow or overflow operators to be invoked at the first IO activity of the iostream. In the underflow function we arrange for the common buffer to reference our read buffer and for the write pointer set to be disabled. If a write operation is performed by the iostream this will cause the overflow function to be invoked. In the overflow function we arrange for the common buffer to reference our write buffer and for the read pointer set to be disabled. This causes the underflow function to be invoked when the iostream "changes our mode". The overflow function will also invoke the send_n function to flush the buffered data to our peer. Similarly, the sync and syncout functions will cause send_n to be invoked to send the data. Since socket's and the like do not support seeking, there can be no method for "syncing" the input. However, since we maintain separate read/write buffers, no data is lost by "syncing" the input. It simply remains buffered.


Constructor & Destructor Documentation

ACE_Streambuf::~ACE_Streambuf ( void  ) [virtual]

If the default allocation strategy were used the common buffer would be deleted when the object destructs. Since we are providing separate read/write buffers, it is up to us to manage their memory.

ACE_Streambuf::ACE_Streambuf ( u_int  streambuf_size,
int  io_mode 
) [protected]

Member Function Documentation

int ACE_Streambuf::fillbuf ( void  ) [protected]

fillbuf is called in a couple of places. This is the worker of underflow. It will attempt to fill the read buffer from the peer.

int ACE_Streambuf::flushbuf ( void  ) [protected]

flushbuf() is the worker of syncout. It is a separate function because it gets used sometimes in different context.

u_int ACE_Streambuf::get_avail ( void  )

Return the number of bytes in the get area (includes some already gotten); eback + get_avail = egptr

ACE_HANDLE ACE_Streambuf::get_handle ( void  ) [protected, virtual]

Reimplemented in ACE_Streambuf_T< STREAM >.

int ACE_Streambuf::get_one_byte ( void  ) [protected, virtual]

Used by fillbuf and others to get exactly one byte from the peer. recv_n is used to be sure we block until something is available. It is virtual because we really need to override it for datagram-derived objects.

u_int ACE_Streambuf::get_waiting ( void  )

Return the number of bytes not yet gotten. eback + get_waiting = gptr

int ACE_Streambuf::overflow ( int  c = EOF) [protected, virtual]

The overflow function receives the character which caused the overflow.

u_int ACE_Streambuf::put_avail ( void  )

Return the number of bytes to be 'put' onto the stream media. pbase + put_avail = pptr

virtual ssize_t ACE_Streambuf::recv ( char *  buf,
ssize_t  len,
ACE_Time_Value tv = 0 
) [protected, pure virtual]

Implemented in ACE_Streambuf_T< STREAM >.

virtual ssize_t ACE_Streambuf::recv ( char *  buf,
ssize_t  len,
int  flags,
ACE_Time_Value tv = 0 
) [protected, pure virtual]

Implemented in ACE_Streambuf_T< STREAM >.

virtual ssize_t ACE_Streambuf::recv_n ( char *  buf,
ssize_t  len,
int  flags = 0,
ACE_Time_Value tv = 0 
) [protected, pure virtual]

Implemented in ACE_Streambuf_T< STREAM >.

ACE_Time_Value * ACE_Streambuf::recv_timeout ( ACE_Time_Value tv = 0)

Get the current Time_Value pointer and provide a new one.

void ACE_Streambuf::reset_base ( void  ) [protected]

Resets the <base> pointer and streambuf mode. This is used internally when get/put buffers are allocatd.

char * ACE_Streambuf::reset_get_buffer ( char *  newBuffer = 0,
u_int  _streambuf_size = 0,
u_int  _gptr = 0,
u_int  _egptr = 0 
)

Use this to allocate a new/different buffer for get operations. If you do not provide a buffer pointer, one will be allocated. That is the preferred method. If you do provide a buffer, the size must match that being used by the put buffer. If successful, you will receive a pointer to the current get buffer. It is your responsibility to delete this memory when you are done with it.

char * ACE_Streambuf::reset_put_buffer ( char *  newBuffer = 0,
u_int  _streambuf_size = 0,
u_int  _pptr = 0 
)

Use this to allocate a new/different buffer for put operations. If you do not provide a buffer pointer, one will be allocated. That is the preferred method. If you do provide a buffer, the size must match that being used by the get buffer. If successful, you will receive a pointer to the current put buffer. It is your responsibility to delete this memory when you are done with it.

virtual ssize_t ACE_Streambuf::send ( char *  buf,
ssize_t  len 
) [protected, pure virtual]

Stream connections and "unconnected connections" (ie -- datagrams) need to work just a little differently. We derive custom Streambuf objects for them and provide these functions at that time.

Implemented in ACE_Streambuf_T< STREAM >.

u_int ACE_Streambuf::streambuf_size ( void  )

Query the streambuf for the size of its buffers.

int ACE_Streambuf::sync ( void  ) [protected, virtual]

Sync both input and output. See syncin/syncout below for descriptions.

int ACE_Streambuf::syncin ( void  ) [protected]

syncin is called when the input needs to be synced with the source file. In a filebuf, this results in the <seek> system call being used. We can't do that on socket-like connections, so this does basically nothing. That's safe because we have a separate read buffer to maintain the already-read data. In a filebuf, the single common buffer is used forcing the <seek> call.

int ACE_Streambuf::syncout ( void  ) [protected]

syncout() is called when the output needs to be flushed. This is easily done by calling the peer's send_n function.

u_char ACE_Streambuf::timeout ( void  )

Did we take an error because of an IO operation timeout?

Note:
Invoking this resets the flag.
int ACE_Streambuf::underflow ( void  ) [protected, virtual]

Member Data Documentation

u_char ACE_Streambuf::cur_mode_ [protected]
char* ACE_Streambuf::eback_saved_ [protected]
char* ACE_Streambuf::egptr_saved_ [protected]
char* ACE_Streambuf::epptr_saved_ [protected]
const u_char ACE_Streambuf::get_mode_ [protected]
char* ACE_Streambuf::gptr_saved_ [protected]
int ACE_Streambuf::mode_ [protected]

mode tells us if we're working for an istream, ostream, or iostream.

char* ACE_Streambuf::pbase_saved_ [protected]
char* ACE_Streambuf::pptr_saved_ [protected]
const u_char ACE_Streambuf::put_mode_ [protected]

We want to allow the user to provide Time_Value pointers to prevent infinite blocking while waiting to receive data.

const u_int ACE_Streambuf::streambuf_size_ [protected]

This defines the size of the input and output buffers. It can be set by the object constructor.

u_char ACE_Streambuf::timeout_ [protected]

Did we take an error because of an IO operation timeout?


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines