/export/rook1/users/build/gfcppsancout64/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 "gf_types.hpp"
00014 #include "Serializable.hpp"
00015 #include "CacheableString.hpp"
00016 
00022 #if GF_DEBUG_ASSERTS == 1
00023 #define DINP_THROWONERROR_DEFAULT true
00024 #else
00025 #define DINP_THROWONERROR_DEFAULT false
00026 #endif
00027 
00028 #define checkBufferSize(x) _checkBufferSize(x,__LINE__)
00029 
00030 namespace gemfire
00031 {
00032 
00033 extern int gf_sprintf(char* buffer, const char* fmt, ...);
00034 
00042 class CPPCACHE_EXPORT DataInput
00043 {
00044 public:
00045 
00051   inline void read( uint8_t* value )
00052   {
00053     checkBufferSize(1);
00054     *value = *(m_buf++);
00055   }
00056 
00062   inline void read( int8_t* value )
00063   {
00064     checkBufferSize(1);
00065     *value = *(m_buf++);
00066   }
00067 
00073   inline void readBoolean( bool* value )
00074   {
00075     checkBufferSize(1);
00076     *value = (*m_buf == 1 ? true : false);
00077     m_buf++;
00078   }
00079 
00090   inline void readBytesOnly(uint8_t* buffer, uint32_t len)
00091   {
00092     if (len > 0) {
00093       checkBufferSize(len);
00094       memcpy( buffer, m_buf, len );
00095       m_buf += len;
00096     }
00097   }
00098 
00109   inline void readBytesOnly(int8_t* buffer, uint32_t len)
00110   {
00111     if (len > 0) {
00112       checkBufferSize(len);
00113       memcpy( buffer, m_buf, len );
00114       m_buf += len;
00115     }
00116   }
00117 
00128   inline void readBytes( uint8_t** bytes, int32_t* len )
00129   {
00130     int32_t length;
00131     readArrayLen( &length );
00132     *len = length;
00133     uint8_t* buffer = NULL;
00134     if ( length > 0 ) {
00135       checkBufferSize(length);
00136       GF_NEW( buffer, uint8_t[ length ] );
00137       memcpy( buffer, m_buf, length );
00138       m_buf += length;
00139     }
00140     *bytes = buffer;
00141   }
00142 
00153   inline void readBytes( int8_t** bytes, int32_t* len )
00154   {
00155     int32_t length;
00156     readArrayLen( &length );
00157     *len = length;
00158     int8_t* buffer = NULL;
00159     if ( length > 0 ) {
00160       checkBufferSize(length);
00161       GF_NEW( buffer, int8_t[ length ] );
00162       memcpy( buffer, m_buf, length );
00163       m_buf += length;
00164     }
00165     *bytes = buffer;
00166   }
00167 
00174   inline void readInt( uint16_t* value )
00175   {
00176     checkBufferSize(2);
00177     uint16_t tmp = *(m_buf++);
00178     tmp = (tmp << 8) | *(m_buf++);
00179     *value = tmp;
00180   }
00181 
00188   inline void readInt( uint32_t* value )
00189   {
00190     checkBufferSize(4);
00191     uint32_t tmp = *(m_buf++);
00192     tmp = (tmp << 8) | *(m_buf++);
00193     tmp = (tmp << 8) | *(m_buf++);
00194     tmp = (tmp << 8) | *(m_buf++);
00195     *value = tmp;
00196   }
00197 
00204   inline void readInt( uint64_t* value )
00205   {
00206     checkBufferSize(8);
00207     uint64_t tmp;
00208     if ( sizeof( long ) == 8 ) {
00209       tmp = *(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       tmp = (tmp << 8) | *(m_buf++);
00216       tmp = (tmp << 8) | *(m_buf++);
00217     } else {
00218       uint32_t hword = *(m_buf++);
00219       hword = (hword << 8) | *(m_buf++);
00220       hword = (hword << 8) | *(m_buf++);
00221       hword = (hword << 8) | *(m_buf++);
00222 
00223       tmp = hword;
00224       hword = *(m_buf++);
00225       hword = (hword << 8) | *(m_buf++);
00226       hword = (hword << 8) | *(m_buf++);
00227       hword = (hword << 8) | *(m_buf++);
00228       tmp = (tmp << 32) | hword;
00229     }
00230     *value = tmp;
00231   }
00232 
00239   inline void readInt( int16_t* value )
00240   {
00241     checkBufferSize(2);
00242     readInt( (uint16_t*)value );
00243   }
00244 
00251   inline void readInt( int32_t* value )
00252   {
00253     checkBufferSize(4);
00254     readInt( (uint32_t*)value );
00255   }
00256 
00263   inline void readInt( int64_t* value )
00264   {
00265     checkBufferSize(8);
00266     readInt( (uint64_t*)value );
00267   }
00268 
00277   inline void readArrayLen( int32_t* len )
00278   {
00279     uint8_t code;
00280     read(&code);
00281     if (code == 0xFF) {
00282       *len = -1;
00283     } else {
00284       int32_t result = code;
00285       if (result > 252) {  // 252 is java's ((byte)-4 && 0xFF)
00286         if (code == 0xFE) {
00287           uint16_t val;
00288           readInt(&val);
00289           result = val;
00290         } else if (code == 0xFD) {
00291           uint32_t val;
00292           readInt(&val);
00293           result = val;
00294         } else {
00295           throw IllegalStateException("unexpected array length code");
00296         }
00297       }
00298       *len = result;
00299     }
00300   }
00301 
00307   inline void readFloat( float* value )
00308   {
00309     checkBufferSize(4);
00310     union float_uint32_t
00311     {
00312         float f;
00313         uint32_t u;
00314     }v;
00315     readInt( (uint32_t*)&v.u);
00316     *value = v.f;
00317   }
00318 
00325   inline void readDouble( double* value )
00326   {
00327     checkBufferSize(8);
00328     union double_uint64_t
00329     {
00330         double d;
00331         uint64_t        ll;
00332     }v;
00333     readInt( (uint64_t*)&v.ll);
00334     *value = v.d;
00335   }
00336 
00342   static inline void freeUTFMemory( char* value )
00343   {
00344     delete [] value;
00345   }
00346 
00352   static inline void freeUTFMemory( wchar_t* value )
00353   {
00354     delete [] value;
00355   }
00356 
00372   inline void readASCII( char** value, uint16_t* len = NULL )
00373   {
00374     uint16_t length;
00375     readInt( &length );
00376     checkBufferSize(length);
00377     if ( len != NULL ) {
00378       *len = length;
00379     }
00380     char* str;
00381     GF_NEW( str, char[ length + 1 ] );
00382     *value = str;
00383     readBytesOnly((int8_t*)str, length);
00384     str[ length ] = '\0';
00385   }
00386 
00401   inline void readASCIIHuge( char** value, uint32_t* len = NULL )
00402   {
00403     uint32_t length;
00404     readInt( &length );
00405     if ( len != NULL ) {
00406       *len = length;
00407     }
00408     char* str;
00409     GF_NEW( str, char[ length + 1 ] );
00410     *value = str;
00411     readBytesOnly( (int8_t*)str, length );
00412     str[ length ] = '\0';
00413   }
00414 
00431   inline void readUTF( char** value, uint16_t* len = NULL )
00432   {
00433     uint16_t length;
00434     readInt( &length );
00435     checkBufferSize(length);
00436     uint16_t decodedLen = (uint16_t)getDecodedLength( m_buf, length );
00437     if ( len != NULL ) {
00438       *len = decodedLen;
00439     }
00440     char* str;
00441     GF_NEW( str, char[ decodedLen + 1 ] );
00442     *value = str;
00443     for( uint16_t i = 0; i < decodedLen; i++ ) {
00444       decodeChar( str++ );
00445     }
00446     *str = '\0'; // null terminate for c-string.
00447   }
00448 
00458   inline void readUTFNoLen(wchar_t** value, uint16_t decodedLen)
00459   {
00460     wchar_t* str;
00461     GF_NEW(str, wchar_t[decodedLen + 1]);
00462     *value = str;
00463     for (uint16_t i = 0; i < decodedLen; i++) {
00464       decodeChar(str++);
00465     }
00466     *str = L'\0'; // null terminate for c-string.
00467   }
00468 
00483   inline void readUTFHuge( char** value, uint32_t* len = NULL )
00484   {
00485     uint32_t length;
00486     readInt( &length );
00487     if ( len != NULL ) {
00488       *len = length;
00489     }
00490     char* str;
00491     GF_NEW( str, char[ length + 1 ] );
00492     *value = str;
00493     for( uint32_t i = 0; i < length; i++ ) {
00494       int8_t item;
00495       read(&item); // ignore this - should be higher order zero byte
00496       read(&item);
00497       *str = item;
00498       str++;
00499     }
00500     *str = '\0'; // null terminate for c-string.
00501   }
00502 
00519   inline void readUTF( wchar_t** value, uint16_t* len = NULL )
00520   {
00521     uint16_t length;
00522     readInt( &length );
00523     checkBufferSize(length);
00524     uint16_t decodedLen = (uint16_t)getDecodedLength( m_buf, length );
00525     if ( len != NULL ) {
00526       *len = decodedLen;
00527     }
00528     wchar_t* str;
00529     GF_NEW( str, wchar_t[ decodedLen + 1 ] );
00530     *value = str;
00531     for( uint16_t i = 0; i < decodedLen; i++ ) {
00532       decodeChar( str++ );
00533     }
00534     *str = L'\0'; // null terminate for c-string.
00535   }
00536 
00551   inline void readUTFHuge( wchar_t** value, uint32_t* len = NULL )
00552   {
00553     uint32_t length;
00554     readInt( &length );
00555     if ( len != NULL ) {
00556       *len = length;
00557     }
00558     wchar_t* str;
00559     GF_NEW( str, wchar_t[ length + 1 ] );
00560     *value = str;
00561     for( uint32_t i = 0; i < length; i++ ) {
00562       uint8_t hibyte;
00563       read(&hibyte);
00564       uint8_t lobyte;
00565       read(&lobyte);
00566       *str = (((uint16_t)hibyte) << 8) | (uint16_t)lobyte;
00567       str++;
00568     }
00569     *str = L'\0'; // null terminate for c-string.
00570   }
00571 
00591   template< class PTR >
00592   inline void readObject( SharedPtr<PTR>& ptr,
00593       bool throwOnError = DINP_THROWONERROR_DEFAULT )
00594   {
00595     SerializablePtr sPtr;
00596     readObjectInternal( sPtr );
00597     if ( throwOnError ) {
00598       ptr = dynCast< SharedPtr<PTR> >( sPtr );
00599     } else {
00600       ptr = staticCast< SharedPtr<PTR> >( sPtr );
00601     }
00602   }
00603 
00604   inline bool readNativeBool( )
00605   {
00606     int8_t typeId = 0;
00607     read( &typeId );
00608     
00609     bool val;
00610     readBoolean(&val);
00611     return val;
00612   }
00613 
00614   inline int32_t readNativeInt32( )
00615   {
00616     int8_t typeId = 0;
00617     read( &typeId );
00618     
00619     int32_t val;
00620     readInt(&val);
00621     return val;
00622   }
00623 
00624   inline bool readNativeString(CacheableStringPtr& csPtr)
00625   {
00626     int8_t typeId = 0;
00627     read( &typeId );
00628     int64_t compId = typeId;
00629     if (compId == GemfireTypeIds::NullObj) {
00630      csPtr = NULLPTR;
00631     }
00632     else if (compId == GemfireTypeIds::CacheableNullString) {
00633       csPtr = CacheableStringPtr(dynamic_cast<CacheableString *>(CacheableString::createDeserializable()));
00634     }
00635     else if ( compId == gemfire::GemfireTypeIds::CacheableASCIIString) {
00636       csPtr = CacheableStringPtr(dynamic_cast<CacheableString *>(CacheableString::createDeserializable()));
00637       csPtr.ptr()->fromData(*this);
00638     }
00639     else if ( compId == gemfire::GemfireTypeIds::CacheableASCIIStringHuge) {
00640       csPtr = CacheableStringPtr(dynamic_cast<CacheableString *>(CacheableString::createDeserializableHuge()));
00641       csPtr.ptr()->fromData(*this);
00642     }
00643     else if ( compId == gemfire::GemfireTypeIds::CacheableString) {
00644       csPtr = CacheableStringPtr(dynamic_cast<CacheableString *>(CacheableString::createUTFDeserializable()));
00645       csPtr.ptr()->fromData(*this);
00646     }
00647     else if ( compId == gemfire::GemfireTypeIds::CacheableStringHuge) {
00648       csPtr = CacheableStringPtr(dynamic_cast<CacheableString *>(CacheableString::createUTFDeserializableHuge()));
00649       csPtr.ptr()->fromData(*this);
00650     }
00651     else {
00652       LOGDEBUG("In readNativeString something is wrong while expecting string");
00653       rewindCursor(1);
00654       csPtr = NULLPTR;
00655       return false;
00656     }
00657     return true;
00658   }
00659 
00660   inline void readDirectObject( SerializablePtr& ptr, int8_t typeId = -1 )
00661   {
00662     readObjectInternal( ptr, typeId );
00663   }
00664 
00669   inline void readObject( SerializablePtr& ptr )
00670   {
00671     readObjectInternal( ptr );
00672   }
00673 
00684   static int32_t getDecodedLength( const uint8_t* value, int32_t length )
00685   {
00686     const uint8_t* end = value + length;
00687     int32_t decodedLen = 0;
00688     while ( value < end ) {
00689        // get next byte unsigned
00690     int32_t b = *value++ & 0xff;
00691     int32_t k = b >> 5;
00692     // classify based on the high order 3 bits
00693       switch (  k )
00694         {       
00695         case 6:
00696           {
00697             value++;
00698             break;
00699           }
00700         case 7:
00701           {
00702             value += 2;
00703             break;
00704           }
00705         default:
00706           break;
00707         }
00708       decodedLen += 1;
00709     }
00710     if ( value > end ) decodedLen--;
00711     return decodedLen;
00712   }
00713 
00715   DataInput(const uint8_t* m_buffer, int32_t len)
00716     : m_buf(m_buffer), m_bufHead(m_buffer), m_bufLength(len), m_poolName(NULL)
00717   {
00718   }
00719 
00721   ~DataInput( ) { }
00722 
00728   inline const uint8_t* currentBufferPosition() const
00729   {
00730     return m_buf;
00731   }
00732 
00734   inline int32_t getBytesRead() const
00735   {
00736     return static_cast<int32_t>(m_buf - m_bufHead);
00737   }
00738 
00740   inline int32_t getBytesRemaining() const
00741   {
00742     return (m_bufLength - getBytesRead());
00743   }
00744 
00746   inline void advanceCursor(int32_t offset)
00747   {
00748     m_buf += offset;
00749   }
00750 
00752   inline void rewindCursor(int32_t offset)
00753   {
00754     m_buf -= offset;
00755   }
00756 
00758   inline void reset()
00759   {
00760     m_buf = m_bufHead;
00761   }
00762 
00763   inline void reset(int32_t offset )
00764   {
00765     m_buf = m_bufHead + offset;
00766   }
00767 
00768   uint8_t * getBufferCopyFrom(const uint8_t *from, uint32_t length)
00769   {
00770     uint8_t * result;
00771     GF_NEW( result, uint8_t[ length ] );
00772     memcpy( result, from, length);
00773     
00774     return result;
00775   }
00776 
00777   static uint8_t * getBufferCopy(const uint8_t *from, uint32_t length)
00778   {
00779     uint8_t * result;
00780     GF_NEW( result, uint8_t[ length ] );
00781     memcpy( result, from, length);
00782     
00783     return result;
00784   }
00785 
00786   /*
00787    * This is for internal use
00788    */
00789   const char* getPoolName()
00790   {
00791     return m_poolName;
00792   }
00793 
00794   /*
00795    * This is for internal use
00796    */
00797   void setPoolName(const char* poolName)
00798   {
00799     m_poolName = poolName;
00800   }
00801 
00802 private:
00803 
00804   const uint8_t* m_buf;
00805   const uint8_t* m_bufHead;
00806   int32_t m_bufLength;
00807   const char* m_poolName;
00808 
00809   void readObjectInternal( SerializablePtr& ptr, int8_t typeId = -1 );
00810 
00811   inline void _checkBufferSize(int32_t size, int32_t line)
00812   {
00813     if ((m_bufLength - (m_buf - m_bufHead)) < size) {
00814       char exMsg[128];
00815       gf_sprintf(exMsg, "DataInput: attempt to read beyond buffer at line %d: "
00816           "available buffer size %d, attempted read of size %d ", line,
00817           m_bufLength - (m_buf - m_bufHead), size);
00818       throw OutOfRangeException(exMsg);
00819     }
00820   }
00821 
00822   inline void decodeChar( char* str )
00823   {
00824     uint8_t bt = *(m_buf++);
00825     if ( bt & 0x80 ) {
00826       if ( bt & 0x20 ) {
00827         // three bytes.
00828         *str = ((bt & 0x0f) << 12) | (((*m_buf++) & 0x3f) << 6);
00829         *str |= ((*m_buf++) & 0x3f);
00830       } else {
00831         // two bytes.
00832         *str = ((bt & 0x1f) << 6) | ((*m_buf++) & 0x3f);
00833       }
00834     } else {
00835       // single byte...
00836       *str = bt;
00837     }
00838   }
00839 
00840   inline void decodeChar( wchar_t* str )
00841   {
00842     // get next byte unsigned
00843     int32_t b = *m_buf++ & 0xff;
00844     int32_t k = b >> 5;
00845     // classify based on the high order 3 bits
00846     switch (  k )
00847       {     
00848       case 6:
00849         {
00850           // two byte encoding
00851           // 110yyyyy 10xxxxxx
00852           // use low order 6 bits
00853           int32_t y = b & 0x1f;
00854           // use low order 6 bits of the next byte
00855           // It should have high order bits 10, which we don't check.
00856           int32_t x = *m_buf++ & 0x3f;
00857           // 00000yyy yyxxxxxx
00858           *str = ( y << 6 | x );
00859           break;
00860         }
00861     case 7:
00862       {
00863         // three byte encoding
00864         // 1110zzzz 10yyyyyy 10xxxxxx
00865         //assert ( b & 0x10 )
00866           //     == 0 : "UTF8Decoder does not handle 32-bit characters";
00867         // use low order 4 bits
00868         int32_t z = b & 0x0f;
00869         // use low order 6 bits of the next byte
00870         // It should have high order bits 10, which we don't check.
00871         int32_t y = *m_buf++ & 0x3f;
00872         // use low order 6 bits of the next byte
00873         // It should have high order bits 10, which we don't check.
00874         int32_t x = *m_buf++ & 0x3f;
00875         // zzzzyyyy yyxxxxxx
00876         int32_t asint = ( z << 12 | y << 6 | x );
00877         *str =  asint;
00878         break;
00879       }
00880        default:
00881         // one byte encoding
00882         // 0xxxxxxx
00883         // use just low order 7 bits
00884         // 00000000 0xxxxxxx
00885         *str = ( b & 0x7f );
00886         break;
00887     }    
00888   }
00889 
00890   // disable other constructors and assignment
00891   DataInput();
00892   DataInput(const DataInput&);
00893   DataInput& operator =(const DataInput&);
00894 };
00895 
00896 }
00897 
00898 #endif // __GEMFIRE_DATAINPUT_H__

GemFire C++ Cache API Documentation