-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix user defined struct array serialization failure #235
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -616,5 +616,87 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type | |
return os; | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeNullableIntArray() | ||
{ | ||
SerializeAndAssert(new int?[]{1, 2, 3, 4, 5}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeLongArray() | ||
{ | ||
SerializeAndAssert(new []{1L, 2L, 3L, 4L, 5L}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeNullableLongArray() | ||
{ | ||
SerializeAndAssert(new long?[]{1L, 2L, 3L, 4L, 5L}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeShortArray() | ||
{ | ||
SerializeAndAssert(new short[]{1, 2, 3, 4, 5}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeNullableShortArray() | ||
{ | ||
SerializeAndAssert(new short?[]{1, 2, 3, 4, 5}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeStringArray() | ||
{ | ||
SerializeAndAssert(new []{"1", "2", "3", "4", "5"}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeDateTimeOffsetArray() | ||
{ | ||
SerializeAndAssert(new [] | ||
{ | ||
DateTimeOffset.Now, | ||
DateTimeOffset.UtcNow, | ||
}); | ||
} | ||
|
||
[Fact] | ||
public void CanSerializeStructArray() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the new spec for the failing serialization. |
||
{ | ||
SerializeAndAssert(new IStructInterface[] | ||
{ | ||
new PrimitiveStruct {Int = 1, Long = 1, String = "1"}, | ||
new PrimitiveStruct {Int = 2, Long = 2, String = "2"}, | ||
new PrimitiveStruct {Int = 3, Long = 3, String = "3"}, | ||
new PrimitiveStruct {Int = 4, Long = 4, String = "4"}, | ||
new PrimitiveStruct {Int = 5, Long = 5, String = "5"}, | ||
}); | ||
} | ||
|
||
private interface IStructInterface | ||
{ | ||
int Int { get; set; } | ||
long Long { get; set; } | ||
string String { get; set; } | ||
} | ||
|
||
private struct PrimitiveStruct : IStructInterface | ||
{ | ||
public int Int { get; set; } | ||
public long Long { get; set; } | ||
public string String { get; set; } | ||
} | ||
|
||
private void SerializeAndAssert<T>(T[] expected) | ||
{ | ||
Serialize(expected); | ||
Reset(); | ||
var res = Deserialize<T[]>(); | ||
Assert.Equal(expected, res); | ||
AssertMemoryStreamConsumed(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,10 @@ | |
#endregion | ||
|
||
using System; | ||
using System.Collections; | ||
using System.Collections.Concurrent; | ||
using System.IO; | ||
using System.Linq; | ||
using Hyperion.Extensions; | ||
using Hyperion.ValueSerializers; | ||
|
||
|
@@ -21,7 +23,7 @@ internal sealed class ArraySerializerFactory : ValueSerializerFactory | |
|
||
public override bool CanDeserialize(Serializer serializer, Type type) => CanSerialize(serializer, type); | ||
|
||
private static void WriteValues<T>(T[] array, Stream stream, Type elementType, ValueSerializer elementSerializer, SerializerSession session) | ||
private static void WriteValues(Array array, Stream stream, Type elementType, ValueSerializer elementSerializer, SerializerSession session) | ||
{ | ||
Int32Serializer.WriteValueImpl(stream, array.Length, session); | ||
var preserveObjectReferences = session.Serializer.Options.PreserveObjectReferences; | ||
|
@@ -30,12 +32,13 @@ private static void WriteValues<T>(T[] array, Stream stream, Type elementType, V | |
stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session); | ||
} | ||
} | ||
private static void ReadValues<T>(int length, Stream stream, DeserializerSession session, T[] array) | ||
|
||
private static void ReadValues(int length, Stream stream, DeserializerSession session, Array array) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to change generic type to untyped Array array. Generic typed array does not play nice with user defined structs. |
||
{ | ||
for (var i = 0; i < length; i++) | ||
{ | ||
var value = (T)stream.ReadObject(session); | ||
array[i] = value; | ||
var value = stream.ReadObject(session); | ||
array.SetValue(value, i); | ||
} | ||
} | ||
|
||
|
@@ -57,7 +60,7 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type | |
session.TrackDeserializedObject(array); | ||
} | ||
|
||
ReadValues(length, stream, session, (dynamic)array); | ||
ReadValues(length, stream, session, array); | ||
|
||
return array; | ||
}; | ||
|
@@ -68,7 +71,8 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type | |
session.TrackSerializedObject(arr); | ||
} | ||
|
||
WriteValues((dynamic)arr, stream, elementType, elementSerializer, session); | ||
// This janky way of converting array to Array is done to get around the problem of ValueType arrays | ||
WriteValues(((IEnumerable)arr).Cast<object>().ToArray(), stream, elementType, elementSerializer, session); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only way to convert an array of user defined struct object into an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is less janky that casting to a |
||
}; | ||
arraySerializer.Initialize(reader, writer); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New tests look good