VMware GemFire Native C++ Reference  10.1.5
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 
39 namespace apache {
40 namespace geode {
41 namespace client {
42 
43 class Cache;
44 class CacheableString;
45 class DataInput;
46 class Serializable;
47 class SerializationRegistry;
48 class CacheImpl;
49 class DataInputInternal;
50 class Pool;
51 
59 class APACHE_GEODE_EXPORT DataInput {
60  public:
66  inline int8_t read() {
67  _GEODE_CHECK_BUFFER_SIZE(1);
68  return readNoCheck();
69  }
70 
76  inline bool readBoolean() {
77  _GEODE_CHECK_BUFFER_SIZE(1);
78  return *(m_buf++) == 1 ? true : false;
79  }
80 
91  inline void readBytesOnly(uint8_t* buffer, size_t len) {
92  if (len > 0) {
93  _GEODE_CHECK_BUFFER_SIZE(len);
94  std::memcpy(buffer, m_buf, len);
95  m_buf += len;
96  }
97  }
98 
109  inline void readBytesOnly(int8_t* buffer, size_t len) {
110  if (len > 0) {
111  _GEODE_CHECK_BUFFER_SIZE(len);
112  std::memcpy(buffer, m_buf, len);
113  m_buf += len;
114  }
115  }
116 
127  inline void readBytes(uint8_t** bytes, int32_t* len) {
128  auto length = readArrayLength();
129  *len = length;
130  uint8_t* buffer = nullptr;
131  if (length > 0) {
132  _GEODE_CHECK_BUFFER_SIZE(length);
133  _GEODE_NEW(buffer, uint8_t[length]);
134  std::memcpy(buffer, m_buf, length);
135  m_buf += length;
136  }
137  *bytes = buffer;
138  }
139 
150  inline void readBytes(int8_t** bytes, int32_t* len) {
151  auto length = readArrayLength();
152  *len = length;
153  int8_t* buffer = nullptr;
154  if (length > 0) {
155  _GEODE_CHECK_BUFFER_SIZE(length);
156  _GEODE_NEW(buffer, int8_t[length]);
157  std::memcpy(buffer, m_buf, length);
158  m_buf += length;
159  }
160  *bytes = buffer;
161  }
162 
168  inline int16_t readInt16() {
169  _GEODE_CHECK_BUFFER_SIZE(2);
170  return readInt16NoCheck();
171  }
172 
179  inline int32_t readInt32() {
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++);
185  return tmp;
186  }
187 
194  inline int64_t readInt64() {
195  _GEODE_CHECK_BUFFER_SIZE(8);
196  int64_t tmp;
197  tmp = *(m_buf++);
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++);
205  return tmp;
206  }
207 
216  inline int32_t readArrayLength() {
217  const uint8_t code = read();
218  if (code == 0xFF) {
219  return -1;
220  } else {
221  int32_t result = code;
222  if (result > 252) { // 252 is java's ((byte)-4 && 0xFF)
223  if (code == 0xFE) {
224  uint16_t val = readInt16();
225  result = val;
226  } else if (code == 0xFD) {
227  uint32_t val = readInt32();
228  result = val;
229  } else {
230  throw IllegalStateException("unexpected array length code");
231  }
232  }
233  return result;
234  }
235  }
236 
243  inline int64_t readUnsignedVL() {
244  int32_t shift = 0;
245  int64_t result = 0;
246  while (shift < 64) {
247  const auto b = read();
248  result |= static_cast<int64_t>(b & 0x7F) << shift;
249  if ((b & 0x80) == 0) {
250  return result;
251  }
252  shift += 7;
253  }
254  throw IllegalStateException("Malformed variable length integer");
255  }
256 
262  inline float readFloat() {
263  _GEODE_CHECK_BUFFER_SIZE(4);
264  union float_uint32_t {
265  float f;
266  uint32_t u;
267  } v;
268  v.u = readInt32();
269  return v.f;
270  }
271 
278  inline double readDouble() {
279  _GEODE_CHECK_BUFFER_SIZE(8);
280  union double_uint64_t {
281  double d;
282  uint64_t ll;
283  } v;
284  v.ll = readInt64();
285  return v.d;
286  }
287 
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);
292  return value;
293  }
294 
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());
299  switch (type) {
300  case internal::DSCode::CacheableString:
301  readJavaModifiedUtf8(value);
302  break;
303  case internal::DSCode::CacheableStringHuge:
304  readUtf16Huge(value);
305  break;
306  case internal::DSCode::CacheableASCIIString:
307  readAscii(value);
308  break;
309  case internal::DSCode::CacheableASCIIStringHuge:
310  readAsciiHuge(value);
311  break;
312  case internal::DSCode::CacheableNullString:
313  // empty string
314  break;
315  // TODO: What's the right response here?
316  default:
317  break;
318  }
319  return value;
320  }
321 
322  inline bool readNativeBool() {
323  read(); // ignore type id
324  return readBoolean();
325  }
326 
327  inline int32_t readNativeInt32() {
328  read(); // ignore type id
329  return readInt32();
330  }
331 
332  inline std::shared_ptr<Serializable> readDirectObject(int8_t typeId = -1) {
333  return readObjectInternal(typeId);
334  }
335 
341  inline std::shared_ptr<Serializable> readObject() {
342  return readObjectInternal();
343  }
344 
349  inline void readObject(std::shared_ptr<Serializable>& ptr) {
350  ptr = readObjectInternal();
351  }
352 
353  inline void readObject(char16_t* value) { *value = readInt16(); }
354 
355  inline void readObject(bool* value) { *value = readBoolean(); }
356 
357  inline void readObject(int8_t* value) { *value = read(); }
358 
359  inline void readObject(int16_t* value) { *value = readInt16(); }
360 
361  inline void readObject(int32_t* value) { *value = readInt32(); }
362 
363  inline void readObject(int64_t* value) { *value = readInt64(); }
364 
365  inline void readObject(float* value) { *value = readFloat(); }
366 
367  inline void readObject(double* value) { *value = readDouble(); }
368 
369  inline std::vector<char16_t> readCharArray() { return readArray<char16_t>(); }
370 
371  inline std::vector<bool> readBooleanArray() { return readArray<bool>(); }
372 
373  inline std::vector<int8_t> readByteArray() { return readArray<int8_t>(); }
374 
375  inline std::vector<int16_t> readShortArray() { return readArray<int16_t>(); }
376 
377  inline std::vector<int32_t> readIntArray() { return readArray<int32_t>(); }
378 
379  inline std::vector<int64_t> readLongArray() { return readArray<int64_t>(); }
380 
381  inline std::vector<float> readFloatArray() { return readArray<float>(); }
382 
383  inline std::vector<double> readDoubleArray() { return readArray<double>(); }
384 
385  inline std::vector<std::string> readStringArray() {
386  std::vector<std::string> value;
387 
388  auto arrLen = readArrayLength();
389  if (arrLen > 0) {
390  value.reserve(arrLen);
391  for (int i = 0; i < arrLen; i++) {
392  value.push_back(readString());
393  }
394  }
395 
396  return value;
397  }
398 
399  inline void readArrayOfByteArrays(int8_t*** arrayofBytearr,
400  int32_t& arrayLength,
401  int32_t** elementLength) {
402  auto arrLen = readArrayLength();
403  arrayLength = arrLen;
404 
405  if (arrLen == -1) {
406  *arrayofBytearr = nullptr;
407  return;
408  } else {
409  int8_t** tmpArray;
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]);
415  }
416  *arrayofBytearr = tmpArray;
417  *elementLength = tmpLengtharr;
418  }
419  }
420 
426  inline const uint8_t* currentBufferPosition() const { return m_buf; }
427 
429  inline size_t getBytesRead() const { return m_buf - m_bufHead; }
430 
432  inline size_t getBytesRemaining() const {
433  return (m_bufLength - getBytesRead());
434  }
435 
437  inline void advanceCursor(size_t offset) { m_buf += offset; }
438 
440  inline void rewindCursor(size_t offset) { m_buf -= offset; }
441 
443  inline void reset() { m_buf = m_bufHead; }
444 
445  inline void setBuffer() {
446  m_buf = currentBufferPosition();
447  m_bufLength = getBytesRemaining();
448  }
449 
450  inline void resetPdx(size_t offset) { m_buf = m_bufHead + offset; }
451 
452  inline size_t getPdxBytes() const { return m_bufLength; }
453 
454  static uint8_t* getBufferCopy(const uint8_t* from, size_t length) {
455  uint8_t* result;
456  _GEODE_NEW(result, uint8_t[length]);
457  std::memcpy(result, from, length);
458 
459  return result;
460  }
461 
462  inline void reset(size_t offset) { m_buf = m_bufHead + offset; }
463 
464  uint8_t* getBufferCopyFrom(const uint8_t* from, size_t length) {
465  uint8_t* result;
466  _GEODE_NEW(result, uint8_t[length]);
467  std::memcpy(result, from, length);
468 
469  return result;
470  }
471 
472  virtual Cache* getCache() const;
473 
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;
480 
481  protected:
483  DataInput(const uint8_t* buffer, size_t len, const CacheImpl* cache,
484  Pool* pool);
485 
486  virtual const SerializationRegistry& getSerializationRegistry() const;
487 
488  private:
489  const uint8_t* m_buf;
490  const uint8_t* m_bufHead;
491  size_t m_bufLength;
492  Pool* m_pool;
493  const CacheImpl* m_cache;
494 
495  std::shared_ptr<Serializable> readObjectInternal(int8_t typeId = -1);
496 
497  template <typename mType>
498  void readObject(mType** value, int32_t& length) {
499  auto arrayLen = readArrayLength();
500  length = arrayLen;
501  mType* objArray;
502  if (arrayLen > 0) {
503  objArray = new mType[arrayLen];
504  int i = 0;
505  for (i = 0; i < arrayLen; i++) {
506  mType tmp = 0;
507  readObject(&tmp);
508  objArray[i] = tmp; //*value[i] = tmp;
509  }
510  *value = objArray;
511  }
512  }
513 
514  template <typename T>
515  std::vector<T> readArray() {
516  auto arrayLen = readArrayLength();
517  std::vector<T> objArray;
518  if (arrayLen >= 0) {
519  objArray.reserve(arrayLen);
520  int i = 0;
521  for (i = 0; i < arrayLen; i++) {
522  T tmp = 0;
523  readObject(&tmp);
524  objArray.push_back(tmp);
525  }
526  }
527  return objArray;
528  }
529 
530  inline char readPdxChar() { return static_cast<char>(readInt16()); }
531 
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));
539  }
540  }
541 
542  inline int8_t readNoCheck() { return *(m_buf++); }
543 
544  inline int16_t readInt16NoCheck() {
545  int16_t tmp = *(m_buf++);
546  tmp = static_cast<int16_t>((tmp << 8) | *(m_buf++));
547  return tmp;
548  }
549 
550  template <class CharT, class... Tail>
551  inline void readAscii(std::basic_string<CharT, Tail...>& value,
552  size_t length) {
553  _GEODE_CHECK_BUFFER_SIZE(length);
554  value.reserve(length);
555  while (length-- > 0) {
556  // blindly assumes ASCII so mask off 7 bits
557  value += readNoCheck() & 0x7F;
558  }
559  }
560 
561  template <class CharT, class... Tail>
562  inline void readAscii(std::basic_string<CharT, Tail...>& value) {
563  readAscii(value, static_cast<uint16_t>(readInt16()));
564  }
565 
566  template <class CharT, class... Tail>
567  inline void readAsciiHuge(std::basic_string<CharT, Tail...>& value) {
568  readAscii(value, static_cast<uint32_t>(readInt32()));
569  }
570 
571  template <class _CharT, class _Traits, class _Allocator>
572  void readJavaModifiedUtf8(
573  std::basic_string<_CharT, _Traits, _Allocator>& value);
574 
575  template <class _Traits, class _Allocator>
576  void readJavaModifiedUtf8(
577  std::basic_string<char16_t, _Traits, _Allocator>& value);
578 
579  template <class _Traits, class _Allocator>
580  void readJavaModifiedUtf8(
581  std::basic_string<char, _Traits, _Allocator>& value);
582 
583  template <class _Traits, class _Allocator>
584  void readJavaModifiedUtf8(
585  std::basic_string<char32_t, _Traits, _Allocator>& value);
586 
587  template <class _Traits, class _Allocator>
588  inline void readJavaModifiedUtf8(
589  std::basic_string<wchar_t, _Traits, _Allocator>& value) {
590  // TODO string optimize
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;
595 
596  auto tmp = std::basic_string<_WcharT>();
597  readJavaModifiedUtf8(tmp);
598  value.assign(reinterpret_cast<const wchar_t*>(tmp.data()), tmp.length());
599  }
600 
601  template <class _CharT, class _Traits, class _Allocator>
602  void readUtf16Huge(std::basic_string<_CharT, _Traits, _Allocator>& value);
603 
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();
612  }
613  }
614 
615  template <class _Traits, class _Allocator>
616  void readUtf16Huge(std::basic_string<char, _Traits, _Allocator>& value);
617 
618  template <class _Traits, class _Allocator>
619  void readUtf16Huge(std::basic_string<char32_t, _Traits, _Allocator>& value);
620 
621  template <class _Traits, class _Allocator>
622  inline void readUtf16Huge(
623  std::basic_string<wchar_t, _Traits, _Allocator>& value) {
624  // TODO string optimize
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;
629 
630  auto tmp = std::basic_string<_WcharT>();
631  readUtf16Huge(tmp);
632  value.assign(reinterpret_cast<const wchar_t*>(tmp.data()), tmp.length());
633  }
634 
635  Pool* getPool() const { return m_pool; }
636 
637  friend Cache;
638  friend CacheImpl;
639  friend DataInputInternal;
640  friend CacheableString;
641 };
642 } // namespace client
643 } // namespace geode
644 } // namespace apache
645 
646 #endif // GEODE_DATAINPUT_H_
apache::geode::client::DataInput::readArrayLength
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:216
apache::geode::client::DataInput::rewindCursor
void rewindCursor(size_t offset)
rewind the cursor by given offset
Definition: DataInput.hpp:440
apache::geode::client::Pool
A pool of connections to connect from a client to a set of Geode Cache Servers.
Definition: Pool.hpp:63
apache::geode::client::DataInput::readBytes
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:127
apache::geode::client::IllegalStateException
Thrown when the state of cache is manipulated to be illegal.
Definition: ExceptionTypes.hpp:64
apache::geode::client::DataInput::currentBufferPosition
const uint8_t * currentBufferPosition() const
Get the pointer to current buffer position.
Definition: DataInput.hpp:426
apache::geode::client::DataInput::advanceCursor
void advanceCursor(size_t offset)
advance the cursor by given offset
Definition: DataInput.hpp:437
apache::geode::client::Serializable
This base class is the superclass of all user objects in the cache that can be serialized.
Definition: Serializable.hpp:53
apache::geode::client::DataInput::readBytesOnly
void readBytesOnly(int8_t *buffer, size_t len)
Read the given number of signed bytes from the DataInput.
Definition: DataInput.hpp:109
apache::geode::client::DataInput::readBytes
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:150
apache::geode::client::DataInput::readBytesOnly
void readBytesOnly(uint8_t *buffer, size_t len)
Read the given number of unsigned bytes from the DataInput.
Definition: DataInput.hpp:91
apache::geode::client::DataInput::readInt64
int64_t readInt64()
Read a 64-bit signed integer from the DataInput.
Definition: DataInput.hpp:194
apache::geode::client::DataInput::read
int8_t read()
Read a signed byte from the DataInput.
Definition: DataInput.hpp:66
apache::geode::client::DataInput::readObject
void readObject(std::shared_ptr< Serializable > &ptr)
Read a Serializable object from the DataInput.
Definition: DataInput.hpp:349
apache::geode::client::DataInput::readFloat
float readFloat()
Read a float from the DataInput.
Definition: DataInput.hpp:262
apache::geode::client::DataInput::readObject
std::shared_ptr< Serializable > readObject()
Read a Serializable object from the DataInput.
Definition: DataInput.hpp:341
apache::geode::client::DataInput::readInt16
int16_t readInt16()
Read a 16-bit signed integer from the DataInput.
Definition: DataInput.hpp:168
apache::geode::client::DataInput
Provide operations for reading primitive data values, byte arrays, strings, Serializable objects from...
Definition: DataInput.hpp:59
apache::geode::client::DataInput::readBoolean
bool readBoolean()
Read a boolean value from the DataInput.
Definition: DataInput.hpp:76
apache::geode::client::DataInput::readDouble
double readDouble()
Read a double precision number from the DataInput.
Definition: DataInput.hpp:278
apache::geode::client::DataInput::getBytesRead
size_t getBytesRead() const
get the number of bytes read in the buffer
Definition: DataInput.hpp:429
apache::geode::client::DataInput::reset
void reset()
reset the cursor to the start of buffer
Definition: DataInput.hpp:443
apache::geode::client::DataInput::readUnsignedVL
int64_t readUnsignedVL()
Decode a 64 bit integer as a variable length array.
Definition: DataInput.hpp:243
apache::geode::client::DataInput::getBytesRemaining
size_t getBytesRemaining() const
get the number of bytes remaining to be read in the buffer
Definition: DataInput.hpp:432
apache::geode::client::DataInput::readInt32
int32_t readInt32()
Read a 32-bit signed integer from the DataInput.g.
Definition: DataInput.hpp:179

Apache Geode C++ Cache API Documentation