#pragma once

#ifndef GEODE_GFCPP_DATAINPUT_H_
#define GEODE_GFCPP_DATAINPUT_H_

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "gfcpp_globals.hpp"
#include "ExceptionTypes.hpp"
#include <string.h>
#include "gf_types.hpp"
#include "Serializable.hpp"
#include "CacheableString.hpp"

/**
 * @file
 */

#if GF_DEBUG_ASSERTS == 1
#define DINP_THROWONERROR_DEFAULT true
#else
#define DINP_THROWONERROR_DEFAULT false
#endif

#define checkBufferSize(x) _checkBufferSize(x, __LINE__)

namespace apache {
namespace geode {
namespace client {

extern int gf_sprintf(char* buffer, const char* fmt, ...);

/**
 * Provide operations for reading primitive data values, byte arrays,
 * strings, <code>Serializable</code> objects from a byte stream.
 * This class is intentionally not thread safe.
 * @remarks None of the output parameters in the methods below can be NULL
 *   unless otherwise noted.
 */
class CPPCACHE_EXPORT DataInput {
 public:
  /**
   * Read an unsigned byte from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the unsigned byte read from stream
   */
  inline void read(uint8_t* value) {
    checkBufferSize(1);
    *value = *(m_buf++);
  }

  /**
   * Read a signed byte from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the signed byte read from stream
   */
  inline void read(int8_t* value) {
    checkBufferSize(1);
    *value = *(m_buf++);
  }

  /**
   * Read a boolean value from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the boolean read from stream
   */
  inline void readBoolean(bool* value) {
    checkBufferSize(1);
    *value = (*m_buf == 1 ? true : false);
    m_buf++;
  }

  /**
   * Read the given number of unsigned bytes from the <code>DataInput</code>.
   * @remarks This method is complimentary to
   *   <code>DataOutput::writeBytesOnly</code> and, unlike
   *   <code>readBytes</code>, does not expect the length of array
   *   in the stream.
   *
   * @param buffer array to hold the bytes read from stream
   * @param len number of unsigned bytes to be read
   */
  inline void readBytesOnly(uint8_t* buffer, uint32_t len) {
    if (len > 0) {
      checkBufferSize(len);
      memcpy(buffer, m_buf, len);
      m_buf += len;
    }
  }

  /**
   * Read the given number of signed bytes from the <code>DataInput</code>.
   * @remarks This method is complimentary to
   *   <code>DataOutput::writeBytesOnly</code> and, unlike
   *   <code>readBytes</code>, does not expect the length of array
   *   in the stream.
   *
   * @param buffer array to hold the bytes read from stream
   * @param len number of signed bytes to be read
   */
  inline void readBytesOnly(int8_t* buffer, uint32_t len) {
    if (len > 0) {
      checkBufferSize(len);
      memcpy(buffer, m_buf, len);
      m_buf += len;
    }
  }

  /**
   * Read an array of unsigned bytes from the <code>DataInput</code>
   * expecting to find the length of array in the stream at the start.
   * @remarks This method is complimentary to
   *   <code>DataOutput::writeBytes</code>.
   *
   * @param bytes output array to hold the bytes read from stream; the array
   *   is allocated by this method
   * @param len output parameter to hold the length of array read from stream
   */
  inline void readBytes(uint8_t** bytes, int32_t* len) {
    int32_t length;
    readArrayLen(&length);
    *len = length;
    uint8_t* buffer = NULL;
    if (length > 0) {
      checkBufferSize(length);
      GF_NEW(buffer, uint8_t[length]);
      memcpy(buffer, m_buf, length);
      m_buf += length;
    }
    *bytes = buffer;
  }

  /**
   * Read an array of signed bytes from the <code>DataInput</code>
   * expecting to find the length of array in the stream at the start.
   * @remarks This method is complimentary to
   *   <code>DataOutput::writeBytes</code>.
   *
   * @param bytes output array to hold the bytes read from stream; the array
   *   is allocated by this method
   * @param len output parameter to hold the length of array read from stream
   */
  inline void readBytes(int8_t** bytes, int32_t* len) {
    int32_t length;
    readArrayLen(&length);
    *len = length;
    int8_t* buffer = NULL;
    if (length > 0) {
      checkBufferSize(length);
      GF_NEW(buffer, int8_t[length]);
      memcpy(buffer, m_buf, length);
      m_buf += length;
    }
    *bytes = buffer;
  }

