Skip to content
This repository was archived by the owner on Nov 14, 2022. It is now read-only.

Commit f20831b

Browse files
Merge pull request #7 from lukasz-pyrzyk/develop
1.0.3
2 parents 76f8336 + 1c95e5b commit f20831b

File tree

10 files changed

+294
-15
lines changed

10 files changed

+294
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ BinaryFormatter is a byte serialized/deserializer for .NET Core, created for Dis
2121
- DateTime
2222
- byte[]
2323
- classes
24+
- collections
2425

2526
### Not supported types
26-
- Collections
2727
- structures
2828

2929

src/BinaryFormatter/BinaryConverter.cs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Reflection;
55
using BinaryFormatter.TypeConverter;
66
using BinaryFormatter.Types;
7+
using System.Collections;
78

89
namespace BinaryFormatter
910
{
@@ -27,16 +28,24 @@ public class BinaryConverter
2728
[typeof(decimal)] = new DecimalConverter(),
2829
[typeof(string)] = new StringConverter(),
2930
[typeof(DateTime)] = new DatetimeConverter(),
30-
[typeof(byte[])] = new ByteArrayConverter()
31+
[typeof(byte[])] = new ByteArrayConverter(),
32+
[typeof(IEnumerable)] = new IEnumerableConverter()
3133
};
3234

3335
public byte[] Serialize(object obj)
3436
{
3537
Type t = obj.GetType();
38+
3639
BaseTypeConverter converter;
3740
if (_converters.TryGetValue(t, out converter))
3841
{
3942
return converter.Serialize(obj);
43+
} else if (obj is IEnumerable)
44+
{
45+
if (_converters.TryGetValue(typeof(IEnumerable), out converter))
46+
{
47+
return converter.Serialize(obj);
48+
}
4049
}
4150

4251
return SerializeProperties(obj);
@@ -63,25 +72,49 @@ private byte[] GetBytesFromProperty(object element)
6372
if (element == null) return new byte[0];
6473

6574
Type t = element.GetType();
75+
BaseTypeConverter converter;
6676
if (_converters.ContainsKey(t))
6777
{
68-
BaseTypeConverter converter = _converters[t];
78+
converter = _converters[t];
6979
return converter.Serialize(element);
80+
} else if (element is IEnumerable)
81+
{
82+
if (_converters.TryGetValue(typeof(IEnumerable), out converter))
83+
{
84+
return converter.Serialize(element);
85+
}
7086
}
7187

72-
// TODO serialize if IEnumerable
73-
7488
return SerializeProperties(element);
7589
}
7690

7791
public T Deserialize<T>(byte[] stream)
7892
{
7993
Type type = typeof(T);
8094

95+
bool isEnumerableType = type.GetTypeInfo().ImplementedInterfaces
96+
.Where(t => t == typeof(IEnumerable)).Count() > 0;
97+
8198
BaseTypeConverter converter;
8299
if (_converters.TryGetValue(type, out converter))
83100
{
84-
return (T)converter.DeserializeToObject(stream);
101+
return (T)converter.DeserializeToObject(stream);
102+
} else if (isEnumerableType)
103+
{
104+
if (_converters.TryGetValue(typeof(IEnumerable), out converter))
105+
{
106+
var prepearedData = converter.DeserializeToObject(stream) as IEnumerable;
107+
108+
var listType = typeof(List<>);
109+
var genericArgs = type.GenericTypeArguments;
110+
var concreteType = listType.MakeGenericType(genericArgs);
111+
var data = Activator.CreateInstance(concreteType);
112+
foreach (var item in prepearedData)
113+
{
114+
((IList)data).Add(item);
115+
}
116+
return (T)data;
117+
}
85118
}
86119

87120
T instance = (T)Activator.CreateInstance(type);
@@ -116,8 +149,25 @@ private void DeserializeProperty<T>(PropertyInfo property, T instance, byte[] st
116149
offset += sizeof(short);
117150

118151
BaseTypeConverter converter = _converters.First(x => x.Value.Type == type).Value;
119-
object data = converter.DeserializeToObject(stream, ref offset);
120-
property.SetValue(instance, data);
152+
object data;
153+
if (type == SerializedType.IEnumerable)
154+
{
155+
var prepearedData = converter.DeserializeToObject(stream, ref offset) as IEnumerable;
156+
157+
var prop = property;
158+
var listType = typeof(List<>);
159+
var genericArgs = prop.PropertyType.GenericTypeArguments;
160+
var concreteType = listType.MakeGenericType(genericArgs);
161+
data = Activator.CreateInstance(concreteType);
162+
foreach (var item in prepearedData)
163+
{
164+
((IList)data).Add(item);
165+
}
166+
} else
167+
{
168+
data = converter.DeserializeToObject(stream, ref offset);
169+
}
170+
property.SetValue(instance, data, property.GetIndexParameters());
121171
}
122172
}
123173
}

