20 #ifndef GEODE_DATAINPUT_H_
21 #define GEODE_DATAINPUT_H_
29 #include "ExceptionTypes.hpp"
30 #include "internal/DSCode.hpp"
31 #include "internal/geode_globals.hpp"
37 #define _GEODE_CHECK_BUFFER_SIZE(x) _checkBufferSize(x, __LINE__)
44 class CacheableString;
47 class SerializationRegistry;
49 class DataInputInternal;
67 _GEODE_CHECK_BUFFER_SIZE(1);
77 _GEODE_CHECK_BUFFER_SIZE(1);
78 return *(m_buf++) == 1 ?
true :
false;
93 _GEODE_CHECK_BUFFER_SIZE(len);
94 std::memcpy(buffer, m_buf, len);
111 _GEODE_CHECK_BUFFER_SIZE(len);
112 std::memcpy(buffer, m_buf, len);
128 auto length = readArrayLength();
130 uint8_t* buffer =
nullptr;
132 _GEODE_CHECK_BUFFER_SIZE(length);
133 _GEODE_NEW(buffer, uint8_t[length]);
134 std::memcpy(buffer, m_buf, length);
151 auto length = readArrayLength();
153 int8_t* buffer =
nullptr;
155 _GEODE_CHECK_BUFFER_SIZE(length);
156 _GEODE_NEW(buffer, int8_t[length]);
157 std::memcpy(buffer, m_buf, length);
169 _GEODE_CHECK_BUFFER_SIZE(2);
170 return readInt16NoCheck();
180 _GEODE_CHECK_BUFFER_SIZE(4);
181 int32_t tmp = *(m_buf++);
182 tmp = (tmp << 8) | *(m_buf++);
183 tmp = (tmp << 8) | *(m_buf++);
184 tmp = (tmp << 8) | *(m_buf++);
195 _GEODE_CHECK_BUFFER_SIZE(8);
198 tmp = (tmp << 8) | *(m_buf++);
199 tmp = (tmp << 8) | *(m_buf++);
200 tmp = (tmp << 8) | *(m_buf++);
201 tmp = (tmp << 8) | *(m_buf++);
202 tmp = (tmp << 8) | *(m_buf++);
203 tmp = (tmp << 8) | *(m_buf++);
204 tmp = (tmp << 8) | *(m_buf++);
217 const uint8_t code = read();
221 int32_t result = code;
224 uint16_t val = readInt16();
226 }
else if (code == 0xFD) {
227 uint32_t val = readInt32();
247 const auto b = read();
248 result |=
static_cast<int64_t
>(b & 0x7F) << shift;
249 if ((b & 0x80) == 0) {
263 _GEODE_CHECK_BUFFER_SIZE(4);
264 union float_uint32_t {
279 _GEODE_CHECK_BUFFER_SIZE(8);
280 union double_uint64_t {
288 template <
class CharT = char,
class... Tail>
289 inline std::basic_string<CharT, Tail...> readUTF() {
290 std::basic_string<CharT, Tail...> value;
291 readJavaModifiedUtf8(value);
295 template <
class CharT = char,
class... Tail>
296 inline std::basic_string<CharT, Tail...> readString() {
297 std::basic_string<CharT, Tail...> value;
298 auto type =
static_cast<internal::DSCode
>(read());
300 case internal::DSCode::CacheableString:
301 readJavaModifiedUtf8(value);
303 case internal::DSCode::CacheableStringHuge:
304 readUtf16Huge(value);
306 case internal::DSCode::CacheableASCIIString:
309 case internal::DSCode::CacheableASCIIStringHuge:
310 readAsciiHuge(value);
312 case internal::DSCode::CacheableNullString:
322 inline bool readNativeBool() {
324 return readBoolean();
327 inline int32_t readNativeInt32() {
332 inline std::shared_ptr<Serializable> readDirectObject(int8_t typeId = -1) {
333 return readObjectInternal(typeId);
342 return readObjectInternal();
350 ptr = readObjectInternal();
353 inline void readObject(char16_t* value) { *value = readInt16(); }
355 inline void readObject(
bool* value) { *value = readBoolean(); }
357 inline void readObject(int8_t* value) { *value = read(); }
359 inline void readObject(int16_t* value) { *value = readInt16(); }
361 inline void readObject(int32_t* value) { *value = readInt32(); }
363 inline void readObject(int64_t* value) { *value = readInt64(); }
365 inline void readObject(
float* value) { *value = readFloat(); }
367 inline void readObject(
double* value) { *value = readDouble(); }
369 inline std::vector<char16_t> readCharArray() {
return readArray<char16_t>(); }
371 inline std::vector<bool> readBooleanArray() {
return readArray<bool>(); }
373 inline std::vector<int8_t> readByteArray() {
return readArray<int8_t>(); }
375 inline std::vector<int16_t> readShortArray() {
return readArray<int16_t>(); }
377 inline std::vector<int32_t> readIntArray() {
return readArray<int32_t>(); }
379 inline std::vector<int64_t> readLongArray() {
return readArray<int64_t>(); }
381 inline std::vector<float> readFloatArray() {
return readArray<float>(); }
383 inline std::vector<double> readDoubleArray() {
return readArray<double>(); }
385 inline std::vector<std::string> readStringArray() {
386 std::vector<std::string> value;
388 auto arrLen = readArrayLength();
390 value.reserve(arrLen);
391 for (
int i = 0; i < arrLen; i++) {
392 value.push_back(readString());
399 inline void readArrayOfByteArrays(int8_t*** arrayofBytearr,
400 int32_t& arrayLength,
401 int32_t** elementLength) {
402 auto arrLen = readArrayLength();
403 arrayLength = arrLen;
406 *arrayofBytearr =
nullptr;
410 int32_t* tmpLengtharr;
411 _GEODE_NEW(tmpArray, int8_t * [arrLen]);
412 _GEODE_NEW(tmpLengtharr, int32_t[arrLen]);
413 for (
int i = 0; i < arrLen; i++) {
414 readBytes(&tmpArray[i], &tmpLengtharr[i]);
416 *arrayofBytearr = tmpArray;
417 *elementLength = tmpLengtharr;
433 return (m_bufLength - getBytesRead());
443 inline void reset() { m_buf = m_bufHead; }
445 inline void setBuffer() {
446 m_buf = currentBufferPosition();
447 m_bufLength = getBytesRemaining();
450 inline void resetPdx(
size_t offset) { m_buf = m_bufHead + offset; }
452 inline size_t getPdxBytes()
const {
return m_bufLength; }
454 static uint8_t* getBufferCopy(
const uint8_t* from,
size_t length) {
456 _GEODE_NEW(result, uint8_t[length]);
457 std::memcpy(result, from, length);
462 inline void reset(
size_t offset) { m_buf = m_bufHead + offset; }
464 uint8_t* getBufferCopyFrom(
const uint8_t* from,
size_t length) {
466 _GEODE_NEW(result, uint8_t[length]);
467 std::memcpy(result, from, length);
472 virtual Cache* getCache()
const;
474 DataInput() =
delete;
475 virtual ~DataInput() noexcept = default;
476 DataInput(const DataInput&) = delete;
477 DataInput& operator=(const DataInput&) = delete;
478 DataInput(DataInput&&) = default;
479 DataInput& operator=(DataInput&&) = default;
483 DataInput(const uint8_t* buffer,
size_t len, const CacheImpl* cache,
486 virtual const SerializationRegistry& getSerializationRegistry() const;
489 const uint8_t* m_buf;
490 const uint8_t* m_bufHead;
493 const CacheImpl* m_cache;
495 std::shared_ptr<
Serializable> readObjectInternal(int8_t typeId = -1);
497 template <typename mType>
498 void readObject(mType** value, int32_t& length) {
499 auto arrayLen = readArrayLength();
503 objArray =
new mType[arrayLen];
505 for (i = 0; i < arrayLen; i++) {
514 template <
typename T>
515 std::vector<T> readArray() {
516 auto arrayLen = readArrayLength();
517 std::vector<T> objArray;
519 objArray.reserve(arrayLen);
521 for (i = 0; i < arrayLen; i++) {
524 objArray.push_back(tmp);
530 inline char readPdxChar() {
return static_cast<char>(readInt16()); }
532 inline void _checkBufferSize(
size_t size, int32_t line) {
533 if ((m_bufLength - (m_buf - m_bufHead)) < size) {
534 throw OutOfRangeException(
535 "DataInput: attempt to read beyond buffer at line " +
536 std::to_string(line) +
": available buffer size " +
537 std::to_string(m_bufLength - (m_buf - m_bufHead)) +
538 ", attempted read of size " + std::to_string(size));
542 inline int8_t readNoCheck() {
return *(m_buf++); }
544 inline int16_t readInt16NoCheck() {
545 int16_t tmp = *(m_buf++);
546 tmp =
static_cast<int16_t
>((tmp << 8) | *(m_buf++));
550 template <
class CharT,
class... Tail>
551 inline void readAscii(std::basic_string<CharT, Tail...>& value,
553 _GEODE_CHECK_BUFFER_SIZE(length);
554 value.reserve(length);
555 while (length-- > 0) {
557 value += readNoCheck() & 0x7F;
561 template <
class CharT,
class... Tail>
562 inline void readAscii(std::basic_string<CharT, Tail...>& value) {
563 readAscii(value,
static_cast<uint16_t
>(readInt16()));
566 template <
class CharT,
class... Tail>
567 inline void readAsciiHuge(std::basic_string<CharT, Tail...>& value) {
568 readAscii(value,
static_cast<uint32_t
>(readInt32()));
571 template <
class _CharT,
class _Traits,
class _Allocator>
572 void readJavaModifiedUtf8(
573 std::basic_string<_CharT, _Traits, _Allocator>& value);
575 template <
class _Traits,
class _Allocator>
576 void readJavaModifiedUtf8(
577 std::basic_string<char16_t, _Traits, _Allocator>& value);
579 template <
class _Traits,
class _Allocator>
580 void readJavaModifiedUtf8(
581 std::basic_string<char, _Traits, _Allocator>& value);
583 template <
class _Traits,
class _Allocator>
584 void readJavaModifiedUtf8(
585 std::basic_string<char32_t, _Traits, _Allocator>& value);
587 template <
class _Traits,
class _Allocator>
588 inline void readJavaModifiedUtf8(
589 std::basic_string<wchar_t, _Traits, _Allocator>& value) {
591 typedef std::conditional<
592 sizeof(wchar_t) ==
sizeof(char16_t), char16_t,
593 std::conditional<
sizeof(wchar_t) ==
sizeof(char32_t), char32_t,
594 char>::type>::type _WcharT;
596 auto tmp = std::basic_string<_WcharT>();
597 readJavaModifiedUtf8(tmp);
598 value.assign(
reinterpret_cast<const wchar_t*
>(tmp.data()), tmp.length());
601 template <
class _CharT,
class _Traits,
class _Allocator>
602 void readUtf16Huge(std::basic_string<_CharT, _Traits, _Allocator>& value);
604 template <
class _Traits,
class _Allocator>
605 inline void readUtf16Huge(
606 std::basic_string<char16_t, _Traits, _Allocator>& value) {
607 uint32_t length = readInt32();
608 _GEODE_CHECK_BUFFER_SIZE(length);
609 value.reserve(length);
610 while (length-- > 0) {
611 value += readInt16NoCheck();
615 template <
class _Traits,
class _Allocator>
616 void readUtf16Huge(std::basic_string<char, _Traits, _Allocator>& value);
618 template <
class _Traits,
class _Allocator>
619 void readUtf16Huge(std::basic_string<char32_t, _Traits, _Allocator>& value);
621 template <
class _Traits,
class _Allocator>
622 inline void readUtf16Huge(
623 std::basic_string<wchar_t, _Traits, _Allocator>& value) {
625 typedef std::conditional<
626 sizeof(wchar_t) ==
sizeof(char16_t), char16_t,
627 std::conditional<
sizeof(wchar_t) ==
sizeof(char32_t), char32_t,
628 char>::type>::type _WcharT;
630 auto tmp = std::basic_string<_WcharT>();
632 value.assign(
reinterpret_cast<const wchar_t*
>(tmp.data()), tmp.length());
635 Pool* getPool()
const {
return m_pool; }
639 friend DataInputInternal;
640 friend CacheableString;
646 #endif // GEODE_DATAINPUT_H_