00001 #ifndef __GEMFIRE_DATAOUTPUT_H__
00002 #define __GEMFIRE_DATAOUTPUT_H__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "gfcpp_globals.hpp"
00013 #include "ExceptionTypes.hpp"
00014 #include "Log.hpp"
00015 #include "Serializable.hpp"
00016 #include "CacheableString.hpp"
00017
00018 extern "C" {
00019 #include <string.h>
00020 #include <stdlib.h>
00021 }
00022
00027 namespace gemfire {
00028
00033 #define GF_ALLOC(v,t,s) \
00034 { \
00035 v = (t*)malloc((s) * sizeof(t)); \
00036 if ((v) == NULL) { \
00037 throw OutOfMemoryException( \
00038 "Out of Memory while allocating buffer for "#t" of size "#s); \
00039 } \
00040 }
00041
00046 #define GF_RESIZE(v,t,s) \
00047 { \
00048 v = (t*)realloc(v, (s) * sizeof(t)); \
00049 if ((v) == NULL) { \
00050 throw OutOfMemoryException( \
00051 "Out of Memory while resizing buffer for "#t); \
00052 } \
00053 }
00054
00055 #define GF_FREE(v) free(v)
00056
00062 class CPPCACHE_EXPORT DataOutput
00063 {
00064 public:
00065
00070 DataOutput();
00071
00077 inline void write(uint8_t value)
00078 {
00079 ensureCapacity(1);
00080 writeNoCheck(value);
00081 }
00082
00088 inline void write(int8_t value)
00089 {
00090 write((uint8_t)value);
00091 }
00092
00098 inline void writeBoolean( bool value )
00099 {
00100 write( (uint8_t)value );
00101 }
00102
00109 inline void writeBytes( const uint8_t* bytes, int32_t len )
00110 {
00111 if (len >= 0) {
00112 ensureCapacity( len + 5 );
00113 writeArrayLen( bytes==NULL ? 0 : len );
00114 if ( len > 0 && bytes != NULL) {
00115 memcpy( m_buf, bytes, len );
00116 m_buf += len;
00117 }
00118 } else {
00119 write((int8_t) -1 );
00120 }
00121 }
00122
00129 inline void writeBytes( const int8_t* bytes, int32_t len )
00130 {
00131 writeBytes( (const uint8_t*)bytes, len );
00132 }
00133
00145 inline void writeBytesOnly( const uint8_t* bytes, uint32_t len )
00146 {
00147 ensureCapacity( len );
00148 memcpy( m_buf, bytes, len );
00149 m_buf += len;
00150 }
00151
00163 inline void writeBytesOnly( const int8_t* bytes, uint32_t len )
00164 {
00165 writeBytesOnly( (const uint8_t*)bytes, len );
00166 }
00167
00173 inline void writeInt( uint16_t value )
00174 {
00175 ensureCapacity( 2 );
00176 *(m_buf++) = (uint8_t)(value >> 8);
00177 *(m_buf++) = (uint8_t)value;
00178 }
00179
00185 inline void writeChar( uint16_t value )
00186 {
00187 ensureCapacity( 2 );
00188 *(m_buf++) = (uint8_t)(value >> 8);
00189 *(m_buf++) = (uint8_t)value;
00190 }
00191
00197 inline void writeInt( uint32_t value )
00198 {
00199 ensureCapacity( 4 );
00200 *(m_buf++) = (uint8_t)(value >> 24);
00201 *(m_buf++) = (uint8_t)(value >> 16);
00202 *(m_buf++) = (uint8_t)(value >> 8);
00203 *(m_buf++) = (uint8_t)value;
00204 }
00205
00211 inline void writeInt( uint64_t value )
00212 {
00213 ensureCapacity( 8 );
00214
00215
00216
00217
00218 if ( sizeof( long ) == 8 ) {
00219 *(m_buf++) = (uint8_t)(value >> 56);
00220 *(m_buf++) = (uint8_t)(value >> 48);
00221 *(m_buf++) = (uint8_t)(value >> 40);
00222 *(m_buf++) = (uint8_t)(value >> 32);
00223 *(m_buf++) = (uint8_t)(value >> 24);
00224 *(m_buf++) = (uint8_t)(value >> 16);
00225 *(m_buf++) = (uint8_t)(value >> 8);
00226 *(m_buf++) = (uint8_t)value;
00227 } else {
00228 uint32_t hword = (uint32_t)(value >> 32);
00229 *(m_buf++) = (uint8_t)(hword >> 24);
00230 *(m_buf++) = (uint8_t)(hword >> 16);
00231 *(m_buf++) = (uint8_t)(hword >> 8);
00232 *(m_buf++) = (uint8_t)hword;
00233
00234 hword = (uint32_t)value;
00235 *(m_buf++) = (uint8_t)(hword >> 24);
00236 *(m_buf++) = (uint8_t)(hword >> 16);
00237 *(m_buf++) = (uint8_t)(hword >> 8);
00238 *(m_buf++) = (uint8_t)hword;
00239 }
00240 }
00241
00247 inline void writeInt( int16_t value )
00248 {
00249 writeInt( (uint16_t)value );
00250 }
00251
00257 inline void writeInt( int32_t value )
00258 {
00259 writeInt( (uint32_t)value );
00260 }
00261
00267 inline void writeInt( int64_t value )
00268 {
00269 writeInt( (uint64_t)value );
00270 }
00271
00279 inline void writeArrayLen( int32_t len )
00280 {
00281 if (len == -1) {
00282 write((int8_t) -1);
00283 } else if (len <= 252) {
00284 write((uint8_t)len);
00285 } else if (len <= 0xFFFF) {
00286 write((int8_t) -2);
00287 writeInt((uint16_t)len);
00288 } else {
00289 write((int8_t) -3);
00290 writeInt(len);
00291 }
00292 }
00293
00299 inline void writeFloat( float value )
00300 {
00301 union float_uint32_t
00302 {
00303 float f;
00304 uint32_t u;
00305 }v;
00306 v.f = value;
00307 writeInt( v.u );
00308 }
00309
00315 inline void writeDouble( double value )
00316 {
00317 union double_uint64_t
00318 {
00319 double d;
00320 uint64_t ll;
00321 }v;
00322 v.d = value;
00323 writeInt( v.ll );
00324 }
00325
00338 inline void writeASCII(const char* value, uint32_t length = 0)
00339 {
00340 if ( value != NULL ) {
00341 if ( length == 0 ) {
00342 length = (uint32_t)strlen( value );
00343 }
00344 uint16_t len = (uint16_t)( length > 0xFFFF ? 0xFFFF : length );
00345 writeInt( len );
00346 writeBytesOnly( (int8_t*)value, len );
00347 } else {
00348 writeInt( (uint16_t)0 );
00349 }
00350 }
00351
00352 inline void writeNativeString(const char* value)
00353 {
00354
00355
00356
00357 CacheableStringPtr csPtr = CacheableString::create(value);
00358 write(csPtr->typeId());
00359 csPtr->toData(*this);
00360 }
00361
00373 inline void writeASCIIHuge(const char* value, uint32_t length = 0)
00374 {
00375 if ( value != NULL ) {
00376 if ( length == 0 ) {
00377 length = (uint32_t)strlen( value );
00378 }
00379 writeInt( (uint32_t) length );
00380 writeBytesOnly( (int8_t*)value, (uint32_t) length );
00381 } else {
00382 writeInt( (uint32_t)0 );
00383 }
00384 }
00385
00386
00397 inline void writeFullUTF(const char* value, uint32_t length = 0)
00398 {
00399 if ( value != NULL ) {
00400 int32_t len = getEncodedLength( value, length );
00401 uint16_t encodedLen = (uint16_t)( len > 0xFFFF ? 0xFFFF : len );
00402 writeInt( (int32_t)encodedLen );
00403 ensureCapacity( encodedLen );
00404 write((int8_t)0);
00405 uint8_t* end = m_buf + encodedLen;
00406 while( m_buf < end ) {
00407 encodeChar( *value++ );
00408 }
00409 if ( m_buf > end ) m_buf = end;
00410 } else {
00411 writeInt( (uint16_t)0 );
00412 }
00413 }
00414
00426 inline void writeUTF(const char* value, uint32_t length = 0)
00427 {
00428 if ( value != NULL ) {
00429 int32_t len = getEncodedLength( value, length );
00430 uint16_t encodedLen = (uint16_t)( len > 0xFFFF ? 0xFFFF : len );
00431 writeInt( encodedLen );
00432 ensureCapacity( encodedLen );
00433 uint8_t* end = m_buf + encodedLen;
00434 while( m_buf < end ) {
00435 encodeChar( *value++ );
00436 }
00437 if ( m_buf > end ) m_buf = end;
00438 } else {
00439 writeInt( (uint16_t)0 );
00440 }
00441 }
00442
00455 inline void writeUTFHuge(const char* value, uint32_t length = 0)
00456 {
00457 if (value != NULL) {
00458 if (length == 0) {
00459 length = (uint32_t)strlen(value);
00460 }
00461 writeInt(length);
00462 ensureCapacity(length * 2);
00463 for (uint32_t pos = 0; pos < length; pos++) {
00464 writeNoCheck((int8_t)0);
00465 writeNoCheck((int8_t)value[pos]);
00466 }
00467 }
00468 else {
00469 writeInt((uint32_t)0);
00470 }
00471 }
00472
00484 inline void writeUTF(const wchar_t* value, uint32_t length = 0)
00485 {
00486 if ( value != NULL ) {
00487 int32_t len = getEncodedLength( value, length );
00488 uint16_t encodedLen = (uint16_t)( len > 0xFFFF ? 0xFFFF : len );
00489 writeInt( encodedLen );
00490 ensureCapacity( encodedLen );
00491 uint8_t* end = m_buf + encodedLen;
00492 while( m_buf < end ) {
00493 encodeChar( *value++ );
00494 }
00495 if ( m_buf > end ) m_buf = end;
00496 } else {
00497 writeInt( (uint16_t)0 );
00498 }
00499 }
00500
00511 inline void writeUTFHuge(const wchar_t* value, uint32_t length = 0)
00512 {
00513 if (value != NULL) {
00514 if (length == 0) {
00515 length = (uint32_t)wcslen(value);
00516 }
00517 writeInt(length);
00518 ensureCapacity(length * 2);
00519 for (uint32_t pos = 0; pos < length; pos++) {
00520 uint16_t item = (uint16_t)value[pos];
00521 writeNoCheck((uint8_t)((item & 0xFF00) >> 8));
00522 writeNoCheck((uint8_t)(item & 0xFF));
00523 }
00524 }
00525 else {
00526 writeInt((uint32_t)0);
00527 }
00528 }
00529
00540 inline static int32_t getEncodedLength( const char* value,
00541 int32_t length = 0, uint32_t* valLength = NULL )
00542 {
00543 if ( value == NULL ) return 0;
00544 char currentChar;
00545 int32_t encodedLen = 0;
00546 const char* start = value;
00547 if ( length == 0 ) {
00548 while ( (currentChar = *value) != '\0' ) {
00549 getEncodedLength( currentChar, encodedLen );
00550 value++;
00551 }
00552 } else {
00553 const char* end = value + length;
00554 while ( value < end ) {
00555 currentChar = *value;
00556 getEncodedLength( currentChar, encodedLen );
00557 value++;
00558 }
00559 }
00560 if ( valLength != NULL ) {
00561 *valLength = static_cast<uint32_t>(value - start);
00562 }
00563 return encodedLen;
00564 }
00565
00576 inline static int32_t getEncodedLength( const wchar_t* value,
00577 int32_t length = 0, uint32_t* valLength = NULL )
00578 {
00579 if ( value == NULL ) return 0;
00580 wchar_t currentChar;
00581 int32_t encodedLen = 0;
00582 const wchar_t* start = value;
00583 if ( length == 0 ) {
00584 while ( (currentChar = *value) != 0 ) {
00585 getEncodedLength( currentChar, encodedLen );
00586 value++;
00587 }
00588 } else {
00589 const wchar_t* end = value + length;
00590 while ( value < end ) {
00591 currentChar = *value;
00592 getEncodedLength( currentChar, encodedLen );
00593 value++;
00594 }
00595 }
00596 if ( valLength != NULL ) {
00597 *valLength = static_cast<uint32_t>(value - start);
00598 }
00599 return encodedLen;
00600 }
00601
00608 template< class PTR >
00609 void writeObject( const SharedPtr<PTR>& objptr, bool isDelta = false )
00610 {
00611 writeObjectInternal( objptr.ptr( ), isDelta );
00612 }
00613
00620 void writeObject( const Serializable* objptr )
00621 {
00622 writeObjectInternal( objptr );
00623 }
00624
00629 const uint8_t* getCursor()
00630 {
00631 return m_buf;
00632 }
00633
00639 void advanceCursor(uint32_t offset)
00640 {
00641 ensureCapacity(offset);
00642 m_buf += offset;
00643 }
00644
00650 void rewindCursor(uint32_t offset)
00651 {
00652 m_buf -= offset;
00653 }
00654
00655 void updateValueAtPos(uint32_t offset, uint8_t value)
00656 {
00657 m_bytes[offset] = value;
00658 }
00659
00660 uint8_t getValueAtPos(uint32_t offset)
00661 {
00662 return m_bytes[offset];
00663 }
00665 ~DataOutput( )
00666 {
00667 reset();
00668 DataOutput::checkinBuffer(m_bytes, m_size);
00669 }
00670
00674 inline const uint8_t* getBuffer( ) const
00675 {
00676
00677 return m_bytes;
00678 }
00679
00683 inline uint32_t getRemainingBufferLength( ) const
00684 {
00685
00686 return m_size - getBufferLength();
00687 }
00688
00695 inline const uint8_t* getBuffer( uint32_t* rsize ) const
00696 {
00697 *rsize = (uint32_t)( m_buf - m_bytes );
00698
00699 return m_bytes;
00700 }
00701
00702 inline uint8_t* getBufferCopy( )
00703 {
00704 uint32_t size = (uint32_t)( m_buf - m_bytes );
00705 uint8_t * result;
00706 GF_ALLOC(result, uint8_t, size);
00707 memcpy( result, m_bytes, size );
00708 return result;
00709 }
00710
00715 inline uint32_t getBufferLength() const {
00716 return (uint32_t)( m_buf - m_bytes );
00717 }
00718
00722 inline void reset()
00723 {
00724 if (m_haveBigBuffer) {
00725
00726 GF_FREE(m_bytes);
00727
00728 GF_ALLOC(m_bytes, uint8_t, m_lowWaterMark);
00729 m_size = m_lowWaterMark;
00730
00731 m_haveBigBuffer = false;
00732
00733 releaseLock();
00734 }
00735 m_buf = m_bytes;
00736 }
00737
00738
00739 inline void ensureCapacity( uint32_t size )
00740 {
00741 uint32_t offset = (uint32_t)( m_buf - m_bytes );
00742 if ( (m_size - offset) < size ) {
00743 uint32_t newSize = m_size * 2 + (8192 * (size / 8192));
00744 if (newSize >= m_highWaterMark && !m_haveBigBuffer) {
00745
00746 acquireLock();
00747
00748 m_haveBigBuffer = true;
00749 }
00750 m_size = newSize;
00751 GF_RESIZE( m_bytes, uint8_t, m_size );
00752 m_buf = m_bytes + offset;
00753 }
00754 }
00755
00756
00757
00758
00759 const char* getPoolName()
00760 {
00761 return m_poolName;
00762 }
00763
00764
00765
00766
00767 void setPoolName(const char* poolName)
00768 {
00769 m_poolName = poolName;
00770 }
00771
00772 uint8_t * getBufferCopyFrom(const uint8_t *from, uint32_t length)
00773 {
00774 uint8_t * result;
00775 GF_NEW( result, uint8_t[ length ] );
00776 memcpy( result, from, length);
00777
00778 return result;
00779 }
00780
00781 static void safeDelete(uint8_t* src)
00782 {
00783 GF_SAFE_DELETE(src);
00784 }
00785
00786 static DataOutput* getDataOutput()
00787 {
00788 return new DataOutput();
00789 }
00790 static void releaseDataOutput(DataOutput* dataOutput)
00791 {
00792 GF_SAFE_DELETE(dataOutput);
00793 }
00794 private:
00795
00796 void writeObjectInternal( const Serializable* ptr, bool isDelta = false );
00797
00798 static void acquireLock();
00799 static void releaseLock();
00800
00801
00802
00803 const char* m_poolName;
00804
00805 uint8_t* m_bytes;
00806
00807 uint8_t* m_buf;
00808
00809 uint32_t m_size;
00810
00811 static uint32_t m_lowWaterMark;
00812 static uint32_t m_highWaterMark;
00813
00814 volatile bool m_haveBigBuffer;
00815
00816 inline static void getEncodedLength( const char val, int32_t& encodedLen )
00817 {
00818 if ( (val == 0) || (val & 0x80) ) {
00819
00820 encodedLen += 2;
00821 } else {
00822
00823 encodedLen++;
00824 }
00825 }
00826
00827 inline static void getEncodedLength( const wchar_t val, int32_t& encodedLen )
00828 {
00829 if( val == 0)
00830 {
00831 encodedLen += 2;
00832 }
00833 else if ( val < 0x80 )
00834 {
00835 encodedLen++;
00836 }
00837 else if ( val < 0x800 )
00838 {
00839 encodedLen += 2;
00840 }
00841 else
00842 {
00843 encodedLen += 3;
00844 }
00845 }
00846
00847 inline void encodeChar( const char value )
00848 {
00849 uint8_t tmp = (uint8_t)value;
00850 if ( (tmp == 0) || (tmp & 0x80) ) {
00851
00852 *(m_buf++) = (uint8_t)(0xc0 | ((tmp & 0xc0 ) >> 6));
00853 *(m_buf++) = (uint8_t)(0x80 | (tmp & 0x3f ));
00854 } else {
00855
00856 *(m_buf++) = tmp;
00857 }
00858 }
00859
00860
00861 inline void encodeChar( const wchar_t value )
00862 {
00863 uint16_t c = (uint16_t)value;
00864 if ( c == 0 ) {
00865 *(m_buf++) = 0xc0;
00866 *(m_buf++) = 0x80;
00867 }
00868 else if ( c < 0x80 ) {
00869 *(m_buf++) = (uint8_t)c;
00870 }
00871 else if ( c < 0x800 ) {
00872 *(m_buf++) = (uint8_t)( 0xC0 | c >> 6 );
00873 *(m_buf++) = (uint8_t)( 0x80 | (c & 0x3F) );
00874 }
00875 else {
00876 *(m_buf++) = (uint8_t)( 0xE0 | c >> 12 );
00877 *(m_buf++) = (uint8_t)( 0x80 | ((c >> 6) & 0x3F) );
00878 *(m_buf++) = (uint8_t)( 0x80 | (c & 0x3F) );
00879 }
00880 }
00881
00882 inline void writeNoCheck(uint8_t value)
00883 {
00884 *(m_buf++) = value;
00885 }
00886
00887 inline void writeNoCheck(int8_t value)
00888 {
00889 writeNoCheck((uint8_t)value);
00890 }
00891
00892
00893 static uint8_t* checkoutBuffer( uint32_t* size );
00894 static void checkinBuffer( uint8_t* buffer, uint32_t size );
00895
00896
00897 DataOutput(const DataOutput&);
00898 DataOutput& operator =(const DataOutput&);
00899 };
00900
00901 }
00902
00903 #endif // __GEMFIRE_DATAOUTPUT_H__