Skip to content

Commit bc41932

Browse files
authored
Merge pull request #184 from jogibear9988/dev
bugfix not using know serializers when defined
2 parents 81ff792 + 5c0dc6f commit bc41932

7 files changed

+272
-6
lines changed

src/Hyperion.Tests/Bugs.cs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,31 @@
88
#endregion
99

1010
using System;
11+
using System.Collections;
1112
using System.Collections.Generic;
1213
using System.Collections.Immutable;
1314
using System.IO;
15+
using System.Linq;
1416
using System.Reflection;
1517
using System.Reflection.Emit;
1618
using System.Text;
1719
using FluentAssertions;
1820
using Hyperion.Extensions;
1921
using Xunit;
22+
using Xunit.Abstractions;
2023

2124
namespace Hyperion.Tests
2225
{
2326

2427
public class Bugs
2528
{
29+
private readonly ITestOutputHelper _output;
30+
31+
public Bugs(ITestOutputHelper output)
32+
{
33+
_output = output;
34+
}
35+
2636
#region issue 58
2737

2838
public enum TrustLevel { Unknown, Suspicious, Partial, Fully }
@@ -246,5 +256,224 @@ public Recover(SnapshotSelectionCriteria fromSnapshot, long toSequenceNr = long.
246256
/// </summary>
247257
public long ReplayMax { get; private set; }
248258
}
259+
260+
delegate int TestDelegate(int x, int y);
261+
262+
class Temp : IEquatable<Temp>
263+
{
264+
public object[] SubArray { get; set; }
265+
public int[] IntArray { get; set; }
266+
public int[,] IntIntArray { get; set; }
267+
public Poco Poco { get; set; }
268+
public string String { get; set; }
269+
public Dictionary<int,string> Dictionary { get; set; }
270+
public TestDelegate Delegate { get; set; }
271+
public IEnumerable<int> TestEnum { get; set; }
272+
public Exception Exception { get; set; }
273+
public ImmutableList<int> ImmutableList { get; set; }
274+
public ImmutableDictionary<int, string> ImmutableDictionary { get; set; }
275+
276+
public bool Equals(Temp other)
277+
{
278+
if (other == null)
279+
throw new Exception("Equals failed.");
280+
if (ReferenceEquals(this, other))
281+
throw new Exception("Equals failed.");
282+
if (IntIntArray.Rank != other.IntIntArray.Rank)
283+
throw new Exception("Equals failed.");
284+
285+
for (var i = 0; i < IntIntArray.Rank; ++i)
286+
{
287+
for (var j = 0; j < IntIntArray.GetLength(i); ++j)
288+
{
289+
if (IntIntArray[j, i] != other.IntIntArray[j, i])
290+
throw new Exception("Equals failed.");
291+
}
292+
}
293+
294+
if (Exception.GetType() != other.Exception.GetType())
295+
throw new Exception("Equals failed.");
296+
if (Exception.Message != other.Exception.Message)
297+
throw new Exception("Equals failed.");
298+
if(Exception.InnerException != null
299+
&& Exception.InnerException.GetType() != other.Exception.InnerException.GetType())
300+
throw new Exception("Equals failed.");
301+
302+
for (var i = 0; i < SubArray.Length; i++)
303+
{
304+
if (SubArray[i].GetType() != other.SubArray[i].GetType())
305+
throw new Exception("Equals failed.");
306+
307+
if (SubArray[i] is Array arr)
308+
{
309+
var oArr = (Array)other.SubArray[i];
310+
for (var j = 0; j < arr.Length; ++j)
311+
{
312+
if (!arr.GetValue(j).Equals(oArr.GetValue(j)))
313+
throw new Exception("Equals failed.");
314+
}
315+
} else if (!SubArray[i].Equals(other.SubArray[i]))
316+
throw new Exception("Equals failed.");
317+
}
318+
319+
foreach (var key in Dictionary.Keys)
320+
{
321+
if (!Dictionary[key].Equals(other.Dictionary[key]))
322+
throw new Exception("Equals failed.");
323+
}
324+
325+
foreach (var key in ImmutableDictionary.Keys)
326+
{
327+
if (!ImmutableDictionary[key].Equals(other.ImmutableDictionary[key]))
328+
throw new Exception("Equals failed.");
329+
}
330+
331+
if (other.Delegate(2, 2) != 4)
332+
throw new Exception("Equals failed.");
333+
334+
if(!IntArray.SequenceEqual(other.IntArray))
335+
throw new Exception("Equals failed.");
336+
if(!Equals(Poco, other.Poco))
337+
throw new Exception("Equals failed.");
338+
if (String != other.String)
339+
throw new Exception("Equals failed.");
340+
if(!TestEnum.SequenceEqual(other.TestEnum))
341+
throw new Exception("Equals failed.");
342+
if(!ImmutableList.SequenceEqual(other.ImmutableList))
343+
throw new Exception("Equals failed.");
344+
345+
return true;
346+
}
347+
348+
public override bool Equals(object obj)
349+
{
350+
if (obj == null) throw new Exception("Equals failed.");
351+
if (ReferenceEquals(this, obj)) return true;
352+
if (obj.GetType() != this.GetType()) throw new Exception("Equals failed.");
353+
return Equals((Temp) obj);
354+
}
355+
356+
public override int GetHashCode()
357+
{
358+
unchecked
359+
{
360+
var hashCode = (SubArray != null ? SubArray.GetHashCode() : 0);
361+
hashCode = (hashCode * 397) ^ (IntArray != null ? IntArray.GetHashCode() : 0);
362+
hashCode = (hashCode * 397) ^ (IntIntArray != null ? IntIntArray.GetHashCode() : 0);
363+
hashCode = (hashCode * 397) ^ (Poco != null ? Poco.GetHashCode() : 0);
364+
hashCode = (hashCode * 397) ^ (String != null ? String.GetHashCode() : 0);
365+
hashCode = (hashCode * 397) ^ (Dictionary != null ? Dictionary.GetHashCode() : 0);
366+
hashCode = (hashCode * 397) ^ (Delegate != null ? Delegate.GetHashCode() : 0);
367+
hashCode = (hashCode * 397) ^ (TestEnum != null ? TestEnum.GetHashCode() : 0);
368+
hashCode = (hashCode * 397) ^ (Exception != null ? Exception.GetHashCode() : 0);
369+
hashCode = (hashCode * 397) ^ (ImmutableList != null ? ImmutableList.GetHashCode() : 0);
370+
return hashCode;
371+
}
372+
}
373+
}
374+
375+
class Poco : IEquatable<Poco>
376+
{
377+
public Poco()
378+
{ }
379+
380+
public Poco(int intValue, string stringValue)
381+
{
382+
Int = intValue;
383+
String = stringValue;
384+
}
385+
386+
public int Int { get; set; }
387+
public string String { get; set; }
388+
389+
public bool Equals(Poco other)
390+
{
391+
if (ReferenceEquals(null, other))
392+
throw new Exception("Equals failed.");
393+
if (ReferenceEquals(this, other))
394+
throw new Exception("Equals failed.");
395+
if(Int != other.Int)
396+
throw new Exception("Equals failed.");
397+
if(String != other.String)
398+
throw new Exception("Equals failed.");
399+
return true;
400+
}
401+
402+
public override bool Equals(object obj)
403+
{
404+
if (ReferenceEquals(null, obj)) throw new Exception("Equals failed.");
405+
if (ReferenceEquals(this, obj)) return true;
406+
if (obj.GetType() != this.GetType()) throw new Exception("Equals failed.");
407+
return Equals((Poco) obj);
408+
}
409+
410+
public override int GetHashCode()
411+
{
412+
unchecked
413+
{
414+
return (Int * 397) ^ (String != null ? String.GetHashCode() : 0);
415+
}
416+
}
417+
}
418+
419+
[Fact]
420+
public void WritesManifestEvenIfKnown()
421+
{
422+
var stream = new MemoryStream();
423+
var msg = new Temp
424+
{
425+
SubArray = new object[] { 1, (byte)2, new object[] { 3 } },
426+
IntArray = new [] {1, 2, 3, 4, 5},
427+
IntIntArray = new [,] {{1, 2}, {3,4}, {5,6}, {7,8}},
428+
Poco = new Poco(999, "666"),
429+
String = "huhu",
430+
Dictionary = new Dictionary<int, string>
431+
{
432+
{ 666, "b" },
433+
{ 999, "testString" },
434+
{ 42, "iMaGiNe" }
435+
},
436+
Delegate = (x, y) => x * y,
437+
TestEnum = new[]{4,8,9,3,2},
438+
Exception = new ArgumentException("Test Exception", new IndexOutOfRangeException("-999")),
439+
ImmutableList = new [] {9, 4, 6, 2, 5}.ToImmutableList(),
440+
ImmutableDictionary = new Dictionary<int, string>
441+
{
442+
{ 666, "b" },
443+
{ 999, "testString" },
444+
{ 42, "iMaGiNe" }
445+
}.ToImmutableDictionary(),
446+
};
447+
var serializer = new Serializer(new SerializerOptions(knownTypes: new[]
448+
{
449+
typeof(object[]),
450+
typeof(int[]),
451+
typeof(int[,]),
452+
typeof(Dictionary<int, string>),
453+
typeof(DictionaryEntry),
454+
typeof(KeyValuePair<int,string>),
455+
typeof(Temp),
456+
typeof(TestDelegate),
457+
typeof(Enumerable),
458+
typeof(IEnumerable<int>),
459+
typeof(Exception),
460+
typeof(ArgumentException),
461+
typeof(IndexOutOfRangeException),
462+
typeof(FieldInfo),
463+
typeof(ImmutableList),
464+
typeof(ImmutableList<int>),
465+
typeof(ImmutableDictionary<int, string>),
466+
typeof(MethodInfo),
467+
typeof(PropertyInfo),
468+
}));
469+
serializer.Serialize(msg, stream);
470+
stream.Position = 0;
471+
var a = stream.ToArray();
472+
var text = string.Join("", a.Select(x => x < 32 || x > 126 ? "" : ((char)x).ToString()));
473+
_output.WriteLine(text);
474+
var res = (Temp)serializer.Deserialize(stream);
475+
Assert.DoesNotContain("System.Collections.Generic.Dictionary", text);
476+
Assert.Equal(msg, res);
477+
}
249478
}
250479
}

