From 5420caef7e6b060ff9c25d91f5a080852b12ca85 Mon Sep 17 00:00:00 2001 From: Davipb Date: Sat, 25 Feb 2017 13:06:49 -0300 Subject: [PATCH] Make boolean packing optional through PackAttribute --- .../ConstantSizePackedBooleanClass.cs | 6 +++--- .../EndianAwarePackedBooleanClass.cs | 4 ++-- .../PackedBoolean/ValidPackedBooleanClass.cs | 2 +- .../Graph/TypeGraph/ContainerTypeNode.cs | 17 +++++++++++++---- BinarySerializer/PackAttribute.cs | 14 ++++++++++++++ 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 BinarySerializer/PackAttribute.cs diff --git a/BinarySerializer.Test/PackedBoolean/ConstantSizePackedBooleanClass.cs b/BinarySerializer.Test/PackedBoolean/ConstantSizePackedBooleanClass.cs index cc053cc9..adef2af8 100644 --- a/BinarySerializer.Test/PackedBoolean/ConstantSizePackedBooleanClass.cs +++ b/BinarySerializer.Test/PackedBoolean/ConstantSizePackedBooleanClass.cs @@ -10,11 +10,11 @@ public class ConstantSizePackedBooleanClass [Ignore] public const int LengthConstraint = 2; [FieldCount(CountConstraint)] - [FieldOrder(0)] + [FieldOrder(0), Pack] public bool[] ConstantCountArray { get; set; } - [FieldLength(2)] - [FieldOrder(1)] + [FieldLength(LengthConstraint)] + [FieldOrder(1), Pack] public bool[] ConstantLengthArray { get; set; } } } diff --git a/BinarySerializer.Test/PackedBoolean/EndianAwarePackedBooleanClass.cs b/BinarySerializer.Test/PackedBoolean/EndianAwarePackedBooleanClass.cs index 4dc08e68..33f310c5 100644 --- a/BinarySerializer.Test/PackedBoolean/EndianAwarePackedBooleanClass.cs +++ b/BinarySerializer.Test/PackedBoolean/EndianAwarePackedBooleanClass.cs @@ -5,11 +5,11 @@ namespace BinarySerialization.Test.PackedBoolean public class EndianAwarePackedBooleanClass { [FieldEndianness(BinarySerialization.Endianness.Little)] - [FieldOrder(0)] + [FieldOrder(0), Pack] public bool[] LittleEndianArray { get; set; } [FieldEndianness(BinarySerialization.Endianness.Big)] - [FieldOrder(1)] + [FieldOrder(1), Pack] public bool[] BigEndianArray { get; set; } } } diff --git a/BinarySerializer.Test/PackedBoolean/ValidPackedBooleanClass.cs b/BinarySerializer.Test/PackedBoolean/ValidPackedBooleanClass.cs index ca6b1715..db35fb52 100644 --- a/BinarySerializer.Test/PackedBoolean/ValidPackedBooleanClass.cs +++ b/BinarySerializer.Test/PackedBoolean/ValidPackedBooleanClass.cs @@ -10,7 +10,7 @@ public class ValidPackedBooleanClass [FieldOrder(1)] public long BooleanArrayLength { get; set; } [FieldCount(nameof(BooleanArrayCount)), FieldLength(nameof(BooleanArrayLength))] - [FieldOrder(2)] + [FieldOrder(2), Pack] public bool[] BooleanArray { get; set; } } } diff --git a/BinarySerializer/Graph/TypeGraph/ContainerTypeNode.cs b/BinarySerializer/Graph/TypeGraph/ContainerTypeNode.cs index fc78e0bd..d39e8146 100644 --- a/BinarySerializer/Graph/TypeGraph/ContainerTypeNode.cs +++ b/BinarySerializer/Graph/TypeGraph/ContainerTypeNode.cs @@ -1,6 +1,8 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; namespace BinarySerialization.Graph.TypeGraph @@ -45,7 +47,7 @@ protected TypeNode GenerateChild(Type parentType, MemberInfo memberInfo) { ThrowOnBadType(memberType); - var nodeType = GetNodeType(memberType); + var nodeType = GetNodeType(memberType, memberInfo.GetCustomAttributes()); return (TypeNode) Activator.CreateInstance(nodeType, this, parentType, memberInfo); } @@ -84,7 +86,8 @@ private static void ThrowOnBadType(Type type) } // ReSharper restore UnusedParameter.Local - private static Type GetNodeType(Type type) + private static Type GetNodeType(Type type) => GetNodeType(type, Enumerable.Empty()); + private static Type GetNodeType(Type type, IEnumerable attributes) { var nullableType = Nullable.GetUnderlyingType(type); @@ -100,8 +103,14 @@ private static Type GetNodeType(Type type) return typeof(ValueTypeNode); } - if (type == typeof(bool[])) - return typeof(PackedBooleanArrayTypeNode); + if (attributes.OfType().Any()) + { + if (type == typeof(bool[])) + return typeof(PackedBooleanArrayTypeNode); + + throw new InvalidOperationException($"Cannot use the Pack attribute on member of type {type.Name}."); + } + if (type.IsArray) { return typeof(ArrayTypeNode); diff --git a/BinarySerializer/PackAttribute.cs b/BinarySerializer/PackAttribute.cs new file mode 100644 index 00000000..918a971b --- /dev/null +++ b/BinarySerializer/PackAttribute.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BinarySerialization +{ + /// Tells the to pack the decorated member. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] + public sealed class PackAttribute : Attribute + { + /// Initializes a new instance of the class. + public PackAttribute() { } + } +}