You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/10/22 11:27:36 UTC
[44/50] [abbrv] ignite git commit: Merge branch 'ignite-1282' into
ignite-1651
http://git-wip-us.apache.org/repos/asf/ignite/blob/ec58b87c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
----------------------------------------------------------------------
diff --cc modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
index 0000000,b490460..6146362
mode 000000,100644..100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@@ -1,0 -1,1619 +1,1620 @@@
+ /*
+ * 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.
+ */
+
+ namespace Apache.Ignite.Core.Impl.Portable
+ {
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.IO;
+
+ using Apache.Ignite.Core.Impl.Portable.IO;
+ using Apache.Ignite.Core.Impl.Portable.Metadata;
+ using Apache.Ignite.Core.Impl.Portable.Structure;
+ using Apache.Ignite.Core.Portable;
+
+ using PU = PortableUtils;
+
+ /// <summary>
+ /// Portable writer implementation.
+ /// </summary>
+ internal class PortableWriterImpl : IPortableWriter, IPortableRawWriter
+ {
+ /** Marshaller. */
+ private readonly PortableMarshaller _marsh;
+
+ /** Stream. */
+ private readonly IPortableStream _stream;
+
+ /** Builder (used only during build). */
+ private PortableBuilderImpl _builder;
+
+ /** Handles. */
+ private PortableHandleDictionary<object, long> _hnds;
+
+ /** Metadatas collected during this write session. */
+ private IDictionary<int, IPortableMetadata> _metas;
+
+ /** Current type ID. */
+ private int _curTypeId;
+
+ /** Current name converter */
+ private IPortableNameMapper _curConverter;
+
+ /** Current mapper. */
+ private IPortableIdMapper _curMapper;
+
+ /** Current raw position. */
+ private long _curRawPos;
+
+ /** Current type structure. */
+ private PortableStructure _curStruct;
+
+ /** Current type structure path index. */
+ private int _curStructPath;
+
+ /** Current type structure action index. */
+ private int _curStructAction;
+
+ /** Current type structure updates. */
+ private List<PortableStructureUpdate> _curStructUpdates;
+
+ /** Whether we are currently detaching an object. */
+ private bool _detaching;
+
+ /// <summary>
+ /// Gets the marshaller.
+ /// </summary>
+ internal PortableMarshaller Marshaller
+ {
+ get { return _marsh; }
+ }
+
+ /// <summary>
+ /// Write named boolean value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Boolean value.</param>
+ public void WriteBoolean(string fieldName, bool val)
+ {
+ WriteFieldId(fieldName, PU.TypeBool);
+
+ _stream.WriteInt(PU.LengthTypeId + 1);
+ _stream.WriteByte(PU.TypeBool);
+ _stream.WriteBool(val);
+ }
+
+ /// <summary>
+ /// Write boolean value.
+ /// </summary>
+ /// <param name="val">Boolean value.</param>
+ public void WriteBoolean(bool val)
+ {
+ _stream.WriteBool(val);
+ }
+
+ /// <summary>
+ /// Write named boolean array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Boolean array.</param>
+ public void WriteBooleanArray(string fieldName, bool[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayBool);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + val.Length);
+ _stream.WriteByte(PU.TypeArrayBool);
+ PU.WriteBooleanArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write boolean array.
+ /// </summary>
+ /// <param name="val">Boolean array.</param>
+ public void WriteBooleanArray(bool[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayBool);
+ PU.WriteBooleanArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named byte value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Byte value.</param>
+ public void WriteByte(string fieldName, byte val)
+ {
+ WriteFieldId(fieldName, PU.TypeBool);
+
+ _stream.WriteInt(PU.LengthTypeId + 1);
+ _stream.WriteByte(PU.TypeByte);
+ _stream.WriteByte(val);
+ }
+
+ /// <summary>
+ /// Write byte value.
+ /// </summary>
+ /// <param name="val">Byte value.</param>
+ public void WriteByte(byte val)
+ {
+ _stream.WriteByte(val);
+ }
+
+ /// <summary>
+ /// Write named byte array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Byte array.</param>
+ public void WriteByteArray(string fieldName, byte[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayByte);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + val.Length);
+ _stream.WriteByte(PU.TypeArrayByte);
+ PU.WriteByteArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write byte array.
+ /// </summary>
+ /// <param name="val">Byte array.</param>
+ public void WriteByteArray(byte[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayByte);
+ PU.WriteByteArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named short value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Short value.</param>
+ public void WriteShort(string fieldName, short val)
+ {
+ WriteFieldId(fieldName, PU.TypeShort);
+
+ _stream.WriteInt(PU.LengthTypeId + 2);
+ _stream.WriteByte(PU.TypeShort);
+ _stream.WriteShort(val);
+ }
+
+ /// <summary>
+ /// Write short value.
+ /// </summary>
+ /// <param name="val">Short value.</param>
+ public void WriteShort(short val)
+ {
+ _stream.WriteShort(val);
+ }
+
+ /// <summary>
+ /// Write named short array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Short array.</param>
+ public void WriteShortArray(string fieldName, short[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayShort);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 1));
+ _stream.WriteByte(PU.TypeArrayShort);
+ PU.WriteShortArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write short array.
+ /// </summary>
+ /// <param name="val">Short array.</param>
+ public void WriteShortArray(short[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayShort);
+ PU.WriteShortArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named char value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Char value.</param>
+ public void WriteChar(string fieldName, char val)
+ {
+ WriteFieldId(fieldName, PU.TypeChar);
+
+ _stream.WriteInt(PU.LengthTypeId + 2);
+ _stream.WriteByte(PU.TypeChar);
+ _stream.WriteChar(val);
+ }
+
+ /// <summary>
+ /// Write char value.
+ /// </summary>
+ /// <param name="val">Char value.</param>
+ public void WriteChar(char val)
+ {
+ _stream.WriteChar(val);
+ }
+
+ /// <summary>
+ /// Write named char array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Char array.</param>
+ public void WriteCharArray(string fieldName, char[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayChar);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 1));
+ _stream.WriteByte(PU.TypeArrayChar);
+ PU.WriteCharArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write char array.
+ /// </summary>
+ /// <param name="val">Char array.</param>
+ public void WriteCharArray(char[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayChar);
+ PU.WriteCharArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named int value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Int value.</param>
+ public void WriteInt(string fieldName, int val)
+ {
+ WriteFieldId(fieldName, PU.TypeInt);
+
+ _stream.WriteInt(PU.LengthTypeId + 4);
+ _stream.WriteByte(PU.TypeInt);
+ _stream.WriteInt(val);
+ }
+
+ /// <summary>
+ /// Write int value.
+ /// </summary>
+ /// <param name="val">Int value.</param>
+ public void WriteInt(int val)
+ {
+ _stream.WriteInt(val);
+ }
+
+ /// <summary>
+ /// Write named int array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Int array.</param>
+ public void WriteIntArray(string fieldName, int[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayInt);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 2));
+ _stream.WriteByte(PU.TypeArrayInt);
+ PU.WriteIntArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write int array.
+ /// </summary>
+ /// <param name="val">Int array.</param>
+ public void WriteIntArray(int[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayInt);
+ PU.WriteIntArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named long value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Long value.</param>
+ public void WriteLong(string fieldName, long val)
+ {
+ WriteFieldId(fieldName, PU.TypeLong);
+
+ _stream.WriteInt(PU.LengthTypeId + 8);
+ _stream.WriteByte(PU.TypeLong);
+ _stream.WriteLong(val);
+ }
+
+ /// <summary>
+ /// Write long value.
+ /// </summary>
+ /// <param name="val">Long value.</param>
+ public void WriteLong(long val)
+ {
+ _stream.WriteLong(val);
+ }
+
+ /// <summary>
+ /// Write named long array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Long array.</param>
+ public void WriteLongArray(string fieldName, long[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayLong);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 3));
+ _stream.WriteByte(PU.TypeArrayLong);
+ PU.WriteLongArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write long array.
+ /// </summary>
+ /// <param name="val">Long array.</param>
+ public void WriteLongArray(long[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayLong);
+ PU.WriteLongArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named float value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Float value.</param>
+ public void WriteFloat(string fieldName, float val)
+ {
+ WriteFieldId(fieldName, PU.TypeFloat);
+
+ _stream.WriteInt(PU.LengthTypeId + 4);
+ _stream.WriteByte(PU.TypeFloat);
+ _stream.WriteFloat(val);
+ }
+
+ /// <summary>
+ /// Write float value.
+ /// </summary>
+ /// <param name="val">Float value.</param>
+ public void WriteFloat(float val)
+ {
+ _stream.WriteFloat(val);
+ }
+
+ /// <summary>
+ /// Write named float array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Float array.</param>
+ public void WriteFloatArray(string fieldName, float[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayFloat);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 2));
+ _stream.WriteByte(PU.TypeArrayFloat);
+ PU.WriteFloatArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write float array.
+ /// </summary>
+ /// <param name="val">Float array.</param>
+ public void WriteFloatArray(float[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayFloat);
+ PU.WriteFloatArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named double value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Double value.</param>
+ public void WriteDouble(string fieldName, double val)
+ {
+ WriteFieldId(fieldName, PU.TypeDouble);
+
+ _stream.WriteInt(PU.LengthTypeId + 8);
+ _stream.WriteByte(PU.TypeDouble);
+ _stream.WriteDouble(val);
+ }
+
+ /// <summary>
+ /// Write double value.
+ /// </summary>
+ /// <param name="val">Double value.</param>
+ public void WriteDouble(double val)
+ {
+ _stream.WriteDouble(val);
+ }
+
+ /// <summary>
+ /// Write named double array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Double array.</param>
+ public void WriteDoubleArray(string fieldName, double[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayDouble);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 3));
+ _stream.WriteByte(PU.TypeArrayDouble);
+ PU.WriteDoubleArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write double array.
+ /// </summary>
+ /// <param name="val">Double array.</param>
+ public void WriteDoubleArray(double[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayDouble);
+ PU.WriteDoubleArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named decimal value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Decimal value.</param>
+ public void WriteDecimal(string fieldName, decimal? val)
+ {
+ WriteFieldId(fieldName, PU.TypeDecimal);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeDecimal);
+ PortableUtils.WriteDecimal(val.Value, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write decimal value.
+ /// </summary>
+ /// <param name="val">Decimal value.</param>
+ public void WriteDecimal(decimal? val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeDecimal);
+ PortableUtils.WriteDecimal(val.Value, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named decimal array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Decimal array.</param>
+ public void WriteDecimalArray(string fieldName, decimal?[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayDecimal);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeArrayDecimal);
+ PU.WriteDecimalArray(val, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write decimal array.
+ /// </summary>
+ /// <param name="val">Decimal array.</param>
+ public void WriteDecimalArray(decimal?[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayDecimal);
+ PU.WriteDecimalArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named date value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Date value.</param>
+ public void WriteDate(string fieldName, DateTime? val)
+ {
+ WriteFieldId(fieldName, PU.TypeDate);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + 12);
+
+ _stream.WriteByte(PortableUtils.TypeDate);
+ PortableUtils.WriteDate(val.Value, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write date value.
+ /// </summary>
+ /// <param name="val">Date value.</param>
+ public void WriteDate(DateTime? val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PortableUtils.TypeDate);
+ PortableUtils.WriteDate(val.Value, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named date array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Date array.</param>
+ public void WriteDateArray(string fieldName, DateTime?[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeDate);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PortableUtils.TypeArrayDate);
+ PortableUtils.WriteDateArray(val, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write date array.
+ /// </summary>
+ /// <param name="val">Date array.</param>
+ public void WriteDateArray(DateTime?[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PortableUtils.TypeArrayDate);
+ PortableUtils.WriteDateArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named string value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">String value.</param>
+ public void WriteString(string fieldName, string val)
+ {
+ WriteFieldId(fieldName, PU.TypeString);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeString);
+ PU.WriteString(val, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write string value.
+ /// </summary>
+ /// <param name="val">String value.</param>
+ public void WriteString(string val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeString);
+ PU.WriteString(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named string array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">String array.</param>
+ public void WriteStringArray(string fieldName, string[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayString);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeArrayString);
+ PU.WriteStringArray(val, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write string array.
+ /// </summary>
+ /// <param name="val">String array.</param>
+ public void WriteStringArray(string[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayString);
+ PU.WriteStringArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named GUID value.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">GUID value.</param>
+ public void WriteGuid(string fieldName, Guid? val)
+ {
+ WriteFieldId(fieldName, PU.TypeGuid);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ _stream.WriteInt(PU.LengthTypeId + 16);
+
+ _stream.WriteByte(PU.TypeGuid);
+ PU.WriteGuid(val.Value, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write GUID value.
+ /// </summary>
+ /// <param name="val">GUID value.</param>
+ public void WriteGuid(Guid? val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeGuid);
+ PU.WriteGuid(val.Value, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named GUID array.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">GUID array.</param>
+ public void WriteGuidArray(string fieldName, Guid?[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayGuid);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeArrayGuid);
+ PU.WriteGuidArray(val, _stream);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write GUID array.
+ /// </summary>
+ /// <param name="val">GUID array.</param>
+ public void WriteGuidArray(Guid?[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayGuid);
+ PU.WriteGuidArray(val, _stream);
+ }
+ }
+
+ /// <summary>
+ /// Write named enum value.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Enum value.</param>
+ public void WriteEnum<T>(string fieldName, T val)
+ {
+ WriteFieldId(fieldName, PU.TypeEnum);
+
+ _stream.WriteInt(PU.LengthTypeId + 16);
+
+ _stream.WriteByte(PU.TypeEnum);
+ PortableUtils.WriteEnum(_stream, (Enum)(object)val);
+ }
+
+ /// <summary>
+ /// Write enum value.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="val">Enum value.</param>
+ public void WriteEnum<T>(T val)
+ {
+ _stream.WriteByte(PU.TypeEnum);
+ PortableUtils.WriteEnum(_stream, (Enum)(object)val);
+ }
+
+ /// <summary>
+ /// Write named enum array.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Enum array.</param>
+ public void WriteEnumArray<T>(string fieldName, T[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArrayEnum);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeArrayEnum);
+ PortableUtils.WriteArray(val, this, true);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write enum array.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="val">Enum array.</param>
+ public void WriteEnumArray<T>(T[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArrayEnum);
+ PortableUtils.WriteArray(val, this, true);
+ }
+ }
+
+ /// <summary>
+ /// Write named object value.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Object value.</param>
+ public void WriteObject<T>(string fieldName, T val)
+ {
+ WriteFieldId(fieldName, PU.TypeObject);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ Write(val);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write object value.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="val">Object value.</param>
+ public void WriteObject<T>(T val)
+ {
+ Write(val);
+ }
+
+ /// <summary>
+ /// Write named object array.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Object array.</param>
+ public void WriteObjectArray<T>(string fieldName, T[] val)
+ {
+ WriteFieldId(fieldName, PU.TypeArray);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ _stream.WriteByte(PU.TypeArray);
+ PortableUtils.WriteArray(val, this, true);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write object array.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="val">Object array.</param>
+ public void WriteObjectArray<T>(T[] val)
+ {
+ if (val == null)
+ WriteNullRawField();
+ else
+ {
+ _stream.WriteByte(PU.TypeArray);
+ PortableUtils.WriteArray(val, this, true);
+ }
+ }
+
+ /// <summary>
+ /// Write named collection.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Collection.</param>
+ public void WriteCollection(string fieldName, ICollection val)
+ {
+ WriteFieldId(fieldName, PU.TypeCollection);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ Write(val);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write collection.
+ /// </summary>
+ /// <param name="val">Collection.</param>
+ public void WriteCollection(ICollection val)
+ {
+ Write(val);
+ }
+
+ /// <summary>
+ /// Write named generic collection.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Collection.</param>
+ public void WriteGenericCollection<T>(string fieldName, ICollection<T> val)
+ {
+ WriteFieldId(fieldName, PU.TypeCollection);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ Write(val);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write generic collection.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="val">Collection.</param>
+ public void WriteGenericCollection<T>(ICollection<T> val)
+ {
+ Write(val);
+ }
+
+ /// <summary>
+ /// Write named dictionary.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Dictionary.</param>
+ public void WriteDictionary(string fieldName, IDictionary val)
+ {
+ WriteFieldId(fieldName, PU.TypeDictionary);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ Write(val);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write dictionary.
+ /// </summary>
+ /// <param name="val">Dictionary.</param>
+ public void WriteDictionary(IDictionary val)
+ {
+ Write(val);
+ }
+
+ /// <summary>
+ /// Write named generic dictionary.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="val">Dictionary.</param>
+ public void WriteGenericDictionary<TK, TV>(string fieldName, IDictionary<TK, TV> val)
+ {
+ WriteFieldId(fieldName, PU.TypeDictionary);
+
+ if (val == null)
+ WriteNullField();
+ else
+ {
+ int pos = SkipFieldLength();
+
+ Write(val);
+
+ WriteFieldLength(_stream, pos);
+ }
+ }
+
+ /// <summary>
+ /// Write generic dictionary.
+ /// </summary>
+ /// <param name="val">Dictionary.</param>
+ public void WriteGenericDictionary<TK, TV>(IDictionary<TK, TV> val)
+ {
+ Write(val);
+ }
+
+ /// <summary>
+ /// Write NULL field.
+ /// </summary>
+ public void WriteNullField()
+ {
+ _stream.WriteInt(1);
+ _stream.WriteByte(PU.HdrNull);
+ }
+
+ /// <summary>
+ /// Write NULL raw field.
+ /// </summary>
+ public void WriteNullRawField()
+ {
+ _stream.WriteByte(PU.HdrNull);
+ }
+
+ /// <summary>
+ /// Get raw writer.
+ /// </summary>
+ /// <returns>
+ /// Raw writer.
+ /// </returns>
+ public IPortableRawWriter GetRawWriter()
+ {
+ if (_curRawPos == 0)
+ _curRawPos = _stream.Position;
+
+ return this;
+ }
+
+ /// <summary>
+ /// Set new builder.
+ /// </summary>
+ /// <param name="builder">Builder.</param>
+ /// <returns>Previous builder.</returns>
+ internal PortableBuilderImpl Builder(PortableBuilderImpl builder)
+ {
+ PortableBuilderImpl ret = _builder;
+
+ _builder = builder;
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="marsh">Marshaller.</param>
+ /// <param name="stream">Stream.</param>
+ internal PortableWriterImpl(PortableMarshaller marsh, IPortableStream stream)
+ {
+ _marsh = marsh;
+ _stream = stream;
+ }
+
+ /// <summary>
+ /// Write object.
+ /// </summary>
+ /// <param name="obj">Object.</param>
+ public void Write<T>(T obj)
+ {
+ // Handle special case for null.
+ if (obj == null)
+ {
+ _stream.WriteByte(PU.HdrNull);
+
+ return;
+ }
+
+ // We use GetType() of a real object instead of typeof(T) to take advantage of
+ // automatic Nullable'1 unwrapping.
+ Type type = obj.GetType();
+
+ // Handle common case when primitive is written.
+ if (type.IsPrimitive)
+ {
+ WritePrimitive(obj, type);
+
+ return;
+ }
+
+ // Handle special case for builder.
+ if (WriteBuilderSpecials(obj))
+ return;
+
+ // Suppose that we faced normal object and perform descriptor lookup.
+ IPortableTypeDescriptor desc = _marsh.GetDescriptor(type);
+
+ if (desc != null)
+ {
+ // Writing normal object.
+ var pos = _stream.Position;
+
+ // Dealing with handles.
+ if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
+ return;
+
+ // Write header.
+ _stream.WriteByte(PU.HdrFull);
++ _stream.WriteByte(PU.ProtoVer);
+ _stream.WriteBool(desc.UserType);
+ _stream.WriteInt(desc.TypeId);
+ _stream.WriteInt(obj.GetHashCode());
+
+ // Skip length as it is not known in the first place.
+ _stream.Seek(8, SeekOrigin.Current);
+
+ // Preserve old frame.
+ int oldTypeId = _curTypeId;
+ IPortableNameMapper oldConverter = _curConverter;
+ IPortableIdMapper oldMapper = _curMapper;
+ long oldRawPos = _curRawPos;
+
+ PortableStructure oldStruct = _curStruct;
+ int oldStructPath = _curStructPath;
+ int oldStructAction = _curStructAction;
+ var oldStructUpdates = _curStructUpdates;
+
+ // Push new frame.
+ _curTypeId = desc.TypeId;
+ _curConverter = desc.NameConverter;
+ _curMapper = desc.Mapper;
+ _curRawPos = 0;
+
+ _curStruct = desc.TypeStructure;
+ _curStructPath = 0;
+ _curStructAction = 0;
+ _curStructUpdates = null;
+
+ // Write object fields.
+ desc.Serializer.WritePortable(obj, this);
+
+ // Calculate and write length.
+ int len = _stream.Position - pos;
+
- _stream.WriteInt(pos + 10, len);
++ _stream.Seek(pos + PU.OffsetLen, SeekOrigin.Begin);
+
+ if (_curRawPos != 0)
- _stream.WriteInt(pos + 14, (int)(_curRawPos - pos));
++ _stream.WriteInt(pos + PU.OffsetRaw, (int)(_curRawPos - pos));
+ else
- _stream.WriteInt(pos + 14, len);
++ _stream.WriteInt(pos + PU.OffsetRaw, len);
+
+ // Apply structure updates if any.
+ if (_curStructUpdates != null)
+ {
+ desc.UpdateStructure(_curStruct, _curStructPath, _curStructUpdates);
+
+ IPortableMetadataHandler metaHnd = _marsh.GetMetadataHandler(desc);
+
+ if (metaHnd != null)
+ {
+ foreach (var u in _curStructUpdates)
+ metaHnd.OnFieldWrite(u.FieldId, u.FieldName, u.FieldType);
+
+ IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished();
+
+ if (meta != null)
+ SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+ }
+ }
+
+ // Restore old frame.
+ _curTypeId = oldTypeId;
+ _curConverter = oldConverter;
+ _curMapper = oldMapper;
+ _curRawPos = oldRawPos;
+
+ _curStruct = oldStruct;
+ _curStructPath = oldStructPath;
+ _curStructAction = oldStructAction;
+ _curStructUpdates = oldStructUpdates;
+ }
+ else
+ {
+ // Are we dealing with a well-known type?
+ PortableSystemWriteDelegate handler = PortableSystemHandlers.GetWriteHandler(type);
+
+ if (handler != null)
+ handler.Invoke(this, obj);
+ else
+ {
+ // Last chance: is object seializable?
+ if (type.IsSerializable)
+ Write(new SerializableObjectHolder(obj));
+ else
+ // We did our best, object cannot be marshalled.
+ throw new PortableException("Unsupported object type [type=" + type + ", object=" + obj + ']');
+ }
+ }
+ }
+
+ /// <summary>
+ /// Write primitive type.
+ /// </summary>
+ /// <param name="val">Object.</param>
+ /// <param name="type">Type.</param>
+ public unsafe void WritePrimitive<T>(T val, Type type)
+ {
+ // .Net defines 14 primitive types. We support 12 - excluding IntPtr and UIntPtr.
+ // Types check sequence is designed to minimize comparisons for the most frequent types.
+
+ if (type == typeof(int))
+ {
+ _stream.WriteByte(PU.TypeInt);
+ _stream.WriteInt((int)(object)val);
+ }
+ else if (type == typeof(long))
+ {
+ _stream.WriteByte(PU.TypeLong);
+ _stream.WriteLong((long)(object)val);
+ }
+ else if (type == typeof(bool))
+ {
+ _stream.WriteByte(PU.TypeBool);
+ _stream.WriteBool((bool)(object)val);
+ }
+ else if (type == typeof(byte))
+ {
+ _stream.WriteByte(PU.TypeByte);
+ _stream.WriteByte((byte)(object)val);
+ }
+ else if (type == typeof(short))
+ {
+ _stream.WriteByte(PU.TypeShort);
+ _stream.WriteShort((short)(object)val);
+ }
+ else if (type == typeof (char))
+ {
+ _stream.WriteByte(PU.TypeChar);
+ _stream.WriteChar((char)(object)val);
+ }
+ else if (type == typeof(float))
+ {
+ _stream.WriteByte(PU.TypeFloat);
+ _stream.WriteFloat((float)(object)val);
+ }
+ else if (type == typeof(double))
+ {
+ _stream.WriteByte(PU.TypeDouble);
+ _stream.WriteDouble((double)(object)val);
+ }
+ else if (type == typeof(sbyte))
+ {
+ sbyte val0 = (sbyte)(object)val;
+
+ _stream.WriteByte(PU.TypeByte);
+ _stream.WriteByte(*(byte*)&val0);
+ }
+ else if (type == typeof(ushort))
+ {
+ ushort val0 = (ushort)(object)val;
+
+ _stream.WriteByte(PU.TypeShort);
+ _stream.WriteShort(*(short*)&val0);
+ }
+ else if (type == typeof(uint))
+ {
+ uint val0 = (uint)(object)val;
+
+ _stream.WriteByte(PU.TypeInt);
+ _stream.WriteInt(*(int*)&val0);
+ }
+ else if (type == typeof(ulong))
+ {
+ ulong val0 = (ulong)(object)val;
+
+ _stream.WriteByte(PU.TypeLong);
+ _stream.WriteLong(*(long*)&val0);
+ }
+ else
+ throw new PortableException("Unsupported object type [type=" + type.FullName + ", object=" + val + ']');
+ }
+
+ /// <summary>
+ /// Try writing object as special builder type.
+ /// </summary>
+ /// <param name="obj">Object.</param>
+ /// <returns>True if object was written, false otherwise.</returns>
+ private bool WriteBuilderSpecials<T>(T obj)
+ {
+ if (_builder != null)
+ {
+ // Special case for portable object during build.
+ PortableUserObject portObj = obj as PortableUserObject;
+
+ if (portObj != null)
+ {
+ if (!WriteHandle(_stream.Position, portObj))
+ _builder.ProcessPortable(_stream, portObj);
+
+ return true;
+ }
+
+ // Special case for builder during build.
+ PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
+
+ if (portBuilder != null)
+ {
+ if (!WriteHandle(_stream.Position, portBuilder))
+ _builder.ProcessBuilder(_stream, portBuilder);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Add handle to handles map.
+ /// </summary>
+ /// <param name="pos">Position in stream.</param>
+ /// <param name="obj">Object.</param>
+ /// <returns><c>true</c> if object was written as handle.</returns>
+ private bool WriteHandle(long pos, object obj)
+ {
+ if (_hnds == null)
+ {
+ // Cache absolute handle position.
+ _hnds = new PortableHandleDictionary<object, long>(obj, pos);
+
+ return false;
+ }
+
+ long hndPos;
+
+ if (!_hnds.TryGetValue(obj, out hndPos))
+ {
+ // Cache absolute handle position.
+ _hnds.Add(obj, pos);
+
+ return false;
+ }
+
+ _stream.WriteByte(PU.HdrHnd);
+
+ // Handle is written as difference between position before header and handle position.
+ _stream.WriteInt((int)(pos - hndPos));
+
+ return true;
+ }
+
+ /// <summary>
+ /// Perform action with detached semantics.
+ /// </summary>
+ /// <param name="a"></param>
+ internal void WithDetach(Action<PortableWriterImpl> a)
+ {
+ if (_detaching)
+ a(this);
+ else
+ {
+ _detaching = true;
+
+ PortableHandleDictionary<object, long> oldHnds = _hnds;
+ _hnds = null;
+
+ try
+ {
+ a(this);
+ }
+ finally
+ {
+ _detaching = false;
+
+ if (oldHnds != null)
+ {
+ // Merge newly recorded handles with old ones and restore old on the stack.
+ // Otherwise we can use current handles right away.
+ if (_hnds != null)
+ oldHnds.Merge(_hnds);
+
+ _hnds = oldHnds;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stream.
+ /// </summary>
+ internal IPortableStream Stream
+ {
+ get { return _stream; }
+ }
+
+ /// <summary>
+ /// Gets collected metadatas.
+ /// </summary>
+ /// <returns>Collected metadatas (if any).</returns>
+ internal IDictionary<int, IPortableMetadata> Metadata()
+ {
+ return _metas;
+ }
+
+ /// <summary>
+ /// Check whether the given object is portable, i.e. it can be
+ /// serialized with portable marshaller.
+ /// </summary>
+ /// <param name="obj">Object.</param>
+ /// <returns>True if portable.</returns>
+ internal bool IsPortable(object obj)
+ {
+ if (obj != null)
+ {
+ Type type = obj.GetType();
+
+ // We assume object as portable only in case it has descriptor.
+ // Collections, Enums and non-primitive arrays do not have descriptors
+ // and this is fine here because we cannot know whether their members
+ // are portable.
+ return _marsh.GetDescriptor(type) != null || PortableSystemHandlers.GetWriteHandler(type) != null;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Write field ID.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldTypeId">Field type ID.</param>
+ private void WriteFieldId(string fieldName, byte fieldTypeId)
+ {
+ if (_curRawPos != 0)
+ throw new PortableException("Cannot write named fields after raw data is written.");
+
+ int action = _curStructAction++;
+
+ int fieldId;
+
+ if (_curStructUpdates == null)
+ {
+ fieldId = _curStruct.GetFieldId(fieldName, fieldTypeId, ref _curStructPath, action);
+
+ if (fieldId == 0)
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, action);
+ }
+ else
+ fieldId = GetNewFieldId(fieldName, fieldTypeId, action);
+
+ _stream.WriteInt(fieldId);
+ }
+
+ /// <summary>
+ /// Get ID for the new field and save structure update.
+ /// </summary>
+ /// <param name="fieldName">Field name.</param>
+ /// <param name="fieldTypeId">Field type ID.</param>
+ /// <param name="action">Action index.</param>
+ /// <returns>Field ID.</returns>
+ private int GetNewFieldId(string fieldName, byte fieldTypeId, int action)
+ {
+ int fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+ if (_curStructUpdates == null)
+ _curStructUpdates = new List<PortableStructureUpdate>();
+
+ _curStructUpdates.Add(new PortableStructureUpdate(fieldName, fieldId, fieldTypeId, action));
+
+ return fieldId;
+ }
+
+ /// <summary>
+ /// Skip field lenght and return position where it is to be written.
+ /// </summary>
+ /// <returns></returns>
+ private int SkipFieldLength()
+ {
+ int pos = _stream.Position;
+
+ _stream.Seek(4, SeekOrigin.Current);
+
+ return pos;
+ }
+
+ /// <summary>
+ /// Write field length.
+ /// </summary>
+ /// <param name="stream">Stream.</param>
+ /// <param name="pos">Position where length should reside</param>
+ private static void WriteFieldLength(IPortableStream stream, int pos)
+ {
+ // Length is is a difference between current position and previously recorder
+ // length placeholder position minus 4 bytes for the length itself.
+ stream.WriteInt(pos, stream.Position - pos - 4);
+ }
+
+ /// <summary>
+ /// Saves metadata for this session.
+ /// </summary>
+ /// <param name="typeId">Type ID.</param>
+ /// <param name="typeName">Type name.</param>
+ /// <param name="affKeyFieldName">Affinity key field name.</param>
+ /// <param name="fields">Fields metadata.</param>
+ internal void SaveMetadata(int typeId, string typeName, string affKeyFieldName, IDictionary<string, int> fields)
+ {
+ if (_metas == null)
+ {
+ PortableMetadataImpl meta =
+ new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName);
+
+ _metas = new Dictionary<int, IPortableMetadata>(1);
+
+ _metas[typeId] = meta;
+ }
+ else
+ {
+ IPortableMetadata meta;
+
+ if (_metas.TryGetValue(typeId, out meta))
+ {
+ IDictionary<string, int> existingFields = ((PortableMetadataImpl)meta).FieldsMap();
+
+ foreach (KeyValuePair<string, int> field in fields)
+ {
+ if (!existingFields.ContainsKey(field.Key))
+ existingFields[field.Key] = field.Value;
+ }
+ }
+ else
+ _metas[typeId] = new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName);
+ }
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/ignite/blob/ec58b87c/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
----------------------------------------------------------------------
diff --cc modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
index 0000000,5b73171..451386b
mode 000000,100644..100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
@@@ -1,0 -1,192 +1,193 @@@
+ /*
+ * 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.
+ */
+
+ namespace Apache.Ignite.Core.Impl.Portable
+ {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl.Common;
+ using Apache.Ignite.Core.Impl.Portable.IO;
+ using Apache.Ignite.Core.Portable;
+
+ /// <summary>
+ /// Portables implementation.
+ /// </summary>
+ internal class PortablesImpl : IPortables
+ {
+ /** Owning grid. */
+ private readonly PortableMarshaller _marsh;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="marsh">Marshaller.</param>
+ internal PortablesImpl(PortableMarshaller marsh)
+ {
+ _marsh = marsh;
+ }
+
+ /** <inheritDoc /> */
+ public T ToPortable<T>(object obj)
+ {
+ if (obj is IPortableObject)
+ return (T)obj;
+
+ IPortableStream stream = new PortableHeapStream(1024);
+
+ // Serialize.
+ PortableWriterImpl writer = _marsh.StartMarshal(stream);
+
+ try
+ {
+ writer.Write(obj);
+ }
+ finally
+ {
+ // Save metadata.
+ _marsh.FinishMarshal(writer);
+ }
+
+ // Deserialize.
+ stream.Seek(0, SeekOrigin.Begin);
+
+ return _marsh.Unmarshal<T>(stream, PortableMode.ForcePortable);
+ }
+
+ /** <inheritDoc /> */
+ public IPortableBuilder GetBuilder(Type type)
+ {
+ IgniteArgumentCheck.NotNull(type, "type");
+
+ IPortableTypeDescriptor desc = _marsh.GetDescriptor(type);
+
+ if (desc == null)
+ throw new IgniteException("Type is not portable (add it to PortableConfiguration): " +
+ type.FullName);
+
+ return Builder0(null, PortableFromDescriptor(desc), desc);
+ }
+
+ /** <inheritDoc /> */
+ public IPortableBuilder GetBuilder(string typeName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+ IPortableTypeDescriptor desc = _marsh.GetDescriptor(typeName);
+
+ return Builder0(null, PortableFromDescriptor(desc), desc);
+ }
+
+ /** <inheritDoc /> */
+ public IPortableBuilder GetBuilder(IPortableObject obj)
+ {
+ IgniteArgumentCheck.NotNull(obj, "obj");
+
+ PortableUserObject obj0 = obj as PortableUserObject;
+
+ if (obj0 == null)
+ throw new ArgumentException("Unsupported object type: " + obj.GetType());
+
+ IPortableTypeDescriptor desc = _marsh.GetDescriptor(true, obj0.TypeId);
+
+ return Builder0(null, obj0, desc);
+ }
+
+ /** <inheritDoc /> */
+ public int GetTypeId(string typeName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+ return Marshaller.GetDescriptor(typeName).TypeId;
+ }
+
+ /** <inheritDoc /> */
+ public ICollection<IPortableMetadata> GetMetadata()
+ {
+ return Marshaller.Ignite.ClusterGroup.Metadata();
+ }
+
+ /** <inheritDoc /> */
+ public IPortableMetadata GetMetadata(int typeId)
+ {
+ return Marshaller.GetMetadata(typeId);
+ }
+
+ /** <inheritDoc /> */
+ public IPortableMetadata GetMetadata(string typeName)
+ {
+ IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+ return GetMetadata(GetTypeId(typeName));
+ }
+
+ /** <inheritDoc /> */
+ public IPortableMetadata GetMetadata(Type type)
+ {
+ IgniteArgumentCheck.NotNull(type, "type");
+
+ var desc = Marshaller.GetDescriptor(type);
+
+ return desc == null ? null : Marshaller.GetMetadata(desc.TypeId);
+ }
+
+ /// <summary>
+ /// Marshaller.
+ /// </summary>
+ internal PortableMarshaller Marshaller
+ {
+ get
+ {
+ return _marsh;
+ }
+ }
+
+ /// <summary>
+ /// Create empty portable object from descriptor.
+ /// </summary>
+ /// <param name="desc">Descriptor.</param>
+ /// <returns>Empty portable object.</returns>
+ private PortableUserObject PortableFromDescriptor(IPortableTypeDescriptor desc)
+ {
+ PortableHeapStream stream = new PortableHeapStream(18);
+
+ stream.WriteByte(PortableUtils.HdrFull);
++ stream.WriteByte(PortableUtils.ProtoVer);
+ stream.WriteBool(true);
+ stream.WriteInt(desc.TypeId);
+ stream.WriteInt(0); // Hash.
+ stream.WriteInt(PortableUtils.FullHdrLen); // Length.
+ stream.WriteInt(PortableUtils.FullHdrLen); // Raw data offset.
+
+ return new PortableUserObject(_marsh, stream.InternalArray, 0, desc.TypeId, 0);
+ }
+
+ /// <summary>
+ /// Internal builder creation routine.
+ /// </summary>
+ /// <param name="parent">Parent builder.</param>
+ /// <param name="obj">Portable object.</param>
+ /// <param name="desc">Type descriptor.</param>
+ /// <returns>Builder.</returns>
+ private PortableBuilderImpl Builder0(PortableBuilderImpl parent, PortableUserObject obj,
+ IPortableTypeDescriptor desc)
+ {
+ return new PortableBuilderImpl(this, parent, obj, desc);
+ }
+ }
+ }