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

Commit 8ef792d

Browse files
authored
Merge pull request #54 from lukasz-pyrzyk/develop
Version 2.0
2 parents c836d7b + 7caacea commit 8ef792d

File tree

64 files changed

+1381
-394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1381
-394
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ BinaryFormatter is a byte serialized/deserializer for .NET Core, created for Dis
2323
- classes
2424
- collections
2525
- structures
26+
- guid
27+
- uri
28+
- enum
2629

2730
### Not supported types
2831
- IDictionary collections

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 1.2.0.{build}
1+
version: 2.0.0.{build}
22
image: Visual Studio 2017
33

44
environment:
Lines changed: 16 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Reflection;
53
using BinaryFormatter.TypeConverter;
64
using BinaryFormatter.Types;
75
using System.Collections;
86
using System.IO;
7+
using BinaryFormatter.Utils;
98

109
namespace BinaryFormatter
1110
{
1211
public class BinaryConverter
1312
{
14-
private static readonly List<string> excludedDlls = new List<string> { "CoreLib", "mscorlib" };
15-
private static readonly ConvertersSelector _selector = new ConvertersSelector();
16-
1713
public byte[] Serialize(object obj)
1814
{
1915
var stream = new MemoryStream();
@@ -23,55 +19,37 @@ public byte[] Serialize(object obj)
2319

2420
public void Serialize(object obj, Stream stream)
2521
{
26-
if (obj == null) return;
27-
28-
BaseTypeConverter converter = _selector.SelectConverter(obj);
29-
if (converter != null)
30-
{
31-
converter.Serialize(obj, stream);
32-
}
33-
else
34-
{
35-
SerializePropertiesToStream(obj, stream);
36-
}
22+
BaseTypeConverter converter = ConvertersSelector.SelectConverter(obj);
23+
converter.Serialize(obj, stream);
3724
}
3825

39-
private void SerializePropertiesToStream(object obj, Stream stream)
26+
public T Deserialize<T>(byte[] stream)
4027
{
41-
Type t = obj.GetType();
42-
ICollection<PropertyInfo> properties = t.GetTypeInfo().DeclaredProperties.ToArray();
28+
var workingStream = new WorkingStream(stream);
4329

44-
foreach (PropertyInfo property in properties)
30+
SerializedType deserializedType = workingStream.ReadSerializedType();
31+
if (deserializedType == SerializedType.Null)
4532
{
46-
object prop = property.GetValue(obj);
47-
Serialize(prop, stream);
33+
return default(T);
4834
}
49-
}
50-
51-
public T Deserialize<T>(byte[] stream)
52-
{
53-
Type type = typeof(T);
5435

55-
BaseTypeConverter converter = _selector.SelectConverter(type);
56-
if (converter == null)
36+
Type sourceType = deserializedType.GetBaseType();
37+
if (sourceType == null)
5738
{
58-
T instance = (T)Activator.CreateInstance(type);
59-
60-
int offset = 0;
61-
DeserializeObject(stream, ref instance, ref offset);
62-
63-
return instance;
39+
byte[] typeInfo = workingStream.ReadBytesWithSizePrefix();
40+
sourceType = TypeUtils.FromUTF8Bytes(typeInfo);
6441
}
6542

43+
BaseTypeConverter converter = ConvertersSelector.SelectConverter(sourceType);
6644
if (converter is IEnumerableConverter)
6745
{
68-
var prepearedData = converter.DeserializeToObject(stream) as IEnumerable;
46+
var preparedData = converter.DeserializeToObject(stream) as IEnumerable;
6947

7048
var listType = typeof(List<>);
71-
var genericArgs = type.GenericTypeArguments;
49+
var genericArgs = sourceType.GenericTypeArguments;
7250
var concreteType = listType.MakeGenericType(genericArgs);
7351
var data = Activator.CreateInstance(concreteType);
74-
foreach (var item in prepearedData)
52+
foreach (var item in preparedData)
7553
{
7654
((IList)data).Add(item);
7755
}
@@ -80,64 +58,6 @@ public T Deserialize<T>(byte[] stream)
8058

8159
return (T)converter.DeserializeToObject(stream);
8260
}
83-
84-
private void DeserializeObject<T>(byte[] stream, ref T instance, ref int offset)
85-
{
86-
foreach (PropertyInfo property in instance.GetType().GetTypeInfo().DeclaredProperties)
87-
{
88-
DeserializeProperty(property, ref instance, stream, ref offset);
89-
if (offset == stream.Length)
90-
return;
91-
}
92-
}
93-
94-
private void DeserializeProperty<T>(PropertyInfo property, ref T instance, byte[] stream, ref int offset)
95-
{
96-
if (!excludedDlls.Any(x => property.PropertyType.AssemblyQualifiedName.Contains(x)))
97-
{
98-
object propertyValue = Activator.CreateInstance(property.PropertyType);
99-
property.SetValue(instance, propertyValue);
100-
DeserializeObject(stream, ref propertyValue, ref offset);
101-
return;
102-
}
103-
104-
Type instanceType = typeof(T);
105-
TypeInfo instanceTypeInfo = instanceType.GetTypeInfo();
106-
SerializedType type = (SerializedType)BitConverter.ToInt16(stream, offset);
107-
offset += sizeof(short);
108-
109-
BaseTypeConverter converter = _selector.ForSerializedType(type);
110-
object data;
111-
if (type == SerializedType.IEnumerable)
112-
{
113-
var prepearedData = converter.DeserializeToObject(stream, ref offset) as IEnumerable;
114-
115-
var prop = property;
116-
var listType = typeof(List<>);
117-
var genericArgs = prop.PropertyType.GenericTypeArguments;
118-
var concreteType = listType.MakeGenericType(genericArgs);
119-
data = Activator.CreateInstance(concreteType);
120-
foreach (var item in prepearedData)
121-
{
122-
((IList)data).Add(item);
123-
}
124-
}
125-
else
126-
{
127-
data = converter.DeserializeToObject(stream, ref offset);
128-
}
129-
130-
if (instanceTypeInfo.IsValueType && !instanceTypeInfo.IsPrimitive)
131-
{
132-
object boxedInstance = (object)instance;
133-
property.SetValue(boxedInstance, data, property.GetIndexParameters());
134-
instance = (T)boxedInstance;
135-
}
136-
else
137-
{
138-
property.SetValue(instance, data, property.GetIndexParameters());
139-
}
140-
}
14161
}
14262
}
14363

src/BinaryFormatter/BinaryFormatter.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<Description>BinaryFormatter - easy and light binary serializer</Description>
55
<Copyright>Łukasz Pyrzyk</Copyright>
6-
<VersionPrefix>1.2.0</VersionPrefix>
6+
<VersionPrefix>2.0.0</VersionPrefix>
77
<Authors>Łukasz Pyrzyk</Authors>
88
<TargetFrameworks>netstandard1.1</TargetFrameworks>
99
<AssemblyName>BinaryFormatter</AssemblyName>

src/BinaryFormatter/ConvertersSelector.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,30 @@ internal class ConvertersSelector
2828
[typeof(string)] = new StringConverter(),
2929
[typeof(DateTime)] = new DatetimeConverter(),
3030
[typeof(byte[])] = new ByteArrayConverter(),
31-
[typeof(IEnumerable)] = new IEnumerableConverter()
31+
[typeof(IEnumerable)] = new IEnumerableConverter(),
32+
[typeof(object)] = new CustomObjectConverter(),
33+
[typeof(Guid)] = new GuidConverter(),
34+
[typeof(Uri)] = new UriConverter(),
35+
[typeof(Enum)] = new EnumConverter()
3236
};
37+
private static readonly BaseTypeConverter NullConverter = new NullConverter();
3338

34-
public BaseTypeConverter SelectConverter(object obj)
39+
private ConvertersSelector()
3540
{
36-
if(obj == null) return null;
41+
}
42+
43+
public static BaseTypeConverter SelectConverter(object obj)
44+
{
45+
if (obj == null) return NullConverter;
46+
3747
Type type = obj.GetType();
3848
return SelectConverter(type);
3949
}
4050

41-
public BaseTypeConverter SelectConverter(Type type)
51+
public static BaseTypeConverter SelectConverter(Type type)
4252
{
53+
if (type == null) return NullConverter;
54+
4355
BaseTypeConverter converter;
4456
if (_converters.TryGetValue(type, out converter))
4557
{
@@ -55,11 +67,23 @@ public BaseTypeConverter SelectConverter(Type type)
5567
}
5668
}
5769

58-
return null;
70+
bool isEnumType = type.GetTypeInfo().IsEnum;
71+
if (isEnumType)
72+
{
73+
if (_converters.TryGetValue(typeof(Enum), out converter))
74+
{
75+
return converter;
76+
}
77+
}
78+
79+
return ForSerializedType(SerializedType.CustomObject);
5980
}
6081

