/*
 * 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 "begin_native.hpp"
#include <geode/Cache.hpp>
#include "SerializationRegistry.hpp"
#include "CacheRegionHelper.hpp"
#include "CacheImpl.hpp"
#include "DataInputInternal.hpp"
#include "end_native.hpp"


#include "DataInput.hpp"
#include "Cache.hpp"
#include "CacheableString.hpp"
#include "CacheableHashMap.hpp"
#include "CacheableStack.hpp"
#include "CacheableVector.hpp"
#include "CacheableArrayList.hpp"
#include "CacheableIDentityHashMap.hpp"
#include "CacheableDate.hpp"
#include "CacheableObjectArray.hpp"
#include "IDataSerializable.hpp"
#include "Serializable.hpp"
#include "impl/PdxHelper.hpp"
#include "impl/PdxWrapper.hpp"

using namespace System;
using namespace System::IO;
using namespace apache::geode::client;

namespace Apache
{
  namespace Geode
  {
    namespace Client
    {
      using namespace msclr::interop;
      namespace native = apache::geode::client;

      DataInput::DataInput(System::Byte* buffer, size_t size, Apache::Geode::Client::Cache^ cache)
      {
        m_ispdxDesrialization = false;
        m_isRootObjectPdx = false;
        m_cache = cache;
        if (buffer != nullptr && size > 0) {
          _GF_MG_EXCEPTION_TRY2

          m_nativeptr = gcnew native_conditional_unique_ptr<native::DataInput>(
            std::make_unique<native::DataInput>(cache->GetNative()->createDataInput(buffer, size)));
          m_cursor = 0;
          m_isManagedObject = false;
          m_forStringDecode = gcnew array<Char>(100);

          try
          {
            m_buffer = const_cast<System::Byte*>(m_nativeptr->get()->currentBufferPosition());
            m_bufferLength = m_nativeptr->get()->getBytesRemaining();
          }
          finally
          {
            GC::KeepAlive(m_nativeptr);
          }

          _GF_MG_EXCEPTION_CATCH_ALL2
        }
        else {
          throw gcnew IllegalArgumentException("DataInput.ctor(): "
                                               "provided buffer is null or empty");
        }
      }

      DataInput::DataInput(array<Byte>^ buffer, Apache::Geode::Client::Cache^ cache)
      {
        m_ispdxDesrialization = false;
        m_isRootObjectPdx = false;
        m_cache =  cache;
        if (buffer != nullptr && buffer->Length > 0) {
          _GF_MG_EXCEPTION_TRY2

            System::Int32 len = buffer->Length;
          _GEODE_NEW(m_buffer, System::Byte[len]);
          pin_ptr<const Byte> pin_buffer = &buffer[0];
          memcpy(m_buffer, (void*)pin_buffer, len);
          m_nativeptr = gcnew native_conditional_unique_ptr<native::DataInput>(
            std::make_unique<native::DataInput>(m_cache->GetNative()->createDataInput(m_buffer, len)));
          m_cursor = 0;
          m_isManagedObject = false;
          m_forStringDecode = gcnew array<Char>(100);

          try
          {
            m_buffer = const_cast<System::Byte*>(m_nativeptr->get()->currentBufferPosition());
            m_bufferLength = m_nativeptr->get()->getBytesRemaining();
          }
          finally
          {
            GC::KeepAlive(m_nativeptr);
          }

          _GF_MG_EXCEPTION_CATCH_ALL2
        }
        else {
          throw gcnew IllegalArgumentException("DataInput.ctor(): "
                                               "provided buffer is null or empty");
        }
      }

      DataInput::DataInput(array<Byte>^ buffer, size_t len, Apache::Geode::Client::Cache^ cache)
      {
        m_ispdxDesrialization = false;
        m_isRootObjectPdx = false;
        m_cache = cache;
        if (buffer != nullptr) {
          if (len == 0 || (System::Int32)len > buffer->Length) {
            throw gcnew IllegalArgumentException(String::Format(
              "DataInput.ctor(): given length {0} is zero or greater than "
              "size of buffer {1}", len, buffer->Length));
          }
          //m_bytes = gcnew array<Byte>(len);
          //System::Array::Copy(buffer, 0, m_bytes, 0, len);
          _GF_MG_EXCEPTION_TRY2

            _GEODE_NEW(m_buffer, System::Byte[len]);
          pin_ptr<const Byte> pin_buffer = &buffer[0];
          memcpy(m_buffer, (void*)pin_buffer, len);
          m_nativeptr = gcnew native_conditional_unique_ptr<native::DataInput>(
            std::make_unique<native::DataInput>(m_cache->GetNative()->createDataInput(m_buffer, len)));

          try
          {
            m_buffer = const_cast<System::Byte*>(m_nativeptr->get()->currentBufferPosition());
            m_bufferLength = m_nativeptr->get()->getBytesRemaining();
          }
          finally
          {
            GC::KeepAlive(m_nativeptr);
          }

          _GF_MG_EXCEPTION_CATCH_ALL2
        }
        else {
          throw gcnew IllegalArgumentException("DataInput.ctor(): "
                                               "provided buffer is null");
        }
      }

      void DataInput::CheckBufferSize(int size)
      {
        if ((unsigned int)(m_cursor + size) > m_bufferLength)
        {
          Log::Debug("DataInput::CheckBufferSize m_cursor:" + m_cursor + " size:" + size + " m_bufferLength:" + m_bufferLength);
          throw gcnew OutOfRangeException("DataInput: attempt to read beyond buffer");
        }
      }

      DataInput^ DataInput::GetClone()
      {
        return gcnew DataInput(m_buffer, m_bufferLength, m_cache);
      }

      Byte DataInput::ReadByte()
      {
        CheckBufferSize(1);
        return m_buffer[m_cursor++];
      }

      SByte DataInput::ReadSByte()
      {
        CheckBufferSize(1);
        return m_buffer[m_cursor++];
      }

      bool DataInput::ReadBoolean()
      {
        CheckBufferSize(1);
        Byte val = m_buffer[m_cursor++];
        if (val == 1)
          return true;
        else
          return false;
      }

      Char DataInput::ReadChar()
      {
        CheckBufferSize(2);
        Char data = m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        return data;
      }

      array<Byte>^ DataInput::ReadBytes()
      {
        System::Int32 length;
        length = ReadArrayLen();

        if (length >= 0) {
          if (length == 0)
            return gcnew array<Byte>(0);
          else {
            array<Byte>^ bytes = ReadBytesOnly(length);
            return bytes;
          }
        }
        return nullptr;
      }

      int DataInput::ReadArrayLen()
      {
        int code;
        int len;

        code = Convert::ToInt32(ReadByte());

        if (code == 0xFF) {
          len = -1;
        }
        else {
          unsigned int result = code;
          if (result > 252) {  // 252 is java's ((byte)-4 && 0xFF)
            if (code == 0xFE) {
              result = ReadUInt16();
            }
            else if (code == 0xFD) {
              result = ReadUInt32();
            }
            else {
              throw gcnew IllegalStateException("unexpected array length code");
            }
            //TODO:: illegal length
          }
          len = (int)result;
        }
        return len;
      }

      array<SByte>^ DataInput::ReadSBytes()
      {
        System::Int32 length;
        length = ReadArrayLen();

        if (length > -1) {
          if (length == 0)
            return gcnew array<SByte>(0);
          else {
            array<SByte>^ bytes = ReadSBytesOnly(length);
            return bytes;
          }
        }
        return nullptr;
      }

      array<Byte>^ DataInput::ReadBytesOnly(System::UInt32 len)
      {
        if (len > 0) {
          CheckBufferSize(len);
          array<Byte>^ bytes = gcnew array<Byte>(len);

          for (unsigned int i = 0; i < len; i++)
            bytes[i] = m_buffer[m_cursor++];

          return bytes;
        }
        return nullptr;
      }

      void DataInput::ReadBytesOnly(array<Byte> ^ buffer, int offset, int count)
      {
        if (count > 0) {
          CheckBufferSize((System::UInt32)count);

          for (int i = 0; i < count; i++)
            buffer[offset + i] = m_buffer[m_cursor++];
        }
      }

      array<SByte>^ DataInput::ReadSBytesOnly(System::UInt32 len)
      {
        if (len > 0) {
          CheckBufferSize(len);
          array<SByte>^ bytes = gcnew array<SByte>(len);

          for (unsigned int i = 0; i < len; i++)
            bytes[i] = (SByte)m_buffer[m_cursor++];

          return bytes;
        }
        return nullptr;
      }

      System::UInt16 DataInput::ReadUInt16()
      {
        CheckBufferSize(2);
        System::UInt16 data = m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        return data;
      }

      System::UInt32 DataInput::ReadUInt32()
      {
        CheckBufferSize(4);
        System::UInt32 data = m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];

        return data;
      }

      System::UInt64 DataInput::ReadUInt64()
      {
        System::UInt64 data;

        CheckBufferSize(8);

        data = m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];
        data = (data << 8) | m_buffer[m_cursor++];

        return data;
      }

      System::Int16 DataInput::ReadInt16()
      {
        return ReadUInt16();
      }

      System::Int32 DataInput::ReadInt32()
      {
        return ReadUInt32();
      }

      System::Int64 DataInput::ReadInt64()
      {
        return ReadUInt64();
      }

      array<Byte>^ DataInput::ReadReverseBytesOnly(int len)
      {
        CheckBufferSize(len);

        int i = 0;
        auto j = m_cursor + len - 1;
        array<Byte>^ bytes = gcnew array<Byte>(len);

        while (i < len)
        {
          bytes[i++] = m_buffer[j--];
        }
        m_cursor += len;
        return bytes;
      }

      float DataInput::ReadFloat()
      {
        float data;

        array<Byte>^ bytes = nullptr;
        if (BitConverter::IsLittleEndian)
          bytes = ReadReverseBytesOnly(4);
        else
          bytes = ReadBytesOnly(4);

        data = BitConverter::ToSingle(bytes, 0);

        return data;
      }

      double DataInput::ReadDouble()
      {
        double data;

        array<Byte>^ bytes = nullptr;
        if (BitConverter::IsLittleEndian)
          bytes = ReadReverseBytesOnly(8);
        else
          bytes = ReadBytesOnly(8);

        data = BitConverter::ToDouble(bytes, 0);

        return data;
      }

      String^ DataInput::ReadUTF()
      {
        int length = ReadUInt16();
        CheckBufferSize(length);
        String^ str = DecodeBytes(length);
        return str;
      }

      String^ DataInput::ReadUTFHuge()
      {
        int length = ReadUInt32();
        CheckBufferSize(length);

        array<Char>^ chArray = gcnew array<Char>(length);

        for (int i = 0; i < length; i++)
        {
          Char ch = ReadByte();
          ch = ((ch << 8) | ReadByte());
          chArray[i] = ch;
        }

        String^ str = gcnew String(chArray);

        return str;
      }

      String^ DataInput::ReadASCIIHuge()
      {
        int length = ReadInt32();
        CheckBufferSize(length);
        String^ str = DecodeBytes(length);
        return str;
      }

      Object^ DataInput::ReadObject()
      {
        return ReadInternalObject();
      }

      /*	Object^ DataInput::ReadGenericObject( )
        {
        return ReadInternalGenericObject();
        }*/

      Object^ DataInput::ReadDotNetTypes(int8_t typeId)
      {
        switch (static_cast<apache::geode::client::internal::DSCode>(typeId))
        {
        case apache::geode::client::internal::DSCode::CacheableByte:
        {
          return ReadByte();
        }
        case apache::geode::client::internal::DSCode::CacheableBoolean:
        {
          bool obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableCharacter:
        {
          Char obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableDouble:
        {
          Double obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableASCIIString:
        {
          /*	CacheableString^ cs = static_cast<CacheableString^>(CacheableString::CreateDeserializable());
            cs->FromData(this);
            return cs->Value;*/
          return ReadUTF();
        }
        case apache::geode::client::internal::DSCode::CacheableASCIIStringHuge:
        {
          /*CacheableString^ cs = static_cast<CacheableString^>(CacheableString::createDeserializableHuge());
          cs->FromData(this);
          return cs->Value;*/
          return ReadASCIIHuge();
        }
        case apache::geode::client::internal::DSCode::CacheableString:
        {
          /*CacheableString^ cs = static_cast<CacheableString^>(CacheableString::createUTFDeserializable());
          cs->FromData(this);
          return cs->Value;*/
          return ReadUTF();
        }
        case apache::geode::client::internal::DSCode::CacheableStringHuge:
        {
          //TODO: need to look all strings types
          /*CacheableString^ cs = static_cast<CacheableString^>(CacheableString::createUTFDeserializableHuge());
          cs->FromData(this);
          return cs->Value;*/
          return ReadUTFHuge();
        }
        case apache::geode::client::internal::DSCode::CacheableFloat:
        {
          float obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt16:
        {
          Int16 obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt32:
        {
          Int32 obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt64:
        {
          Int64 obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableDate:
        {
          CacheableDate^ cd = CacheableDate::Create();
          cd->FromData(this);
          return cd->Value;
        }
        case apache::geode::client::internal::DSCode::CacheableBytes:
        {
          return ReadBytes();
        }
        case apache::geode::client::internal::DSCode::CacheableDoubleArray:
        {
          array<Double>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableFloatArray:
        {
          array<float>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt16Array:
        {
          array<Int16>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt32Array:
        {
          array<Int32>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::BooleanArray:
        {
          array<bool>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CharArray:
        {
          array<Char>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableInt64Array:
        {
          array<Int64>^ obj;
          ReadObject(obj);
          return obj;
        }
        case apache::geode::client::internal::DSCode::CacheableStringArray:
        {
          return ReadStringArray();
        }
        case apache::geode::client::internal::DSCode::CacheableHashTable:
        {
          return ReadHashtable();
        }
        case apache::geode::client::internal::DSCode::CacheableHashMap:
        {
          CacheableHashMap^ chm = static_cast<CacheableHashMap^>(CacheableHashMap::CreateDeserializable());
          chm->FromData(this);
          return chm->Value;
        }
        case apache::geode::client::internal::DSCode::CacheableIdentityHashMap:
        {
          CacheableIdentityHashMap^ chm = static_cast<CacheableIdentityHashMap^>(CacheableIdentityHashMap::CreateDeserializable());
          chm->FromData(this);
          return chm->Value;
        }
        case apache::geode::client::internal::DSCode::CacheableVector:
        {
          /*CacheableVector^ cv = static_cast<CacheableVector^>(CacheableVector::CreateDeserializable());
          cv->FromData(this);
          return cv->Value;*/
          int len = ReadArrayLen();
          System::Collections::ArrayList^ retA = gcnew System::Collections::ArrayList(len);

          for (int i = 0; i < len; i++)
          {
            retA->Add(this->ReadObject());
          }
          return retA;
        }
        case apache::geode::client::internal::DSCode::CacheableArrayList:
        {
          /*CacheableArrayList^ cv = static_cast<CacheableArrayList^>(CacheableArrayList::CreateDeserializable());
          cv->FromData(this);
          return cv->Value;*/
          int len = ReadArrayLen();
          System::Collections::Generic::List<Object^>^ retA = gcnew System::Collections::Generic::List<Object^>(len);
          for (int i = 0; i < len; i++)
          {
            retA->Add(this->ReadObject());
          }
          return retA;

        }
        case apache::geode::client::internal::DSCode::CacheableLinkedList:
        {
          /*CacheableArrayList^ cv = static_cast<CacheableArrayList^>(CacheableArrayList::CreateDeserializable());
          cv->FromData(this);
          return cv->Value;*/
          int len = ReadArrayLen();
          System::Collections::Generic::LinkedList<Object^>^ retA = gcnew System::Collections::Generic::LinkedList<Object^>();
          for (int i = 0; i < len; i++)
          {
            retA->AddLast(this->ReadObject());
          }
          return retA;

        }
        case apache::geode::client::internal::DSCode::CacheableStack:
        {
          CacheableStack^ cv = static_cast<CacheableStack^>(CacheableStack::CreateDeserializable());
          cv->FromData(this);
          return cv->Value;
        }
        default:
          return nullptr;
        }
      }

      Object^ DataInput::ReadInternalObject()
      {
        try
        {
          //Log::Debug("DataInput::ReadInternalObject m_cursor " + m_cursor);
          bool findinternal = false;
          int8_t typeId = ReadByte();
          System::Int64 compId;
          TypeFactoryMethod^ createType = nullptr;

          switch (static_cast<DSCode>(typeId)) 
          {
            case DSCode::NullObj:
              return nullptr;
            case DSCode::PDX: 
            {
              //cache current state and reset after reading pdx object
              auto cacheCursor = m_cursor;
              System::Byte* cacheBuffer = m_buffer;
              auto cacheBufferLength = m_bufferLength;
              Object^ ret = Internal::PdxHelper::DeserializePdx(this, false, CacheRegionHelper::getCacheImpl(m_cache->GetNative().get())->getSerializationRegistry().get());
              auto tmp = m_nativeptr->get()->getBytesRemaining();
              m_cursor = cacheBufferLength - tmp;
              m_buffer = cacheBuffer;
              m_bufferLength = cacheBufferLength;
              m_nativeptr->get()->rewindCursor(m_cursor);

              if (ret != nullptr)
              {
                if (auto pdxWrapper = dynamic_cast<Apache::Geode::Client::PdxWrapper^>(ret))
                {
                  return pdxWrapper->GetObject();
                }
              }
              return ret;
            }
            case DSCode::PDX_ENUM: 
            {
              int8_t dsId = ReadByte();
              int tmp = ReadArrayLen();
              int enumId = (dsId << 24) | (tmp & 0xFFFFFF);

              Object^ enumVal = Internal::PdxHelper::GetEnum(enumId, m_cache);
              return enumVal;
            }
            case DSCode::CacheableNullString:
              return nullptr;
            case DSCode::CacheableUserData:
              compId = ReadByte();
              break;
            case DSCode::CacheableUserData2:
              compId = ReadInt16();
              break;
            case DSCode::CacheableUserData4:
              compId = ReadInt32();
              break;
            case DSCode::FixedIDByte:
              compId = ReadByte();
              findinternal = true;
              break;
            case DSCode::FixedIDShort:
              compId = ReadInt16();
              findinternal = true;
              break;
            case DSCode::FixedIDInt:
              compId = ReadInt32();
              findinternal = true;
              break;
          }

          if (findinternal) 
          {
            createType = m_cache->TypeRegistry->GetDataSerializableFixedTypeFactoryMethodForFixedId(static_cast<Int32>(compId));
          }
          else 
          {
            createType = m_cache->TypeRegistry->GetManagedObjectFactory(compId);
            if (createType == nullptr)
            {
              Object^ retVal = ReadDotNetTypes(typeId);

              if (retVal != nullptr)
                return retVal;

              if (m_ispdxDesrialization && static_cast<DSCode>(typeId) == DSCode::CacheableObjectArray)
              {//object array and pdxSerialization
                return readDotNetObjectArray();
              }
              
              createType = m_cache->TypeRegistry->GetDataSerializablePrimitiveTypeFactoryMethodForDsCode(typeId);
            }
          }

          if (createType == nullptr) 
          {
            throw gcnew IllegalStateException("Unregistered typeId " + typeId + " in deserialization, aborting.");
          }

          bool isPdxDeserialization = m_ispdxDesrialization;
          m_ispdxDesrialization = false;//for nested objects
          ISerializable^ newObj = createType();

          if (auto dataSerializable = dynamic_cast<IDataSerializablePrimitive^>(newObj))
          {
            dataSerializable->FromData(this);
          }
          else if (auto dataSerializable = dynamic_cast<IDataSerializable^>(newObj))
          {
            dataSerializable->FromData(this);
          }
          else if (auto dataSerializableFixedId = dynamic_cast<IDataSerializableFixedId^>(newObj))
          {
            dataSerializableFixedId->FromData(this);
          }
          else
          {
            throw gcnew IllegalStateException("Unknown serialization type.");
          }

          m_ispdxDesrialization = isPdxDeserialization;
          return newObj;
        }
        finally
        {
          GC::KeepAlive(m_nativeptr);
        }
      }

      Object^ DataInput::readDotNetObjectArray()
      {
        int len = ReadArrayLen();
        String^ className = nullptr;
        if (len >= 0)
        {
          ReadByte(); // ignore CLASS typeid
          className = (String^)ReadObject();
          className = m_cache->TypeRegistry->GetLocalTypeName(className);
          System::Collections::IList^ list = nullptr;
          if (len == 0)
          {
            list = (System::Collections::IList^)m_cache->TypeRegistry->GetArrayObject(className, len);
            return list;
          }
          //read first object

          Object^ ret = ReadObject();//in case it returns pdxinstance or java.lang.object

          list = (System::Collections::IList^)m_cache->TypeRegistry->GetArrayObject(ret->GetType()->FullName, len);

          list[0] = ret;
          for (System::Int32 index = 1; index < list->Count; ++index)
          {
            list[index] = ReadObject();
          }
          return list;
        }
        return nullptr;
      }

      size_t DataInput::BytesRead::get()
      {
        AdvanceUMCursor();
        SetBuffer();

        try
        {
          return m_nativeptr->get()->getBytesRead();
        }
        finally
        {
          GC::KeepAlive(m_nativeptr);
        }
      }

      size_t DataInput::BytesReadInternally::get()
      {
        return m_cursor;
      }

      size_t DataInput::BytesRemaining::get()
      {
        AdvanceUMCursor();
        SetBuffer();
        try
        {
          return m_nativeptr->get()->getBytesRemaining();
        }
        finally
        {
          GC::KeepAlive(m_nativeptr);
        }
      }

      void DataInput::AdvanceCursor(size_t offset)
      {
        m_cursor += offset;
      }

      void DataInput::RewindCursor(size_t offset)
      {
        AdvanceUMCursor();
        try
        {
          m_nativeptr->get()->rewindCursor(offset);
        }
        finally
        {
          GC::KeepAlive(m_nativeptr);
        }
        SetBuffer();
      }

      void DataInput::Reset()
      {
        AdvanceUMCursor();
        try
        {
          m_nativeptr->get()->reset();
        }
        finally
        {
          GC::KeepAlive(m_nativeptr);
        }
        SetBuffer();
      }

      void DataInput::Cleanup()
      {
        //TODO:
        //GF_SAFE_DELETE_ARRAY(m_buffer);
      }

      void DataInput::ReadDictionary(System::Collections::IDictionary^ dict)
      {
        int len = this->ReadArrayLen();

        if (len > 0)
        {
          for (int i = 0; i < len; i++)
          {
            Object^ key = this->ReadObject();
            Object^ val = this->ReadObject();

            dict->Add(key, val);
          }
        }
      }

      IDictionary<Object^, Object^>^ DataInput::ReadDictionary()
      {
        int len = this->ReadArrayLen();

        if (len == -1)
          return nullptr;
        else
        {
          IDictionary<Object^, Object^>^ dict = gcnew Dictionary<Object^, Object^>();
          for (int i = 0; i < len; i++)
          {
            Object^ key = this->ReadObject();
            Object^ val = this->ReadObject();

            dict->Add(key, val);
          }
          return dict;
        }
      }

      System::DateTime DataInput::ReadDate()
      {
        long ticks = (long)ReadInt64();
        if (ticks != -1L)
        {
          m_cursor -= 8;//for above
          CacheableDate^ cd = CacheableDate::Create();
          cd->FromData(this);
          return cd->Value;
        }
        else
        {
          DateTime dt(0);
          return dt;
        }
      }

      void DataInput::ReadCollection(System::Collections::IList^ coll)
      {
        int len = ReadArrayLen();
        for (int i = 0; i < len; i++)
        {
          coll->Add(ReadObject());
        }
      }

      array<Char>^ DataInput::ReadCharArray()
      {
        array<Char>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<bool>^ DataInput::ReadBooleanArray()
      {
        array<bool>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<Int16>^ DataInput::ReadShortArray()
      {
        array<Int16>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<Int32>^ DataInput::ReadIntArray()
      {
        array<Int32>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<Int64>^ DataInput::ReadLongArray()
      {
        array<Int64>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<float>^ DataInput::ReadFloatArray()
      {
        array<float>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      array<double>^ DataInput::ReadDoubleArray()
      {
        array<double>^ arr;
        this->ReadObject(arr);
        return arr;
      }

      List<Object^>^ DataInput::ReadObjectArray()
      {
        //this to know whether it is null or it is empty
        auto storeCursor = m_cursor;
        auto len = this->ReadArrayLen();
        if (len == -1)
          return nullptr;
        //this will be read further by fromdata
        m_cursor = m_cursor - (m_cursor - storeCursor);


        CacheableObjectArray^ coa = CacheableObjectArray::Create();
        coa->FromData(this);
        List<Object^>^ retObj = (List<Object^>^)coa;

        if (retObj->Count >= 0)
          return retObj;
        return nullptr;
      }

      array<array<Byte>^>^ DataInput::ReadArrayOfByteArrays()
      {
        int len = ReadArrayLen();
        if (len >= 0)
        {
          array<array<Byte>^>^ retVal = gcnew array<array<Byte>^>(len);
          for (int i = 0; i < len; i++)
          {
            retVal[i] = this->ReadBytes();
          }
          return retVal;
        }
        else
          return nullptr;
      }

      void DataInput::ReadObject(array<UInt16>^% obj)
      {
        int len = ReadArrayLen();
        if (len >= 0)
        {
          obj = gcnew array<UInt16>(len);
          for (int i = 0; i < len; i++)
          {
            obj[i] = this->ReadUInt16();
          }
        }
      }

      void DataInput::ReadObject(array<UInt32>^% obj)
      {
        int len = ReadArrayLen();
        if (len >= 0)
        {
          obj = gcnew array<UInt32>(len);
          for (int i = 0; i < len; i++)
          {
            obj[i] = this->ReadUInt32();
          }
        }
      }

      void DataInput::ReadObject(array<UInt64>^% obj)
      {
        int len = ReadArrayLen();
        if (len >= 0)
        {
          obj = gcnew array<UInt64>(len);
          for (int i = 0; i < len; i++)
          {
            obj[i] = this->ReadUInt64();
          }
        }
      }

      String^ DataInput::ReadString()
      {
        switch (static_cast<DSCode>(ReadByte()))
        {
          case DSCode::CacheableNullString:
            return nullptr;
          case DSCode::CacheableASCIIString:
          case DSCode::CacheableString:
            return ReadUTF();
          case DSCode::CacheableASCIIStringHuge:
            return ReadASCIIHuge();
          default:
            return ReadUTFHuge();
        }
      }

      native::Pool* DataInput::GetPool()
      {
        try
        {
          return native::DataInputInternal::getPool(*m_nativeptr);
        }
        finally {
          GC::KeepAlive(m_nativeptr);
        }
      }

    }  // namespace Client
  }  // namespace Geode
}  // namespace Apache

