Skip to content

Commit

Permalink
Serialize array of complex objects. #187
Browse files Browse the repository at this point in the history
  • Loading branch information
xinchen10 committed Mar 6, 2017
1 parent 9e7f6ef commit 84695bd
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/Serialization/AmqpSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,12 @@ SerializableType CompileCollectionTypes(Type type)
MethodAccessor addAccess = null;
Type itemType = null;

if (type.IsArray)
{
// array of custom types. encode it as list
return SerializableType.CreateArrayType(this, type, type.GetElementType());
}

foreach (Type it in type.GetInterfaces())
{
if (it.IsGenericType())
Expand Down
37 changes: 37 additions & 0 deletions src/Serialization/SerializableType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public static SerializableType CreateAmqpSerializableType(AmqpSerializer seriali
return new AmqpSerializableType(serializer, type);
}

public static SerializableType CreateArrayType(AmqpSerializer serializer, Type type, Type itemType)
{
return new ArrayType(serializer, type, itemType);
}

public static SerializableType CreateGenericListType(
AmqpSerializer serializer,
Type type,
Expand Down Expand Up @@ -366,6 +371,38 @@ protected static void ReadSizeAndCount(ByteBuffer buffer, byte formatCode, out i
}
}

sealed class ArrayType : SerializableType
{
readonly Type itemType;
readonly SerializableType listType;

public ArrayType(AmqpSerializer serializer, Type type, Type itemType)
: base(serializer, type)
{
this.itemType = itemType;
this.listType = serializer.GetType(typeof(List<>).MakeGenericType(itemType));
}

public override void WriteObject(ByteBuffer buffer, object graph)
{
this.listType.WriteObject(buffer, graph);
}

public override object ReadObject(ByteBuffer buffer)
{
object value = this.listType.ReadObject(buffer);
if (value != null)
{
ICollection list = (ICollection)value;
Array array = Array.CreateInstance(this.itemType, list.Count);
list.CopyTo(array, 0);
value = array;
}

return value;
}
}

sealed class GenericListType : CollectionType
{
readonly SerializableType itemType;
Expand Down
2 changes: 1 addition & 1 deletion src/Types/Encoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ internal static bool TryGetCodec(Type type, out Encode encoder, out Decode decod
Serializer codec = (Serializer)codecByType[type];
if (codec == null)
{
if (type.IsArray)
if (type.IsArray && codecByType[type.GetElementType()] != null)
{
codec = serializers[20];
}
Expand Down
30 changes: 30 additions & 0 deletions test/Common/AmqpSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,36 @@ public void AmqpSerializerMessageBodyTest()
(x, y) => CollectionAssert.AreEqual(x, y));
}

[TestMethod]
public void AmqpSerializerCustomTypeArrayTest()
{
Person[] value = new Person[]
{
new Student("Tom") { Age = 13 },
new Teacher("Bob") { Sallary = 1234 },
null,
new Student("Al") { Age = 12 },
};

ByteBuffer b = new ByteBuffer(512, true);
AmqpSerializer.Serialize(b, value);
Person[] o = AmqpSerializer.Deserialize<Person[]>(b);
Assert.AreEqual(value.Length, o.Length);
for (int i = 0; i < value.Length; i++)
{
if (value[i] == null)
{
Assert.IsTrue(o[i] == null);
}
else
{
Assert.AreEqual(value[i].GetType(), o[i].GetType());
Assert.AreEqual(value[i].Name, o[i].Name);
Assert.AreEqual(value[i].Age + 1, o[i].Age);
}
}
}

#if !DOTNET
[TestMethod]
public void MessageSerializationTest()
Expand Down

0 comments on commit 84695bd

Please sign in to comment.