public ObjectSerializer(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
Type = type;
//TODO: remove version info
var typeName = type.GetShortAssemblyQualifiedName();
// ReSharper disable once PossibleNullReferenceException
// ReSharper disable once AssignNullToNotNullAttribute
var typeNameBytes = typeName.ToUtf8Bytes();
var fields = type.GetFieldInfosForType();
var fieldNames = fields.Select(field => field.Name.ToUtf8Bytes()).ToList();
var versionInfo = TypeEx.GetTypeManifest(fieldNames);
//precalculate the entire manifest for this serializer
//this helps us to minimize calls to Stream.Write/WriteByte
_manifest =
new[] {ManifestFull}
.Concat(BitConverter.GetBytes(typeNameBytes.Length))
.Concat(typeNameBytes)
.ToArray(); //serializer id 255 + assembly qualified name
//TODO: this should only work this way for standard poco objects
//custom object serializers should not emit their inner fields
//this is the same as the above, but including all field names of the type, in alphabetical order
_manifestWithVersionInfo =
new[] {ManifestVersion}
.Concat(BitConverter.GetBytes(typeNameBytes.Length))
.Concat(typeNameBytes)
.Concat(versionInfo)
.ToArray(); //serializer id 255 + assembly qualified name + versionInfo
//initialize reader and writer with dummy handlers that wait until the serializer is fully initialized
_writer = (stream, o, session) =>
{
SpinWait.SpinUntil(() => _isInitialized);
WriteValue(stream, o, session);
};
_reader = (stream, session) =>
{
SpinWait.SpinUntil(() => _isInitialized);
return ReadValue(stream, session);
};
}