blob: 51bdc7c78800790893693a39453c5d8047126dd9 [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 "PdxLocalWriter.hpp"
#include "PdxHelper.hpp"
#include "PdxTypeRegistry.hpp"
#include "../DataOutput.hpp"
#include "DotNetTypes.hpp"
#include "../Cache.hpp"
using namespace System;
namespace Apache
{
namespace Geode
{
namespace Client
{
namespace Internal
{
PdxLocalWriter::PdxLocalWriter(DataOutput^ dataOutput, PdxType^ pdxType)
{
m_dataOutput = dataOutput;
m_pdxType = pdxType;
m_currentOffsetIndex = 0;
m_preserveData = nullptr;
if (pdxType != nullptr)
m_pdxClassName = pdxType->PdxClassName;
//m_pdxDomainType = nullptr;
initialize();
}
PdxLocalWriter::PdxLocalWriter(DataOutput^ dataOutput, PdxType^ pdxType, String^ pdxClassName)
{
m_dataOutput = dataOutput;
m_pdxType = pdxType;
m_currentOffsetIndex = 0;
m_preserveData = nullptr;
// m_pdxDomainType = pdxDomainType;
m_pdxClassName = pdxClassName;
initialize();
}
void PdxLocalWriter::initialize()
{
if(m_pdxType != nullptr)
{
m_currentOffsetIndex = 0;
//TODO:: 1 offset below if you can avoid
m_offsets = gcnew array<int>(m_pdxType->NumberOfVarLenFields);
}
//start position, this should start of c++ dataoutput buffer and then use bufferlen
m_startPosition = m_dataOutput->GetStartBufferPosition();
//TODO: need to use this carefully
m_startPositionOffset = static_cast<int>(m_dataOutput->BufferLength);//data has been write
m_dataOutput->AdvanceCursor(PdxHelper::PdxHeader);//to write pdx header
}
void PdxLocalWriter::AddOffset()
{
//bufferlength gives lenght which has been writeen to unmanged Dataoutput
//m_startPositionOffset: from where pdx header length starts
int bufferLen = static_cast<int>(m_dataOutput->BufferLength - m_startPositionOffset);
int offset = bufferLen - PdxHelper::PdxHeader/* this needs to subtract*/;
m_offsets[m_currentOffsetIndex++] = offset;
}
void PdxLocalWriter::EndObjectWriting()
{
//write header
WritePdxHeader();
}
System::Byte* PdxLocalWriter::GetPdxStream(int& pdxLen)
{
System::Byte* stPos = m_dataOutput->GetStartBufferPosition() + m_startPositionOffset;
int len = PdxHelper::ReadInt32(stPos);
pdxLen = len;
//ignore len and typeid
return m_dataOutput->GetBytes(stPos + 8, len );
}
void PdxLocalWriter::WritePdxHeader()
{
Int32 len = calculateLenWithOffsets();
Int32 typeId = m_pdxType->TypeId;
//GetStartBufferPosition ; if unmanaged dataoutput get change
System::Byte* starpos = m_dataOutput->GetStartBufferPosition() + m_startPositionOffset;
PdxHelper::WriteInt32(starpos , len);
PdxHelper::WriteInt32(starpos + 4, typeId);
WriteOffsets(len);
}
Int32 PdxLocalWriter::calculateLenWithOffsets()
{
//int bufferLen = m_dataOutput->GetCursorPdx();
int bufferLen = static_cast<int>(m_dataOutput->BufferLength - m_startPositionOffset);
Int32 totalOffsets = 0;
if(m_offsets->Length > 0)
totalOffsets = m_offsets->Length -1;//for first var len no need to append offset
Int32 totalLen = bufferLen - PdxHelper::PdxHeader + totalOffsets;
if(totalLen <= 0xff)//1 byte
return totalLen;
else if (totalLen + totalOffsets <= 0xffff)//2 byte
return totalLen + totalOffsets ;
else//4 byte
return totalLen + totalOffsets*3 ;
}
void PdxLocalWriter::WriteOffsets(Int32 len)
{
if(len <= 0xff)
{
for(int i = m_offsets->Length-1; i >0 ; i--)
m_dataOutput->WriteByte((Byte)m_offsets[i]);
}
else if(len <= 0xffff)
{
for(int i = m_offsets->Length-1; i >0 ; i--)
m_dataOutput->WriteUInt16((UInt16)m_offsets[i]);
}
else
{
for(int i = m_offsets->Length-1; i >0 ; i--)
m_dataOutput->WriteUInt32((UInt32)m_offsets[i]);
}
}
bool PdxLocalWriter::isFieldWritingStarted()
{
return true;
}
IPdxWriter^ PdxLocalWriter::WriteUnreadFields(IPdxUnreadFields^ unread)
{
if(isFieldWritingStarted())
{
throw gcnew IllegalStateException("WriteUnreadFields must be called before "
+ "any other fields are written.");
}
if(unread != nullptr)
{
m_preserveData = (PdxRemotePreservedData^)unread;
m_pdxType = m_dataOutput->Cache->GetPdxTypeRegistry()->GetPdxType(m_preserveData->MergedTypeId);
if(m_pdxType == nullptr)
{//its local type
//this needs to fix for IPdxTypemapper
m_pdxType = GetLocalPdxType(m_pdxClassName);
}
m_offsets = gcnew array<int>(m_pdxType->NumberOfVarLenFields);
}
return this;
}
IPdxWriter^ PdxLocalWriter::WriteByte( String^ fieldName, SByte value )
{
m_dataOutput->WriteSByte(value);
return this;
}
void PdxLocalWriter::WriteByte(Byte byte)
{
m_dataOutput->WriteByte(byte);
}
IPdxWriter^ PdxLocalWriter::WriteSByte( String^ fieldName, SByte value )
{
m_dataOutput->WriteSByte(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteBoolean( String^ fieldName, bool value )
{
m_dataOutput->WriteBoolean(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteChar( String^ fieldName, Char value )
{
m_dataOutput->WriteChar(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUInt16( String^ fieldName, System::UInt16 value )
{
m_dataOutput->WriteUInt16(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUInt32( String^ fieldName, System::UInt32 value )
{
m_dataOutput->WriteUInt32(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUInt64( String^ fieldName, System::UInt64 value )
{
m_dataOutput->WriteUInt64(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteShort( String^ fieldName, System::Int16 value )
{
m_dataOutput->WriteInt16(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteInt( String^ fieldName, System::Int32 value )
{
m_dataOutput->WriteInt32(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteLong( String^ fieldName, Int64 value )
{
m_dataOutput->WriteInt64(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteFloat( String^ fieldName, float value )
{
m_dataOutput->WriteFloat(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteDouble( String^ fieldName, double value )
{
m_dataOutput->WriteDouble(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteString( String^ fieldName, String^ value )
{
AddOffset();
m_dataOutput->WriteString(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUTFHuge( String^ fieldName, String^ value )
{
AddOffset();
m_dataOutput->WriteUTFHuge(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteASCIIHuge( String^ fieldName, String^ value )
{
AddOffset();
m_dataOutput->WriteASCIIHuge(value);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteObject( String^ fieldName, Object^ obj )
{
AddOffset();
m_dataOutput->WriteObject(obj);
return this;
}
//TODO:
//IPdxWriter^ PdxLocalWriter::WriteMap( String^ fieldName, System::Collections::IDictionary^ map );
IPdxWriter^ PdxLocalWriter::WriteCollection( String^ fieldName, System::Collections::IList^ obj)
{
AddOffset();
m_dataOutput->WriteCollection(obj);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteDate( String^ fieldName, System::DateTime date)
{
m_dataOutput->WriteDate(date);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteBooleanArray( String^ fieldName, array<bool>^ boolArray)
{
AddOffset();
m_dataOutput->WriteBooleanArray(boolArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteCharArray(String^ fieldName, array<Char>^ charArray)
{
AddOffset();
m_dataOutput->WriteCharArray(charArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteByteArray(String^ fieldName, array<Byte>^ byteArray)
{
AddOffset();
m_dataOutput->WriteBytes(byteArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteSByteArray(String^ fieldName, array<SByte>^ sbyteArray)
{
AddOffset();
m_dataOutput->WriteSBytes(sbyteArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteShortArray(String^ fieldName, array<System::Int16>^ shortArray)
{
AddOffset();
m_dataOutput->WriteShortArray(shortArray);//TODO::this don't write typeid looks confusing
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUnsignedShortArray(String^ fieldName, array<System::UInt16>^ ushortArray)
{
AddOffset();
// m_dataOutput->WriteObject(ushortArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteIntArray(String^ fieldName, array<System::Int32>^ intArray)
{
AddOffset();
m_dataOutput->WriteIntArray(intArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUnsignedIntArray(String^ fieldName, array<System::UInt32>^ uintArray)
{
AddOffset();
// m_dataOutput->WriteObject(uintArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteLongArray(String^ fieldName, array<Int64>^ longArray)
{
AddOffset();
m_dataOutput->WriteLongArray(longArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteUnsignedLongArray(String^ fieldName, array<System::UInt64>^ ulongArray)
{
AddOffset();
//m_dataOutput->WriteObject(ulongArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteFloatArray(String^ fieldName, array<float>^ floatArray)
{
AddOffset();
m_dataOutput->WriteFloatArray(floatArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteDoubleArray(String^ fieldName, array<double>^ doubleArray)
{
AddOffset();
m_dataOutput->WriteDoubleArray(doubleArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteStringArray(String^ fieldName, array<String^>^ stringArray)
{
AddOffset();
m_dataOutput->WriteStringArray(stringArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteObjectArray(String^ fieldName, List<Object^>^ objectArray)
{
AddOffset();
m_dataOutput->WriteObjectArray(objectArray);
return this;
}
IPdxWriter^ PdxLocalWriter::WriteArrayOfByteArrays(String^ fieldName, array<array<Byte>^>^ byteArrays)
{
AddOffset();
m_dataOutput->WriteArrayOfByteArrays(byteArrays);
return this;
}
//TODO:
//IPdxWriter^ PdxLocalWriter::WriteEnum(String^ fieldName, Enum e) ;
//IPdxWriter^ PdxLocalWriter::WriteInetAddress(String^ fieldName, InetAddress address);
IPdxWriter^ PdxLocalWriter::MarkIdentityField(String^ fieldName)
{
return this;
}
IPdxWriter^ PdxLocalWriter::WriteField(String^ fieldName, Object^ fieldValue, Type^ type)
{
if(type->Equals(DotNetTypes::IntType))
{
return this->WriteInt(fieldName, (int)fieldValue);
}
else if(type->Equals(DotNetTypes::StringType))
{
return this->WriteString(fieldName, (String^)fieldValue);
}
else if(type->Equals(DotNetTypes::BooleanType))
{
return this->WriteBoolean(fieldName, (bool)fieldValue);
}
else if(type->Equals(DotNetTypes::FloatType))
{
return this->WriteFloat(fieldName, (float)fieldValue);
}
else if(type->Equals(DotNetTypes::DoubleType))
{
return this->WriteDouble(fieldName, (double)fieldValue);
}
else if(type->Equals(DotNetTypes::CharType))
{
return this->WriteChar(fieldName, (Char)fieldValue);
}
else if(type->Equals(DotNetTypes::SByteType))
{
return this->WriteByte(fieldName, (SByte)fieldValue);
}
else if(type->Equals(DotNetTypes::ShortType))
{
return this->WriteShort(fieldName, (short)fieldValue);
}
else if(type->Equals(DotNetTypes::LongType))
{
return this->WriteLong(fieldName, (Int64)fieldValue);
}
else if(type->Equals(DotNetTypes::ByteArrayType))
{
return this->WriteByteArray(fieldName, (array<Byte>^)fieldValue);
}
else if(type->Equals(DotNetTypes::DoubleArrayType))
{
return this->WriteDoubleArray(fieldName, (array<double>^)fieldValue);
}
else if(type->Equals(DotNetTypes::FloatArrayType))
{
return this->WriteFloatArray(fieldName, (array<float>^)fieldValue);
}
else if(type->Equals(DotNetTypes::ShortArrayType))
{
return this->WriteShortArray(fieldName, (array<Int16>^)fieldValue);
}
else if(type->Equals(DotNetTypes::IntArrayType))
{
return this->WriteIntArray(fieldName, (array<System::Int32>^)fieldValue);
}
else if(type->Equals(DotNetTypes::LongArrayType))
{
return this->WriteLongArray(fieldName, (array<Int64>^)fieldValue);
}
else if(type->Equals(DotNetTypes::BoolArrayType))
{
return this->WriteBooleanArray(fieldName, (array<bool>^)fieldValue);
}
else if(type->Equals(DotNetTypes::CharArrayType))
{
return this->WriteCharArray(fieldName, (array<Char>^)fieldValue);
}
else if(type->Equals(DotNetTypes::StringArrayType))
{
return this->WriteStringArray(fieldName, (array<String^>^)fieldValue);
}
else if(type->Equals(DotNetTypes::DateType))
{
return this->WriteDate(fieldName, (DateTime)fieldValue);
}
else if(type->Equals(DotNetTypes::ByteArrayOfArrayType))
{
return this->WriteArrayOfByteArrays(fieldName, (array<array<Byte>^>^)fieldValue);
}
else if(type->Equals(DotNetTypes::ObjectArrayType))
{
return this->WriteObjectArray(fieldName, safe_cast<System::Collections::Generic::List<Object^>^>(fieldValue));
}
else
{
return this->WriteObject(fieldName, fieldValue);
}
}
PdxType^ PdxLocalWriter::GetLocalPdxType(String^ pdxClassName)
{
return m_dataOutput->Cache->GetPdxTypeRegistry()->GetLocalPdxType(pdxClassName);
}
Apache::Geode::Client::Cache^ PdxLocalWriter::Cache::get() { return m_dataOutput->Cache; }
} // namespace Internal
} // namespace Client
} // namespace Geode
} // namespace Apache