00001 #ifndef __GEMFIRE_DATAINPUT_H__
00002 #define __GEMFIRE_DATAINPUT_H__
00003
00004
00005
00006
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) {
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';
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';
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);
00494 read(&item);
00495 *str = item;
00496 str++;
00497 }
00498 *str = '\0';
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';
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';
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
00627 int32_t b = *value++ & 0xff;
00628 int32_t k = b >> 5;
00629
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
00734 *str = ((bt & 0x0f) << 12) | (((*m_buf++) & 0x3f) << 6);
00735 *str |= ((*m_buf++) & 0x3f);
00736 } else {
00737
00738 *str = ((bt & 0x1f) << 6) | ((*m_buf++) & 0x3f);
00739 }
00740 } else {
00741
00742 *str = bt;
00743 }
00744 }
00745
00746 inline void decodeChar( wchar_t* str )
00747 {
00748
00749 int32_t b = *m_buf++ & 0xff;
00750 int32_t k = b >> 5;
00751
00752 switch ( k )
00753 {
00754 case 6:
00755 {
00756
00757
00758
00759 int32_t y = b & 0x1f;
00760
00761
00762 int32_t x = *m_buf++ & 0x3f;
00763
00764 *str = ( y << 6 | x );
00765 break;
00766 }
00767 case 7:
00768 {
00769
00770
00771
00772
00773
00774 int32_t z = b & 0x0f;
00775
00776
00777 int32_t y = *m_buf++ & 0x3f;
00778
00779
00780 int32_t x = *m_buf++ & 0x3f;
00781
00782 int32_t asint = ( z << 12 | y << 6 | x );
00783 *str = asint;
00784 break;
00785 }
00786 default:
00787
00788
00789
00790
00791 *str = ( b & 0x7f );
00792 break;
00793 }
00794 }
00795
00796
00797 DataInput();
00798 DataInput(const DataInput&);
00799 DataInput& operator =(const DataInput&);
00800 };
00801
00802 }
00803
00804 #endif // __GEMFIRE_DATAINPUT_H__