/* * This file is part of UAS2. * * UAS2 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * UAS2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with UASv1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file Message.h */ #ifndef __MESSAGE_H #define __MESSAGE_H #include #include #include #include "Shared.h" #define BUFFER_BLOCK_SIZE 1024 class cMessage { class cBlock { friend class cMessage; mutable BYTE *m_pStart, *m_pUsed; public: cBlock (); cBlock ( const cBlock &from ); ~cBlock (); BOOL pasteData ( BYTE *&pData, int &nBytes ); int getAlign ( int nBoundary ) const; BOOL pasteAlign ( int &nBytes ); size_t getUsed () const { return ( m_pUsed - m_pStart ); } BOOL getData ( size_t &nOffset, size_t &nLength, BYTE * &pBuffer ) const; private: // Disabled functions cBlock &operator= ( const cBlock & ); }; typedef std::deque< cBlock > cBlockList; cBlockList m_blocks; // Place a block of data into the message public: cMessage (); cMessage (BYTE* pbPacket, int nSize); ~cMessage( ) { while ( !m_blocks.empty( ) ) m_blocks.pop_front( ); } // Basic functions for inserting data void pasteData ( BYTE *pData, int nBytes ); void pasteAlign ( int nBoundary ); void pasteString ( const char *str ); // Functions for retrieving data size_t getSize () const; void getData ( size_t nOffset, size_t nLength, BYTE *pBuffer ) const; template< class DataT > inline void paste ( DataT dt ) { pasteData ( reinterpret_cast< BYTE * > ( &dt ), sizeof ( DataT ) ); } // String pastes template<> inline void paste ( char *str ) { pasteString ( static_cast< const char * >( str ) ); } template<> inline void paste ( const char *str ) { pasteString ( static_cast< const char * >( str ) ); } // Collection pastes template< class ItemT > void paste ( std::vector< ItemT > &vec ) { for ( std::vector< ItemT >::iterator i = vec.begin(); i != vec.end(); ++ i ) i->encode ( *this ); // Always realign after doing a vector pasteAlign ( sizeof ( unsigned long ) ); } void CannedData( BYTE *pbData, DWORD dwSize ) { pasteData( pbData, dwSize ); } inline BYTE& operator[]( int iElem ) const { // #ifdef _DEBUG // if ( getSize( ) > 0 ) // assert( iElem < getSize( ) ); // #endif return (m_blocks.begin( ) + (iElem / BUFFER_BLOCK_SIZE))->m_pStart[iElem % BUFFER_BLOCK_SIZE]; } private: class cBlockDispenser { HANDLE m_hHeap; public: cBlockDispenser (); ~cBlockDispenser (); BYTE *get (); void release (BYTE *pBlock); }; static cBlockDispenser g_dispenser; friend cBlock; }; template< class DataT > cMessage &operator<< ( cMessage &buf, DataT t ) { buf.paste ( t ); return buf; } #endif // #ifndef __MESSAGE_H