Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id D5E36200C72 for ; Fri, 12 May 2017 12:56:42 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id D457B160BB8; Fri, 12 May 2017 10:56:42 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 2D0CA160BA3 for ; Fri, 12 May 2017 12:56:41 +0200 (CEST) Received: (qmail 16277 invoked by uid 500); 12 May 2017 10:56:40 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 16268 invoked by uid 99); 12 May 2017 10:56:40 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 12 May 2017 10:56:40 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E9014DFFB2; Fri, 12 May 2017 10:56:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: ptupitsyn@apache.org To: commits@ignite.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: ignite git commit: IGNITE-5207 .NET: Support non-Int32 enums Date: Fri, 12 May 2017 10:56:39 +0000 (UTC) archived-at: Fri, 12 May 2017 10:56:43 -0000 Repository: ignite Updated Branches: refs/heads/master 4b2b68434 -> ed4a7a131 IGNITE-5207 .NET: Support non-Int32 enums This closes #1933 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ed4a7a13 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ed4a7a13 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ed4a7a13 Branch: refs/heads/master Commit: ed4a7a131ee92143f7dec003c445142af207ee96 Parents: 4b2b684 Author: Pavel Tupitsyn Authored: Fri May 12 13:56:25 2017 +0300 Committer: Pavel Tupitsyn Committed: Fri May 12 13:56:25 2017 +0300 ---------------------------------------------------------------------- .../Apache.Ignite.Core.Tests.csproj | 1 + .../Binary/BinarySelfTest.cs | 7 +- .../Binary/EnumsTest.cs | 274 +++++++++++++++++++ .../Compute/ComputeApiTest.cs | 2 +- .../Impl/Binary/BinaryObject.cs | 2 +- .../Impl/Binary/BinaryReflectiveActions.cs | 6 +- .../Impl/Binary/BinarySystemHandlers.cs | 271 +++++++++--------- .../Impl/Binary/BinaryUtils.cs | 30 -- .../Impl/Binary/BinaryWriter.cs | 48 +++- 9 files changed, 441 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj index 7adbbbe..1c84a4d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj @@ -80,6 +80,7 @@ + http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs index bdc0d65..01f108e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs @@ -2436,12 +2436,7 @@ namespace Apache.Ignite.Core.Tests.Binary } } - public enum TestEnum - { - Val1, Val2, Val3 = 10 - } - - public enum TestEnum2 + public enum TestEnum : short { Val1, Val2, Val3 = 10 } http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/EnumsTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/EnumsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/EnumsTest.cs new file mode 100644 index 0000000..f896ef4 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/EnumsTest.cs @@ -0,0 +1,274 @@ +/* + * 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.Tests.Binary +{ + using System; + using System.Runtime.Serialization; + using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Binary; + using Apache.Ignite.Core.Impl.Common; + using NUnit.Framework; + + /// + /// Tests enums serialization. + /// + public class EnumsTest + { + /// + /// Tests direct enum value serialization. + /// + [Test] + public void TestDirectValue() + { + CheckValue(ByteEnum.Foo); + CheckValue(ByteEnum.Bar); + + CheckValue(SByteEnum.Foo); + CheckValue(SByteEnum.Bar); + + CheckValue(ShortEnum.Foo); + CheckValue(ShortEnum.Bar); + + CheckValue(UShortEnum.Foo); + CheckValue(UShortEnum.Bar); + + CheckValue(IntEnum.Foo); + CheckValue(IntEnum.Bar); + + CheckValue(UIntEnum.Foo); + CheckValue(UIntEnum.Bar); + + CheckValue(LongEnum.Foo, false); + CheckValue(LongEnum.Bar, false); + + CheckValue(ULongEnum.Foo, false); + CheckValue(ULongEnum.Bar, false); + } + + /// + /// Checks the enum value serialization. + /// + private static void CheckValue(T val, bool isBinaryEnum = true) + { + var marsh = new Marshaller(null) {CompactFooter = false}; + var bytes = marsh.Marshal(val); + var res = marsh.Unmarshal(bytes); + var binRes = marsh.Unmarshal(bytes, BinaryMode.ForceBinary); + + Assert.AreEqual(val, res); + Assert.AreEqual(val, binRes.Deserialize()); + + if (isBinaryEnum) + { + Assert.AreEqual(TypeCaster.Cast(val), binRes.EnumValue); + } + else + { + Assert.AreEqual(val, binRes.GetField("value__")); + } + + // Check array. + var arr = new[] {val, val}; + var arrRes = TestUtils.SerializeDeserialize(arr); + + Assert.AreEqual(arr, arrRes); + } + + /// + /// Tests enums as a field in binarizable object. + /// + [Test] + public void TestBinarizableField() + { + // Min values. + var val = new EnumsBinarizable(); + + var res = TestUtils.SerializeDeserialize(val); + Assert.AreEqual(val, res); + + // Max values. + val = new EnumsBinarizable + { + Byte = ByteEnum.Bar, + Int = IntEnum.Bar, + Long = LongEnum.Bar, + SByte = SByteEnum.Bar, + Short = ShortEnum.Bar, + UInt = UIntEnum.Bar, + ULong = ULongEnum.Bar, + UShort = UShortEnum.Bar + }; + + res = TestUtils.SerializeDeserialize(val); + Assert.AreEqual(val, res); + } + + /// + /// Tests enums as a field in ISerializable object. + /// + [Test] + public void TestSerializableField() + { + // Min values. + var val = new EnumsSerializable(); + + var res = TestUtils.SerializeDeserialize(val); + Assert.AreEqual(val, res); + + // Max values. + val = new EnumsSerializable + { + Byte = ByteEnum.Bar, + Int = IntEnum.Bar, + Long = LongEnum.Bar, + SByte = SByteEnum.Bar, + Short = ShortEnum.Bar, + UInt = UIntEnum.Bar, + ULong = ULongEnum.Bar, + UShort = UShortEnum.Bar + }; + + res = TestUtils.SerializeDeserialize(val); + Assert.AreEqual(val, res); + } + + private enum ByteEnum : byte + { + Foo = byte.MinValue, + Bar = byte.MaxValue + } + + private enum SByteEnum : sbyte + { + Foo = sbyte.MinValue, + Bar = sbyte.MaxValue + } + + private enum ShortEnum : short + { + Foo = short.MinValue, + Bar = short.MaxValue + } + + private enum UShortEnum : ushort + { + Foo = ushort.MinValue, + Bar = ushort.MaxValue + } + + private enum IntEnum + { + Foo = int.MinValue, + Bar = int.MaxValue + } + + private enum UIntEnum : uint + { + Foo = uint.MinValue, + Bar = uint.MaxValue + } + + private enum LongEnum : long + { + Foo = long.MinValue, + Bar = long.MaxValue + } + + private enum ULongEnum : ulong + { + Foo = ulong.MinValue, + Bar = ulong.MaxValue + } + + private class EnumsBinarizable + { + public ByteEnum Byte { get; set; } + public SByteEnum SByte { get; set; } + public ShortEnum Short { get; set; } + public UShortEnum UShort { get; set; } + public IntEnum Int { get; set; } + public UIntEnum UInt { get; set; } + public LongEnum Long { get; set; } + public ULongEnum ULong { get; set; } + + private bool Equals(EnumsBinarizable other) + { + return Byte == other.Byte && SByte == other.SByte && Short == other.Short + && UShort == other.UShort && Int == other.Int && UInt == other.UInt + && Long == other.Long && ULong == other.ULong; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((EnumsBinarizable) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) Byte; + hashCode = (hashCode * 397) ^ (int) SByte; + hashCode = (hashCode * 397) ^ (int) Short; + hashCode = (hashCode * 397) ^ (int) UShort; + hashCode = (hashCode * 397) ^ (int) Int; + hashCode = (hashCode * 397) ^ (int) UInt; + hashCode = (hashCode * 397) ^ Long.GetHashCode(); + hashCode = (hashCode * 397) ^ ULong.GetHashCode(); + return hashCode; + } + } + } + + [Serializable] + private class EnumsSerializable : EnumsBinarizable, ISerializable + { + public EnumsSerializable() + { + // No-op. + } + + protected EnumsSerializable(SerializationInfo info, StreamingContext context) + { + Byte = (ByteEnum) info.GetValue("byte", typeof(ByteEnum)); + SByte = (SByteEnum) info.GetValue("sbyte", typeof(SByteEnum)); + Short = (ShortEnum) info.GetValue("short", typeof(ShortEnum)); + UShort = (UShortEnum) info.GetValue("ushort", typeof(UShortEnum)); + Int = (IntEnum) info.GetValue("int", typeof(IntEnum)); + UInt = (UIntEnum) info.GetValue("uint", typeof(UIntEnum)); + Long = (LongEnum) info.GetValue("long", typeof(LongEnum)); + ULong = (ULongEnum) info.GetValue("ulong", typeof(ULongEnum)); + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("byte", Byte); + info.AddValue("sbyte", SByte); + info.AddValue("short", Short); + info.AddValue("ushort", UShort); + info.AddValue("int", Int); + info.AddValue("uint", UInt); + info.AddValue("long", Long); + info.AddValue("ulong", ULong); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs index e403d93..b9b7a04 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs @@ -1532,7 +1532,7 @@ namespace Apache.Ignite.Core.Tests.Compute } } - public enum PlatformComputeEnum + public enum PlatformComputeEnum : ushort { Foo, Bar, http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs index 690a0a4..480e0e6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs @@ -132,7 +132,7 @@ namespace Apache.Ignite.Core.Impl.Binary get { throw new NotSupportedException("IBinaryObject.Value is only supported for enums. " + - "Check IBinaryObject.IsEnum property before accessing Value."); + "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value."); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs index 907b465..6aaf5f9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs @@ -476,7 +476,7 @@ namespace Apache.Ignite.Core.Impl.Binary : GetWriter(field, (f, w, o) => w.WriteGuid(f, o)); readAction = raw ? GetRawReader(field, r => r.ReadGuid()) : GetReader(field, (f, r) => r.ReadGuid(f)); } - else if (type.IsEnum) + else if (type.IsEnum && !new[] {typeof(long), typeof(ulong)}.Contains(Enum.GetUnderlyingType(type))) { writeAction = raw ? GetRawWriter(field, (w, o) => w.WriteEnum(o), true) @@ -503,7 +503,7 @@ namespace Apache.Ignite.Core.Impl.Binary ? GetRawReader(field, r => r.ReadCollection()) : GetReader(field, (f, r) => r.ReadCollection(f)); } - else if (type == typeof (DateTime) && IsQueryField(field) && !raw) + else if (type == typeof(DateTime) && IsQueryField(field) && !raw) { // Special case for DateTime and query fields. // If a field is marked with [QuerySqlField], write it as TimeStamp so that queries work. @@ -514,7 +514,7 @@ namespace Apache.Ignite.Core.Impl.Binary writeAction = GetWriter(field, (f, w, o) => w.WriteTimestamp(f, o)); readAction = GetReader(field, (f, r) => r.ReadObject(f)); } - else if (nullableType == typeof (DateTime) && IsQueryField(field) && !raw) + else if (nullableType == typeof(DateTime) && IsQueryField(field) && !raw) { writeAction = GetWriter(field, (f, w, o) => w.WriteTimestamp(f, o)); readAction = GetReader(field, (f, r) => r.ReadTimestamp(f)); http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/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 index a30b981..1dfc3b6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs @@ -31,8 +31,8 @@ namespace Apache.Ignite.Core.Impl.Binary internal static class BinarySystemHandlers { /** Write handlers. */ - private static readonly CopyOnWriteConcurrentDictionary WriteHandlers = - new CopyOnWriteConcurrentDictionary(); + private static readonly CopyOnWriteConcurrentDictionary WriteHandlers = + new CopyOnWriteConcurrentDictionary(); /** Read handlers. */ private static readonly IBinarySystemReader[] ReadHandlers = new IBinarySystemReader[255]; @@ -160,15 +160,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// /// - public static BinarySystemWriteHandler GetWriteHandler(Type type) + public static IBinarySystemWriteHandler GetWriteHandler(Type type) { return WriteHandlers.GetOrAdd(type, t => { - bool supportsHandles; - - var handler = FindWriteHandler(t, out supportsHandles); - - return handler == null ? null : new BinarySystemWriteHandler(handler, supportsHandles); + return FindWriteHandler(t); }); } @@ -176,37 +172,49 @@ namespace Apache.Ignite.Core.Impl.Binary /// Find write handler for type. /// /// Type. - /// Flag indicating whether returned delegate supports handles. /// /// Write handler or NULL. /// - private static Action FindWriteHandler(Type type, out bool supportsHandles) + private static IBinarySystemWriteHandler FindWriteHandler(Type type) { - supportsHandles = false; - // 1. Well-known types. if (type == typeof(string)) - return WriteString; + return new BinarySystemWriteHandler(WriteString, false); if (type == typeof(decimal)) - return WriteDecimal; + return new BinarySystemWriteHandler(WriteDecimal, false); if (type == typeof(Guid)) - return WriteGuid; + return new BinarySystemWriteHandler(WriteGuid, false); if (type == typeof (BinaryObject)) - return WriteBinary; + return new BinarySystemWriteHandler(WriteBinary, false); if (type == typeof (BinaryEnum)) - return WriteBinaryEnum; + return new BinarySystemWriteHandler(WriteBinaryEnum, false); if (type.IsEnum) - return WriteEnum; + { + var underlyingType = Enum.GetUnderlyingType(type); + + if (underlyingType == typeof(int)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(i, type), false); + if (underlyingType == typeof(uint)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(unchecked((int) i), type), false); + if (underlyingType == typeof(byte)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(i, type), false); + if (underlyingType == typeof(sbyte)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(i, type), false); + if (underlyingType == typeof(short)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(i, type), false); + if (underlyingType == typeof(ushort)) + return new BinarySystemWriteHandler((w, i) => w.WriteEnum(i, type), false); + + return null; // Other enums, such as long and ulong, can't be expressed as int. + } if (type == typeof(Ignite)) - return WriteIgnite; + return new BinarySystemWriteHandler(WriteIgnite, false); // All types below can be written as handles. - supportsHandles = true; - if (type == typeof (ArrayList)) - return WriteArrayList; + return new BinarySystemWriteHandler(WriteArrayList, true); if (type == typeof (Hashtable)) - return WriteHashtable; + return new BinarySystemWriteHandler(WriteHashtable, true); if (type.IsArray) { @@ -215,49 +223,66 @@ namespace Apache.Ignite.Core.Impl.Binary // Primitives. if (elemType == typeof (bool)) - return WriteBoolArray; + return new BinarySystemWriteHandler(WriteBoolArray, true); if (elemType == typeof(byte)) - return WriteByteArray; + return new BinarySystemWriteHandler(WriteByteArray, true); if (elemType == typeof(short)) - return WriteShortArray; + return new BinarySystemWriteHandler(WriteShortArray, true); if (elemType == typeof(char)) - return WriteCharArray; + return new BinarySystemWriteHandler(WriteCharArray, true); if (elemType == typeof(int)) - return WriteIntArray; + return new BinarySystemWriteHandler(WriteIntArray, true); if (elemType == typeof(long)) - return WriteLongArray; + return new BinarySystemWriteHandler(WriteLongArray, true); if (elemType == typeof(float)) - return WriteFloatArray; + return new BinarySystemWriteHandler(WriteFloatArray, true); if (elemType == typeof(double)) - return WriteDoubleArray; + return new BinarySystemWriteHandler(WriteDoubleArray, true); // Non-CLS primitives. if (elemType == typeof(sbyte)) - return WriteSbyteArray; + return new BinarySystemWriteHandler(WriteByteArray, true); if (elemType == typeof(ushort)) - return WriteUshortArray; + return new BinarySystemWriteHandler(WriteShortArray, true); if (elemType == typeof(uint)) - return WriteUintArray; + return new BinarySystemWriteHandler(WriteIntArray, true); if (elemType == typeof(ulong)) - return WriteUlongArray; + return new BinarySystemWriteHandler(WriteLongArray, true); // Special types. if (elemType == typeof (decimal?)) - return WriteDecimalArray; + return new BinarySystemWriteHandler(WriteDecimalArray, true); if (elemType == typeof(string)) - return WriteStringArray; + return new BinarySystemWriteHandler(WriteStringArray, true); if (elemType == typeof(Guid?)) - return WriteGuidArray; + return new BinarySystemWriteHandler(WriteGuidArray, true); // Enums. - if (elemType.IsEnum || elemType == typeof(BinaryEnum)) - return WriteEnumArray; + if (IsIntEnum(elemType) || elemType == typeof(BinaryEnum)) + return new BinarySystemWriteHandler(WriteEnumArray, true); // Object array. - return WriteArray; + return new BinarySystemWriteHandler(WriteArray, true); } return null; } /// + /// Determines whether specified type is an enum which fits into Int32. + /// + private static bool IsIntEnum(Type type) + { + if (!type.IsEnum) + return false; + + var underlyingType = Enum.GetUnderlyingType(type); + + return underlyingType == typeof(int) + || underlyingType == typeof(short) + || underlyingType == typeof(ushort) + || underlyingType == typeof(byte) + || underlyingType == typeof(sbyte); + } + + /// /// Find write handler for type. /// /// Type. @@ -300,11 +325,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteDecimal(BinaryWriter ctx, object obj) + private static void WriteDecimal(BinaryWriter ctx, decimal obj) { ctx.Stream.WriteByte(BinaryUtils.TypeDecimal); - BinaryUtils.WriteDecimal((decimal)obj, ctx.Stream); + BinaryUtils.WriteDecimal(obj, ctx.Stream); } /// @@ -312,11 +337,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Object. - private static void WriteString(BinaryWriter ctx, object obj) + private static void WriteString(BinaryWriter ctx, string obj) { ctx.Stream.WriteByte(BinaryUtils.TypeString); - BinaryUtils.WriteString((string)obj, ctx.Stream); + BinaryUtils.WriteString(obj, ctx.Stream); } /// @@ -324,11 +349,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteGuid(BinaryWriter ctx, object obj) + private static void WriteGuid(BinaryWriter ctx, Guid obj) { ctx.Stream.WriteByte(BinaryUtils.TypeGuid); - BinaryUtils.WriteGuid((Guid)obj, ctx.Stream); + BinaryUtils.WriteGuid(obj, ctx.Stream); } /// @@ -336,11 +361,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteBoolArray(BinaryWriter ctx, object obj) + private static void WriteBoolArray(BinaryWriter ctx, bool[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayBool); - BinaryUtils.WriteBooleanArray((bool[])obj, ctx.Stream); + BinaryUtils.WriteBooleanArray(obj, ctx.Stream); } /// @@ -348,23 +373,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteByteArray(BinaryWriter ctx, object obj) - { - ctx.Stream.WriteByte(BinaryUtils.TypeArrayByte); - - BinaryUtils.WriteByteArray((byte[])obj, ctx.Stream); - } - - /// - /// Write sbyte array. - /// - /// Context. - /// Value. - private static void WriteSbyteArray(BinaryWriter ctx, object obj) + private static void WriteByteArray(BinaryWriter ctx, byte[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayByte); - BinaryUtils.WriteByteArray((byte[]) obj, ctx.Stream); + BinaryUtils.WriteByteArray(obj, ctx.Stream); } /// @@ -372,26 +385,14 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteShortArray(BinaryWriter ctx, object obj) + private static void WriteShortArray(BinaryWriter ctx, short[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayShort); - BinaryUtils.WriteShortArray((short[])obj, ctx.Stream); + BinaryUtils.WriteShortArray(obj, ctx.Stream); } /// - /// Write ushort array. - /// - /// Context. - /// Value. - private static void WriteUshortArray(BinaryWriter ctx, object obj) - { - ctx.Stream.WriteByte(BinaryUtils.TypeArrayShort); - - BinaryUtils.WriteShortArray((short[]) obj, ctx.Stream); - } - - /// /// Write char array. /// /// Context. @@ -408,23 +409,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteIntArray(BinaryWriter ctx, object obj) + private static void WriteIntArray(BinaryWriter ctx, int[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayInt); - BinaryUtils.WriteIntArray((int[])obj, ctx.Stream); - } - - /// - /// Write uint array. - /// - /// Context. - /// Value. - private static void WriteUintArray(BinaryWriter ctx, object obj) - { - ctx.Stream.WriteByte(BinaryUtils.TypeArrayInt); - - BinaryUtils.WriteIntArray((int[]) obj, ctx.Stream); + BinaryUtils.WriteIntArray(obj, ctx.Stream); } /// @@ -432,23 +421,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteLongArray(BinaryWriter ctx, object obj) - { - ctx.Stream.WriteByte(BinaryUtils.TypeArrayLong); - - BinaryUtils.WriteLongArray((long[])obj, ctx.Stream); - } - - /// - /// Write ulong array. - /// - /// Context. - /// Value. - private static void WriteUlongArray(BinaryWriter ctx, object obj) + private static void WriteLongArray(BinaryWriter ctx, long[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayLong); - BinaryUtils.WriteLongArray((long[]) obj, ctx.Stream); + BinaryUtils.WriteLongArray(obj, ctx.Stream); } /// @@ -456,11 +433,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteFloatArray(BinaryWriter ctx, object obj) + private static void WriteFloatArray(BinaryWriter ctx, float[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayFloat); - BinaryUtils.WriteFloatArray((float[])obj, ctx.Stream); + BinaryUtils.WriteFloatArray(obj, ctx.Stream); } /// @@ -468,11 +445,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteDoubleArray(BinaryWriter ctx, object obj) + private static void WriteDoubleArray(BinaryWriter ctx, double[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayDouble); - BinaryUtils.WriteDoubleArray((double[])obj, ctx.Stream); + BinaryUtils.WriteDoubleArray(obj, ctx.Stream); } /// @@ -480,11 +457,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteDecimalArray(BinaryWriter ctx, object obj) + private static void WriteDecimalArray(BinaryWriter ctx, decimal?[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayDecimal); - BinaryUtils.WriteDecimalArray((decimal?[])obj, ctx.Stream); + BinaryUtils.WriteDecimalArray(obj, ctx.Stream); } /// @@ -492,11 +469,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteStringArray(BinaryWriter ctx, object obj) + private static void WriteStringArray(BinaryWriter ctx, string[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayString); - BinaryUtils.WriteStringArray((string[])obj, ctx.Stream); + BinaryUtils.WriteStringArray(obj, ctx.Stream); } /// @@ -504,11 +481,11 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Context. /// Value. - private static void WriteGuidArray(BinaryWriter ctx, object obj) + private static void WriteGuidArray(BinaryWriter ctx, Guid?[] obj) { ctx.Stream.WriteByte(BinaryUtils.TypeArrayGuid); - BinaryUtils.WriteGuidArray((Guid?[])obj, ctx.Stream); + BinaryUtils.WriteGuidArray(obj, ctx.Stream); } /// @@ -534,47 +511,39 @@ namespace Apache.Ignite.Core.Impl.Binary /** * Write ArrayList. */ - private static void WriteArrayList(BinaryWriter ctx, object obj) + private static void WriteArrayList(BinaryWriter ctx, ICollection obj) { ctx.Stream.WriteByte(BinaryUtils.TypeCollection); - BinaryUtils.WriteCollection((ICollection)obj, ctx, BinaryUtils.CollectionArrayList); + BinaryUtils.WriteCollection(obj, ctx, BinaryUtils.CollectionArrayList); } /** * Write Hashtable. */ - private static void WriteHashtable(BinaryWriter ctx, object obj) + private static void WriteHashtable(BinaryWriter ctx, IDictionary obj) { ctx.Stream.WriteByte(BinaryUtils.TypeDictionary); - BinaryUtils.WriteDictionary((IDictionary)obj, ctx, BinaryUtils.MapHashMap); + BinaryUtils.WriteDictionary(obj, ctx, BinaryUtils.MapHashMap); } /** * Write binary object. */ - private static void WriteBinary(BinaryWriter ctx, object obj) + private static void WriteBinary(BinaryWriter ctx, BinaryObject obj) { ctx.Stream.WriteByte(BinaryUtils.TypeBinary); - BinaryUtils.WriteBinary(ctx.Stream, (BinaryObject)obj); + BinaryUtils.WriteBinary(ctx.Stream, obj); } /// /// Write enum. /// - private static void WriteEnum(BinaryWriter ctx, object obj) + private static void WriteBinaryEnum(BinaryWriter ctx, BinaryEnum obj) { - ctx.WriteEnum(obj); - } - - /// - /// Write enum. - /// - private static void WriteBinaryEnum(BinaryWriter ctx, object obj) - { - var binEnum = (BinaryEnum) obj; + var binEnum = obj; ctx.Stream.WriteByte(BinaryUtils.TypeEnum); @@ -790,20 +759,38 @@ namespace Apache.Ignite.Core.Impl.Binary /// /// Write delegate + handles flag. /// - internal class BinarySystemWriteHandler + internal interface IBinarySystemWriteHandler + { + /// + /// Gets a value indicating whether this handler supports handles. + /// + bool SupportsHandles { get; } + + /// + /// Writes object to a specified writer. + /// + /// The writer. + /// The object. + void Write(BinaryWriter writer, T obj); + } + + /// + /// Write delegate + handles flag. + /// + internal class BinarySystemWriteHandler : IBinarySystemWriteHandler { /** */ - private readonly Action _writeAction; + private readonly Action _writeAction; /** */ private readonly bool _supportsHandles; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The write action. /// Handles flag. - public BinarySystemWriteHandler(Action writeAction, bool supportsHandles) + public BinarySystemWriteHandler(Action writeAction, bool supportsHandles) { Debug.Assert(writeAction != null); @@ -811,19 +798,13 @@ namespace Apache.Ignite.Core.Impl.Binary _supportsHandles = supportsHandles; } - /// - /// Writes object to a specified writer. - /// - /// The writer. - /// The object. - public void Write(BinaryWriter writer, object obj) + /** */ + public void Write(BinaryWriter writer, T obj) { - _writeAction(writer, obj); + _writeAction(writer, TypeCaster.Cast(obj)); } - /// - /// Gets a value indicating whether this handler supports handles. - /// + /** */ public bool SupportsHandles { get { return _supportsHandles; } http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs index dee0a80..5bc68fe 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs @@ -1440,36 +1440,6 @@ namespace Apache.Ignite.Core.Impl.Binary } /// - /// Write enum. - /// - /// Writer. - /// Value. - public static void WriteEnum(BinaryWriter writer, T val) - { - writer.WriteInt(GetEnumTypeId(val.GetType(), writer.Marshaller)); - writer.WriteInt(TypeCaster.Cast(val)); - } - - /// - /// Gets the enum type identifier. - /// - /// The enum type. - /// The marshaller. - /// Enum type id. - private static int GetEnumTypeId(Type enumType, Marshaller marshaller) - { - if (Enum.GetUnderlyingType(enumType) == TypInt) - { - var desc = marshaller.GetDescriptor(enumType); - - return desc.TypeId; - } - - throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " + - enumType.Name); - } - - /// /// Gets the enum value by type id and int representation. /// /// Result type. http://git-wip-us.apache.org/repos/asf/ignite/blob/ed4a7a13/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs index 12cc026..56774d4 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs @@ -858,19 +858,47 @@ namespace Apache.Ignite.Core.Impl.Binary WriteNullField(); else { - var desc = _marsh.GetDescriptor(val.GetType()); + var type = val.GetType(); - var metaHnd = _marsh.GetBinaryTypeHandler(desc); - - _stream.WriteByte(BinaryUtils.TypeEnum); + if (!type.IsEnum) + { + throw new BinaryObjectException("Type is not an enum: " + type); + } - BinaryUtils.WriteEnum(this, val); + var handler = BinarySystemHandlers.GetWriteHandler(type); - SaveMetadata(desc, metaHnd.OnObjectWriteFinished()); + if (handler != null) + { + // All enums except long/ulong. + handler.Write(this, val); + } + else + { + throw new BinaryObjectException(string.Format("Enum '{0}' has unsupported underlying type '{1}'. " + + "Use WriteObject instead of WriteEnum.", + type, Enum.GetUnderlyingType(type))); + } } } /// + /// Write enum value. + /// + /// Enum value. + /// Enum type. + internal void WriteEnum(int val, Type type) + { + var desc = _marsh.GetDescriptor(type); + + _stream.WriteByte(BinaryUtils.TypeEnum); + _stream.WriteInt(desc.TypeId); + _stream.WriteInt(val); + + var metaHnd = _marsh.GetBinaryTypeHandler(desc); + SaveMetadata(desc, metaHnd.OnObjectWriteFinished()); + } + + /// /// Write named enum array. /// /// @@ -1120,14 +1148,6 @@ namespace Apache.Ignite.Core.Impl.Binary return; } - // Handle enums. - if (type.IsEnum) - { - WriteEnum(obj); - - return; - } - // Handle special case for builder. if (WriteBuilderSpecials(obj)) return;