  /**
   * Read a 16-bit unsigned integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 16-bit unsigned integer
   *   read from stream
   */
  inline void readInt(uint16_t* value) {
    checkBufferSize(2);
    uint16_t tmp = *(m_buf++);
    tmp = static_cast<uint16_t>((tmp << 8) | *(m_buf++));
    *value = tmp;
  }

  /**
   * Read a 32-bit unsigned integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 32-bit unsigned integer
   *   read from stream
   */
  inline void readInt(uint32_t* value) {
    checkBufferSize(4);
    uint32_t tmp = *(m_buf++);
    tmp = (tmp << 8) | *(m_buf++);
    tmp = (tmp << 8) | *(m_buf++);
    tmp = (tmp << 8) | *(m_buf++);
    *value = tmp;
  }

  /**
   * Read a 64-bit unsigned integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 64-bit unsigned integer
   *   read from stream
   */
  inline void readInt(uint64_t* value) {
    checkBufferSize(8);
    uint64_t tmp;
    if (sizeof(long) == 8) {
      tmp = *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
      tmp = (tmp << 8) | *(m_buf++);
    } else {
      uint32_t hword = *(m_buf++);
      hword = (hword << 8) | *(m_buf++);
      hword = (hword << 8) | *(m_buf++);
      hword = (hword << 8) | *(m_buf++);

      tmp = hword;
      hword = *(m_buf++);
      hword = (hword << 8) | *(m_buf++);
      hword = (hword << 8) | *(m_buf++);
      hword = (hword << 8) | *(m_buf++);
      tmp = (tmp << 32) | hword;
    }
    *value = tmp;
  }

  /**
   * Read a 16-bit signed integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 16-bit signed integer
   *   read from stream
   */
  inline void readInt(int16_t* value) {
    checkBufferSize(2);
    readInt(reinterpret_cast<uint16_t*>(value));
  }

  /**
   * Read a 32-bit signed integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 32-bit signed integer
   *   read from stream
   */
  inline void readInt(int32_t* value) {
    checkBufferSize(4);
    readInt(reinterpret_cast<uint32_t*>(value));
  }

  /**
   * Read a 64-bit signed integer from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the 64-bit signed integer
   *   read from stream
   */
  inline void readInt(int64_t* value) {
    checkBufferSize(8);
    readInt(reinterpret_cast<uint64_t*>(value));
  }

  /**
   * Read a 32-bit signed integer array length value from the
   * <code>DataInput</code> in a manner compatible with java server's
   * <code>DataSerializer.readArrayLength</code>.
   *
   * @param len output parameter to hold the 32-bit signed length
   *   read from stream
   */
  inline void readArrayLen(int32_t* len) {
    uint8_t code;
    read(&code);
    if (code == 0xFF) {
      *len = -1;
    } else {
      int32_t result = code;
      if (result > 252) {  // 252 is java's ((byte)-4 && 0xFF)
        if (code == 0xFE) {
          uint16_t val;
          readInt(&val);
          result = val;
        } else if (code == 0xFD) {
          uint32_t val;
          readInt(&val);
          result = val;
        } else {
          throw IllegalStateException("unexpected array length code");
        }
      }
      *len = result;
    }
  }

  /**
   * Decode a 64 bit integer as a variable length array.
   *
   * This is taken from the varint encoding in protobufs (BSD licensed).
   * See https://developers.google.com/protocol-buffers/docs/encoding
   */
  inline void readUnsignedVL(int64_t* value) {
    int32_t shift = 0;
    int64_t result = 0;
    while (shift < 64) {
      int8_t b;
      read(&b);
      result |= static_cast<int64_t>(b & 0x7F) << shift;
      if ((b & 0x80) == 0) {
        *value = result;
        return;
      }
      shift += 7;
    }
    throw IllegalStateException("Malformed variable length integer");
  }

  /**
   * Read a float from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the float read from stream
   */
  inline void readFloat(float* value) {
    checkBufferSize(4);
    union float_uint32_t {
      float f;
      uint32_t u;
    } v;
    readInt(&v.u);
    *value = v.f;
  }

  /**
   * Read a double precision number from the <code>DataInput</code>.
   *
   * @param value output parameter to hold the double precision number
   *   read from stream
   */
  inline void readDouble(double* value) {
    checkBufferSize(8);
    union double_uint64_t {
      double d;
      uint64_t ll;
    } v;
    readInt(&v.ll);
    *value = v.d;
  }

