00001 #ifndef __GEMFIRE_DATAOUTPUT_H__
00002 #define __GEMFIRE_DATAOUTPUT_H__
00003
00004
00005
00006
00007
00008
00009
00010 #include "gfcpp_globals.hpp"
00011 #include "ExceptionTypes.hpp"
00012 #include "Log.hpp"
00013 #include "Serializable.hpp"
00014 #include "CacheableString.hpp"
00015
00016 extern "C" {
00017 #include <string.h>
00018 #include <stdlib.h>
00019 }
00020
00025 namespace gemfire {
00026
00031 #define GF_ALLOC(v,t,s) \
00032 { \
00033 v = (t*)malloc((s) * sizeof(t)); \
00034 if ((v) == NULL) { \
00035 throw OutOfMemoryException( \
00036 "Out of Memory while allocating buffer for "#t" of size "#s); \
00037 } \
00038 }
00039
00044 #define GF_RESIZE(v,t,s) \
00045 { \
00046 v = (t*)realloc(v, (s) * sizeof(t)); \
00047 if ((v) == NULL) { \
00048 throw OutOfMemoryException( \
00049 "Out of Memory while resizing buffer for "#t); \
00050 } \
00051 }
00052
00053 #define GF_FREE(v) free(v)
00054
00060 class CPPCACHE_EXPORT DataOutput
00061 {
00062 public:
00063
00068 DataOutput();
00069
00075 inline void write(uint8_t value)
00076 {
00077 ensureCapacity(1);
00078 writeNoCheck(value);
00079 }
00080
00086 inline void write(int8_t value)
00087 {
00088 write((uint8_t)value);
00089 }
00090
00096 inline void writeBoolean( bool value )
00097 {
00098 write( (uint8_t)value );
00099 }
00100
00107 inline void writeBytes( const uint8_t* bytes, int32_t len )
00108 {
00109 if (len >= 0) {
00110 ensureCapacity( len + 5 );
00111 writeArrayLen( bytes==NULL ? 0 : len );
00112 if ( len > 0 && bytes != NULL) {
00113 memcpy( m_buf, bytes, len );
00114 m_buf += len;
00115 }
00116 } else {
00117 write((int8_t) -1 );
00118 }
00119 }
00120
00127 inline void writeBytes( const int8_t* bytes, int32_t len )
00128 {
00129 writeBytes( (const uint8_t*)bytes, len );
00130 }
00131
00143 inline void writeBytesOnly( const uint8_t* bytes, uint32_t len )
00144 {
00145 ensureCapacity( len );
00146 memcpy( m_buf, bytes, len );
00147 m_buf += len;
00148 }
00149
00161 inline void writeBytesOnly( const int8_t* bytes, uint32_t len )
00162 {
00163 writeBytesOnly( (const uint8_t*)bytes, len );
00164 }
00165
00171 inline void writeInt( uint16_t value )
00172 {
00173 ensureCapacity( 2 );
00174 *(m_buf++) = (uint8_t)(value >> 8);
00175 *(m_buf++) = (uint8_t)value;
00176 }
00177
00183 inline void writeInt( uint32_t value )
00184 {
00185 ensureCapacity( 4 );
00186 *(m_buf++) = (uint8_t)(value >> 24);
00187 *(m_buf++) = (uint8_t)(value >> 16);
00188 *(m_buf++) = (uint8_t)(value >> 8);
00189 *(m_buf++) = (uint8_t)value;
00190 }
00191
00197 inline void writeInt( uint64_t value )
00198 {
00199 ensureCapacity( 8 );
00200
00201
00202
00203
00204 if ( sizeof( long ) == 8 ) {
00205 *(m_buf++) = (uint8_t)(value >> 56);
00206 *(m_buf++) = (uint8_t)(value >> 48);
00207 *(m_buf++) = (uint8_t)(value >> 40);
00208 *(m_buf++) = (uint8_t)(value >> 32);
00209 *(m_buf++) = (uint8_t)(value >> 24);
00210 *(m_buf++) = (uint8_t)(value >> 16);
00211 *(m_buf++) = (uint8_t)(value >> 8);
00212 *(m_buf++) = (uint8_t)value;
00213 } else {
00214 uint32_t hword = (uint32_t)(value >> 32);
00215 *(m_buf++) = (uint8_t)(hword >> 24);
00216 *(m_buf++) = (uint8_t)(hword >> 16);
00217 *(m_buf++) = (uint8_t)(hword >> 8);
00218 *(m_buf++) = (uint8_t)hword;
00219
00220 hword = (uint32_t)value;
00221 *(m_buf++) = (uint8_t)(hword >> 24);
00222 *(m_buf++) = (uint8_t)(hword >> 16);
00223 *(m_buf++) = (uint8_t)(hword >> 8);
00224 *(m_buf++) = (uint8_t)hword;
00225 }
00226 }
00227
00233 inline void writeInt( int16_t value )
00234 {
00235 writeInt( (uint16_t)value );
00236 }
00237
00243 inline void writeInt( int32_t value )
00244 {
00245 writeInt( (uint32_t)value );
00246 }
00247
00253 inline void writeInt( int64_t value )
00254 {
00255 writeInt( (uint64_t)value );
00256 }
00257
00265 inline void writeArrayLen( int32_t len )
00266 {
00267 if (len == -1) {
00268 write((int8_t) -1);
00269 } else if (len <= 252) {
00270 write((uint8_t)len);
00271 } else if (len <= 0xFFFF) {
00272 write((int8_t) -2);
00273 writeInt((uint16_t)len);
00274 } else {
00275 write((int8_t) -3);
00276 writeInt(len);
00277 }
00278 }
00279
00285 inline void writeFloat( float value )
00286 {
00287 union float_uint32_t
00288 {
00289 float f;
00290 uint32_t u;
00291 }v;
00292 v.f = value;
00293 writeInt( v.u );
00294 }
00295
00301 inline void writeDouble( double value )
00302 {
00303 union double_uint64_t
00304 {
00305 double d;
00306 uint64_t ll;
00307 }v;
00308 v.d = value;
00309 writeInt( v.ll );
00310 }
00311
00324 inline void writeASCII(const char* value, uint32_t length = 0)
00325 {
00326 if ( value != NULL ) {
00327 if ( length == 0 ) {
00328 length = (uint32_t)strlen( value );
00329 }
00330 uint16_t len = (uint16_t)( length > 0xFFFF ? 0xFFFF : length );
00331 writeInt( len );
00332 writeBytesOnly( (int8_t*)value, len );
00333 } else {
00334 writeInt( (uint16_t)0 );
00335 }
00336 }
00337
00338 inline void writeNativeString(const char* value)
00339 {
00340
00341
00342
00343 CacheableStringPtr csPtr = CacheableString::create(value);
00344 write(csPtr->typeId());
00345 csPtr->toData(*this);
00346 }
00347
00359 inline void writeASCIIHuge(const char* value, uint32_t length = 0)
00360 {
00361 if ( value != NULL ) {
00362 if ( length == 0 ) {
00363 length = (uint32_t)strlen( value );
00364 }
00365 writeInt( (uint32_t) length );
00366 writeBytesOnly( (int8_t*)value, (uint32_t) length );
00367 } else {
00368 writeInt( (uint32_t)0 );
00369 }
00370 }
00371
00383 inline void writeUTF(const char* value, uint32_t length = 0)
00384 {
00385 if ( value != NULL ) {
00386 int32_t len = getEncodedLength( value, length );
00387 uint16_t encodedLen = (uint16_t)( len > 0xFFFF ? 0xFFFF : len );
00388 writeInt( encodedLen );
00389 ensureCapacity( encodedLen );
00390 uint8_t* end = m_buf + encodedLen;
00391 while( m_buf < end ) {
00392 encodeChar( *value++ );
00393 }
00394 if ( m_buf > end ) m_buf = end;
00395 } else {
00396 writeInt( (uint16_t)0 );
00397 }
00398 }
00399
00412 inline void writeUTFHuge(const char* value, uint32_t length = 0)
00413 {
00414 if (value != NULL) {
00415 if (length == 0) {
00416 length = (uint32_t)strlen(value);
00417 }
00418 writeInt(length);
00419 ensureCapacity(length * 2);
00420 for (uint32_t pos = 0; pos < length; pos++) {
00421 writeNoCheck((int8_t)0);
00422 writeNoCheck((int8_t)value[pos]);
00423 }
00424 }
00425 else {
00426 writeInt((uint32_t)0);
00427 }
00428 }
00429
00441 inline void writeUTF(const wchar_t* value, uint32_t length = 0)
00442 {
00443 if ( value != NULL ) {
00444 int32_t len = getEncodedLength( value, length );
00445 uint16_t encodedLen = (uint16_t)( len > 0xFFFF ? 0xFFFF : len );
00446 writeInt( encodedLen );
00447 ensureCapacity( encodedLen );
00448 uint8_t* end = m_buf + encodedLen;
00449 while( m_buf < end ) {
00450 encodeChar( *value++ );
00451 }
00452 if ( m_buf > end ) m_buf = end;
00453 } else {
00454 writeInt( (uint16_t)0 );
00455 }
00456 }
00457
00468 inline void writeUTFHuge(const wchar_t* value, uint32_t length = 0)
00469 {
00470 if (value != NULL) {
00471 if (length == 0) {
00472 length = (uint32_t)wcslen(value);
00473 }
00474 writeInt(length);
00475 ensureCapacity(length * 2);
00476 for (uint32_t pos = 0; pos < length; pos++) {
00477 uint16_t item = (uint16_t)value[pos];
00478 writeNoCheck((uint8_t)((item & 0xFF00) >> 8));
00479 writeNoCheck((uint8_t)(item & 0xFF));
00480 }
00481 }
00482 else {
00483 writeInt((uint32_t)0);
00484 }
00485 }
00486
00497 inline static int32_t getEncodedLength( const char* value,
00498 int32_t length = 0, uint32_t* valLength = NULL )
00499 {
00500 if ( value == NULL ) return 0;
00501 uint8_t currentChar;
00502 int32_t encodedLen = 0;
00503 const char* start = value;
00504 if ( length == 0 ) {
00505 while ( (currentChar = *value) != '\0' ) {
00506 getEncodedLength( currentChar, encodedLen );
00507 value++;
00508 }
00509 } else {
00510 const char* end = value + length;
00511 while ( value < end ) {
00512 currentChar = *value;
00513 getEncodedLength( currentChar, encodedLen );
00514 value++;
00515 }
00516 }
00517 if ( valLength != NULL ) {
00518 *valLength = static_cast<uint32_t>(value - start);
00519 }
00520 return encodedLen;
00521 }
00522
00533 inline static int32_t getEncodedLength( const wchar_t* value,
00534 int32_t length = 0, uint32_t* valLength = NULL )
00535 {
00536 if ( value == NULL ) return 0;
00537 uint16_t currentChar;
00538 int32_t encodedLen = 0;
00539 const wchar_t* start = value;
00540 if ( length == 0 ) {
00541 while ( (currentChar = *value) != 0 ) {
00542 getEncodedLength( currentChar, encodedLen );
00543 value++;
00544 }
00545 } else {
00546 const wchar_t* end = value + length;
00547 while ( value < end ) {
00548 currentChar = *value;
00549 getEncodedLength( currentChar, encodedLen );
00550 value++;
00551 }
00552 }
00553 if ( valLength != NULL ) {
00554 *valLength = static_cast<uint32_t>(value - start);
00555 }
00556 return encodedLen;
00557 }
00558
00565 template< class PTR >
00566 void writeObject( const SharedPtr<PTR>& objptr, bool isDelta = false )
00567 {
00568 writeObjectInternal( objptr.ptr( ), isDelta );
00569 }
00570
00577 void writeObject( const Serializable* objptr )
00578 {
00579 writeObjectInternal( objptr );
00580 }
00581
00586 const uint8_t* getCursor()
00587 {
00588 return m_buf;
00589 }
00590
00596 void advanceCursor(uint32_t offset)
00597 {
00598 ensureCapacity(offset);
00599 m_buf += offset;
00600 }
00601
00607 void rewindCursor(uint32_t offset)
00608 {
00609 m_buf -= offset;
00610 }
00611
00613 ~DataOutput( )
00614 {
00615 reset();
00616 DataOutput::checkinBuffer(m_bytes, m_size);
00617 }
00618
00622 inline const uint8_t* getBuffer( ) const
00623 {
00624
00625 return m_bytes;
00626 }
00627
00631 inline uint32_t getRemainingBufferLength( ) const
00632 {
00633
00634 return m_size - getBufferLength();
00635 }
00636
00643 inline const uint8_t* getBuffer( uint32_t* rsize ) const
00644 {
00645 *rsize = (uint32_t)( m_buf - m_bytes );
00646
00647 return m_bytes;
00648 }
00649
00650 inline uint8_t* getBufferCopy( )
00651 {
00652 uint32_t size = (uint32_t)( m_buf - m_bytes );
00653 uint8_t * result;
00654 GF_ALLOC(result, uint8_t, size);
00655 memcpy( result, m_bytes, size );
00656 return result;
00657 }
00658
00663 inline uint32_t getBufferLength() const {
00664 return (uint32_t)( m_buf - m_bytes );
00665 }
00666
00670 inline void reset()
00671 {
00672 if (m_haveBigBuffer) {
00673
00674 GF_FREE(m_bytes);
00675
00676 GF_ALLOC(m_bytes, uint8_t, m_lowWaterMark);
00677 m_size = m_lowWaterMark;
00678
00679 m_haveBigBuffer = false;
00680
00681 releaseLock();
00682 }
00683 m_buf = m_bytes;
00684 }
00685
00686
00687 inline void ensureCapacity( uint32_t size )
00688 {
00689 uint32_t offset = (uint32_t)( m_buf - m_bytes );
00690 if ( (m_size - offset) < size ) {
00691 uint32_t newSize = m_size * 2 + (8192 * (size / 8192));
00692 if (newSize >= m_highWaterMark && !m_haveBigBuffer) {
00693
00694 acquireLock();
00695
00696 m_haveBigBuffer = true;
00697 }
00698 m_size = newSize;
00699 GF_RESIZE( m_bytes, uint8_t, m_size );
00700 m_buf = m_bytes + offset;
00701 }
00702 }
00703
00704
00705
00706
00707 const char* getPoolName()
00708 {
00709 return m_poolName;
00710 }
00711
00712
00713
00714
00715 void setPoolName(const char* poolName)
00716 {
00717 m_poolName = poolName;
00718 }
00719
00720 uint8_t * getBufferCopyFrom(const uint8_t *from, uint32_t length)
00721 {
00722 uint8_t * result;
00723 GF_NEW( result, uint8_t[ length ] );
00724 memcpy( result, from, length);
00725
00726 return result;
00727 }
00728
00729 static void safeDelete(uint8_t* src)
00730 {
00731 GF_SAFE_DELETE(src);
00732 }
00733
00734 static DataOutput* getDataOutput()
00735 {
00736 return new DataOutput();
00737 }
00738 static void releaseDataOutput(DataOutput* dataOutput)
00739 {
00740 GF_SAFE_DELETE(dataOutput);
00741 }
00742 private:
00743
00744 void writeObjectInternal( const Serializable* ptr, bool isDelta = false );
00745
00746 static void acquireLock();
00747 static void releaseLock();
00748
00749
00750
00751 const char* m_poolName;
00752
00753 uint8_t* m_bytes;
00754
00755 uint8_t* m_buf;
00756
00757 uint32_t m_size;
00758
00759 static uint32_t m_lowWaterMark;
00760 static uint32_t m_highWaterMark;
00761
00762 volatile bool m_haveBigBuffer;
00763
00764 inline static void getEncodedLength( const uint8_t val, int32_t& encodedLen )
00765 {
00766 if ( (val == 0) || (val & 0x80) ) {
00767
00768 encodedLen += 2;
00769 } else {
00770
00771 encodedLen++;
00772 }
00773 }
00774
00775 inline static void getEncodedLength( const uint16_t val, int32_t& encodedLen )
00776 {
00777 if( val == 0)
00778 {
00779 encodedLen += 2;
00780 }
00781 else if ( val < 0x80 )
00782 {
00783 encodedLen++;
00784 }
00785 else if ( val < 0x800 )
00786 {
00787 encodedLen += 2;
00788 }
00789 else
00790 {
00791 encodedLen += 3;
00792 }
00793 }
00794
00795 inline void encodeChar( const char value )
00796 {
00797 uint8_t tmp = (uint8_t)value;
00798 if ( (tmp == 0) || (tmp & 0x80) ) {
00799
00800 *(m_buf++) = 0xc0 | ((tmp & 0xc0 ) >> 6);
00801 *(m_buf++) = 0x80 | (tmp & 0x3f );
00802 } else {
00803
00804 *(m_buf++) = tmp;
00805 }
00806 }
00807
00808
00809 inline void encodeChar( const wchar_t value )
00810 {
00811 uint16_t c = (uint16_t)value;
00812 if ( c == 0 ) {
00813 *(m_buf++) = 0xc0;
00814 *(m_buf++) = 0x80;
00815 }
00816 else if ( c < 0x80 ) {
00817 *(m_buf++) = (uint8_t)c;
00818 }
00819 else if ( c < 0x800 ) {
00820 *(m_buf++) = ( 0xC0 | c >> 6 );
00821 *(m_buf++) = ( 0x80 | c & 0x3F );
00822 }
00823 else {
00824 *(m_buf++) = ( 0xE0 | c >> 12 );
00825 *(m_buf++) = ( 0x80 | c >> 6 & 0x3F );
00826 *(m_buf++) = ( 0x80 | c & 0x3F );
00827 }
00828 }
00829
00830 inline void writeNoCheck(uint8_t value)
00831 {
00832 *(m_buf++) = value;
00833 }
00834
00835 inline void writeNoCheck(int8_t value)
00836 {
00837 writeNoCheck((uint8_t)value);
00838 }
00839
00840
00841 static uint8_t* checkoutBuffer( uint32_t* size );
00842 static void checkinBuffer( uint8_t* buffer, uint32_t size );
00843
00844
00845 DataOutput(const DataOutput&);
00846 DataOutput& operator =(const DataOutput&);
00847 };
00848
00849 }
00850
00851 #endif // __GEMFIRE_DATAOUTPUT_H__