-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Serialization library major refactoring
- moved serializer assembly out of factor and into builder - comprehensive polymorphic type support - removed all "on-the-fly" registrations - binary serializer serializes registrations - lots of bug fixes - far more robust
- Loading branch information
1 parent
907ef02
commit 57201c1
Showing
71 changed files
with
2,147 additions
and
1,380 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Hydrogen; | ||
|
||
public sealed class ObjectSerializer : ItemSerializerDecorator<object> { | ||
|
||
public ObjectSerializer(SerializerFactory factory) | ||
: base(new ReferenceSerializer<object>(new PolymorphicSerializer<object>( factory, factory.GetPureSerializer<object>()))) { | ||
} | ||
} | ||
|
||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,101 @@ | ||
namespace Hydrogen; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
namespace Hydrogen; | ||
|
||
/// <summary> | ||
/// Replacement for BinarySerializer deprecated in .NET 5.0 using Hydrogen's serialization framework. | ||
/// </summary> | ||
public sealed class BinarySerializer : ItemSerializerDecorator<object> { | ||
public sealed class BinarySerializer : ItemSerializerDecorator<object, ReferenceSerializer<object>> { | ||
private readonly RegistrationSerializer _registrationsSerializer; | ||
private readonly SerializerFactory _staticFactory; | ||
|
||
private record struct FactoryRegistration(Type Type, long TypeCode); | ||
|
||
public BinarySerializer() : this(SerializerFactory.Default) { | ||
} | ||
|
||
public BinarySerializer(SerializerFactory serializerFactory) | ||
: base(new PolymorphicSerializer<object>(serializerFactory)) { | ||
: base(new ReferenceSerializer<object>(new PolymorphicSerializer<object>(serializerFactory))) { | ||
_registrationsSerializer = new RegistrationSerializer(); | ||
_staticFactory = serializerFactory; | ||
} | ||
|
||
|
||
public override long CalculateSize(SerializationContext context, object item) { | ||
context.SetEphemeralFactory(new SerializerFactory(_staticFactory)); | ||
try { | ||
// calculate item size | ||
var itemSize = base.CalculateSize(context, item); | ||
|
||
// calculate registrations size | ||
context.EphemeralFactory.FinishRegistrations(); | ||
var registrations = context.GetEphemeralRegistrations().Select(x => new FactoryRegistration(x.DataType, x.TypeCode)); | ||
var registrationsSize = _registrationsSerializer.CalculateSize(registrations); // don't use context | ||
|
||
return registrationsSize + itemSize; | ||
} finally { | ||
context.ClearEphemeralFactory(); | ||
} | ||
} | ||
|
||
public override void Serialize(object item, EndianBinaryWriter writer, SerializationContext context) { | ||
context.SetEphemeralFactory(new SerializerFactory(_staticFactory)); | ||
try { | ||
// serialize item into temp buffer | ||
using var memoryStream = new MemoryStream(); | ||
using var memoryWriter = new EndianBinaryWriter(writer.BitConverter, memoryStream); | ||
base.Serialize(item, memoryWriter, context); | ||
var buffer = memoryStream.ToArray(); | ||
|
||
// serialize registrations first | ||
context.EphemeralFactory.FinishRegistrations(); | ||
var registrations = context.GetEphemeralRegistrations().Select(x => new FactoryRegistration(x.DataType, x.TypeCode));; | ||
_registrationsSerializer.Serialize(registrations, writer); // don't use context | ||
|
||
// serialize item (buffer) | ||
writer.Write(buffer); | ||
} finally { | ||
context.ClearEphemeralFactory(); | ||
} | ||
} | ||
|
||
|
||
public override object Deserialize(EndianBinaryReader reader, SerializationContext context) { | ||
|
||
// Deserialize type registrations | ||
var registrations = _registrationsSerializer.Deserialize(reader); // don't use context | ||
|
||
// Rebuild ephemeral factory used for serialization | ||
context.SetEphemeralFactory(new SerializerFactory(_staticFactory)); | ||
|
||
foreach(var registration in registrations.OrderBy(x => x.TypeCode)) { | ||
if (!context.EphemeralFactory.TryGetRegistration(registration.TypeCode, out var factoryRegistration)) { | ||
SerializerBuilder.FactoryAssemble(context.EphemeralFactory, registration.Type, true, registration.TypeCode); | ||
} else { | ||
// it's already registered (likely as a dependent of prior registration), need to check it matches what we expect | ||
Guard.Ensure(registration.Type == factoryRegistration.DataType, $"Deserialization type-code mismatch for type-code {registration.TypeCode} (expected type {registration.Type.ToStringCS()} but was {factoryRegistration.DataType.ToStringCS()})"); | ||
} | ||
} | ||
context.EphemeralFactory.FinishRegistrations(); | ||
|
||
// Deserialize item | ||
var item = base.Deserialize(reader, context); | ||
|
||
return item; | ||
} | ||
|
||
|
||
|
||
private class RegistrationSerializer : ProjectedSerializer<IEnumerable<(Type, long)>, IEnumerable<FactoryRegistration>> { | ||
public RegistrationSerializer() | ||
: base( | ||
new TaggedTypeCollectionSerializer<long>(PrimitiveSerializer<long>.Instance, SizeDescriptorStrategy.UseCVarInt), | ||
x => x.Select(y => new FactoryRegistration(y.Item1, y.Item2)), | ||
x => x.Select(y => (y.Type, y.TypeCode)) | ||
) { | ||
} | ||
} | ||
} |
Oops, something went wrong.