  /**
   * free the C string allocated by <code>readASCII</code>,
   * <code>readASCIIHuge</code>, <code>readUTF</code>,
   * <code>readUTFHuge</code> methods
   */
  static inline void freeUTFMemory(char* value) { delete[] value; }

  /**
   * free the wide-characted string allocated by <code>readASCII</code>,
   * <code>readASCIIHuge</code>, <code>readUTF</code>,
   * <code>readUTFHuge</code> methods
   */
  static inline void freeUTFMemory(wchar_t* value) { delete[] value; }

  /**
   * Allocates a c string buffer, and reads an ASCII string
   * having maximum length of 64K from <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Like <code>DataOutput::writeASCII</code> the maximum length supported by
   *   this method is 64K; use <code>readASCIIHuge</code> or
   *   <code>readBytes</code> to read strings of length larger than this.
   *
   * @param value output C string to hold the read characters; it is allocated
   *   by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readASCII(char** value, uint16_t* len = NULL) {
    uint16_t length;
    readInt(&length);
    checkBufferSize(length);
    if (len != NULL) {
      *len = length;
    }
    char* str;
    GF_NEW(str, char[length + 1]);
    *value = str;
    readBytesOnly(reinterpret_cast<int8_t*>(str), length);
    str[length] = '\0';
  }

  /**
   * Allocates a c string buffer, and reads an ASCII string
   * from <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Use this instead of <code>readUTF</code> when reading a string of length
   *   greater than 64K.
   *
   * @param value output C string to hold the read characters; it is allocated
   *   by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readASCIIHuge(char** value, uint32_t* len = NULL) {
    uint32_t length;
    readInt(&length);
    if (len != NULL) {
      *len = length;
    }
    char* str;
    GF_NEW(str, char[length + 1]);
    *value = str;
    readBytesOnly(reinterpret_cast<int8_t*>(str), length);
    str[length] = '\0';
  }

  /**
   * Allocates a c string buffer, and reads a java modified UTF-8
   * encoded string having maximum encoded length of 64K from
   * <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Like <code>DataOutput::writeUTF</code> the maximum length supported by
   *   this method is 64K; use <code>readAUTFHuge</code> to read strings of
   *   length larger than this.
   *
   * @param value output C string to hold the read characters; it is allocated
   *   by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readUTF(char** value, uint16_t* len = NULL) {
    uint16_t length;
    readInt(&length);
    checkBufferSize(length);
    uint16_t decodedLen =
        static_cast<uint16_t>(getDecodedLength(m_buf, length));
    if (len != NULL) {
      *len = decodedLen;
    }
    char* str;
    GF_NEW(str, char[decodedLen + 1]);
    *value = str;
    for (uint16_t i = 0; i < decodedLen; i++) {
      decodeChar(str++);
    }
    *str = '\0';  // null terminate for c-string.
  }

  /**
   * Reads a java modified UTF-8 encoded string having maximum encoded length
   * of 64K without reading the length which must be passed as a parameter.
   * Allocates a c string buffer, and deserializes into it. Sets integer at
   * length to hold the length of the string. Value is modified to point to the
   * new allocation. The chars are allocated as an array, so the caller must
   * use freeUTFMemory when done.
   * If len == NULL, then the decoded string length is not set.
   */
  inline void readUTFNoLen(wchar_t** value, uint16_t decodedLen) {
    wchar_t* str;
    GF_NEW(str, wchar_t[decodedLen + 1]);
    *value = str;
    for (uint16_t i = 0; i < decodedLen; i++) {
      decodeChar(str++);
    }
    *str = L'\0';  // null terminate for c-string.
  }