src/Hyperion/SerializerFactories/ArraySerializerFactory.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,14 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
7171
WriteValues((dynamic)arr, stream, elementType, elementSerializer, session);
7272
};
7373
arraySerializer.Initialize(reader, writer);
74-
typeMapping.TryAdd(type, arraySerializer);
74+
75+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
76+
{
77+
var wrapper = new KnownTypeObjectSerializer(arraySerializer, index);
78+
typeMapping.TryAdd(type, wrapper);
79+
}
80+
else
81+
typeMapping.TryAdd(type, arraySerializer);
7582
return arraySerializer;
7683
}
7784
}

src/Hyperion/SerializerFactories/DefaultDictionarySerializerFactory.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
3131
ConcurrentDictionary<Type, ValueSerializer> typeMapping)
3232
{
3333
var ser = new ObjectSerializer(type);
34-
typeMapping.TryAdd(type, ser);
34+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
35+
{
36+
var wrapper = new KnownTypeObjectSerializer(ser, index);
37+
typeMapping.TryAdd(type, wrapper);
38+
}
39+
else
40+
typeMapping.TryAdd(type, ser);
3541
var elementSerializer = serializer.GetSerializerByType(typeof (DictionaryEntry));
3642
var preserveObjectReferences = serializer.Options.PreserveObjectReferences;
3743
ObjectReader reader = (stream, session) =>

src/Hyperion/SerializerFactories/DelegateSerializerFactory.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
3131
ConcurrentDictionary<Type, ValueSerializer> typeMapping)
3232
{
3333
var os = new ObjectSerializer(type);
34-
typeMapping.TryAdd(type, os);
34+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
35+
{
36+
var wrapper = new KnownTypeObjectSerializer(os, index);
37+
typeMapping.TryAdd(type, wrapper);
38+
}
39+
else
40+
typeMapping.TryAdd(type, os);
3541
var methodInfoSerializer = serializer.GetSerializerByType(typeof(MethodInfo));
3642
var preserveObjectReferences = serializer.Options.PreserveObjectReferences;
3743
ObjectReader reader = (stream, session) =>

src/Hyperion/SerializerFactories/ExceptionSerializerFactory.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
9191
StringSerializer.WriteValueImpl(stream, stackTraceString, session);
9292
stream.WriteObjectWithManifest(innerException, session);
9393
});
94-
typeMapping.TryAdd(type, exceptionSerializer);
94+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
95+
{
96+
var wrapper = new KnownTypeObjectSerializer(exceptionSerializer, index);
97+
typeMapping.TryAdd(type, wrapper);
98+
}
99+
else
100+
typeMapping.TryAdd(type, exceptionSerializer);
95101
return exceptionSerializer;
96102
}
97103
}

