Skip to content

Commit

Permalink
Added support for generic collection interfaces to PacketSerializer a…
Browse files Browse the repository at this point in the history
…s long as they are assignable from List
  • Loading branch information
Arcidev committed Oct 15, 2019
1 parent 5a0592f commit b3f2e74
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ public void TestCollectionSerialization()
{
ArrayOfString = new string[] { "123", "456", "789" },
ListOfInt = new List<int>() { 1, 2, 3 },
ListOfObject = new List<TestObject3>() { new TestObject3(), new TestObject3(), new TestObject3() }
ListOfObject = new List<TestObject3>() { new TestObject3(), new TestObject3(), new TestObject3() },
EnumerableOfInt = new List<int>() { 1, 2, 3 }
};

var packet = obj.ToPacket();
Expand All @@ -246,6 +247,7 @@ public void TestCollectionSerialization()
Assert.Equal(obj.ListOfObject.Count, deserializedObject.ListOfObject.Count);
Assert.Equal<string>(obj.ArrayOfString, deserializedObject.ArrayOfString);
Assert.Equal<int>(obj.ListOfInt, deserializedObject.ListOfInt);
Assert.Equal(obj.EnumerableOfInt, deserializedObject.EnumerableOfInt);
}
}
}
3 changes: 3 additions & 0 deletions Arci.Networking.Tests/ObjectTests/Objects/TestObject5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ public class TestObject5

[PacketProperty(3)]
public List<TestObject3> ListOfObject { get; set; }

[PacketProperty(4)]
public IEnumerable<int> EnumerableOfInt { get; set; }
}
}
5 changes: 4 additions & 1 deletion Arci.Networking.Tests/ObjectTests/PacketObjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Arci.Networking.Tests.ObjectTests
{
Expand Down Expand Up @@ -233,7 +234,8 @@ public void TestCollectionSerialization()
{
ArrayOfString = new string[] { "123", "456", "789" },
ListOfInt = new List<int>() { 1, 2, 3 },
ListOfObject = new List<TestObject3>() { new TestObject3(), new TestObject3(), new TestObject3() }
ListOfObject = new List<TestObject3>() { new TestObject3(), new TestObject3(), new TestObject3() },
EnumerableOfInt = new List<int>() { 1, 2, 3 }
};

var packet = obj.ToPacket();
Expand All @@ -247,6 +249,7 @@ public void TestCollectionSerialization()
Assert.AreEqual(obj.ListOfObject.Count, deserializedObject.ListOfObject.Count);
CollectionAssert.AreEqual(obj.ArrayOfString, deserializedObject.ArrayOfString);
CollectionAssert.AreEqual(obj.ListOfInt, deserializedObject.ListOfInt);
CollectionAssert.AreEqual(obj.EnumerableOfInt.ToList(), deserializedObject.EnumerableOfInt.ToList());
}
}
}
35 changes: 13 additions & 22 deletions Arci.Networking/Security/AesEncryptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,15 @@ public byte[] Encrypt(string toEncrypt, Encoding encoding = null)
/// <returns>Encrypted data</returns>
public byte[] Encrypt(byte[] toEncrypt)
{
using (var msEncrypt = new MemoryStream())
using var msEncrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(msEncrypt, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var csEncrypt = new CryptoStream(msEncrypt, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var swEncrypt = new BinaryWriter(csEncrypt))
{
// Write all data to the stream.
swEncrypt.Write(toEncrypt);
}
}

return msEncrypt.ToArray();
using var swEncrypt = new BinaryWriter(csEncrypt);
// Write all data to the stream.
swEncrypt.Write(toEncrypt);
}

return msEncrypt.ToArray();
}