  /**
   * Allocates a c string buffer, and reads a java modified UTF-8
   * encoded string from <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Use this instead of <code>readUTF</code> when reading a string of length
   *   greater than 64K.
   *
   * @param value output C string to hold the read characters; it is allocated
   *   by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readUTFHuge(char** value, uint32_t* len = NULL) {
    uint32_t length;
    readInt(&length);
    if (len != NULL) {
      *len = length;
    }
    char* str;
    GF_NEW(str, char[length + 1]);
    *value = str;
    for (uint32_t i = 0; i < length; i++) {
      int8_t item;
      read(&item);  // ignore this - should be higher order zero byte
      read(&item);
      *str = item;
      str++;
    }
    *str = '\0';  // null terminate for c-string.
  }

  /**
   * Allocates a wide-character string buffer, and reads a java
   * modified UTF-8 encoded string having maximum encoded length of 64K from
   * <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Like <code>DataOutput::writeUTF</code> the maximum length supported by
   *   this method is 64K; use <code>readAUTFHuge</code> to read strings of
   *   length larger than this.
   *
   * @param value output wide-character string to hold the read characters;
   *   it is allocated by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readUTF(wchar_t** value, uint16_t* len = NULL) {
    uint16_t length;
    readInt(&length);
    checkBufferSize(length);
    uint16_t decodedLen =
        static_cast<uint16_t>(getDecodedLength(m_buf, length));
    if (len != NULL) {
      *len = decodedLen;
    }
    wchar_t* str;
    GF_NEW(str, wchar_t[decodedLen + 1]);
    *value = str;
    for (uint16_t i = 0; i < decodedLen; i++) {
      decodeChar(str++);
    }
    *str = L'\0';  // null terminate for c-string.
  }

  /**
   * Allocates a wide-character string buffer, and reads a java
   * modified UTF-8 encoded string from <code>DataInput</code> into it.
   * @remarks Sets integer at length to hold the strlen of the string. Value
   *   is modified to point to the new allocation. The chars are allocated as
   *   an array, so the caller must use <code>freeUTFMemory</code> when done.
   *   Use this instead of <code>readUTF</code> when reading a string of length
   *   greater than 64K.
   *
   * @param value output wide-character string to hold the read characters;
   *   it is allocated by this method
   * @param len output parameter to hold the number of characters read from
   *   stream; not set if NULL
   */
  inline void readUTFHuge(wchar_t** value, uint32_t* len = NULL) {
    uint32_t length;
    readInt(&length);
    if (len != NULL) {
      *len = length;
    }
    wchar_t* str;
    GF_NEW(str, wchar_t[length + 1]);
    *value = str;
    for (uint32_t i = 0; i < length; i++) {
      uint8_t hibyte;
      read(&hibyte);
      uint8_t lobyte;
      read(&lobyte);
      *str = ((static_cast<uint16_t>(hibyte)) << 8) |
             static_cast<uint16_t>(lobyte);
      str++;
    }
    *str = L'\0';  // null terminate for c-string.
  }

  /**
   * Read a <code>Serializable</code> object from the <code>DataInput</code>.
   * Null objects are handled.
   * This accepts an argument <code>throwOnError</code> that
   * specifies whether to check the type dynamically and throw a
   * <code>ClassCastException</code> when the cast fails.
   *
   * @param ptr The object to be read which is output by reference.
   *            The type of this must match the type of object that
   *            the application expects.
   * @param throwOnError Throw a <code>ClassCastException</code> when
   *                     the type of object does not match <code>ptr</code>.
   *                     Default is true when <code>GF_DEBUG_ASSERTS</code>
   *                     macro is set and false in normal case.
   * @throws ClassCastException When <code>dynCast</code> fails
   *                            for the given <code>ptr</code>.
   * @see dynCast
   * @see staticCast
   */
  template <class PTR>
  inline void readObject(SharedPtr<PTR>& ptr,
                         bool throwOnError = DINP_THROWONERROR_DEFAULT) {
    SerializablePtr sPtr;
    readObjectInternal(sPtr);
    if (throwOnError) {
      ptr = dynCast<SharedPtr<PTR> >(sPtr);
    } else {
      ptr = staticCast<SharedPtr<PTR> >(sPtr);
    }
  }

  inline bool readNativeBool() {
    int8_t typeId = 0;
    read(&typeId);

    bool val;
    readBoolean(&val);
    return val;
  }

  inline int32_t readNativeInt32() {
    int8_t typeId = 0;
    read(&typeId);

    int32_t val;
    readInt(&val);
    return val;
  }

