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/11/11 10:13:03 UTC
[16/24] ignite git commit: IGNITE-1845: Adopted new binary API in
.Net.
http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
new file mode 100644
index 0000000..2c10d6a
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
@@ -0,0 +1,832 @@
+/*
+ * 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.Binary
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using Apache.Ignite.Core.Impl.Binary.IO;
+ using Apache.Ignite.Core.Impl.Common;
+
+ /// <summary>
+ /// Write delegate.
+ /// </summary>
+ /// <param name="writer">Write context.</param>
+ /// <param name="obj">Object to write.</param>
+ internal delegate void BinarySystemWriteDelegate(BinaryWriter writer, object obj);
+
+ /**
+ * <summary>Collection of predefined handlers for various system types.</summary>
+ */
+ internal static class BinarySystemHandlers
+ {
+ /** Write handlers. */
+ private static volatile Dictionary<Type, BinarySystemWriteDelegate> _writeHandlers =
+ new Dictionary<Type, BinarySystemWriteDelegate>();
+
+ /** Mutex for write handlers update. */
+ private static readonly object WriteHandlersMux = new object();
+
+ /** Read handlers. */
+ private static readonly IBinarySystemReader[] ReadHandlers = new IBinarySystemReader[255];
+
+ /** Type ids. */
+ private static readonly Dictionary<Type, byte> TypeIds = new Dictionary<Type, byte>
+ {
+ {typeof (bool), BinaryUtils.TypeBool},
+ {typeof (byte), BinaryUtils.TypeByte},
+ {typeof (sbyte), BinaryUtils.TypeByte},
+ {typeof (short), BinaryUtils.TypeShort},
+ {typeof (ushort), BinaryUtils.TypeShort},
+ {typeof (char), BinaryUtils.TypeChar},
+ {typeof (int), BinaryUtils.TypeInt},
+ {typeof (uint), BinaryUtils.TypeInt},
+ {typeof (long), BinaryUtils.TypeLong},
+ {typeof (ulong), BinaryUtils.TypeLong},
+ {typeof (float), BinaryUtils.TypeFloat},
+ {typeof (double), BinaryUtils.TypeDouble},
+ {typeof (string), BinaryUtils.TypeString},
+ {typeof (decimal), BinaryUtils.TypeDecimal},
+ {typeof (Guid), BinaryUtils.TypeGuid},
+ {typeof (Guid?), BinaryUtils.TypeGuid},
+ {typeof (ArrayList), BinaryUtils.TypeCollection},
+ {typeof (Hashtable), BinaryUtils.TypeDictionary},
+ {typeof (DictionaryEntry), BinaryUtils.TypeMapEntry},
+ {typeof (bool[]), BinaryUtils.TypeArrayBool},
+ {typeof (byte[]), BinaryUtils.TypeArrayByte},
+ {typeof (sbyte[]), BinaryUtils.TypeArrayByte},
+ {typeof (short[]), BinaryUtils.TypeArrayShort},
+ {typeof (ushort[]), BinaryUtils.TypeArrayShort},
+ {typeof (char[]), BinaryUtils.TypeArrayChar},
+ {typeof (int[]), BinaryUtils.TypeArrayInt},
+ {typeof (uint[]), BinaryUtils.TypeArrayInt},
+ {typeof (long[]), BinaryUtils.TypeArrayLong},
+ {typeof (ulong[]), BinaryUtils.TypeArrayLong},
+ {typeof (float[]), BinaryUtils.TypeArrayFloat},
+ {typeof (double[]), BinaryUtils.TypeArrayDouble},
+ {typeof (string[]), BinaryUtils.TypeArrayString},
+ {typeof (decimal?[]), BinaryUtils.TypeArrayDecimal},
+ {typeof (Guid?[]), BinaryUtils.TypeArrayGuid},
+ {typeof (object[]), BinaryUtils.TypeArray}
+ };
+
+ /// <summary>
+ /// Initializes the <see cref="BinarySystemHandlers"/> class.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline",
+ Justification = "Readability.")]
+ static BinarySystemHandlers()
+ {
+ // 1. Primitives.
+ ReadHandlers[BinaryUtils.TypeBool] = new BinarySystemReader<bool>(s => s.ReadBool());
+ ReadHandlers[BinaryUtils.TypeByte] = new BinarySystemReader<byte>(s => s.ReadByte());
+ ReadHandlers[BinaryUtils.TypeShort] = new BinarySystemReader<short>(s => s.ReadShort());
+ ReadHandlers[BinaryUtils.TypeChar] = new BinarySystemReader<char>(s => s.ReadChar());
+ ReadHandlers[BinaryUtils.TypeInt] = new BinarySystemReader<int>(s => s.ReadInt());
+ ReadHandlers[BinaryUtils.TypeLong] = new BinarySystemReader<long>(s => s.ReadLong());
+ ReadHandlers[BinaryUtils.TypeFloat] = new BinarySystemReader<float>(s => s.ReadFloat());
+ ReadHandlers[BinaryUtils.TypeDouble] = new BinarySystemReader<double>(s => s.ReadDouble());
+ ReadHandlers[BinaryUtils.TypeDecimal] = new BinarySystemReader<decimal?>(BinaryUtils.ReadDecimal);
+
+ // 2. Date.
+ ReadHandlers[BinaryUtils.TypeTimestamp] = new BinarySystemReader<DateTime?>(BinaryUtils.ReadTimestamp);
+
+ // 3. String.
+ ReadHandlers[BinaryUtils.TypeString] = new BinarySystemReader<string>(BinaryUtils.ReadString);
+
+ // 4. Guid.
+ ReadHandlers[BinaryUtils.TypeGuid] = new BinarySystemReader<Guid?>(BinaryUtils.ReadGuid);
+
+ // 5. Primitive arrays.
+ ReadHandlers[BinaryUtils.TypeArrayBool] = new BinarySystemReader<bool[]>(BinaryUtils.ReadBooleanArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayByte] =
+ new BinarySystemDualReader<byte[], sbyte[]>(BinaryUtils.ReadByteArray, BinaryUtils.ReadSbyteArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayShort] =
+ new BinarySystemDualReader<short[], ushort[]>(BinaryUtils.ReadShortArray,
+ BinaryUtils.ReadUshortArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayChar] =
+ new BinarySystemReader<char[]>(BinaryUtils.ReadCharArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayInt] =
+ new BinarySystemDualReader<int[], uint[]>(BinaryUtils.ReadIntArray, BinaryUtils.ReadUintArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayLong] =
+ new BinarySystemDualReader<long[], ulong[]>(BinaryUtils.ReadLongArray,
+ BinaryUtils.ReadUlongArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayFloat] =
+ new BinarySystemReader<float[]>(BinaryUtils.ReadFloatArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayDouble] =
+ new BinarySystemReader<double[]>(BinaryUtils.ReadDoubleArray);
+
+ ReadHandlers[BinaryUtils.TypeArrayDecimal] =
+ new BinarySystemReader<decimal?[]>(BinaryUtils.ReadDecimalArray);
+
+ // 6. Date array.
+ ReadHandlers[BinaryUtils.TypeArrayTimestamp] =
+ new BinarySystemReader<DateTime?[]>(BinaryUtils.ReadTimestampArray);
+
+ // 7. String array.
+ ReadHandlers[BinaryUtils.TypeArrayString] = new BinarySystemTypedArrayReader<string>();
+
+ // 8. Guid array.
+ ReadHandlers[BinaryUtils.TypeArrayGuid] = new BinarySystemTypedArrayReader<Guid?>();
+
+ // 9. Array.
+ ReadHandlers[BinaryUtils.TypeArray] = new BinarySystemReader(ReadArray);
+
+ // 11. Arbitrary collection.
+ ReadHandlers[BinaryUtils.TypeCollection] = new BinarySystemReader(ReadCollection);
+
+ // 13. Arbitrary dictionary.
+ ReadHandlers[BinaryUtils.TypeDictionary] = new BinarySystemReader(ReadDictionary);
+
+ // 15. Map entry.
+ ReadHandlers[BinaryUtils.TypeMapEntry] = new BinarySystemReader(ReadMapEntry);
+
+ // 16. Enum.
+ ReadHandlers[BinaryUtils.TypeEnum] = new BinarySystemReader<int>(BinaryUtils.ReadEnum<int>);
+ ReadHandlers[BinaryUtils.TypeArrayEnum] = new BinarySystemReader(ReadEnumArray);
+ }
+
+ /// <summary>
+ /// Try getting write handler for type.
+ /// </summary>
+ /// <param name="type"></param>
+ /// <returns></returns>
+ public static BinarySystemWriteDelegate GetWriteHandler(Type type)
+ {
+ BinarySystemWriteDelegate res;
+
+ var writeHandlers0 = _writeHandlers;
+
+ // Have we ever met this type?
+ if (writeHandlers0 != null && writeHandlers0.TryGetValue(type, out res))
+ return res;
+
+ // Determine write handler for type and add it.
+ res = FindWriteHandler(type);
+
+ if (res != null)
+ AddWriteHandler(type, res);
+
+ return res;
+ }
+
+ /// <summary>
+ /// Find write handler for type.
+ /// </summary>
+ /// <param name="type">Type.</param>
+ /// <returns>Write handler or NULL.</returns>
+ private static BinarySystemWriteDelegate FindWriteHandler(Type type)
+ {
+ // 1. Well-known types.
+ if (type == typeof(string))
+ return WriteString;
+ if (type == typeof(decimal))
+ return WriteDecimal;
+ if (type == typeof(DateTime))
+ return WriteDate;
+ if (type == typeof(Guid))
+ return WriteGuid;
+ if (type == typeof (BinaryObject))
+ return WriteBinary;
+ if (type == typeof (ArrayList))
+ return WriteArrayList;
+ if (type == typeof(Hashtable))
+ return WriteHashtable;
+ if (type == typeof(DictionaryEntry))
+ return WriteMapEntry;
+ if (type.IsArray)
+ {
+ // We know how to write any array type.
+ Type elemType = type.GetElementType();
+
+ // Primitives.
+ if (elemType == typeof (bool))
+ return WriteBoolArray;
+ if (elemType == typeof(byte))
+ return WriteByteArray;
+ if (elemType == typeof(short))
+ return WriteShortArray;
+ if (elemType == typeof(char))
+ return WriteCharArray;
+ if (elemType == typeof(int))
+ return WriteIntArray;
+ if (elemType == typeof(long))
+ return WriteLongArray;
+ if (elemType == typeof(float))
+ return WriteFloatArray;
+ if (elemType == typeof(double))
+ return WriteDoubleArray;
+ // Non-CLS primitives.
+ if (elemType == typeof(sbyte))
+ return WriteSbyteArray;
+ if (elemType == typeof(ushort))
+ return WriteUshortArray;
+ if (elemType == typeof(uint))
+ return WriteUintArray;
+ if (elemType == typeof(ulong))
+ return WriteUlongArray;
+ // Special types.
+ if (elemType == typeof (decimal?))
+ return WriteDecimalArray;
+ if (elemType == typeof(string))
+ return WriteStringArray;
+ if (elemType == typeof(Guid?))
+ return WriteGuidArray;
+ // Enums.
+ if (elemType.IsEnum)
+ return WriteEnumArray;
+
+ // Object array.
+ if (elemType == typeof (object))
+ return WriteArray;
+ }
+
+ if (type.IsEnum)
+ // We know how to write enums.
+ return WriteEnum;
+
+ if (type.IsSerializable)
+ return WriteSerializable;
+
+ return null;
+ }
+
+ /// <summary>
+ /// Find write handler for type.
+ /// </summary>
+ /// <param name="type">Type.</param>
+ /// <returns>Write handler or NULL.</returns>
+ public static byte GetTypeId(Type type)
+ {
+ byte res;
+
+ if (TypeIds.TryGetValue(type, out res))
+ return res;
+
+ if (type.IsEnum)
+ return BinaryUtils.TypeEnum;
+
+ if (type.IsArray && type.GetElementType().IsEnum)
+ return BinaryUtils.TypeArrayEnum;
+
+ return BinaryUtils.TypeObject;
+ }
+
+ /// <summary>
+ /// Add write handler for type.
+ /// </summary>
+ /// <param name="type"></param>
+ /// <param name="handler"></param>
+ private static void AddWriteHandler(Type type, BinarySystemWriteDelegate handler)
+ {
+ lock (WriteHandlersMux)
+ {
+ if (_writeHandlers == null)
+ {
+ Dictionary<Type, BinarySystemWriteDelegate> writeHandlers0 =
+ new Dictionary<Type, BinarySystemWriteDelegate>();
+
+ writeHandlers0[type] = handler;
+
+ _writeHandlers = writeHandlers0;
+ }
+ else if (!_writeHandlers.ContainsKey(type))
+ {
+ Dictionary<Type, BinarySystemWriteDelegate> writeHandlers0 =
+ new Dictionary<Type, BinarySystemWriteDelegate>(_writeHandlers);
+
+ writeHandlers0[type] = handler;
+
+ _writeHandlers = writeHandlers0;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Reads an object of predefined type.
+ /// </summary>
+ public static T ReadSystemType<T>(byte typeId, BinaryReader ctx)
+ {
+ var handler = ReadHandlers[typeId];
+
+ Debug.Assert(handler != null, "Cannot find predefined read handler: " + typeId);
+
+ return handler.Read<T>(ctx);
+ }
+
+ /// <summary>
+ /// Write decimal.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteDecimal(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeDecimal);
+
+ BinaryUtils.WriteDecimal((decimal)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write date.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteDate(BinaryWriter ctx, object obj)
+ {
+ ctx.Write(new DateTimeHolder((DateTime) obj));
+ }
+
+ /// <summary>
+ /// Write string.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Object.</param>
+ private static void WriteString(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeString);
+
+ BinaryUtils.WriteString((string)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write Guid.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteGuid(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeGuid);
+
+ BinaryUtils.WriteGuid((Guid)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write boolaen array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteBoolArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayBool);
+
+ BinaryUtils.WriteBooleanArray((bool[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write byte array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteByteArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayByte);
+
+ BinaryUtils.WriteByteArray((byte[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write sbyte array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteSbyteArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayByte);
+
+ BinaryUtils.WriteByteArray((byte[])(Array)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write short array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteShortArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayShort);
+
+ BinaryUtils.WriteShortArray((short[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write ushort array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteUshortArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayShort);
+
+ BinaryUtils.WriteShortArray((short[])(Array)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write char array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteCharArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayChar);
+
+ BinaryUtils.WriteCharArray((char[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write int array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteIntArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayInt);
+
+ BinaryUtils.WriteIntArray((int[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write uint array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteUintArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayInt);
+
+ BinaryUtils.WriteIntArray((int[])(Array)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write long array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteLongArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayLong);
+
+ BinaryUtils.WriteLongArray((long[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write ulong array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteUlongArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayLong);
+
+ BinaryUtils.WriteLongArray((long[])(Array)obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write float array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteFloatArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayFloat);
+
+ BinaryUtils.WriteFloatArray((float[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write double array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteDoubleArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayDouble);
+
+ BinaryUtils.WriteDoubleArray((double[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write decimal array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteDecimalArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayDecimal);
+
+ BinaryUtils.WriteDecimalArray((decimal?[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write string array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteStringArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayString);
+
+ BinaryUtils.WriteStringArray((string[])obj, ctx.Stream);
+ }
+
+ /// <summary>
+ /// Write nullable GUID array.
+ /// </summary>
+ /// <param name="ctx">Context.</param>
+ /// <param name="obj">Value.</param>
+ private static void WriteGuidArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayGuid);
+
+ BinaryUtils.WriteGuidArray((Guid?[])obj, ctx.Stream);
+ }
+
+ /**
+ * <summary>Write enum array.</summary>
+ */
+ private static void WriteEnumArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArrayEnum);
+
+ BinaryUtils.WriteArray((Array)obj, ctx);
+ }
+
+ /**
+ * <summary>Write array.</summary>
+ */
+ private static void WriteArray(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeArray);
+
+ BinaryUtils.WriteArray((Array)obj, ctx);
+ }
+
+ /**
+ * <summary>Write ArrayList.</summary>
+ */
+ private static void WriteArrayList(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeCollection);
+
+ BinaryUtils.WriteCollection((ICollection)obj, ctx, BinaryUtils.CollectionArrayList);
+ }
+
+ /**
+ * <summary>Write Hashtable.</summary>
+ */
+ private static void WriteHashtable(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeDictionary);
+
+ BinaryUtils.WriteDictionary((IDictionary)obj, ctx, BinaryUtils.MapHashMap);
+ }
+
+ /**
+ * <summary>Write map entry.</summary>
+ */
+ private static void WriteMapEntry(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeMapEntry);
+
+ BinaryUtils.WriteMapEntry(ctx, (DictionaryEntry)obj);
+ }
+
+ /**
+ * <summary>Write binary object.</summary>
+ */
+ private static void WriteBinary(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeBinary);
+
+ BinaryUtils.WriteBinary(ctx.Stream, (BinaryObject)obj);
+ }
+
+ /// <summary>
+ /// Write enum.
+ /// </summary>
+ private static void WriteEnum(BinaryWriter ctx, object obj)
+ {
+ ctx.Stream.WriteByte(BinaryUtils.TypeEnum);
+
+ BinaryUtils.WriteEnum(ctx.Stream, (Enum)obj);
+ }
+
+ /// <summary>
+ /// Writes serializable.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="o">The object.</param>
+ private static void WriteSerializable(BinaryWriter writer, object o)
+ {
+ writer.Write(new SerializableObjectHolder(o));
+ }
+
+ /**
+ * <summary>Read enum array.</summary>
+ */
+ private static object ReadEnumArray(BinaryReader ctx, Type type)
+ {
+ return BinaryUtils.ReadTypedArray(ctx, true, type.GetElementType());
+ }
+
+ /**
+ * <summary>Read array.</summary>
+ */
+ private static object ReadArray(BinaryReader ctx, Type type)
+ {
+ var elemType = type.IsArray ? type.GetElementType() : typeof(object);
+
+ return BinaryUtils.ReadTypedArray(ctx, true, elemType);
+ }
+
+ /**
+ * <summary>Read collection.</summary>
+ */
+ private static object ReadCollection(BinaryReader ctx, Type type)
+ {
+ return BinaryUtils.ReadCollection(ctx, null, null);
+ }
+
+ /**
+ * <summary>Read dictionary.</summary>
+ */
+ private static object ReadDictionary(BinaryReader ctx, Type type)
+ {
+ return BinaryUtils.ReadDictionary(ctx, null);
+ }
+
+ /**
+ * <summary>Read map entry.</summary>
+ */
+ private static object ReadMapEntry(BinaryReader ctx, Type type)
+ {
+ return BinaryUtils.ReadMapEntry(ctx);
+ }
+
+ /**
+ * <summary>Add element to array list.</summary>
+ * <param name="col">Array list.</param>
+ * <param name="elem">Element.</param>
+ */
+
+
+ /**
+ * <summary>Read delegate.</summary>
+ * <param name="ctx">Read context.</param>
+ * <param name="type">Type.</param>
+ */
+ private delegate object BinarySystemReadDelegate(BinaryReader ctx, Type type);
+
+ /// <summary>
+ /// System type reader.
+ /// </summary>
+ private interface IBinarySystemReader
+ {
+ /// <summary>
+ /// Reads a value of specified type from reader.
+ /// </summary>
+ T Read<T>(BinaryReader ctx);
+ }
+
+ /// <summary>
+ /// System type generic reader.
+ /// </summary>
+ private interface IBinarySystemReader<out T>
+ {
+ /// <summary>
+ /// Reads a value of specified type from reader.
+ /// </summary>
+ T Read(BinaryReader ctx);
+ }
+
+ /// <summary>
+ /// Default reader with boxing.
+ /// </summary>
+ private class BinarySystemReader : IBinarySystemReader
+ {
+ /** */
+ private readonly BinarySystemReadDelegate _readDelegate;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BinarySystemReader"/> class.
+ /// </summary>
+ /// <param name="readDelegate">The read delegate.</param>
+ public BinarySystemReader(BinarySystemReadDelegate readDelegate)
+ {
+ Debug.Assert(readDelegate != null);
+
+ _readDelegate = readDelegate;
+ }
+
+ /** <inheritdoc /> */
+ public T Read<T>(BinaryReader ctx)
+ {
+ return (T)_readDelegate(ctx, typeof(T));
+ }
+ }
+
+ /// <summary>
+ /// Reader without boxing.
+ /// </summary>
+ private class BinarySystemReader<T> : IBinarySystemReader
+ {
+ /** */
+ private readonly Func<IBinaryStream, T> _readDelegate;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BinarySystemReader{T}"/> class.
+ /// </summary>
+ /// <param name="readDelegate">The read delegate.</param>
+ public BinarySystemReader(Func<IBinaryStream, T> readDelegate)
+ {
+ Debug.Assert(readDelegate != null);
+
+ _readDelegate = readDelegate;
+ }
+
+ /** <inheritdoc /> */
+ public TResult Read<TResult>(BinaryReader ctx)
+ {
+ return TypeCaster<TResult>.Cast(_readDelegate(ctx.Stream));
+ }
+ }
+
+ /// <summary>
+ /// Reader without boxing.
+ /// </summary>
+ private class BinarySystemTypedArrayReader<T> : IBinarySystemReader
+ {
+ public TResult Read<TResult>(BinaryReader ctx)
+ {
+ return TypeCaster<TResult>.Cast(BinaryUtils.ReadArray<T>(ctx, false));
+ }
+ }
+
+ /// <summary>
+ /// Reader with selection based on requested type.
+ /// </summary>
+ private class BinarySystemDualReader<T1, T2> : IBinarySystemReader, IBinarySystemReader<T2>
+ {
+ /** */
+ private readonly Func<IBinaryStream, T1> _readDelegate1;
+
+ /** */
+ private readonly Func<IBinaryStream, T2> _readDelegate2;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BinarySystemDualReader{T1,T2}"/> class.
+ /// </summary>
+ /// <param name="readDelegate1">The read delegate1.</param>
+ /// <param name="readDelegate2">The read delegate2.</param>
+ public BinarySystemDualReader(Func<IBinaryStream, T1> readDelegate1, Func<IBinaryStream, T2> readDelegate2)
+ {
+ Debug.Assert(readDelegate1 != null);
+ Debug.Assert(readDelegate2 != null);
+
+ _readDelegate1 = readDelegate1;
+ _readDelegate2 = readDelegate2;
+ }
+
+ /** <inheritdoc /> */
+ T2 IBinarySystemReader<T2>.Read(BinaryReader ctx)
+ {
+ return _readDelegate2(ctx.Stream);
+ }
+
+ /** <inheritdoc /> */
+ public T Read<T>(BinaryReader ctx)
+ {
+ // Can't use "as" because of variance.
+ // For example, IBinarySystemReader<byte[]> can be cast to IBinarySystemReader<sbyte[]>, which
+ // will cause incorrect behavior.
+ if (typeof (T) == typeof (T2))
+ return ((IBinarySystemReader<T>) this).Read(ctx);
+
+ return TypeCaster<T>.Cast(_readDelegate1(ctx.Stream));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
new file mode 100644
index 0000000..cc145e9
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
@@ -0,0 +1,62 @@
+/*
+ * 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.Binary
+{
+ using System;
+ using System.Diagnostics;
+ using Apache.Ignite.Core.Binary;
+
+ /// <summary>
+ /// Binary serializer for system types.
+ /// </summary>
+ /// <typeparam name="T">Object type.</typeparam>
+ internal class BinarySystemTypeSerializer<T> : IBinarySystemTypeSerializer where T : IBinaryWriteAware
+ {
+ /** Ctor delegate. */
+ private readonly Func<BinaryReader, T> _ctor;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BinarySystemTypeSerializer{T}"/> class.
+ /// </summary>
+ /// <param name="ctor">Constructor delegate.</param>
+ public BinarySystemTypeSerializer(Func<BinaryReader, T> ctor)
+ {
+ Debug.Assert(ctor != null);
+
+ _ctor = ctor;
+ }
+
+ /** <inheritdoc /> */
+ public void WriteBinary(object obj, IBinaryWriter writer)
+ {
+ ((T) obj).WriteBinary(writer);
+ }
+
+ /** <inheritdoc /> */
+ public void ReadBinary(object obj, IBinaryReader reader)
+ {
+ throw new NotSupportedException("System serializer does not support ReadBinary.");
+ }
+
+ /** <inheritdoc /> */
+ public object ReadInstance(BinaryReader reader)
+ {
+ return _ctor(reader);
+ }
+ }
+}
\ No newline at end of file