61-
public BaseTypeConverter ForSerializedType(SerializedType type)
82+
public static BaseTypeConverter ForSerializedType(SerializedType type)
6283
{
84+
if (type == SerializedType.Null)
85+
return NullConverter;
86+
6387
return _converters.First(x => x.Value.Type == type).Value;
6488
}
6589
}

src/BinaryFormatter/TypeConverter/BaseTypeConverter.cs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,55 @@
22
using System.IO;
33
using BinaryFormatter.Types;
44
using BinaryFormatter.Utils;
5+
using System.Text;
6+
using System.Reflection;
57

68
namespace BinaryFormatter.TypeConverter
79
{
810
internal abstract class BaseTypeConverter<T> : BaseTypeConverter
911
{
1012
public void Serialize(T obj, Stream stream)
1113
{
12-
if (obj == null) throw new ArgumentNullException(nameof(obj));
13-
14+
Type destinationnType = typeof(T);
1415
byte[] objectType = BitConverter.GetBytes((ushort)Type);
1516
stream.Write(objectType);
1617

17-
WriteObjectToStream(obj, stream);
18+
if (obj != null)
19+
{
20+
if (!destinationnType.GetTypeInfo().IsBaseType())
21+
{
22+
byte[] typeInfo = Encoding.UTF8.GetBytes(obj.GetType().AssemblyQualifiedName);
23+
stream.WriteWithLengthPrefix(typeInfo);
24+
}
25+
26+
WriteObjectToStream(obj, stream);
27+
}
1828
}
1929

2030
public override void Serialize(object obj, Stream stream)
2131
{
22-
if (obj == null) throw new ArgumentNullException(nameof(obj));
23-
2432
Serialize((T)obj, stream);
2533
}
2634

27-
public T Deserialize(byte[] stream)
35+
public T Deserialize(byte[] bytes)
2836
{
29-
int offset = sizeof (short);
30-
return ProcessDeserialize(stream, ref offset);
37+
var stream = new WorkingStream(bytes);
38+
SerializedType deserializedType = stream.ReadSerializedType();
39+
Type sourceType = deserializedType.GetBaseType();
40+
41+
if (sourceType == null)
42+
{
43+
byte[] typeInfo = stream.ReadBytesWithSizePrefix();
44+
sourceType = TypeUtils.FromUTF8Bytes(typeInfo);
45+
}
46+
47+
int offset = stream.Offset;
48+
return ProcessDeserialize(bytes, sourceType, ref offset);
3149
}
3250

33-
public T Deserialize(byte[] stream, ref int offset)
51+
public T Deserialize(byte[] bytes, ref int offset)
3452
{
35-
T obj = ProcessDeserialize(stream, ref offset);
53+
T obj = ProcessDeserialize(bytes, typeof(T), ref offset);
3654
offset += GetTypeSize();
3755
return obj;
3856
}
@@ -49,14 +67,7 @@ public override object DeserializeToObject(byte[] stream, ref int offset)
4967

5068
protected abstract int GetTypeSize();
5169
protected abstract void WriteObjectToStream(T obj, Stream stream);
52-
protected abstract T ProcessDeserialize(byte[] stream, ref int offset);
53-
54-
protected virtual SerializedType GetPackageType(byte[] stream, ref int offset)
55-
{
56-
short type = BitConverter.ToInt16(stream, offset);
57-
offset += sizeof (short);
58-
return (SerializedType)type;
59-
}
70+
protected abstract T ProcessDeserialize(byte[] bytes, Type sourceType, ref int offset);
6071
}
6172

6273
internal abstract class BaseTypeConverter

src/BinaryFormatter/TypeConverter/BoolConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ protected override void WriteObjectToStream(bool obj, Stream stream)
1313
stream.Write(data);
1414
}
1515

