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:14:58 UTC

[16/25] 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