blob: 846ff4e62b9b67802d200391b62996b54a6582d5 [file] [log] [blame]
/*
* 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 "CacheRegionHelper.hpp"
#include "CacheImpl.hpp"
#include "DataOutputInternal.hpp"
#include "end_native.hpp"
#include "DataOutput.hpp"
#include "IDataSerializable.hpp"
#include "ISerializable.hpp"
#include "CacheableObjectArray.hpp"
#include "impl/PdxHelper.hpp"
#include "impl/PdxWrapper.hpp"
#include "Cache.hpp"
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace apache::geode::client;
namespace Apache
{
namespace Geode
{
namespace Client
{
using namespace msclr::interop;
DataOutput::DataOutput(Apache::Geode::Client::Cache^ cache)
{
m_cache = cache;
m_nativeptr = gcnew native_conditional_unique_ptr<native::DataOutput>(
std::make_unique<native::DataOutput>(cache->GetNative()->createDataOutput()));
m_isManagedObject = true;
m_cursor = 0;
try
{
m_bytes = const_cast<System::Byte *>(m_nativeptr->get()->getCursor());
m_remainingBufferLength = (System::Int32)m_nativeptr->get()->getRemainingBufferLength();
}
finally
{
GC::KeepAlive(m_nativeptr);
}
m_ispdxSerialization = false;
}
void DataOutput::WriteByte(Byte value)
{
EnsureCapacity(1);
m_bytes[m_cursor++] = value;
}
void DataOutput::WriteSByte(SByte value)
{
EnsureCapacity(1);
m_bytes[m_cursor++] = value;
}
void DataOutput::WriteBoolean(bool value)
{
EnsureCapacity(1);
if (value)
m_bytes[m_cursor++] = 0x01;
else
m_bytes[m_cursor++] = 0x00;
}
void DataOutput::WriteChar(Char value)
{
EnsureCapacity(2);
m_bytes[m_cursor++] = (System::Byte)(value >> 8);
m_bytes[m_cursor++] = (System::Byte)value;
}
void DataOutput::WriteBytes(array<Byte>^ bytes, System::Int32 len)
{
if (bytes != nullptr && bytes->Length >= 0)
{
if (len >= 0 && len <= bytes->Length)
{
WriteArrayLen(len);
EnsureCapacity(len);
for (int i = 0; i < len; i++)
m_bytes[m_cursor++] = bytes[i];
}
else
{
throw gcnew IllegalArgumentException("DataOutput::WriteBytes argument len is not in byte array range.");
}
}
else
{
WriteByte(0xFF);
}
}
void DataOutput::WriteArrayLen(System::Int32 len)
{
if (len == -1) {//0xff
WriteByte(0xFF);
}
else if (len <= 252) { // 252 is java's ((byte)-4 && 0xFF) or 0xfc
WriteByte((Byte)(len));
}
else if (len <= 0xFFFF) {
WriteByte(0xFE);//0xfe
WriteUInt16((len));
}
else {
WriteByte((0xFD));//0xfd
WriteUInt32(len);
}
}
void DataOutput::WriteSBytes(array<SByte>^ bytes, System::Int32 len)
{
if (bytes != nullptr && bytes->Length >= 0)
{
if (len >= 0 && len <= bytes->Length)
{
WriteArrayLen(len);
EnsureCapacity(len);
for (int i = 0; i < len; i++)
m_bytes[m_cursor++] = bytes[i];
}
else
{
throw gcnew IllegalArgumentException("DataOutput::WriteSBytes argument len is not in SByte array range.");
}
}
else
{
WriteByte(0xFF);
}
}
void DataOutput::WriteBytesOnly(array<Byte>^ bytes, System::UInt32 len)
{
WriteBytesOnly(bytes, len, 0);
}
void DataOutput::WriteBytesOnly(array<Byte>^ bytes, System::UInt32 len, System::UInt32 offset)
{
if (bytes != nullptr)
{
if (len >= 0 && len <= ((System::UInt32)bytes->Length - offset))
{
EnsureCapacity(len);
for (System::UInt32 i = 0; i < len; i++)
m_bytes[m_cursor++] = bytes[offset + i];
}
else
{
throw gcnew IllegalArgumentException("DataOutput::WriteBytesOnly argument len is not in Byte array range.");
}
}
}
void DataOutput::WriteSBytesOnly(array<SByte>^ bytes, System::UInt32 len)
{
if (bytes != nullptr)
{
if (len >= 0 && len <= (System::UInt32)bytes->Length)
{
EnsureCapacity(len);
for (System::UInt32 i = 0; i < len; i++)
m_bytes[m_cursor++] = bytes[i];
}
else
{
throw gcnew IllegalArgumentException("DataOutput::WriteSBytesOnly argument len is not in SByte array range.");
}
}
}
void DataOutput::WriteUInt16(System::UInt16 value)
{
EnsureCapacity(2);
m_bytes[m_cursor++] = (System::Byte)(value >> 8);
m_bytes[m_cursor++] = (System::Byte)value;
}
void DataOutput::WriteUInt32(System::UInt32 value)
{
EnsureCapacity(4);
m_bytes[m_cursor++] = (System::Byte)(value >> 24);
m_bytes[m_cursor++] = (System::Byte)(value >> 16);
m_bytes[m_cursor++] = (System::Byte)(value >> 8);
m_bytes[m_cursor++] = (System::Byte)value;
}
void DataOutput::WriteUInt64(System::UInt64 value)
{
EnsureCapacity(8);
m_bytes[m_cursor++] = (System::Byte)(value >> 56);
m_bytes[m_cursor++] = (System::Byte)(value >> 48);
m_bytes[m_cursor++] = (System::Byte)(value >> 40);
m_bytes[m_cursor++] = (System::Byte)(value >> 32);
m_bytes[m_cursor++] = (System::Byte)(value >> 24);
m_bytes[m_cursor++] = (System::Byte)(value >> 16);
m_bytes[m_cursor++] = (System::Byte)(value >> 8);
m_bytes[m_cursor++] = (System::Byte)value;
}
void DataOutput::WriteInt16(System::Int16 value)
{
WriteUInt16(value);
}
void DataOutput::WriteInt32(System::Int32 value)
{
WriteUInt32(value);
}
void DataOutput::WriteInt64(System::Int64 value)
{
WriteUInt64(value);
}
void DataOutput::WriteFloat(float value)
{
array<Byte>^ bytes = BitConverter::GetBytes(value);
EnsureCapacity(4);
for (int i = 4 - 1; i >= 0; i--)
m_bytes[m_cursor++] = bytes[i];
}
void DataOutput::WriteDouble(double value)
{
array<Byte>^ bytes = BitConverter::GetBytes(value);
EnsureCapacity(8);
for (int i = 8 - 1; i >= 0; i--)
m_bytes[m_cursor++] = bytes[i];
}
void DataOutput::WriteDictionary(System::Collections::IDictionary^ dict)
{
if (dict != nullptr)
{
this->WriteArrayLen(dict->Count);
for each(System::Collections::DictionaryEntry^ entry in dict)
{
this->WriteObject(entry->Key);
this->WriteObject(entry->Value);
}
}
else
{
WriteByte((int8_t)-1);
}
}
void DataOutput::WriteCollection(System::Collections::IList^ collection)
{
if (collection != nullptr)
{
this->WriteArrayLen(collection->Count);
for each (Object^ obj in collection) {
this->WriteObject(obj);
}
}
else
this->WriteByte((int8_t)-1);
}
void DataOutput::WriteDate(System::DateTime date)
{
if (date.Ticks != 0L)
{
CacheableDate^ cd = gcnew CacheableDate(date);
cd->ToData(this);
}
else
this->WriteInt64(-1L);
}
void DataOutput::WriteCharArray(array<Char>^ charArray)
{
if (charArray != nullptr)
{
this->WriteArrayLen(charArray->Length);
for (int i = 0; i < charArray->Length; i++) {
this->WriteObject(charArray[i]);
}
}
else
this->WriteByte((int8_t)-1);
}
void DataOutput::WriteObjectArray(List<Object^>^ objectArray)
{
if (objectArray != nullptr)
{
CacheableObjectArray^ coa = CacheableObjectArray::Create(objectArray);
coa->ToData(this);
}
else
this->WriteByte((int8_t)-1);
}
void DataOutput::WriteDotNetObjectArray(Object^ objectArray)
{
System::Collections::IList^ list = (System::Collections::IList^)objectArray;
this->WriteArrayLen(list->Count);
WriteByte((int8_t)apache::geode::client::internal::DSCode::Class);
String^ pdxDomainClassname = m_cache->TypeRegistry->GetPdxTypeName(objectArray->GetType()->GetElementType()->FullName);
WriteByte((int8_t)DSCode::CacheableASCIIString);
WriteUTF(pdxDomainClassname);
for each(Object^ o in list)
WriteObject(o);
}
void DataOutput::WriteArrayOfByteArrays(array<array<Byte>^>^ byteArrays)
{
if (byteArrays != nullptr)
{
int fdLen = byteArrays->Length;
this->WriteArrayLen(byteArrays->Length);
for (int i = 0; i < fdLen; i++) {
this->WriteBytes(byteArrays[i]);
}
}
else
this->WriteByte((int8_t)-1);
}
void DataOutput::WriteUTF(String^ value)
{
if (value != nullptr) {
int len = getEncodedLength(value);
if (len > 0xffff)
len = 0xffff;
WriteUInt16(len);
EnsureCapacity(len);
EncodeUTF8String(value, len);
}
else {
WriteUInt16(0);
}
}
void DataOutput::WriteStringWithType(String^ value)
{
//value will not be null
int len = getEncodedLength(value);
if (len > 0xffff)
{
if (len == value->Length)//huge ascii
{
WriteByte(static_cast<unsigned char>(DSCode::CacheableASCIIStringHuge));
WriteASCIIHuge(value);
}
else//huge utf
{
WriteByte(static_cast<unsigned char>(DSCode::CacheableStringHuge));
WriteUTFHuge(value);
}
return;
}
if (len == value->Length)
{
WriteByte(static_cast<unsigned char>(DSCode::CacheableASCIIString));//ascii string
}
else
{
WriteByte(static_cast<unsigned char>(DSCode::CacheableString));//utf string
}
WriteUInt16(len);
EnsureCapacity(len);
EncodeUTF8String(value, len);
}
void DataOutput::WriteASCIIHuge(String^ value)
{
if (value != nullptr) {
const int strLength = value->Length;
WriteUInt32(strLength);
EnsureCapacity(strLength);
for (int i = 0; i < strLength; i++) {
m_bytes[m_cursor++] = (System::Byte)value[i];
}
}
else {
WriteUInt32(0);
}
}
/* Write UTF-16 */
void DataOutput::WriteUTFHuge(String^ value)
{
if (value != nullptr) {
WriteUInt32(value->Length);
EnsureCapacity(value->Length * 2);
for (int i = 0; i < value->Length; i++)
{
Char ch = value[i];
m_bytes[m_cursor++] = (Byte)((ch & 0xff00) >> 8);
m_bytes[m_cursor++] = (Byte)(ch & 0xff);
}
}
else {
WriteUInt32(0);
}
}
/*void DataOutput::WriteObject( Object^ obj )
{
WriteObjectInternal((ISerializable^)obj);
}*/
/*void DataOutput::WriteObject( Object^ obj )
{
WriteObject( (ISerializable^)obj );
}*/
int8_t DataOutput::GetTypeId(System::UInt32 classId)
{
if (classId >= 0x80000000) {
return (int8_t)((classId - 0x80000000) % 0x20000000);
}
else if (classId <= 0x7F) {
return (int8_t)DSCode::CacheableUserData;
}
else if (classId <= 0x7FFF) {
return (int8_t)DSCode::CacheableUserData2;
}
else {
return (int8_t)DSCode::CacheableUserData4;
}
}
int8_t DataOutput::DSFID(System::UInt32 classId)
{
// convention that [0x8000000, 0xa0000000) is for FixedIDDefault,
// [0xa000000, 0xc0000000) is for FixedIDByte,
// [0xc0000000, 0xe0000000) is for FixedIDShort
// and [0xe0000000, 0xffffffff] is for FixedIDInt
// Note: depends on fact that FixedIDByte is 1, FixedIDShort is 2
// and FixedIDInt is 3; if this changes then correct this accordingly
if (classId >= 0x80000000) {
return (int8_t)((classId - 0x80000000) / 0x20000000);
}
return 0;
}
void DataOutput::WriteObject(Object^ obj)
{
if (obj == nullptr)
{
WriteByte((int8_t)DSCode::NullObj);
return;
}
if (m_ispdxSerialization && obj->GetType()->IsEnum)
{
//need to set
int enumVal = Internal::PdxHelper::GetEnumValue(obj->GetType()->FullName, Enum::GetName(obj->GetType(), obj), obj->GetHashCode(), m_cache);
WriteByte(static_cast<int8_t>(DSCode::PDX_ENUM));
WriteByte(enumVal >> 24);
WriteArrayLen(enumVal & 0xFFFFFF);
return;
}
DSCode typeId = static_cast<DSCode>(m_cache->TypeRegistry->GetDsCodeForManagedType(obj->GetType()));
switch (typeId)
{
case DSCode::CacheableByte:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteByte((Byte)obj);
return;
}
case DSCode::CacheableBoolean:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteBoolean((bool)obj);
return;
}
case DSCode::CacheableCharacter:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((Char)obj);
return;
}
case DSCode::CacheableDouble:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteDouble((Double)obj);
return;
}
case DSCode::CacheableASCIIString:
{
//CacheableString^ cStr = CacheableString::Create((String^)obj);
//// TODO: igfser mapping between generic and non generic
//WriteObjectInternal(cStr);
WriteStringWithType((String^)obj);
return;
}
case DSCode::CacheableFloat:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteFloat((float)obj);
return;
}
case DSCode::CacheableInt16:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteInt16((Int16)obj);
return;
}
case DSCode::CacheableInt32:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteInt32((Int32)obj);
return;
}
case DSCode::CacheableInt64:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteInt64((Int64)obj);
return;
}
case DSCode::CacheableDate:
{
//CacheableDate^ cd = gcnew CacheableDate((DateTime)obj);
// TODO: igfser mapping between generic and non generic
//WriteObjectInternal(cd);
WriteByte(static_cast<unsigned char>(typeId));
WriteDate((DateTime)obj);
return;
}
case DSCode::CacheableBytes:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteBytes((array<Byte>^)obj);
return;
}
case DSCode::CacheableDoubleArray:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<Double>^)obj);
return;
}
case DSCode::CacheableFloatArray:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<float>^)obj);
return;
}
case DSCode::CacheableInt16Array:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<Int16>^)obj);
return;
}
case DSCode::CacheableInt32Array:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<Int32>^)obj);
return;
}
case DSCode::CacheableInt64Array:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<Int64>^)obj);
return;
}
case DSCode::BooleanArray:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<bool>^)obj);
return;
}
case DSCode::CharArray:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<char>^)obj);
return;
}
case DSCode::CacheableStringArray:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteObject((array<String^>^)obj);
return;
}
case DSCode::CacheableHashTable:
case DSCode::CacheableHashMap:
case DSCode::CacheableIdentityHashMap:
{
WriteByte(static_cast<unsigned char>(typeId));
WriteDictionary((System::Collections::IDictionary^)obj);
return;
}
case DSCode::CacheableVector:
{
//CacheableVector^ cv = gcnew CacheableVector((System::Collections::IList^)obj);
//// TODO: igfser mapping between generic and non generic
//WriteObjectInternal(cv);
WriteByte(static_cast<unsigned char>(DSCode::CacheableVector));
WriteList((System::Collections::IList^)obj);
return;
}
case DSCode::CacheableLinkedList:
{
//CacheableArrayList^ cal = gcnew CacheableArrayList((System::Collections::IList^)obj);
//// TODO: igfser mapping between generic and non generic
//WriteObjectInternal(cal);
WriteByte(static_cast<unsigned char>(DSCode::CacheableLinkedList));
System::Collections::ICollection^ linkedList = (System::Collections::ICollection^)obj;
this->WriteArrayLen(linkedList->Count);
for each (Object^ o in linkedList)
this->WriteObject(o);
return;
}
case DSCode::CacheableArrayList:
{
//CacheableArrayList^ cal = gcnew CacheableArrayList((System::Collections::IList^)obj);
//// TODO: igfser mapping between generic and non generic
//WriteObjectInternal(cal);
WriteByte(static_cast<unsigned char>(DSCode::CacheableArrayList));
WriteList((System::Collections::IList^)obj);
return;
}
case DSCode::CacheableStack:
{
CacheableStack^ cs = gcnew CacheableStack((System::Collections::ICollection^)obj);
// TODO: igfser mapping between generic and non generic
WriteObjectInternal(cs);
return;
}
default:
{
if (auto pdxObj = dynamic_cast<IPdxSerializable^>(obj))
{
WriteByte(static_cast<int8_t>(DSCode::PDX));
Internal::PdxHelper::SerializePdx(this, pdxObj);
return;
}
else
{
//pdx serialization and is array of object
if (m_ispdxSerialization && obj->GetType()->IsArray)
{
WriteByte(static_cast<unsigned char>(DSCode::CacheableObjectArray));
WriteDotNetObjectArray(obj);
return;
}
if (auto ct = dynamic_cast<ISerializable^>(obj)) {
WriteObjectInternal(ct);
return;
}
if (m_cache->TypeRegistry->PdxSerializer)
{
auto pdxObj = gcnew PdxWrapper(obj);
WriteByte(static_cast<int8_t>(DSCode::PDX));
Internal::PdxHelper::SerializePdx(this, pdxObj);
return;
}
}
throw gcnew System::Exception("DataOutput not found appropriate type to write it for object: " + obj->GetType());
}
}
}
void DataOutput::WriteStringArray(array<String^>^ strArray)
{
if (strArray != nullptr)
{
this->WriteArrayLen(strArray->Length);
for (int i = 0; i < strArray->Length; i++)
{
// this->WriteUTF(strArray[i]);
WriteObject(strArray[i]);
}
}
else
WriteByte(-1);
}
void DataOutput::WriteObjectInternal(ISerializable^ obj)
{
//CacheableKey^ key = gcnew CacheableKey();
if (obj == nullptr) {
WriteByte((int8_t)DSCode::NullObj);
}
else if (auto dataSerializablePrimitive = dynamic_cast<IDataSerializablePrimitive^>(obj))
{
auto dsCode = dataSerializablePrimitive->DsCode;
WriteByte(dsCode);
dataSerializablePrimitive->ToData(this);
}
else if (auto dataSerializable = dynamic_cast<IDataSerializable^>(obj))
{
auto id = m_cache->TypeRegistry->GetIdForManagedType(dataSerializable->GetType());
auto dsCode = getDataSerializableDsCode(id);
WriteByte(static_cast<int8_t>(dsCode));
switch (dsCode) {
case DSCode::CacheableUserData:
WriteByte(static_cast<int8_t>(id));
break;
case DSCode::CacheableUserData2:
WriteInt16(static_cast<int16_t>(id));
break;
case DSCode::CacheableUserData4:
WriteInt32(static_cast<int32_t>(id));
break;
default:
IllegalStateException("Invalid DS Code.");
}
dataSerializable->ToData(this);
}
else if (auto dataSerializableFixedId = dynamic_cast<IDataSerializableFixedId^>(obj))
{
auto id = dataSerializableFixedId->DSFID;
auto dsCode = getDataSerializableFixedIdDsCode(id);
WriteByte(dsCode);
switch (static_cast<DSCode>(dsCode)) {
case DSCode::FixedIDByte:
WriteByte(static_cast<int8_t>(id));
break;
case DSCode::FixedIDShort:
WriteInt16(static_cast<int16_t>(id));
break;
case DSCode::FixedIDInt:
WriteInt32(static_cast<int32_t>(id));
break;
default:
IllegalStateException("Invalid DS Code.");
}
dataSerializable->ToData(this);
}
else
{
throw gcnew IllegalStateException("Unknown serializable type.");
}
}
void DataOutput::AdvanceCursor(System::UInt32 offset)
{
EnsureCapacity(offset);
m_cursor += offset;
}
void DataOutput::RewindCursor(System::UInt32 offset)
{
//first set native one
WriteBytesToUMDataOutput();
try
{
m_nativeptr->get()->rewindCursor(offset);
}
finally
{
GC::KeepAlive(m_nativeptr);
}
SetBuffer();
}
array<Byte>^ DataOutput::GetBuffer()
{
try
{
WriteBytesToUMDataOutput();
SetBuffer();
auto buffLen = static_cast<int>(m_nativeptr->get()->getBufferLength());
array<Byte>^ buffer = gcnew array<Byte>(buffLen);
if (buffLen > 0) {
pin_ptr<Byte> pin_buffer = &buffer[0];
memcpy((void*)pin_buffer, m_nativeptr->get()->getBuffer(), buffLen);
}
return buffer;
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
size_t DataOutput::BufferLength::get()
{
//first set native one
WriteBytesToUMDataOutput();
SetBuffer();
try
{
return m_nativeptr->get()->getBufferLength();
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
void DataOutput::Reset()
{
WriteBytesToUMDataOutput();
try
{
m_nativeptr->get()->reset();
}
finally
{
GC::KeepAlive(m_nativeptr);
}
SetBuffer();
}
void DataOutput::WriteString(String^ value)
{
if (value == nullptr)
{
this->WriteByte(static_cast<unsigned char>(DSCode::CacheableNullString));
}
else
{
WriteObject(value);
/*CacheableString^ cs = gcnew CacheableString(value);
this->WriteByte( (Byte)(cs->ClassId - 0x80000000));
cs->ToData(this);*/
}
}
void DataOutput::WriteBytesToUMDataOutput()
{
try
{
m_nativeptr->get()->advanceCursor(m_cursor);
}
finally
{
GC::KeepAlive(m_nativeptr);
}
m_cursor = 0;
m_remainingBufferLength = 0;
m_bytes = nullptr;
}
void DataOutput::WriteObject(bool% obj)
{
WriteBoolean(obj);
}
void DataOutput::WriteObject(Byte% obj)
{
WriteByte(obj);
}
void DataOutput::WriteObject(Char% obj)
{
unsigned short us = (unsigned short)obj;
EnsureCapacity(2);
m_bytes[m_cursor++] = us >> 8;
m_bytes[m_cursor++] = (Byte)us;
}
void DataOutput::WriteObject(Double% obj)
{
WriteDouble(obj);
}
void DataOutput::WriteObject(Single% obj)
{
WriteFloat(obj);
}
void DataOutput::WriteObject(System::Int16% obj)
{
WriteInt16(obj);
}
void DataOutput::WriteObject(System::Int32% obj)
{
WriteInt32(obj);
}
void DataOutput::WriteObject(System::Int64% obj)
{
WriteInt64(obj);
}
void DataOutput::WriteObject(UInt16% obj)
{
WriteUInt16(obj);
}
void DataOutput::WriteObject(UInt32% obj)
{
WriteUInt32(obj);
}
void DataOutput::WriteObject(UInt64% obj)
{
WriteUInt64(obj);
}
void DataOutput::WriteBooleanArray(array<bool>^ boolArray)
{
WriteObject<bool>(boolArray);
}
void DataOutput::WriteShortArray(array<Int16>^ shortArray)
{
WriteObject<Int16>(shortArray);
}
void DataOutput::WriteIntArray(array<Int32>^ intArray)
{
WriteObject<Int32>(intArray);
}
void DataOutput::WriteLongArray(array<Int64>^ longArray)
{
WriteObject<Int64>(longArray);
}
void DataOutput::WriteFloatArray(array<float>^ floatArray)
{
WriteObject<float>(floatArray);
}
void DataOutput::WriteDoubleArray(array<double>^ doubleArray)
{
WriteObject<double>(doubleArray);
}
native::Pool* DataOutput::GetPool()
{
try
{
return native::DataOutputInternal::getPool(*m_nativeptr);
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
} // namespace Client
} // namespace Geode
} // namespace Apache