# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

bit_mem_stream.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_BIT_MEM_STREAM_H
00027 #define NL_BIT_MEM_STREAM_H
00028 
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/mem_stream.h"
00031 
00032 
00033 namespace NLMISC {
00034 
00035 
00042 class CBitMemStream : public CMemStream
00043 {
00044 public:
00045 
00047         CBitMemStream( bool inputStream=false, uint32 defaultcapacity=32 );
00048 
00050         CBitMemStream( const CBitMemStream& other );
00051 
00053         CBitMemStream&  operator=( const CBitMemStream& other ) { CMemStream::operator=( other ); _FreeBits = other._FreeBits; return *this; }
00054 
00059         virtual uint32  length() const
00060         {
00061                 if ( isReading() )
00062                 {
00063                         return lengthR();
00064                 }
00065                 else
00066                 {
00067                         if ( _Buffer.getPtr() -  1 == _BufPos )
00068                         {
00069                                 return 0;
00070                         }
00071                         else
00072                         {
00073                                 return lengthS() + 1;
00074                         }
00075                 }
00076         }
00077 
00079         virtual void    invert()
00080         {
00081                 if (isReading())
00082                 {
00083                         CMemStream::invert();
00084                         _BufPos--;
00085                         _FreeBits = 8;
00086                 }
00087                 else
00088                 {
00089                         _BufPos++;
00090                         CMemStream::invert();
00091                         _FreeBits = 8;
00092                 }
00093         }
00094 
00096         virtual void    clear()
00097         {
00098                 CMemStream::clear();
00099                 _FreeBits = 8;
00100                 _BufPos--;
00101         }
00102 
00104         sint32  getPosInBit()
00105         {
00106                 if (isReading())
00107                 {
00108                         return getPos() * 8 + (8 - _FreeBits);
00109                 }
00110                 else
00111                 {
00112                         if (_Buffer.getPtr() - 1 == _BufPos)
00113                                 return 0;
00114                         else if (_FreeBits == 8)
00115                                 return (getPos() + 1) * 8;
00116                         else
00117                                 return getPos() * 8 + (8 - _FreeBits);
00118         /*              if (_Buffer.empty())
00119                                 return 0;
00120                         else if (_FreeBits == 8)
00121                                 return (getPos() + 1) * 8;
00122                         else
00123                                 return getPos() * 8 + (8 - _FreeBits);
00124         */      }
00125         }
00126 
00127 
00129         virtual void    serialBuffer(uint8 *buf, uint len);
00130 
00132         virtual void    serialBit( bool& bit );
00133 
00137         void                    serial( uint32& value, uint nbits, bool resetvalue=true );
00138 
00140         void                    serial( uint64& value, uint nbits )
00141         {
00142                 if ( nbits > 32 )
00143                 {
00144                         if ( isReading() )
00145                         {
00146                                 // Reset and read MSD
00147                                 uint32 msd = 0;
00148                                 serial( msd, nbits-32 );
00149                                 value = (uint64)msd << 32;
00150                                 // Reset and read LSD
00151                                 serial( (uint32&)value, 32 );
00152                         }
00153                         else
00154                         {
00155                                 // Write MSD
00156                                 uint32 msd = (uint32)(value >> 32);
00157                                 serial( msd, nbits-32 );
00158                                 // Write LSD
00159                                 serial( (uint32&)value, 32 );
00160                         }
00161                 }
00162                 else
00163                 {
00164                         if ( isReading() )
00165                         {
00166                                 // Reset MSB (=0 is faster than value&=0xFFFFFFFF)
00167                                 value = 0;
00168                         }
00169                         // Read or write LSB
00170                         serial( (uint32&)value, nbits );
00171                 }
00172         }
00173 
00175     template<class T>
00176         void                    serial(T &obj)                                                  { obj.serial(*this); }
00177 
00178         // CMemStream::serialCont() will call CBitMemStream's virtual serialBuffer()
00179         template<class T>
00180         void                    serialCont(std::vector<T> &cont)                {CMemStream::serialCont(cont);}
00181         template<class T>
00182         void                    serialCont(std::list<T> &cont)                  {CMemStream::serialCont(cont);}
00183         template<class T>
00184         void                    serialCont(std::deque<T> &cont)                 {CMemStream::serialCont(cont);}
00185         template<class T>
00186         void                    serialCont(std::set<T> &cont)                   {CMemStream::serialCont(cont);}
00187         template<class T>
00188         void                    serialCont(std::multiset<T> &cont)              {CMemStream::serialCont(cont);}
00189         template<class K, class T>
00190         void                    serialCont(std::map<K, T> &cont)                {CMemStream::serialCont(cont);}
00191         template<class K, class T>
00192         void                    serialCont(std::multimap<K, T> &cont)   {CMemStream::serialCont(cont);}
00193 
00194         /*template<class T0,class T1>
00195         void                    serial(T0 &a, T1 &b) 
00196         { serial(a); serial(b);}
00197         template<class T0,class T1,class T2>
00198         void                    serial(T0 &a, T1 &b, T2 &c) 
00199         { serial(a); serial(b); serial(c);}
00200         template<class T0,class T1,class T2,class T3>
00201         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d) 
00202         { serial(a); serial(b); serial(c); serial(d);}
00203         template<class T0,class T1,class T2,class T3,class T4>
00204         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d, T4 &e) 
00205         { serial(a); serial(b); serial(c); serial(d); serial(e);}
00206         template<class T0,class T1,class T2,class T3,class T4,class T5>
00207         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d, T4 &e, T5 &f) 
00208         { serial(a); serial(b); serial(c); serial(d); serial(e); serial(f);}*/
00209 
00214 
00215 
00216 #define serialAdapt( b, type ) \
00217         uint32 ub=0; \
00218         if ( isReading() ) \
00219         { \
00220                 serial( ub, sizeof(type)*8 ); \
00221                 b = (type)ub; \
00222         } \
00223         else \
00224         { \
00225                 ub = (uint32)b; \
00226                 serial( ub, sizeof(type)*8 ); \
00227         }
00228 
00229 /*
00230 #define serialAdapt64( b, type ) \
00231         uint32 ubl=0, ubh=0; \
00232         if ( isReading() ) \
00233         { \
00234                 serial( ubh, sizeof(uint32)*8 ); \
00235                 serial( ubl, sizeof(uint32)*8 ); \
00236                 b = (((type)ubh)<<32)+ubl; \
00237         } \
00238         else \
00239         { \
00240                 ubh = (uint32)(b>>32); \
00241                 ubl = (uint32)(b); \
00242                 serial( ubh, sizeof(uint32)*8 ); \
00243                 serial( ubl, sizeof(uint32)*8 ); \
00244         }
00245 */
00246 
00247 #ifdef NL_LITTLE_ENDIAN
00248 
00249 #define serialAdapt64( b ) \
00250         serial( *((uint32*)(&b)), 32); \
00251         serial( *((uint32*)(&b)+1), 32);
00252 
00253 #else
00254 
00255 #define serialAdapt64( b ) \
00256         serial( *((uint32*)(&b)+1), 32); \
00257         serial( *((uint32*)(&b)), 32);
00258 
00259 #endif
00260         
00261         virtual void    serial(uint8 &b) { serialAdapt( b, uint8 ); }
00262         virtual void    serial(sint8 &b) { serialAdapt( b, sint8 ); }
00263         virtual void    serial(uint16 &b) { serialAdapt( b, uint16 ); }
00264         virtual void    serial(sint16 &b) { serialAdapt( b, sint16 ); }
00265         virtual void    serial(uint32 &b) { serialAdapt( b, uint32 ); }
00266         virtual void    serial(sint32 &b) { serialAdapt( b, sint32 ); }
00267         virtual void    serial(uint64 &b) { serialAdapt64( b ); }
00268         virtual void    serial(sint64 &b) { serialAdapt64( b ); }
00269         virtual void    serial(float &b);
00270         virtual void    serial(double &b) { serialAdapt64( b ); }
00271         virtual void    serial(bool &b) { serialBit( b ); }
00272 #ifndef NL_OS_CYGWIN
00273         virtual void    serial(char &b) { serialAdapt( b, char ); }
00274 #endif
00275         virtual void    serial(std::string &b);
00276         //virtual void  serial(ucstring &b);
00277 
00278         virtual void    serial(CBitMemStream &b);
00279         
00281 
00283         virtual void                    serialCont(std::vector<uint8> &cont) { serialVector(cont); }
00285         virtual void                    serialCont(std::vector<sint8> &cont) { serialVector(cont); }
00287         virtual void                    serialCont(std::vector<bool> &cont);
00288 
00289 protected:
00290 
00291         uint                    _FreeBits; // From 8 downto 1
00292 
00293 };
00294 
00295 } // NLMISC
00296 
00297 
00298 #endif // NL_BIT_MEM_STREAM_H
00299 
00300 /* End of bit_mem_stream.h */