  inline bool readNativeString(CacheableStringPtr& csPtr) {
    int8_t typeId = 0;
    read(&typeId);
    int64_t compId = typeId;
    if (compId == GeodeTypeIds::NullObj) {
      csPtr = NULLPTR;
    } else if (compId == GeodeTypeIds::CacheableNullString) {
      csPtr = CacheableStringPtr(dynamic_cast<CacheableString*>(
          CacheableString::createDeserializable()));
    } else if (compId ==
               apache::geode::client::GeodeTypeIds::CacheableASCIIString) {
      csPtr = CacheableStringPtr(dynamic_cast<CacheableString*>(
          CacheableString::createDeserializable()));
      csPtr.ptr()->fromData(*this);
    } else if (compId ==
               apache::geode::client::GeodeTypeIds::CacheableASCIIStringHuge) {
      csPtr = CacheableStringPtr(dynamic_cast<CacheableString*>(
          CacheableString::createDeserializableHuge()));
      csPtr.ptr()->fromData(*this);
    } else if (compId == apache::geode::client::GeodeTypeIds::CacheableString) {
      csPtr = CacheableStringPtr(dynamic_cast<CacheableString*>(
          CacheableString::createUTFDeserializable()));
      csPtr.ptr()->fromData(*this);
    } else if (compId ==
               apache::geode::client::GeodeTypeIds::CacheableStringHuge) {
      csPtr = CacheableStringPtr(dynamic_cast<CacheableString*>(
          CacheableString::createUTFDeserializableHuge()));
      csPtr.ptr()->fromData(*this);
    } else {
      LOGDEBUG("In readNativeString something is wrong while expecting string");
      rewindCursor(1);
      csPtr = NULLPTR;
      return false;
    }
    return true;
  }

  inline void readDirectObject(SerializablePtr& ptr, int8_t typeId = -1) {
    readObjectInternal(ptr, typeId);
  }

  /**
   * Read a <code>Serializable</code> object from the <code>DataInput</code>.
   * Null objects are handled.
   */
  inline void readObject(SerializablePtr& ptr) { readObjectInternal(ptr); }

  inline void readObject(wchar_t* value) {
    uint16_t temp = 0;
    readInt(&temp);
    *value = static_cast<wchar_t>(temp);
  }

  inline void readObject(bool* value) { readBoolean(value); }

  inline void readObject(int8_t* value) { read(value); }

  inline void readObject(int16_t* value) { readInt(value); }

  inline void readObject(int32_t* value) { readInt(value); }

  inline void readObject(int64_t* value) { readInt(value); }

  inline void readObject(float* value) { readFloat(value); }

  inline void readObject(double* value) { readDouble(value); }

  inline void readCharArray(char** value, int32_t& length) {
    int arrayLen = 0;
    readArrayLen(&arrayLen);
    length = arrayLen;
    char* objArray = NULL;
    if (arrayLen > 0) {
      objArray = new char[arrayLen];
      int i = 0;
      for (i = 0; i < arrayLen; i++) {
        char tmp = 0;
        readPdxChar(&tmp);
        objArray[i] = tmp;
      }
      *value = objArray;
    }
  }

