H:/gfcppsancout/product/include/gfcpp/DataInput.hpp

Go to the documentation of this file.
00001 #ifndef __GEMFIRE_DATAINPUT_H__
00002 #define __GEMFIRE_DATAINPUT_H__
00003 
00004 /*=========================================================================
00005  * (c) Copyright 2002-2007, GemStone Systems, Inc. All Rights Reserved.
00006  * 1260 NW Waterhouse Ave., Suite 200,  Beaverton, OR 97006
00007  *=========================================================================
00008  */
00009 
00010 #include "gfcpp_globals.hpp"
00011 #include "ExceptionTypes.hpp"
00012 #include <string.h>
00013 #include "Serializable.hpp"
00014 
00020 #if GF_DEBUG_ASSERTS == 1
00021 #define DINP_THROWONERROR_DEFAULT true
00022 #else
00023 #define DINP_THROWONERROR_DEFAULT false
00024 #endif
00025 
00026 #define checkBufferSize(x) _checkBufferSize(x,__LINE__)
00027 
00028 namespace gemfire
00029 {
00030 
00031 extern int gf_sprintf(char* buffer, const char* fmt, ...);
00032 
00040 class CPPCACHE_EXPORT DataInput
00041 {
00042 public:
00043 
00049   inline void read( uint8_t* value )
00050   {
00051     checkBufferSize(1);
00052     *value = *(m_buf++);
00053   }
00054 
00060   inline void read( int8_t* value )
00061   {
00062     checkBufferSize(1);
00063     *value = *(m_buf++);
00064   }
00065 
00071   inline void readBoolean( bool* value )
00072   {
00073     checkBufferSize(1);
00074     *value = (*m_buf == 1 ? true : false);
00075     m_buf++;
00076   }
00077 
00088   inline void readBytesOnly(uint8_t* buffer, uint32_t len)
00089   {
00090     if (len > 0) {
00091       checkBufferSize(len);
00092       memcpy( buffer, m_buf, len );
00093       m_buf += len;
00094     }
00095   }
00096 
00107   inline void readBytesOnly(int8_t* buffer, uint32_t len)
00108   {
00109     if (len > 0) {
00110       checkBufferSize(len);
00111       memcpy( buffer, m_buf, len );
00112       m_buf += len;
00113     }
00114   }
00115 
00126   inline void readBytes( uint8_t** bytes, int32_t* len )
00127   {
00128     int32_t length;
00129     readArrayLen( &length );
00130     *len = length;
00131     uint8_t* buffer = NULL;
00132     if ( length > 0 ) {
00133       checkBufferSize(length);
00134       GF_NEW( buffer, uint8_t[ length ] );
00135       memcpy( buffer, m_buf, length );
00136       m_buf += length;
00137     }
00138     *bytes = buffer;
00139   }
00140 
00151   inline void readBytes( int8_t** bytes, int32_t* len )
00152   {
00153     int32_t length;
00154     readArrayLen( &length );
00155     *len = length;
00156     int8_t* buffer = NULL;
00157     if ( length > 0 ) {
00158       checkBufferSize(length);
00159       GF_NEW( buffer, int8_t[ length ] );
00160       memcpy( buffer, m_buf, length );
00161       m_buf += length;
00162     }
00163     *bytes = buffer;
00164   }
00165 
00172   inline void readInt( uint16_t* value )
00173   {
00174     checkBufferSize(2);
00175     uint16_t tmp = *(m_buf++);
00176     tmp = (tmp << 8) | *(m_buf++);
00177     *value = tmp;
00178   }
00179 
00186   inline void readInt( uint32_t* value )
00187   {
00188     checkBufferSize(4);
00189     uint32_t tmp = *(m_buf++);
00190     tmp = (tmp << 8) | *(m_buf++);
00191     tmp = (tmp << 8) | *(m_buf++);
00192     tmp = (tmp << 8) | *(m_buf++);
00193     *value = tmp;
00194   }
00195 
00202   inline void readInt( uint64_t* value )
00203   {
00204     checkBufferSize(8);
00205     uint64_t tmp;
00206     if ( sizeof( long ) == 8 ) {
00207       tmp = *(m_buf++);
00208       tmp = (tmp << 8) | *(m_buf++);
00209       tmp = (tmp << 8) | *(m_buf++);
00210       tmp = (tmp << 8) | *(m_buf++);
00211       tmp = (tmp << 8) | *(m_buf++);
00212       tmp = (tmp << 8) | *(m_buf++);
00213       tmp = (tmp << 8) | *(m_buf++);
00214       tmp = (tmp << 8) | *(m_buf++);
00215     } else {
00216       uint32_t hword = *(m_buf++);
00217       hword = (hword << 8) | *(m_buf++);
00218       hword = (hword << 8) | *(m_buf++);
00219       hword = (hword << 8) | *(m_buf++);
00220 
00221       tmp = hword;
00222       hword = *(m_buf++);
00223       hword = (hword << 8) | *(m_buf++);
00224       hword = (hword << 8) | *(m_buf++);
00225       hword = (hword << 8) | *(m_buf++);
00226       tmp = (tmp << 32) | hword;
00227     }
00228     *value = tmp;
00229   }
00230 
00237   inline void readInt( int16_t* value )
00238   {
00239     checkBufferSize(2);
00240     readInt( (uint16_t*)value );
00241   }
00242 
00249   inline void readInt( int32_t* value )
00250   {
00251     checkBufferSize(4);
00252     readInt( (uint32_t*)value );
00253   }
00254 
00261   inline void readInt( int64_t* value )
00262   {
00263     checkBufferSize(8);
00264     readInt( (uint64_t*)value );
00265   }
00266 
00275   inline void readArrayLen( int32_t* len )
00276   {
00277     uint8_t code;
00278     read(&code);
00279     if (code == 0xFF) {
00280       *len = -1;
00281     } else {
00282       int32_t result = code;
00283       if (result > 252) {  // 252 is java's ((byte)-4 && 0xFF)
00284         if (code == 0xFE) {
00285           uint16_t val;
00286           readInt(&val);
00287           result = val;
00288         } else if (code == 0xFD) {
00289           uint32_t val;
00290           readInt(&val);
00291           result = val;
00292         } else {
00293           throw IllegalStateException("unexpected array length code");
00294         }
00295       }
00296       *len = result;
00297     }
00298   }
00299 
00305   inline void readFloat( float* value )
00306   {
00307     checkBufferSize(4);
00308     union float_uint32_t
00309     {
00310         float f;
00311         uint32_t u;
00312     }v;
00313     readInt( (uint32_t*)&v.u);
00314     *value = v.f;
00315   }
00316 
00323   inline void readDouble( double* value )
00324   {
00325     checkBufferSize(8);
00326     union double_uint64_t
00327     {
00328         double d;
00329         uint64_t        ll;
00330     }v;
00331     readInt( (uint64_t*)&v.ll);
00332     *value = v.d;
00333   }
00334 
00340   static inline void freeUTFMemory( char* value )
00341   {
00342     delete [] value;
00343   }
00344 
00350   static inline void freeUTFMemory( wchar_t* value )
00351   {
00352     delete [] value;
00353   }
00354 
00370   inline void readASCII( char** value, uint16_t* len = NULL )
00371   {
00372     uint16_t length;
00373     readInt( &length );
00374     checkBufferSize(length);
00375     if ( len != NULL ) {
00376       *len = length;
00377     }
00378     char* str;
00379     GF_NEW( str, char[ length + 1 ] );
00380     *value = str;
00381     readBytesOnly((int8_t*)str, length);
00382     str[ length ] = '\0';
00383   }
00384 
00399   inline void readASCIIHuge( char** value, uint32_t* len = NULL )
00400   {
00401     uint32_t length;
00402     readInt( &length );
00403     if ( len != NULL ) {
00404       *len = length;
00405     }
00406     char* str;
00407     GF_NEW( str, char[ length + 1 ] );
00408     *value = str;
00409     readBytesOnly( (int8_t*)str, length );
00410     str[ length ] = '\0';
00411   }
00412 
00429   inline void readUTF( char** value, uint16_t* len = NULL )
00430   {
00431     uint16_t length;
00432     readInt( &length );
00433     checkBufferSize(length);
00434     uint16_t decodedLen = (uint16_t)getDecodedLength( m_buf, length );
00435     if ( len != NULL ) {
00436       *len = decodedLen;
00437     }
00438     char* str;
00439     GF_NEW( str, char[ decodedLen + 1 ] );
00440     *value = str;
00441     for( uint16_t i = 0; i < decodedLen; i++ ) {
00442       decodeChar( str++ );
00443     }
00444     *str = '\0'; // null terminate for c-string.
00445   }
00446 
00456   inline void readUTFNoLen(wchar_t** value, uint16_t decodedLen)
00457   {
00458     wchar_t* str;
00459     GF_NEW(str, wchar_t[decodedLen + 1]);
00460     *value = str;
00461     for (uint16_t i = 0; i < decodedLen; i++) {
00462       decodeChar(str++);
00463     }
00464     *str = L'\0'; // null terminate for c-string.
00465   }
00466 
00481   inline void readUTFHuge( char** value, uint32_t* len = NULL )
00482   {
00483     uint32_t length;
00484     readInt( &length );
00485     if ( len != NULL ) {
00486       *len = length;
00487     }
00488     char* str;
00489     GF_NEW( str, char[ length + 1 ] );
00490     *value = str;
00491     for( uint32_t i = 0; i < length; i++ ) {
00492       int8_t item;
00493       read(&item); // ignore this - should be higher order zero byte
00494       read(&item);
00495       *str = item;
00496       str++;
00497     }
00498     *str = '\0'; // null terminate for c-string.
00499   }
00500 
00517   inline void readUTF( wchar_t** value, uint16_t* len = NULL )
00518   {
00519     uint16_t length;
00520     readInt( &length );
00521     checkBufferSize(length);
00522     uint16_t decodedLen = (uint16_t)getDecodedLength( m_buf, length );
00523     if ( len != NULL ) {
00524       *len = decodedLen;
00525     }
00526     wchar_t* str;
00527     GF_NEW( str, wchar_t[ decodedLen + 1 ] );
00528     *value = str;
00529     for( uint16_t i = 0; i < decodedLen; i++ ) {
00530       decodeChar( str++ );
00531     }
00532     *str = L'\0'; // null terminate for c-string.
00533   }
00534 
00549   inline void readUTFHuge( wchar_t** value, uint32_t* len = NULL )
00550   {
00551     uint32_t length;
00552     readInt( &length );
00553     if ( len != NULL ) {
00554       *len = length;
00555     }
00556     wchar_t* str;
00557     GF_NEW( str, wchar_t[ length + 1 ] );
00558     *value = str;
00559     for( uint32_t i = 0; i < length; i++ ) {
00560       uint8_t hibyte;
00561       read(&hibyte);
00562       uint8_t lobyte;
00563       read(&lobyte);
00564       *str = (((uint16_t)hibyte) << 8) | (uint16_t)lobyte;
00565       str++;
00566     }
00567     *str = L'\0'; // null terminate for c-string.
00568   }
00569 
00589   template< class PTR >
00590   inline void readObject( SharedPtr<PTR>& ptr,
00591       bool throwOnError = DINP_THROWONERROR_DEFAULT )
00592   {
00593     SerializablePtr sPtr;
00594     readObjectInternal( sPtr );
00595     if ( throwOnError ) {
00596       ptr = dynCast< SharedPtr<PTR> >( sPtr );
00597     } else {
00598       ptr = staticCast< SharedPtr<PTR> >( sPtr );
00599     }
00600   }
00601 
00606   inline void readObject( SerializablePtr& ptr )
00607   {
00608     readObjectInternal( ptr );
00609   }
00610 
00621   static int32_t getDecodedLength( const uint8_t* value, int32_t length )
00622   {
00623     const uint8_t* end = value + length;
00624     int32_t decodedLen = 0;
00625     while ( value < end ) {
00626        // get next byte unsigned
00627     int32_t b = *value++ & 0xff;
00628     int32_t k = b >> 5;
00629     // classify based on the high order 3 bits
00630       switch (  k )
00631         {       
00632         case 6:
00633           {
00634             value++;
00635             break;
00636           }
00637         case 7:
00638           {
00639             value += 2;
00640             break;
00641           }
00642         default:
00643           break;
00644         }
00645       decodedLen += 1;
00646     }
00647     if ( value > end ) decodedLen--;
00648     return decodedLen;
00649   }
00650 
00652   DataInput(const uint8_t* m_buffer, int32_t len)
00653     : m_buf(m_buffer), m_bufHead(m_buffer), m_bufLength(len)
00654   {
00655   }
00656 
00658   ~DataInput( ) { }
00659 
00665   inline const uint8_t* currentBufferPosition() const
00666   {
00667     return m_buf;
00668   }
00669 
00671   inline int32_t getBytesRead() const
00672   {
00673     return static_cast<int32_t>(m_buf - m_bufHead);
00674   }
00675 
00677   inline int32_t getBytesRemaining() const
00678   {
00679     return (m_bufLength - getBytesRead());
00680   }
00681 
00683   inline void advanceCursor(int32_t offset)
00684   {
00685     m_buf += offset;
00686   }
00687 
00689   inline void rewindCursor(int32_t offset)
00690   {
00691     m_buf -= offset;
00692   }
00693 
00695   inline void reset()
00696   {
00697     m_buf = m_bufHead;
00698   }
00699 
00700   uint8_t * getBufferCopyFrom(const uint8_t *from, uint32_t length)
00701   {
00702     uint8_t * result;
00703     GF_NEW( result, uint8_t[ length ] );
00704     memcpy( result, from, length);
00705     
00706     return result;
00707   }
00708 
00709 private:
00710 
00711   const uint8_t* m_buf;
00712   const uint8_t* m_bufHead;
00713   int32_t m_bufLength;
00714 
00715   void readObjectInternal( SerializablePtr& ptr );
00716 
00717   inline void _checkBufferSize(int32_t size, int32_t line)
00718   {
00719     if ((m_bufLength - (m_buf - m_bufHead)) < size) {
00720       char exMsg[128];
00721       gf_sprintf(exMsg, "DataInput: attempt to read beyond buffer at line %d: "
00722           "available buffer size %d, attempted read of size %d ", line,
00723           m_bufLength - (m_buf - m_bufHead), size);
00724       throw OutOfRangeException(exMsg);
00725     }
00726   }
00727 
00728   inline void decodeChar( char* str )
00729   {
00730     uint8_t bt = *(m_buf++);
00731     if ( bt & 0x80 ) {
00732       if ( bt & 0x20 ) {
00733         // three bytes.
00734         *str = ((bt & 0x0f) << 12) | (((*m_buf++) & 0x3f) << 6);
00735         *str |= ((*m_buf++) & 0x3f);
00736       } else {
00737         // two bytes.
00738         *str = ((bt & 0x1f) << 6) | ((*m_buf++) & 0x3f);
00739       }
00740     } else {
00741       // single byte...
00742       *str = bt;
00743     }
00744   }
00745 
00746   inline void decodeChar( wchar_t* str )
00747   {
00748     // get next byte unsigned
00749     int32_t b = *m_buf++ & 0xff;
00750     int32_t k = b >> 5;
00751     // classify based on the high order 3 bits
00752     switch (  k )
00753       {     
00754       case 6:
00755         {
00756           // two byte encoding
00757           // 110yyyyy 10xxxxxx
00758           // use low order 6 bits
00759           int32_t y = b & 0x1f;
00760           // use low order 6 bits of the next byte
00761           // It should have high order bits 10, which we don't check.
00762           int32_t x = *m_buf++ & 0x3f;
00763           // 00000yyy yyxxxxxx
00764           *str = ( y << 6 | x );
00765           break;
00766         }
00767     case 7:
00768       {
00769         // three byte encoding
00770         // 1110zzzz 10yyyyyy 10xxxxxx
00771         //assert ( b & 0x10 )
00772           //     == 0 : "UTF8Decoder does not handle 32-bit characters";
00773         // use low order 4 bits
00774         int32_t z = b & 0x0f;
00775         // use low order 6 bits of the next byte
00776         // It should have high order bits 10, which we don't check.
00777         int32_t y = *m_buf++ & 0x3f;
00778         // use low order 6 bits of the next byte
00779         // It should have high order bits 10, which we don't check.
00780         int32_t x = *m_buf++ & 0x3f;
00781         // zzzzyyyy yyxxxxxx
00782         int32_t asint = ( z << 12 | y << 6 | x );
00783         *str =  asint;
00784         break;
00785       }
00786        default:
00787         // one byte encoding
00788         // 0xxxxxxx
00789         // use just low order 7 bits
00790         // 00000000 0xxxxxxx
00791         *str = ( b & 0x7f );
00792         break;
00793     }    
00794   }
00795 
00796   // disable other constructors and assignment
00797   DataInput();
00798   DataInput(const DataInput&);
00799   DataInput& operator =(const DataInput&);
00800 };
00801 
00802 }
00803 
00804 #endif // __GEMFIRE_DATAINPUT_H__

GemFire C++ Cache API Documentation