src/BinaryFormatter/BinaryFormatter.csproj

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
<PropertyGroup>
44
<Description>BinaryFormatter - easy and light binary serializer</Description>
5-
<Copyright>Lukasz Pyrzyk</Copyright>
6-
<VersionPrefix>1.0.1</VersionPrefix>
7-
<Authors>Lukasz Pyrzyk</Authors>
5+
<Copyright>Łukasz Pyrzyk</Copyright>
6+
<VersionPrefix>1.0.3</VersionPrefix>
7+
<Authors>Łukasz Pyrzyk</Authors>
88
<TargetFrameworks>netstandard1.1</TargetFrameworks>
99
<AssemblyName>BinaryFormatter</AssemblyName>
1010
<PackageId>BinaryFormatter</PackageId>
1111
<PackageTags>binary serializer formatter deserializer serialization</PackageTags>
1212
<PackageIconUrl>https://raw.githubusercontent.com/lukasz-pyrzyk/BinaryFormatter/master/Nuget/nuget-icon.png</PackageIconUrl>
1313
<PackageProjectUrl>https://raw.githubusercontent.com/lukasz-pyrzyk/BinaryFormatter/</PackageProjectUrl>
1414
<PackageLicenseUrl>https://raw.githubusercontent.com/lukasz-pyrzyk/BinaryFormatter/master/License.txt</PackageLicenseUrl>
15-
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
1615
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
1716
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
1817
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>

src/BinaryFormatter/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[assembly: AssemblyConfiguration("")]
1111
[assembly: AssemblyCompany("")]
1212
[assembly: AssemblyProduct("BinaryFormatter")]
13-
[assembly: AssemblyCopyright("Copyright © 2016")]
13+
[assembly: AssemblyCopyright("Copyright © 2017")]
1414
[assembly: AssemblyTrademark("")]
1515
[assembly: AssemblyCulture("")]
1616
[assembly: InternalsVisibleTo("BinaryFormatterTests")]
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System;
2+
using BinaryFormatter.Types;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
using System.Reflection;
6+
7+
namespace BinaryFormatter.TypeConverter
8+
{
9+
internal class IEnumerableConverter : BaseTypeConverter<object>
10+
{
11+
private int Size { get; set; }
12+
13+
protected override byte[] ProcessSerialize(object obj)
14+
{
15+
byte[] collectionAsByteArray = null;
16+
var objAsIEnumerable = (obj as IEnumerable<object>);
17+
if (objAsIEnumerable != null)
18+
{
19+
BinaryConverter converter = new BinaryConverter();
20+
List<byte> listAsArray = new List<byte>();
21+
22+
foreach (var sourceElementValue in objAsIEnumerable)
23+
{
24+
if (sourceElementValue == null)
25+
continue;
26+
27+
object elementValue = (sourceElementValue as IEnumerable<object>);
28+
if(elementValue == null)
29+
{
30+
elementValue = sourceElementValue;
31+
} else
32+
{
33+
List<object> collectionOfObjects = new List<object>();
34+
foreach (var item in (elementValue as IEnumerable<object>))
35+
{
36+
collectionOfObjects.Add(item);
37+
}
38+
elementValue = collectionOfObjects as IEnumerable<object>;
39+
}
40+
41+
Type elementType = elementValue.GetType();
42+
byte[] typeInfo = Encoding.UTF8.GetBytes(elementType.AssemblyQualifiedName);
43+
byte[] sizeTypeInfo = BitConverter.GetBytes(typeInfo.Length);
44+
45+
byte[] data = converter.Serialize(elementValue);
46+
byte[] sizeData = BitConverter.GetBytes(data.Length);
47+
int elementAsBytesLength =
48+
sizeTypeInfo.Length +
49+
typeInfo.Length +
50+
sizeData.Length +
51+
data.Length;
52+
53+
byte[] elementAsBytes = new byte[elementAsBytesLength];
54+
Array.Copy(sizeTypeInfo, 0, elementAsBytes, 0, sizeTypeInfo.Length);
55+
Array.Copy(typeInfo, 0, elementAsBytes, sizeTypeInfo.Length, typeInfo.Length);
56+
Array.Copy(sizeData, 0, elementAsBytes, sizeTypeInfo.Length + typeInfo.Length, sizeData.Length);
57+
Array.Copy(data, 0, elementAsBytes, sizeTypeInfo.Length + typeInfo.Length + sizeData.Length, data.Length);
58+
59+
listAsArray.AddRange(elementAsBytes);
60+
}
61+
62+
collectionAsByteArray = listAsArray.ToArray();
63+
Size = collectionAsByteArray.Length;
64+
}
65+
66+
return collectionAsByteArray;
67+
}
68+
69+
protected override object ProcessDeserialize(byte[] stream, ref int offset)
70+
{
71+
List<object> deserializedCollection = null;
72+
73+
if (stream.Length > 0)
74+
{
75+
BinaryConverter converter = new BinaryConverter();
76+
deserializedCollection = new List<object>();
77+
78+
while (offset < stream.Length)
79+
{
80+
int sizeTypeInfo = BitConverter.ToInt32(stream, offset);
81+
offset += sizeof(int);
82+
if(sizeTypeInfo == 0)
83+
{
84+
continue;
85+
}
86+
87+
byte[] typeInfo = new byte[sizeTypeInfo];
88+
Array.Copy(stream, offset, typeInfo, 0, sizeTypeInfo);
89+
string typeFullName = Encoding.UTF8.GetString(typeInfo, 0, sizeTypeInfo);
90+
Type valueType = System.Type.GetType(typeFullName);
91+
offset += sizeTypeInfo;
92+
93+
int sizeData = BitConverter.ToInt32(stream, offset);
94+
offset += sizeof(int);
95+
if (sizeData == 0)
96+
{
97+
continue;
98+
}
99+
byte[] dataValue = new byte[sizeData];
100+
Array.Copy(stream, offset, dataValue, 0, sizeData);
101+
MethodInfo method = typeof(BinaryConverter).GetRuntimeMethod("Deserialize", new System.Type[] { typeof(byte[]) });
102+
method = method.MakeGenericMethod(valueType);
103+
object deserializeItem = method.Invoke(converter, new object[] { dataValue });
104+
offset += sizeData;
105+
106+
deserializedCollection.Add(deserializeItem);
107+
}
108+
}
109+
110+
return deserializedCollection;
111+
}
112+
113+
protected override int GetTypeSize()
114+
{
115+
return Size;
116+
}
117+
118+
public override SerializedType Type => SerializedType.IEnumerable;
119+
}
120+
}