/// <summary>
Expand All @@ -121,17 +117,12 @@ public string Decrypt(byte[] toDecode, Encoding encoding)
/// <returns>Decrypted data</returns>
public byte[] Decrypt(byte[] toDecode)
{
using (var msDecrypt = new MemoryStream(toDecode, false))
{
using (var csDecrypt = new CryptoStream(msDecrypt, aes.CreateDecryptor(aes.Key, aes.IV), CryptoStreamMode.Read))
{
using (var srDecrypt = new BinaryReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
return srDecrypt.ReadBytes(toDecode.Length);
}
}
}
using var msDecrypt = new MemoryStream(toDecode, false);
using var csDecrypt = new CryptoStream(msDecrypt, aes.CreateDecryptor(aes.Key, aes.IV), CryptoStreamMode.Read);
using var srDecrypt = new BinaryReader(csDecrypt);

// Read the decrypted bytes from the decrypting stream
return srDecrypt.ReadBytes(toDecode.Length);
}

/// <summary>
Expand Down
50 changes: 29 additions & 21 deletions Arci.Networking/Serialization/PacketSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,6 @@ private static object ReadPacketObject(ByteBuffer byteBuffer, Type type)
{
return byteBuffer.ReadPacketGuid();
}
else if (type.IsGenericType && type.GetInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(ICollection<>)))
{
var instance = Activator.CreateInstance(type);
var count = byteBuffer.ReadUInt16();
for (var i = 0; i < count; i++)
{
var value = ReadPacketProperty(byteBuffer, type.GetGenericArguments()[0]);
type.GetMethod(nameof(ICollection<object>.Add)).Invoke(instance, new[] { value });
}
return instance;
}
else if (type.IsArray)
{
var count = byteBuffer.ReadUInt16();
Expand All @@ -141,6 +130,15 @@ private static object ReadPacketObject(ByteBuffer byteBuffer, Type type)
arr.SetValue(ReadPacketProperty(byteBuffer, type.GetElementType()), i);
return arr;
}
else if (type.IsGenericType && type.IsInterface)
{
var listType = typeof(List<>).MakeGenericType(type.GetGenericArguments().First());
return type.IsAssignableFrom(listType) ? ReadCollection(byteBuffer, listType) : null;
}
else if (type.IsGenericType && type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)))
{
return ReadCollection(byteBuffer, type);
}
else if (type.IsClass && type.GetConstructor(Type.EmptyTypes) != null)
{
var instance = Activator.CreateInstance(type);
Expand All @@ -150,6 +148,18 @@ private static object ReadPacketObject(ByteBuffer byteBuffer, Type type)
return null;
}

private static object ReadCollection(ByteBuffer byteBuffer, Type type)
{
var instance = Activator.CreateInstance(type);
var count = byteBuffer.ReadUInt16();
for (var i = 0; i < count; i++)
{
var value = ReadPacketProperty(byteBuffer, type.GetGenericArguments()[0]);
type.GetMethod(nameof(ICollection<object>.Add)).Invoke(instance, new[] { value });
}
return instance;
}

private static void WritePacketObject(ByteBuffer byteBuffer, object value, Type type)
{
if (type == typeof(Guid))
Expand All @@ -160,20 +170,18 @@ private static void WritePacketObject(ByteBuffer byteBuffer, object value, Type
{
byteBuffer.Write((PacketGuid)value);
}
else if (type.IsArray || (type.IsGenericType && type.GetInterfaces().Any(x => x.GetGenericTypeDefinition() == typeof(ICollection<>))))
else if (type.IsArray || (type.IsGenericType && (type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)) || (type.IsInterface && type.IsAssignableFrom(typeof(List<>).MakeGenericType(type.GetGenericArguments().First()))))))
{
UInt16 count = 0;
using (var itemsBuffer = new ByteBuffer())
using var itemsBuffer = new ByteBuffer();
foreach (var item in (IEnumerable)value)
{
foreach (var item in (IEnumerable)value)
{
WritePacketProperty(itemsBuffer, item, type.GetElementType() ?? type.GetGenericArguments()[0]);
count++;
}

byteBuffer.Write(count);
byteBuffer.Write(itemsBuffer);
WritePacketProperty(itemsBuffer, item, type.GetElementType() ?? type.GetGenericArguments()[0]);
count++;
}

byteBuffer.Write(count);
byteBuffer.Write(itemsBuffer);
}
else if (type.IsClass && type.GetConstructor(Type.EmptyTypes) != null)
WritePacketProperties(byteBuffer, value);
Expand Down

0 comments on commit b3f2e74

Please sign in to comment.