16-
protected override bool ProcessDeserialize(byte[] stream, ref int offset)
16+
protected override bool ProcessDeserialize(byte[] bytes, Type sourceType, ref int offset)
1717
{
18-
bool result = BitConverter.ToBoolean(stream, offset);
18+
bool result = BitConverter.ToBoolean(bytes, offset);
1919
return result;
2020
}
2121

src/BinaryFormatter/TypeConverter/ByteArrayConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ protected override void WriteObjectToStream(byte[] obj, Stream stream)
1616
stream.WriteWithLengthPrefix(obj);
1717
}
1818

19-
protected override byte[] ProcessDeserialize(byte[] stream, ref int offset)
19+
protected override byte[] ProcessDeserialize(byte[] bytes, Type sourceType, ref int offset)
2020
{
21-
int size = BitConverter.ToInt32(stream, offset);
21+
int size = BitConverter.ToInt32(bytes, offset);
2222
offset += sizeof(int);
2323

2424
byte[] deserialized = new byte[size];
25-
Array.Copy(stream, offset, deserialized, 0, size);
25+
Array.Copy(bytes, offset, deserialized, 0, size);
2626
return deserialized;
2727
}
2828

src/BinaryFormatter/TypeConverter/ByteConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ protected override void WriteObjectToStream(byte obj, Stream stream)
1313
stream.Write(data);
1414
}
1515

16-
protected override byte ProcessDeserialize(byte[] stream, ref int offset)
16+
protected override byte ProcessDeserialize(byte[] bytes, Type sourceType, ref int offset)
1717
{
18-
return (byte)BitConverter.ToUInt16(stream, offset);
18+
return (byte)BitConverter.ToUInt16(bytes, offset);
1919
}
2020

2121
protected override int GetTypeSize()

src/BinaryFormatter/TypeConverter/CharConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ protected override void WriteObjectToStream(char obj, Stream stream)
1313
stream.Write(data);
1414
}
1515

16-
protected override char ProcessDeserialize(byte[] stream, ref int offset)
16+
protected override char ProcessDeserialize(byte[] bytes, Type sourceType, ref int offset)
1717
{
18-
char result = BitConverter.ToChar(stream, offset);
18+
char result = BitConverter.ToChar(bytes, offset);
1919
return result;
2020
}
2121

0 commit comments

Comments
 (0)