// -*- c++ -*- //------------------------------------------------------------------------------ // xdrIOBuffer.h //------------------------------------------------------------------------------ // Copyright (c) 2000,2005 by Vladislav Grinchenko // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. //------------------------------------------------------------------------------ // Created: 04/03/2000 //------------------------------------------------------------------------------ #ifndef XDR_IO_BUFFER_H #define XDR_IO_BUFFER_H #include "assa/Assure.h" #include "assa/Socket.h" #include "assa/IPv4Socket.h" #include namespace ASSA { /** @file xdrIOBuffer.h * * This class allows to read XDR-encoded data from Socket stream asynchronously * and then read from it as if from a stream of intermixed strings, integers * and floats. Data are XDR-decoded on a fly. * * Testing xdrIOBuffer object in conditional statement will produce * false if: * * - Not entire buffer has been read yet. * - Socket stream exceptional condition occured. * * Thus, data accumulation and data decoding functions are separated. * * Initially, buffer is in waiting state. In this state, * xdrIOBuffer object waits for bytes from the Socket stream. * * When buffer object becomes full, the state is switched to * xmitted. Now, an application code can read data * from the buffer. The data will be XDR-decoded. * * xdrIOBuffer object yields TRUE in conditional statements only * in xmitted state. In other words, buffer is TRUE if * it is full, and FALSE otherwise. * * xdrIOBuffer can be used only once. You cannot "rewind", and therefore * reuse it. */ class xdrIOBuffer { public: /** @enum state_t */ enum state_t { waiting, xmitted, parsed, error }; /** Constructor. */ xdrIOBuffer (u_int len_); /** Destructor. */ ~xdrIOBuffer (); /** Copy constructor */ xdrIOBuffer (const xdrIOBuffer& rhs_); /** Assign operator. */ xdrIOBuffer& operator= (const xdrIOBuffer& rhs_); /** Read raw data from Socket nonblocking and * store into internal buffer. */ friend Socket& operator>>(Socket& src_, xdrIOBuffer& dest_); /** Read and XDR-decode STL string from the buffer. */ xdrIOBuffer& operator>>(std::string&); /** Read and XDR-decode an integer from the buffer. */ xdrIOBuffer& operator>>(int&); /** Read and XDR-decode a float from the buffer. */ xdrIOBuffer& operator>>(float&); /** Convertion to void* (for testing where bool is required). */ operator void*() const; /** Give verbal interpretation of object's state. */ string get_state () const; /** Return number of bytes in xdrIOBuffer. In waiting state it's bytes transmitted so far. In xmitted state, number of bytes left to decode. */ int size () const; /** Return buffer (maximum expected/allowable) size. */ int buffer_size () const; /** Return pointer to the first byte of xdrIOBuffer. */ const char* str () const; /** Clear up the internal buffer and reset state to waiting. */ void reset (); /** Dump object's internal state to the log file */ void dump () const; protected: /// Copy object from argument void copy (const xdrIOBuffer&); private: /// Buffer char* m_buf; /// Buffer size and maximum expected size int m_sz; /// Pointer for next I/O operation into the buffer char* m_ptr; /// Object state state_t m_state; }; inline xdrIOBuffer:: xdrIOBuffer (const xdrIOBuffer& rhs_) { trace_with_mask("xdrIOBuffer::xdrIOBuffer(xdrIOBuffer&)", XDRBUFTRACE); copy (rhs_); } inline xdrIOBuffer:: operator void*() const { trace_with_mask("xdrIOBuffer::opt void*()", XDRBUFTRACE); return (m_state == waiting || m_state == parsed) ? (void *)0 // bad state : (void *)(-1); // good state } inline int xdrIOBuffer:: size () const { return (m_ptr - m_buf); } inline int xdrIOBuffer:: buffer_size () const { return (m_sz); } inline const char* xdrIOBuffer:: str () const { return ((const char*) m_buf); } } // end namespace ASSA #endif /* XDR_IO_BUFFER_H */