BByteStream.h

Go to the documentation of this file.
00001 //
00002 // Copyright (c) 2000 by Tech Soft 3D, LLC.
00003 // The information contained herein is confidential and proprietary to
00004 // Tech Soft 3D, LLC., and considered a trade secret as defined under
00005 // civil and criminal statutes.  Tech Soft 3D shall pursue its civil
00006 // and criminal remedies in the event of unauthorized use or misappropriation
00007 // of its trade secrets.  Use of this information by anyone other than
00008 // authorized employees of Tech Soft 3D, LLC. is granted only under a
00009 // written non-disclosure agreement, expressly prescribing the scope and
00010 // manner of such use.
00011 //
00012 // $Header: //DWF/Working_Area/Willie.Zhu/w3dtk/BByteStream.h#1 $
00013 //
00014 // This header file is a completely self-contained class that defines all of the
00015 // member functions that it needs inside the declaration.  It is just a utility class
00016 // to stuff unaligned data values into bytes.
00017 //
00018 
00019 #ifndef _B_BYTE_STREAM_H_
00020 #define _B_BYTE_STREAM_H_
00021 
00025 
00026 
00027 #ifndef STATUS_ERROR
00028 #  define STATUS_ERROR 0
00029 #endif
00030 #ifndef STATUS_NORMAL
00031 #  define STATUS_NORMAL 1
00032 #endif
00033 
00034 #ifdef __APPLE_CC__
00035         #ifdef __i386__
00036                 #undef STREAM_BIGENDIAN
00037         #else
00038                 #define STREAM_BIGENDIAN
00039         #endif
00040 #endif
00041 
00043 
00065 class BByteStream {
00066   private:
00067     int byteplace;      
00068     int bitplace;       
00069     int bitsperval;     
00070     int allocated;      
00071     unsigned char *data;    
00072     unsigned short mask;    
00073   public:
00074     BByteStream(int size, unsigned char *cptr, int bpv) {
00075         if( bpv == 9 || bpv == 10 || bpv == 12 ) {
00076             allocated = size;
00077             data = cptr; 
00078             bitsperval = bpv;
00079             byteplace = 0;
00080             bitplace = 16 - bitsperval; 
00081             mask = (unsigned short)((1<<bitsperval)-1);
00082         }
00083         else {
00084             //do nothing.  we deserve the crash.
00085             data = 0;
00086         }
00087     };
00088     BByteStream() { data = NULL; };
00089     /*< write a sample */
00090     void put(unsigned short value) alter {
00091         data[byteplace] |= (value >> (8 - bitplace));
00092         data[byteplace+1] |= (value << bitplace);
00093         bitplace -= bitsperval - 8;
00094         if( bitplace < 0 ) {
00095             byteplace += 2; // consume two bytes
00096             bitplace += 8;
00097         }
00098         else
00099             byteplace++; // consume one byte
00100     };      
00102     void get(unsigned short alter &value) {
00103         value = (unsigned short)((data[byteplace] << 8) | (data[byteplace + 1]));
00104         value = (unsigned short)((value >> bitplace) & mask );
00105         bitplace -= bitsperval - 8;
00106         if( bitplace < 0 ) {
00107             byteplace += 2; // consume two bytes
00108             bitplace += 8;
00109         }
00110         else
00111             byteplace++; // consume one byte
00112     }; 
00113 
00114 }; //end declaration of class BByteStream
00115 
00116 
00117 
00127 class BVarStream {
00128   private:
00129     unsigned int *m_data;   
00130     int m_allocated;        
00131     int m_used;             
00132     int m_bit;              
00133     int m_rused;            
00134     int m_rbit;             
00135     int m_can_reallocate;   
00136     int m_status;           
00137     unsigned int m_mask[33];  
00138     unsigned int m_range[33]; 
00142     void Reset() {
00143         int i;
00144         m_data = 0;
00145         m_allocated = 0;
00146         m_used = 0;
00147         m_bit = 0;
00148         m_rused = 0;
00149         m_rbit = 0;
00150         m_can_reallocate = 0;
00151         m_status = STATUS_NORMAL;
00152         m_mask[0] = 0;
00153         m_range[0] = 0;
00154         for( i = 1 ; i <= 32 ; i++ ) {
00155             m_mask[i] = ((unsigned int)(-1)) >> (32-i);
00156             m_range[i] = (0x1 << (i-1)) - 1;
00157         }
00158     };
00159 
00161     #ifdef STREAM_BIGENDIAN
00162         #ifndef SWAP32
00163             #define SWAP32(i) (\
00164                 (((i) >> 24) & 0x000000ff) |\
00165                 (((i) & 0x00ff0000) >> 8) |\
00166                 (((i) & 0x0000ff00) << 8) |\
00167                 ((i) << 24) \
00168                 )
00169             #endif
00170     void SwapBytes( ) 
00171     {
00172         int i;
00173         for( i = 0 ; i < m_allocated ; i++ )
00174             m_data[i] = SWAP32( m_data[i] );
00175     };
00176 #   else
00177     inline void SwapBytes() {};
00178 #   endif
00179 
00181     void Reallocate( )
00182     {
00183 
00184         if( m_can_reallocate ) {
00185             unsigned int *temp;
00186             m_allocated *= 2;
00187             temp = new unsigned int[ m_allocated ];
00188             if( temp == NULL ) {
00189                 /* Allocation failed.  Declare error, jettison all data to avoid a seg fault */
00190                 m_status = STATUS_ERROR;
00191                 m_used = 0; 
00192             }
00193             else {
00194                 memcpy( temp, m_data, (m_used+1) * sizeof( unsigned int ) );
00195                 delete [] m_data;
00196                 m_data = temp;
00197             }
00198         }
00199         else {
00200             /* We don't own the poitner. Declare error, jettison all data to avoid a seg fault */
00201             m_status = STATUS_ERROR;
00202             m_used = 0;
00203         }
00204     };
00205 
00207     void Put2( int numbits, int val ) 
00208     {
00209         if( m_bit + numbits <= 32 ) {
00210             m_data[m_used] |= val << (32 - m_bit - numbits);
00211             m_bit += numbits;
00212         }
00213         else {
00214             int shift = (numbits + m_bit - 32);
00215 
00216             if( m_used + 1 >= m_allocated )
00217                 Reallocate( );
00218             m_data[m_used++] |= val >> shift;
00219             m_data[m_used] = val << (32-shift);
00220             m_bit += numbits - 32;
00221         }
00222     };
00223 
00225     void Get2( int numbits, int *val ) 
00226     {
00227         if( m_rbit + numbits <= 32 ) {
00228             *val = (m_data[m_rused] >> (32 - m_rbit - numbits)) & m_mask[numbits];
00229             m_rbit += numbits;
00230         }
00231         else {
00232             int shift = (numbits + m_rbit - 32);
00233             *val = (m_data[m_rused++] << shift) & m_mask[numbits];
00234             *val |= m_data[m_rused] >> (32-shift);
00235             m_rbit += numbits - 32;
00236         }
00237     };
00238 
00239 
00240   public:
00241 
00242     BVarStream() {
00243         m_can_reallocate = 0;
00244         m_data = NULL;
00245     };
00246 
00247     ~BVarStream( )
00248     {
00249         if( m_data != NULL ) {
00250             if( m_can_reallocate )
00251                 delete [] m_data;
00252             m_data = NULL;
00253         }
00254     };
00255 
00260     void InitWrite( int size, void *pointer ) {
00261         Reset();
00262         m_allocated = size/4;
00263         m_data = (unsigned int *) pointer;
00264         m_data[0] = 0;
00265         m_can_reallocate = 1;
00266     };
00267 
00272     void InitRead( int size, const void *pointer )
00273     {
00274         Reset();
00275         m_allocated = size/4;
00276         m_data = (unsigned int *) pointer;
00277         m_can_reallocate = 0;
00278     };
00279 
00284     int Put( int *numbits_array, int val )
00285     {
00286         int temprange = 0, i;
00287 
00288         i = 0;
00289         for(;;){
00290             temprange = m_range[ numbits_array[i] ];
00291             if( val < -temprange || val > temprange ) {
00292                 /* Put an escape sequence as a signal to "fall back to the next level" */
00293                 Put2( numbits_array[i], m_mask[ numbits_array[i] ] );
00294                 i++;
00295             }
00296             else {
00297                 /* Put the real data.  We've found a range that works, so we're done. */
00298                 Put2( numbits_array[i], val+temprange );
00299                 break;
00300             }
00301         }
00302         return m_status;
00303     };
00304 
00311     int Get( int *numbits_array ) 
00312     {
00313         int i = 0;
00314         int val;
00315 
00316         for(;;) {
00317             Get2( numbits_array[i], &val );
00318             if( val == (int)m_mask[ numbits_array[i] ] )
00319                 i++;
00320             else
00321                 break;
00322         }
00323         val -= m_range[ numbits_array[i] ];
00324         return val;
00325     };
00326 
00327 }; /* end definition of class BVarStream */
00328 
00329 
00330 
00331 
00343 class BPack {
00344   private:
00345     unsigned int *m_data; 
00346     int m_allocated;    
00347     int m_used;     
00348     int m_bit;      
00349     int m_rused;        
00350     int m_rbit;     
00351     int m_can_reallocate; 
00352     int m_status;       
00353     unsigned int m_mask[33]; 
00354     unsigned int m_range[33]; 
00358     void Reset() {
00359         int i;
00360         m_data = 0;
00361         m_allocated = 0;
00362         m_used = 0;
00363         m_bit = 0;
00364         m_rused = 0;
00365         m_rbit = 0;
00366         m_can_reallocate = 0;
00367         m_status = STATUS_NORMAL;
00368         m_mask[0] = 0;
00369         m_range[0] = 0;
00370         for( i = 1 ; i <= 32 ; i++ ) {
00371             m_mask[i] = ((unsigned int)(-1)) >> (32-i);
00372             m_range[i] = (0x1 << (i-1)) - 1;
00373         }
00374     };
00375 
00377     void Reallocate( )
00378     {
00379 
00380         if( m_can_reallocate ) {
00381             unsigned int *temp;
00382             m_allocated *= 2;
00383             temp = new unsigned int[ m_allocated ];
00384             if( temp == NULL ) {
00385                 /* Allocation failed.  Declare error, jettison all data to avoid a seg fault */
00386                 m_status = STATUS_ERROR;
00387                 m_used = 0; 
00388             }
00389             else {
00390                 memcpy( temp, m_data, (m_used+1) * sizeof( unsigned int ) );
00391                 delete [] m_data;
00392                 m_data = temp;
00393             }
00394         }
00395         else {
00396             /* We don't own the poitner. Declare error, jettison all data to avoid a seg fault */
00397             m_status = STATUS_ERROR;
00398             m_used = 0;
00399         }
00400     };
00401 
00402 
00403 
00404   public:
00405 
00406     BPack() { 
00407         m_can_reallocate = 0;
00408         m_data = NULL;
00409     };
00410 
00411     ~BPack( ) {
00412         if( m_data != NULL ) {
00413             if( m_can_reallocate )
00414                 delete [] m_data;
00415             m_data = NULL;
00416         }
00417     };
00418 
00423     void InitWrite( int size, void *pointer ) {
00424         Reset();
00425         m_allocated = size/4;
00426         m_data = (unsigned int *) pointer;
00427         if (m_data) m_data[0] = 0;
00428         m_can_reallocate = 0;
00429     };
00430 
00435     void InitRead( int size, const void *pointer )
00436     {
00437         Reset();
00438         m_allocated = size/4;
00439         m_data = (unsigned int *) pointer;
00440         m_can_reallocate = 0;
00441     };
00442 
00443     void Put( int numbits, int val ) 
00444     {
00445         if( m_bit + numbits <= 32 ) {
00446             m_data[m_used] |= val << (32 - m_bit - numbits);
00447             m_bit += numbits;
00448         }
00449         else {
00450             int shift = (numbits + m_bit - 32);
00451 
00452             if( m_used + 1 >= m_allocated )
00453                 Reallocate( );
00454             m_data[m_used++] |= val >> shift;
00455             m_data[m_used] = val << (32-shift);
00456             m_bit += numbits - 32;
00457         }
00458     };
00459 
00460     int Get( int numbits ) 
00461     {
00462         int return_val;
00463 
00464         if( m_rbit + numbits <= 32 ) {
00465             return_val = (m_data[m_rused] >> (32 - m_rbit - numbits)) & m_mask[numbits];
00466             m_rbit += numbits;
00467         }
00468         else {
00469             int shift = (numbits + m_rbit - 32);
00470             return_val = (m_data[m_rused++] << shift) & m_mask[numbits];
00471             return_val |= m_data[m_rused] >> (32-shift);
00472             m_rbit += numbits - 32;
00473         }
00474         return return_val;
00475     };
00476 
00477     int NumBytes() const { return (m_used+(m_bit?1:0)) * 4; };
00478     void SetCanReallocate(int val) alter { m_can_reallocate = val; };
00479     int GetStatus() const { return m_status; };
00480 
00482     #ifdef STREAM_BIGENDIAN
00483         void SwapBytes( ) 
00484         {
00485             int i;
00486             for( i = 0 ; i < m_allocated ; i++ )
00487                 m_data[i] = SWAP32( m_data[i] );
00488         };
00489     #else
00490         inline void SwapBytes() {};
00491     #endif
00492 
00493 }; /* end definition of class BPack */
00494 
00495 
00496 #endif /* _B_BYTE_STREAM_H_ */
00497 

Generated on Tue Jan 6 22:41:34 2009 for Autodesk DWF 3D Toolkit by  doxygen 1.4.5