3 #ifndef GEODE_DATAOUTPUT_H_
4 #define GEODE_DATAOUTPUT_H_
23 #include "geode_globals.hpp"
45 #define GF_ALLOC(v, t, s) \
47 v = (t*)malloc((s) * sizeof(t)); \
49 throw OutOfMemoryException( \
50 "Out of Memory while allocating buffer for " #t " of size " #s); \
58 #define GF_RESIZE(v, t, s) \
60 v = (t*)realloc(v, (s) * sizeof(t)); \
62 throw OutOfMemoryException( \
63 "Out of Memory while resizing buffer for " #t); \
67 #define GF_FREE(v) free(v)
86 inline void write(uint8_t value) {
96 inline void write(int8_t value) {
write(static_cast<uint8_t>(value)); }
103 inline void writeBoolean(
bool value) { write(static_cast<uint8_t>(value)); }
113 ensureCapacity(len + 5);
114 writeArrayLen(bytes == NULL ? 0 : len);
115 if (len > 0 && bytes != NULL) {
116 std::memcpy(m_buf, bytes, len);
120 write(static_cast<int8_t>(-1));
131 writeBytes(reinterpret_cast<const uint8_t*>(bytes), len);
147 std::memcpy(m_buf, bytes, len);
163 writeBytesOnly(reinterpret_cast<const uint8_t*>(bytes), len);
173 *(m_buf++) = static_cast<uint8_t>(value >> 8);
174 *(m_buf++) = static_cast<uint8_t>(value);
184 *(m_buf++) = static_cast<uint8_t>(value >> 8);
185 *(m_buf++) = static_cast<uint8_t>(value);
195 *(m_buf++) = static_cast<uint8_t>(value >> 24);
196 *(m_buf++) = static_cast<uint8_t>(value >> 16);
197 *(m_buf++) = static_cast<uint8_t>(value >> 8);
198 *(m_buf++) = static_cast<uint8_t>(value);
212 if (
sizeof(
long) == 8) {
213 *(m_buf++) = static_cast<uint8_t>(value >> 56);
214 *(m_buf++) = static_cast<uint8_t>(value >> 48);
215 *(m_buf++) = static_cast<uint8_t>(value >> 40);
216 *(m_buf++) = static_cast<uint8_t>(value >> 32);
217 *(m_buf++) = static_cast<uint8_t>(value >> 24);
218 *(m_buf++) = static_cast<uint8_t>(value >> 16);
219 *(m_buf++) = static_cast<uint8_t>(value >> 8);
220 *(m_buf++) = static_cast<uint8_t>(value);
222 uint32_t hword = static_cast<uint32_t>(value >> 32);
223 *(m_buf++) = static_cast<uint8_t>(hword >> 24);
224 *(m_buf++) = static_cast<uint8_t>(hword >> 16);
225 *(m_buf++) = static_cast<uint8_t>(hword >> 8);
226 *(m_buf++) = static_cast<uint8_t>(hword);
228 hword = static_cast<uint32_t>(value);
229 *(m_buf++) = static_cast<uint8_t>(hword >> 24);
230 *(m_buf++) = static_cast<uint8_t>(hword >> 16);
231 *(m_buf++) = static_cast<uint8_t>(hword >> 8);
232 *(m_buf++) = static_cast<uint8_t>(hword);
242 writeInt(static_cast<uint16_t>(value));
251 writeInt(static_cast<uint32_t>(value));
260 writeInt(static_cast<uint64_t>(value));
272 write(static_cast<int8_t>(-1));
273 }
else if (len <= 252) {
274 write(static_cast<uint8_t>(len));
275 }
else if (len <= 0xFFFF) {
276 write(static_cast<int8_t>(-2));
277 writeInt(static_cast<uint16_t>(len));
279 write(static_cast<int8_t>(-3));
290 union float_uint32_t {
304 union double_uint64_t {
324 inline void writeASCII(
const char* value, uint32_t length = 0) {
327 length = static_cast<uint32_t>(strlen(value));
329 uint16_t len = static_cast<uint16_t>(length > 0xFFFF ? 0xFFFF : length);
331 writeBytesOnly((int8_t*)value, len);
333 writeInt(static_cast<uint16_t>(0));
337 inline void writeNativeString(
const char* value) {
360 length = static_cast<uint32_t>(strlen(value));
363 writeBytesOnly((int8_t*)value, length);
365 writeInt(static_cast<uint32_t>(0));
381 int32_t encodedLen = getEncodedLength(value, length);
382 writeInt(encodedLen);
383 ensureCapacity(encodedLen);
384 write(static_cast<int8_t>(0));
385 uint8_t* end = m_buf + encodedLen;
386 while (m_buf < end) {
387 encodeChar(*value++);
389 if (m_buf > end) m_buf = end;
391 writeInt(static_cast<uint16_t>(0));
406 inline void writeUTF(
const char* value, uint32_t length = 0) {
408 int32_t len = getEncodedLength(value, length);
409 uint16_t encodedLen = static_cast<uint16_t>(len > 0xFFFF ? 0xFFFF : len);
410 writeInt(encodedLen);
411 ensureCapacity(encodedLen);
412 uint8_t* end = m_buf + encodedLen;
413 while (m_buf < end) {
414 encodeChar(*value++);
416 if (m_buf > end) m_buf = end;
418 writeInt(static_cast<uint16_t>(0));
437 length = static_cast<uint32_t>(strlen(value));
440 ensureCapacity(length * 2);
441 for (uint32_t pos = 0; pos < length; pos++) {
442 writeNoCheck(static_cast<int8_t>(0));
443 writeNoCheck(static_cast<int8_t>(value[pos]));
446 writeInt(static_cast<uint32_t>(0));
461 inline void writeUTF(
const wchar_t* value, uint32_t length = 0) {
463 int32_t len = getEncodedLength(value, length);
464 uint16_t encodedLen = static_cast<uint16_t>(len > 0xFFFF ? 0xFFFF : len);
465 writeInt(encodedLen);
466 ensureCapacity(encodedLen);
467 uint8_t* end = m_buf + encodedLen;
468 while (m_buf < end) {
469 encodeChar(*value++);
471 if (m_buf > end) m_buf = end;
473 writeInt(static_cast<uint16_t>(0));
490 length = static_cast<uint32_t>(wcslen(value));
493 ensureCapacity(length * 2);
494 for (uint32_t pos = 0; pos < length; pos++) {
495 uint16_t item = static_cast<uint16_t>(value[pos]);
496 writeNoCheck(static_cast<uint8_t>((item & 0xFF00) >> 8));
497 writeNoCheck(static_cast<uint8_t>(item & 0xFF));
500 writeInt(static_cast<uint32_t>(0));
515 uint32_t* valLength = NULL) {
516 if (value == NULL)
return 0;
518 int32_t encodedLen = 0;
519 const char* start = value;
521 while ((currentChar = *value) !=
'\0') {
522 getEncodedLength(currentChar, encodedLen);
526 const char* end = value + length;
527 while (value < end) {
528 currentChar = *value;
529 getEncodedLength(currentChar, encodedLen);
533 if (valLength != NULL) {
534 *valLength = static_cast<uint32_t>(value - start);
551 uint32_t* valLength = NULL) {
552 if (value == NULL)
return 0;
554 int32_t encodedLen = 0;
555 const wchar_t* start = value;
557 while ((currentChar = *value) != 0) {
558 getEncodedLength(currentChar, encodedLen);
562 const wchar_t* end = value + length;
563 while (value < end) {
564 currentChar = *value;
565 getEncodedLength(currentChar, encodedLen);
569 if (valLength != NULL) {
570 *valLength = static_cast<uint32_t>(value - start);
583 writeObjectInternal(objptr.ptr(), isDelta);
606 ensureCapacity(offset);
617 void updateValueAtPos(uint32_t offset, uint8_t value) {
618 m_bytes[offset] = value;
621 uint8_t getValueAtPos(uint32_t offset) {
return m_bytes[offset]; }
625 DataOutput::checkinBuffer(m_bytes, m_size);
641 return m_size - getBufferLength();
650 inline const uint8_t*
getBuffer(uint32_t* rsize)
const {
651 *rsize = static_cast<uint32_t>(m_buf - m_bytes);
656 inline uint8_t* getBufferCopy() {
657 uint32_t size = static_cast<uint32_t>(m_buf - m_bytes);
660 std::memcpy(result, m_bytes, size);
669 return static_cast<uint32_t>(m_buf - m_bytes);
676 if (m_haveBigBuffer) {
680 GF_ALLOC(m_bytes, uint8_t, m_lowWaterMark);
681 m_size = m_lowWaterMark;
683 m_haveBigBuffer =
false;
691 inline void ensureCapacity(uint32_t size) {
692 uint32_t offset = static_cast<uint32_t>(m_buf - m_bytes);
693 if ((m_size - offset) < size) {
694 uint32_t newSize = m_size * 2 + (8192 * (size / 8192));
695 if (newSize >= m_highWaterMark && !m_haveBigBuffer) {
699 m_haveBigBuffer =
true;
703 m_buf = m_bytes + offset;
710 const char* getPoolName() {
return m_poolName; }
715 void setPoolName(
const char* poolName) { m_poolName = poolName; }
717 uint8_t* getBufferCopyFrom(
const uint8_t* from, uint32_t length) {
719 GF_NEW(result, uint8_t[length]);
720 std::memcpy(result, from, length);
727 static DataOutput* getDataOutput() {
return new DataOutput(); }
728 static void releaseDataOutput(DataOutput* dataOutput) {
733 void writeObjectInternal(
const Serializable* ptr,
bool isDelta =
false);
735 static void acquireLock();
736 static void releaseLock();
738 const char* m_poolName;
746 static uint32_t m_lowWaterMark;
747 static uint32_t m_highWaterMark;
749 volatile bool m_haveBigBuffer;
751 inline static void getEncodedLength(
const char val, int32_t& encodedLen) {
752 if ((val == 0) || (val & 0x80)) {
761 inline static void getEncodedLength(
const wchar_t val, int32_t& encodedLen) {
764 }
else if (val < 0x80)
767 }
else if (val < 0x800) {
774 inline void encodeChar(
const char value) {
775 uint8_t tmp = static_cast<uint8_t>(value);
776 if ((tmp == 0) || (tmp & 0x80)) {
778 *(m_buf++) = static_cast<uint8_t>(0xc0 | ((tmp & 0xc0) >> 6));
779 *(m_buf++) = static_cast<uint8_t>(0x80 | (tmp & 0x3f));
787 inline void encodeChar(
const wchar_t value) {
788 uint16_t c = static_cast<uint16_t>(value);
792 }
else if (c < 0x80) {
793 *(m_buf++) = static_cast<uint8_t>(c);
794 }
else if (c < 0x800) {
795 *(m_buf++) = static_cast<uint8_t>(0xC0 | c >> 6);
796 *(m_buf++) = static_cast<uint8_t>(0x80 | (c & 0x3F));
798 *(m_buf++) = static_cast<uint8_t>(0xE0 | c >> 12);
799 *(m_buf++) = static_cast<uint8_t>(0x80 | ((c >> 6) & 0x3F));
800 *(m_buf++) = static_cast<uint8_t>(0x80 | (c & 0x3F));
804 inline void writeNoCheck(uint8_t value) { *(m_buf++) = value; }
806 inline void writeNoCheck(int8_t value) {
807 writeNoCheck(static_cast<uint8_t>(value));
810 static uint8_t* checkoutBuffer(uint32_t* size);
811 static void checkinBuffer(uint8_t* buffer, uint32_t size);
814 DataOutput(
const DataOutput&);
815 DataOutput& operator=(
const DataOutput&);
821 #endif // GEODE_DATAOUTPUT_H_