Apache Geode Native C++ Reference 1.15.0
DataInput.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#ifndef GEODE_DATAINPUT_H_
21#define GEODE_DATAINPUT_H_
22
23#include <cstring>
24#include <iosfwd>
25#include <memory>
26#include <string>
27#include <vector>
28
29#include "ExceptionTypes.hpp"
30#include "internal/DSCode.hpp"
31#include "internal/geode_globals.hpp"
32
37#define _GEODE_CHECK_BUFFER_SIZE(x) _checkBufferSize(x, __LINE__)
38
39namespace apache {
40namespace geode {
41namespace client {
42
43class Cache;
44class CacheableString;
45class DataInput;
46class Serializable;
47class SerializationRegistry;
48class CacheImpl;
49class DataInputInternal;
50class Pool;
51
59class APACHE_GEODE_EXPORT DataInput {
60 public:
66 inline int8_t read() {
67 _GEODE_CHECK_BUFFER_SIZE(1);
68 return readNoCheck();
69 }
70
74 inline bool readBoolean() {
75 _GEODE_CHECK_BUFFER_SIZE(1);
76 return *(m_buf++) == 1 ? true : false;
77 }
78
89 inline void readBytesOnly(uint8_t* buffer, size_t len) {
90 if (len > 0) {
91 _GEODE_CHECK_BUFFER_SIZE(len);
92 std::memcpy(buffer, m_buf, len);
93 m_buf += len;
94 }
95 }
96
107 inline void readBytesOnly(int8_t* buffer, size_t len) {
108 if (len > 0) {
109 _GEODE_CHECK_BUFFER_SIZE(len);
110 std::memcpy(buffer, m_buf, len);
111 m_buf += len;
112 }
113 }
114
125 inline void readBytes(uint8_t** bytes, int32_t* len) {
126 auto length = readArrayLength();
127 *len = length;
128 uint8_t* buffer = nullptr;
129 if (length > 0) {
130 _GEODE_CHECK_BUFFER_SIZE(length);
131 _GEODE_NEW(buffer, uint8_t[length]);
132 std::memcpy(buffer, m_buf, length);
133 m_buf += length;
134 }
135 *bytes = buffer;
136 }
137
148 inline void readBytes(int8_t** bytes, int32_t* len) {
149 auto length = readArrayLength();
150 *len = length;
151 int8_t* buffer = nullptr;
152 if (length > 0) {
153 _GEODE_CHECK_BUFFER_SIZE(length);
154 _GEODE_NEW(buffer, int8_t[length]);
155 std::memcpy(buffer, m_buf, length);
156 m_buf += length;
157 }
158 *bytes = buffer;
159 }
160
166 inline int16_t readInt16() {
167 _GEODE_CHECK_BUFFER_SIZE(2);
168 return readInt16NoCheck();
169 }
170
174 inline int32_t readInt32() {
175 _GEODE_CHECK_BUFFER_SIZE(4);
176 int32_t tmp = *(m_buf++);
177 tmp = (tmp << 8) | *(m_buf++);
178 tmp = (tmp << 8) | *(m_buf++);
179 tmp = (tmp << 8) | *(m_buf++);
180 return tmp;
181 }
182
186 inline int64_t readInt64() {
187 _GEODE_CHECK_BUFFER_SIZE(8);
188 int64_t tmp;
189 tmp = *(m_buf++);
190 tmp = (tmp << 8) | *(m_buf++);
191 tmp = (tmp << 8) | *(m_buf++);
192 tmp = (tmp << 8) | *(m_buf++);
193 tmp = (tmp << 8) | *(m_buf++);
194 tmp = (tmp << 8) | *(m_buf++);
195 tmp = (tmp << 8) | *(m_buf++);
196 tmp = (tmp << 8) | *(m_buf++);
197 return tmp;
198 }
199
205 inline int32_t readArrayLength() {
206 const uint8_t code = read();
207 if (code == 0xFF) {
208 return -1;
209 } else {
210 int32_t result = code;
211 if (result > 252) { // 252 is java's ((byte)-4 && 0xFF)
212 if (code == 0xFE) {
213 uint16_t val = readInt16();
214 result = val;
215 } else if (code == 0xFD) {
216 uint32_t val = readInt32();
217 result = val;
218 } else {
219 throw IllegalStateException("unexpected array length code");
220 }
221 }
222 return result;
223 }
224 }
225
232 inline int64_t readUnsignedVL() {
233 int32_t shift = 0;
234 int64_t result = 0;
235 while (shift < 64) {
236 const auto b = read();
237 result |= static_cast<int64_t>(b & 0x7F) << shift;
238 if ((b & 0x80) == 0) {
239 return result;
240 }
241 shift += 7;
242 }
243 throw IllegalStateException("Malformed variable length integer");
244 }
245
249 inline float readFloat() {
250 _GEODE_CHECK_BUFFER_SIZE(4);
251 union float_uint32_t {
252 float f;
253 uint32_t u;
254 } v;
255 v.u = readInt32();
256 return v.f;
257 }
258
262 inline double readDouble() {
263 _GEODE_CHECK_BUFFER_SIZE(8);
264 union double_uint64_t {
265 double d;
266 uint64_t ll;
267 } v;
268 v.ll = readInt64();
269 return v.d;
270 }
271
272 template <class CharT = char, class... Tail>
273 inline std::basic_string<CharT, Tail...> readUTF() {
274 std::basic_string<CharT, Tail...> value;
275 readJavaModifiedUtf8(value);
276 return value;
277 }
278
279 template <class CharT = char, class... Tail>
280 inline std::basic_string<CharT, Tail...> readString() {
281 std::basic_string<CharT, Tail...> value;
282 auto type = static_cast<internal::DSCode>(read());
283 if (type == internal::DSCode::CacheableString) {
284 readJavaModifiedUtf8(value);
285 } else if (type == internal::DSCode::CacheableStringHuge) {
286 readUtf16Huge(value);
287 } else if (type == internal::DSCode::CacheableASCIIString) {
288 readAscii(value);
289 } else if (type == internal::DSCode::CacheableASCIIStringHuge) {
290 readAsciiHuge(value);
291 }
292 return value;
293 }
294
295 inline bool readNativeBool() {
296 read(); // ignore type id
297 return readBoolean();
298 }
299
300 inline int32_t readNativeInt32() {
301 read(); // ignore type id
302 return readInt32();
303 }
304
305 inline std::shared_ptr<Serializable> readDirectObject(int8_t typeId = -1) {
306 return readObjectInternal(typeId);
307 }
308
314 inline std::shared_ptr<Serializable> readObject() {
315 return readObjectInternal();
316 }
317
322 inline void readObject(std::shared_ptr<Serializable>& ptr) {
323 ptr = readObjectInternal();
324 }
325
326 inline void readObject(char16_t* value) { *value = readInt16(); }
327
328 inline void readObject(bool* value) { *value = readBoolean(); }
329
330 inline void readObject(int8_t* value) { *value = read(); }
331
332 inline void readObject(int16_t* value) { *value = readInt16(); }
333
334 inline void readObject(int32_t* value) { *value = readInt32(); }
335
336 inline void readObject(int64_t* value) { *value = readInt64(); }
337
338 inline void readObject(float* value) { *value = readFloat(); }
339
340 inline void readObject(double* value) { *value = readDouble(); }
341
342 inline std::vector<char16_t> readCharArray() { return readArray<char16_t>(); }
343
344 inline std::vector<bool> readBooleanArray() { return readArray<bool>(); }
345
346 inline std::vector<int8_t> readByteArray() { return readArray<int8_t>(); }
347
348 inline std::vector<int16_t> readShortArray() { return readArray<int16_t>(); }
349
350 inline std::vector<int32_t> readIntArray() { return readArray<int32_t>(); }
351
352 inline std::vector<int64_t> readLongArray() { return readArray<int64_t>(); }
353
354 inline std::vector<float> readFloatArray() { return readArray<float>(); }
355
356 inline std::vector<double> readDoubleArray() { return readArray<double>(); }
357
358 inline std::vector<std::string> readStringArray() {
359 std::vector<std::string> value;
360
361 auto arrLen = readArrayLength();
362 if (arrLen > 0) {
363 value.reserve(arrLen);
364 for (int i = 0; i < arrLen; i++) {
365 value.push_back(readString());
366 }
367 }
368
369 return value;
370 }
371
372 inline void readArrayOfByteArrays(int8_t*** arrayofBytearr,
373 int32_t& arrayLength,
374 int32_t** elementLength) {
375 auto arrLen = readArrayLength();
376 arrayLength = arrLen;
377
378 if (arrLen == -1) {
379 *arrayofBytearr = nullptr;
380 return;
381 } else {
382 int8_t** tmpArray;
383 int32_t* tmpLengtharr;
384 _GEODE_NEW(tmpArray, int8_t* [arrLen]);
385 _GEODE_NEW(tmpLengtharr, int32_t[arrLen]);
386 for (int i = 0; i < arrLen; i++) {
387 readBytes(&tmpArray[i], &tmpLengtharr[i]);
388 }
389 *arrayofBytearr = tmpArray;
390 *elementLength = tmpLengtharr;
391 }
392 }
393
399 inline const uint8_t* currentBufferPosition() const { return m_buf; }
400
402 inline size_t getBytesRead() const { return m_buf - m_bufHead; }
403
405 inline size_t getBytesRemaining() const {
406 return (m_bufLength - getBytesRead());
407 }
408
410 inline void advanceCursor(size_t offset) { m_buf += offset; }
411
413 inline void rewindCursor(size_t offset) { m_buf -= offset; }
414
416 inline void reset() { m_buf = m_bufHead; }
417
418 inline void setBuffer() {
419 m_buf = currentBufferPosition();
420 m_bufLength = getBytesRemaining();
421 }
422
423 inline void resetPdx(size_t offset) { m_buf = m_bufHead + offset; }
424
425 inline size_t getPdxBytes() const { return m_bufLength; }
426
427 static uint8_t* getBufferCopy(const uint8_t* from, size_t length) {
428 uint8_t* result;
429 _GEODE_NEW(result, uint8_t[length]);
430 std::memcpy(result, from, length);
431
432 return result;
433 }
434
435 inline void reset(size_t offset) { m_buf = m_bufHead + offset; }
436
437 uint8_t* getBufferCopyFrom(const uint8_t* from, size_t length) {
438 uint8_t* result;
439 _GEODE_NEW(result, uint8_t[length]);
440 std::memcpy(result, from, length);
441
442 return result;
443 }
444
445 virtual Cache* getCache() const;
446
447 DataInput() = delete;
448 virtual ~DataInput() noexcept = default;
449 DataInput(const DataInput&) = delete;
450 DataInput& operator=(const DataInput&) = delete;
451 DataInput(DataInput&&) = default;
452 DataInput& operator=(DataInput&&) = default;
453
454 protected:
456 DataInput(const uint8_t* buffer, size_t len, const CacheImpl* cache,
457 Pool* pool);
458
459 virtual const SerializationRegistry& getSerializationRegistry() const;
460
461 private:
462 const uint8_t* m_buf;
463 const uint8_t* m_bufHead;
464 size_t m_bufLength;
465 Pool* m_pool;
466 const CacheImpl* m_cache;
467
468 std::shared_ptr<Serializable> readObjectInternal(int8_t typeId = -1);
469
470 template <typename mType>
471 void readObject(mType** value, int32_t& length) {
472 auto arrayLen = readArrayLength();
473 length = arrayLen;
474 mType* objArray;
475 if (arrayLen > 0) {
476 objArray = new mType[arrayLen];
477 int i = 0;
478 for (i = 0; i < arrayLen; i++) {
479 mType tmp = 0;
480 readObject(&tmp);
481 objArray[i] = tmp; //*value[i] = tmp;
482 }
483 *value = objArray;
484 }
485 }
486
487 template <typename T>
488 std::vector<T> readArray() {
489 auto arrayLen = readArrayLength();
490 std::vector<T> objArray;
491 if (arrayLen >= 0) {
492 objArray.reserve(arrayLen);
493 int i = 0;
494 for (i = 0; i < arrayLen; i++) {
495 T tmp = 0;
496 readObject(&tmp);
497 objArray.push_back(tmp);
498 }
499 }
500 return objArray;
501 }
502
503 inline char readPdxChar() { return static_cast<char>(readInt16()); }
504
505 inline void _checkBufferSize(size_t size, int32_t line) {
506 if ((m_bufLength - (m_buf - m_bufHead)) < size) {
507 throw OutOfRangeException(
508 "DataInput: attempt to read beyond buffer at line " +
509 std::to_string(line) + ": available buffer size " +
510 std::to_string(m_bufLength - (m_buf - m_bufHead)) +
511 ", attempted read of size " + std::to_string(size));
512 }
513 }
514
515 inline int8_t readNoCheck() { return *(m_buf++); }
516
517 inline int16_t readInt16NoCheck() {
518 int16_t tmp = *(m_buf++);
519 tmp = static_cast<int16_t>((tmp << 8) | *(m_buf++));
520 return tmp;
521 }
522
523 template <class CharT, class... Tail>
524 inline void readAscii(std::basic_string<CharT, Tail...>& value,
525 size_t length) {
526 _GEODE_CHECK_BUFFER_SIZE(length);
527 value.reserve(length);
528 while (length-- > 0) {
529 // blindly assumes ASCII so mask off 7 bits
530 value += readNoCheck() & 0x7F;
531 }
532 }
533
534 template <class CharT, class... Tail>
535 inline void readAscii(std::basic_string<CharT, Tail...>& value) {
536 readAscii(value, static_cast<uint16_t>(readInt16()));
537 }
538
539 template <class CharT, class... Tail>
540 inline void readAsciiHuge(std::basic_string<CharT, Tail...>& value) {
541 readAscii(value, static_cast<uint32_t>(readInt32()));
542 }
543
544 template <class _CharT, class _Traits, class _Allocator>
545 void readJavaModifiedUtf8(
546 std::basic_string<_CharT, _Traits, _Allocator>& value);
547
548 template <class _Traits, class _Allocator>
549 void readJavaModifiedUtf8(
550 std::basic_string<char16_t, _Traits, _Allocator>& value);
551
552 template <class _Traits, class _Allocator>
553 void readJavaModifiedUtf8(
554 std::basic_string<char, _Traits, _Allocator>& value);
555
556 template <class _Traits, class _Allocator>
557 void readJavaModifiedUtf8(
558 std::basic_string<char32_t, _Traits, _Allocator>& value);
559
560 template <class _Traits, class _Allocator>
561 inline void readJavaModifiedUtf8(
562 std::basic_string<wchar_t, _Traits, _Allocator>& value) {
563 // TODO string optimize
564 typedef std::conditional<
565 sizeof(wchar_t) == sizeof(char16_t), char16_t,
566 std::conditional<sizeof(wchar_t) == sizeof(char32_t), char32_t,
567 char>::type>::type _WcharT;
568
569 auto tmp = std::basic_string<_WcharT>();
570 readJavaModifiedUtf8(tmp);
571 value.assign(reinterpret_cast<const wchar_t*>(tmp.data()), tmp.length());
572 }
573
574 template <class _CharT, class _Traits, class _Allocator>
575 void readUtf16Huge(std::basic_string<_CharT, _Traits, _Allocator>& value);
576
577 template <class _Traits, class _Allocator>
578 inline void readUtf16Huge(
579 std::basic_string<char16_t, _Traits, _Allocator>& value) {
580 uint32_t length = readInt32();
581 _GEODE_CHECK_BUFFER_SIZE(length);
582 value.reserve(length);
583 while (length-- > 0) {
584 value += readInt16NoCheck();
585 }
586 }
587
588 template <class _Traits, class _Allocator>
589 void readUtf16Huge(std::basic_string<char, _Traits, _Allocator>& value);
590
591 template <class _Traits, class _Allocator>
592 void readUtf16Huge(std::basic_string<char32_t, _Traits, _Allocator>& value);
593
594 template <class _Traits, class _Allocator>
595 inline void readUtf16Huge(
596 std::basic_string<wchar_t, _Traits, _Allocator>& value) {
597 // TODO string optimize
598 typedef std::conditional<
599 sizeof(wchar_t) == sizeof(char16_t), char16_t,
600 std::conditional<sizeof(wchar_t) == sizeof(char32_t), char32_t,
601 char>::type>::type _WcharT;
602
603 auto tmp = std::basic_string<_WcharT>();
604 readUtf16Huge(tmp);
605 value.assign(reinterpret_cast<const wchar_t*>(tmp.data()), tmp.length());
606 }
607
608 Pool* getPool() const { return m_pool; }
609
610 friend Cache;
611 friend CacheImpl;
612 friend DataInputInternal;
613 friend CacheableString;
614};
615} // namespace client
616} // namespace geode
617} // namespace apache
618
619#endif // GEODE_DATAINPUT_H_
Provide operations for reading primitive data values, byte arrays, strings, Serializable objects from...
Definition: DataInput.hpp:59
void readBytes(uint8_t **bytes, int32_t *len)
Read an array of unsigned bytes from the DataInput expecting to find the length of array in the strea...
Definition: DataInput.hpp:125
void rewindCursor(size_t offset)
rewind the cursor by given offset
Definition: DataInput.hpp:413
void readBytesOnly(int8_t *buffer, size_t len)
Read the given number of signed bytes from the DataInput.
Definition: DataInput.hpp:107
int64_t readUnsignedVL()
Decode a 64 bit integer as a variable length array.
Definition: DataInput.hpp:232
void readBytesOnly(uint8_t *buffer, size_t len)
Read the given number of unsigned bytes from the DataInput.
Definition: DataInput.hpp:89
int32_t readArrayLength()
Read a 32-bit signed integer array length value from the DataInput in a manner compatible with java s...
Definition: DataInput.hpp:205
void readBytes(int8_t **bytes, int32_t *len)
Read an array of signed bytes from the DataInput expecting to find the length of array in the stream ...
Definition: DataInput.hpp:148
int64_t readInt64()
Read a 64-bit signed integer from the DataInput.
Definition: DataInput.hpp:186
int16_t readInt16()
Read a 16-bit signed integer from the DataInput.
Definition: DataInput.hpp:166
bool readBoolean()
Read a boolean value from the DataInput.
Definition: DataInput.hpp:74
const uint8_t * currentBufferPosition() const
Get the pointer to current buffer position.
Definition: DataInput.hpp:399
void advanceCursor(size_t offset)
advance the cursor by given offset
Definition: DataInput.hpp:410
size_t getBytesRead() const
get the number of bytes read in the buffer
Definition: DataInput.hpp:402
double readDouble()
Read a double precision number from the DataInput.
Definition: DataInput.hpp:262
void readObject(std::shared_ptr< Serializable > &ptr)
Read a Serializable object from the DataInput.
Definition: DataInput.hpp:322
std::shared_ptr< Serializable > readObject()
Read a Serializable object from the DataInput.
Definition: DataInput.hpp:314
size_t getBytesRemaining() const
get the number of bytes remaining to be read in the buffer
Definition: DataInput.hpp:405
int8_t read()
Read a signed byte from the DataInput.
Definition: DataInput.hpp:66
float readFloat()
Read a float from the DataInput.
Definition: DataInput.hpp:249
void reset()
reset the cursor to the start of buffer
Definition: DataInput.hpp:416
int32_t readInt32()
Read a 32-bit signed integer from the DataInput.g.
Definition: DataInput.hpp:174
Thrown when the state of cache is manipulated to be illegal.
Definition: ExceptionTypes.hpp:64
A pool of connections to connect from a client to a set of Geode Cache Servers.
Definition: Pool.hpp:59
This base class is the superclass of all user objects in the cache that can be serialized.
Definition: Serializable.hpp:53

Apache Geode C++ Cache API Documentation