  inline void readWideCharArray(wchar_t** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readBooleanArray(bool** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readByteArray(int8_t** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readShortArray(int16_t** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readIntArray(int32_t** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readLongArray(int64_t** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readFloatArray(float** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readDoubleArray(double** value, int32_t& length) {
    readObject(value, length);
  }

  inline void readString(char** value) {
    int8_t typeId;
    read(&typeId);

    // Check for NULL String
    if (typeId == GeodeTypeIds::CacheableNullString) {
      *value = NULL;
      return;
    }
    /*
    if (typeId == GeodeTypeIds::CacheableString) {
      readUTF(value);
    } else {
      readUTFHuge(value);
    }
    */
    if (typeId == static_cast<int8_t>(GeodeTypeIds::CacheableASCIIString) ||
        typeId == static_cast<int8_t>(GeodeTypeIds::CacheableString)) {
      // readUTF( value);
      readASCII(value);
      // m_len = shortLen;
    } else if (typeId == static_cast<int8_t>(
                             GeodeTypeIds::CacheableASCIIStringHuge) ||
               typeId ==
                   static_cast<int8_t>(GeodeTypeIds::CacheableStringHuge)) {
      // readUTFHuge( value);
      readASCIIHuge(value);
    } else {
      throw IllegalArgumentException(
          "DI readString error:: String type not supported ");
    }
  }

  inline void readWideString(wchar_t** value) {
    int8_t typeId;
    read(&typeId);

    // Check for NULL String
    if (typeId == GeodeTypeIds::CacheableNullString) {
      *value = NULL;
      return;
    }

    if (typeId == static_cast<int8_t>(GeodeTypeIds::CacheableASCIIString) ||
        typeId == static_cast<int8_t>(GeodeTypeIds::CacheableString)) {
      readUTF(value);
    } else if (typeId == static_cast<int8_t>(
                             GeodeTypeIds::CacheableASCIIStringHuge) ||
               typeId ==
                   static_cast<int8_t>(GeodeTypeIds::CacheableStringHuge)) {
      readUTFHuge(value);
    } else {
      throw IllegalArgumentException(
          "DI readWideString error:: WideString type provided is not "
          "supported ");
    }
  }

  inline void readStringArray(char*** strArray, int32_t& length) {
    int32_t arrLen;
    readArrayLen(&arrLen);
    length = arrLen;
    if (arrLen == -1) {
      *strArray = NULL;
      return;
    } else {
      char** tmpArray;
      GF_NEW(tmpArray, char * [arrLen]);
      for (int i = 0; i < arrLen; i++) {
        readString(&tmpArray[i]);
      }
      *strArray = tmpArray;
    }
  }

  inline void readWideStringArray(wchar_t*** strArray, int32_t& length) {
    int32_t arrLen;
    readArrayLen(&arrLen);
    length = arrLen;
    if (arrLen == -1) {
      *strArray = NULL;
      return;
    } else {
      wchar_t** tmpArray;
      GF_NEW(tmpArray, wchar_t * [arrLen]);
      for (int i = 0; i < arrLen; i++) {
        readWideString(&tmpArray[i]);
      }
      *strArray = tmpArray;
    }
  }

  inline void readArrayOfByteArrays(int8_t*** arrayofBytearr,
                                    int32_t& arrayLength,
                                    int32_t** elementLength) {
    int32_t arrLen;
    readArrayLen(&arrLen);
    arrayLength = arrLen;

    if (arrLen == -1) {
      *arrayofBytearr = NULL;
      return;
    } else {
      int8_t** tmpArray;
      int32_t* tmpLengtharr;
      GF_NEW(tmpArray, int8_t * [arrLen]);
      GF_NEW(tmpLengtharr, int32_t[arrLen]);
      for (int i = 0; i < arrLen; i++) {
        readBytes(&tmpArray[i], &tmpLengtharr[i]);
      }
      *arrayofBytearr = tmpArray;
      *elementLength = tmpLengtharr;
    }
  }

  /**
   * Get the length required to represent a given UTF-8 encoded string
   * (created using {@link DataOutput::writeUTF} or
   * <code>java.io.DataOutput.writeUTF</code>) in wide-character format.
   *
   * @param value The UTF-8 encoded stream.
   * @param length The length of the stream to be read.
   * @return The length of the decoded string.
   * @see DataOutput::getEncodedLength
   */
  static int32_t getDecodedLength(const uint8_t* value, int32_t length) {
    const uint8_t* end = value + length;
    int32_t decodedLen = 0;
    while (value < end) {
      // get next byte unsigned
      int32_t b = *value++ & 0xff;
      int32_t k = b >> 5;
      // classify based on the high order 3 bits
      switch (k) {
        case 6: {
          value++;
          break;
        }
        case 7: {
          value += 2;
          break;
        }
        default:
          break;
      }
      decodedLen += 1;
    }
    if (value > end) decodedLen--;
    return decodedLen;
  }

  /** constructor given a pre-allocated byte array with size */
  DataInput(const uint8_t* m_buffer, int32_t len)
      : m_buf(m_buffer),
        m_bufHead(m_buffer),
        m_bufLength(len),
        m_poolName(NULL) {}

  /** destructor */
  ~DataInput() {}

  /**
   * Get the pointer to current buffer position. This should be treated
   * as readonly and modification of contents using this internal pointer
   * has undefined behavior.
   */
  inline const uint8_t* currentBufferPosition() const { return m_buf; }

  /** get the number of bytes read in the buffer */
  inline int32_t getBytesRead() const {
    return static_cast<int32_t>(m_buf - m_bufHead);
  }

  /** get the number of bytes remaining to be read in the buffer */
  inline int32_t getBytesRemaining() const {
    return (m_bufLength - getBytesRead());
  }

  /** advance the cursor by given offset */
  inline void advanceCursor(int32_t offset) { m_buf += offset; }

  /** rewind the cursor by given offset */
  inline void rewindCursor(int32_t offset) { m_buf -= offset; }

  /** reset the cursor to the start of buffer */
  inline void reset() { m_buf = m_bufHead; }

  inline void setBuffer() {
    m_buf = currentBufferPosition();
    m_bufLength = getBytesRemaining();
  }

  inline void resetPdx(int32_t offset) { m_buf = m_bufHead + offset; }

  inline int32_t getPdxBytes() const { return m_bufLength; }

  static uint8_t* getBufferCopy(const uint8_t* from, uint32_t length) {
    uint8_t* result;
    GF_NEW(result, uint8_t[length]);
    memcpy(result, from, length);

    return result;
  }

  inline void reset(int32_t offset) { m_buf = m_bufHead + offset; }

  uint8_t* getBufferCopyFrom(const uint8_t* from, uint32_t length) {
    uint8_t* result;
    GF_NEW(result, uint8_t[length]);
    memcpy(result, from, length);

    return result;
  }

  /*
   * This is for internal use
   */
  const char* getPoolName() { return m_poolName; }

  /*
   * This is for internal use
   */
  void setPoolName(const char* poolName) { m_poolName = poolName; }

 private:
  const uint8_t* m_buf;
  const uint8_t* m_bufHead;
  int32_t m_bufLength;
  const char* m_poolName;

  void readObjectInternal(SerializablePtr& ptr, int8_t typeId = -1);

  template <typename mType>
  void readObject(mType** value, int32_t& length) {
    int arrayLen;
    readArrayLen(&arrayLen);
    length = arrayLen;
    mType* objArray;
    if (arrayLen > 0) {
      objArray = new mType[arrayLen];
      int i = 0;
      for (i = 0; i < arrayLen; i++) {
        mType tmp = 0;
        readObject(&tmp);
        objArray[i] = tmp;  //*value[i] = tmp;
      }
      *value = objArray;
    }
  }

  inline void readPdxChar(char* value) {
    int16_t val = 0;
    readInt(&val);
    *value = static_cast<char>(val);
  }

  inline void _checkBufferSize(int32_t size, int32_t line) {
    if ((m_bufLength - (m_buf - m_bufHead)) < size) {
      char exMsg[128];
      gf_sprintf(exMsg,
                 "DataInput: attempt to read beyond buffer at line %d: "
                 "available buffer size %d, attempted read of size %d ",
                 line, m_bufLength - (m_buf - m_bufHead), size);
      throw OutOfRangeException(exMsg);
    }
  }

  inline void decodeChar(char* str) {
    uint8_t bt = *(m_buf++);
    if (bt & 0x80) {
      if (bt & 0x20) {
        // three bytes.
        *str =
            static_cast<char>(((bt & 0x0f) << 12) | (((*m_buf++) & 0x3f) << 6));
        *str |= static_cast<char>((*m_buf++) & 0x3f);
      } else {
        // two bytes.
        *str = static_cast<char>(((bt & 0x1f) << 6) | ((*m_buf++) & 0x3f));
      }
    } else {
      // single byte...
      *str = bt;
    }
  }

  inline void decodeChar(wchar_t* str) {
    // get next byte unsigned
    int32_t b = *m_buf++ & 0xff;
    int32_t k = b >> 5;
    // classify based on the high order 3 bits
    switch (k) {
      case 6: {
        // two byte encoding
        // 110yyyyy 10xxxxxx
        // use low order 6 bits
        int32_t y = b & 0x1f;
        // use low order 6 bits of the next byte
        // It should have high order bits 10, which we don't check.
        int32_t x = *m_buf++ & 0x3f;
        // 00000yyy yyxxxxxx
        *str = (y << 6 | x);
        break;
      }
      case 7: {
        // three byte encoding
        // 1110zzzz 10yyyyyy 10xxxxxx
        // assert ( b & 0x10 )
        //     == 0 : "UTF8Decoder does not handle 32-bit characters";
        // use low order 4 bits
        int32_t z = b & 0x0f;
        // use low order 6 bits of the next byte
        // It should have high order bits 10, which we don't check.
        int32_t y = *m_buf++ & 0x3f;
        // use low order 6 bits of the next byte
        // It should have high order bits 10, which we don't check.
        int32_t x = *m_buf++ & 0x3f;
        // zzzzyyyy yyxxxxxx
        int32_t asint = (z << 12 | y << 6 | x);
        *str = asint;
        break;
      }
      default:
        // one byte encoding
        // 0xxxxxxx
        // use just low order 7 bits
        // 00000000 0xxxxxxx
        *str = (b & 0x7f);
        break;
    }
  }

  // disable other constructors and assignment
  DataInput();
  DataInput(const DataInput&);
  DataInput& operator=(const DataInput&);
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif // GEODE_GFCPP_DATAINPUT_H_