src/BinaryFormatter/Types/SerializedType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ internal enum SerializedType : ushort
1717
Decimal = 13,
1818
String = 14,
1919
Datetime = 15,
20-
ByteArray = 16
20+
ByteArray = 16,
21+
IEnumerable = 17
2122
}
2223
}

src/Tests/BinaryFormatterTests/BinaryConverterTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Text;
33
using BinaryFormatter;
44
using Xunit;
5+
using System.Collections.Generic;
56

67
namespace BinaryFormatterTests
78
{
@@ -210,5 +211,19 @@ public void CanSerialize_ByteArray()
210211

211212
Assert.Equal(value, deserializedValue);
212213
}
214+
215+
[Fact]
216+
public void CanSerialize_IEnumerable()
217+
{
218+
List<string> value = new List<string>();
219+
value.Add("lorem ipsum");
220+
value.Add("Кто не ходит, тот и не падает.");
221+
222+
BinaryConverter converter = new BinaryConverter();
223+
byte[] bytes = converter.Serialize(value);
224+
List<string> deserializedValue = converter.Deserialize<List<string>>(bytes);
225+
226+
Assert.Equal(value, deserializedValue);
227+
}
213228
}
214229
}

src/Tests/BinaryFormatterTests/BinaryFormatterTests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta1-build3642" />
2525
</ItemGroup>
2626

27+
<ItemGroup>
28+
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
29+
</ItemGroup>
30+
2731
</Project>

src/Tests/BinaryFormatterTests/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[assembly: AssemblyConfiguration("")]
1111
[assembly: AssemblyCompany("")]
1212
[assembly: AssemblyProduct("BinaryFormatterTests")]
13-
[assembly: AssemblyCopyright("Copyright © 2016")]
13+
[assembly: AssemblyCopyright("Copyright © 2017")]
1414
[assembly: AssemblyTrademark("")]
1515
[assembly: AssemblyCulture("")]
1616

0 commit comments

Comments
 (0)