src/Hyperion/SerializerFactories/ImmutableCollectionsSerializerFactory.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
4949
ConcurrentDictionary<Type, ValueSerializer> typeMapping)
5050
{
5151
var x = new ObjectSerializer(type);
52-
typeMapping.TryAdd(type, x);
52+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
53+
{
54+
var wrapper = new KnownTypeObjectSerializer(x, index);
55+
typeMapping.TryAdd(type, wrapper);
56+
}
57+
else
58+
typeMapping.TryAdd(type, x);
5359
var preserveObjectReferences = serializer.Options.PreserveObjectReferences;
5460

5561
var elementType = GetEnumerableType(type) ?? typeof (object);

src/Hyperion/SerializerFactories/MultipleDimensionalArraySerialzierFactory.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,13 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
142142
WriteValues((Array)arr, stream, elementType, elementSerializer, session);
143143
};
144144
arraySerializer.Initialize(reader, writer);
145-
typeMapping.TryAdd(type, arraySerializer);
145+
if (serializer.Options.KnownTypesDict.TryGetValue(type, out var index))
146+
{
147+
var wrapper = new KnownTypeObjectSerializer(arraySerializer, index);
148+
typeMapping.TryAdd(type, wrapper);
149+
}
150+
else
151+
typeMapping.TryAdd(type, arraySerializer);
146152
return arraySerializer;
147153
}
148154

0 commit comments

Comments
 (0)