ln.objects/serialization/json/JSONSerializer.cs

68 lines
2.4 KiB
C#

using ln.json;
using ln.json.mapping;
using ln.logging;
using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
namespace ln.objects.serialization.json
{
public class JSONSerializer : Serializer
{
public JSONMapper Mapper { get; }
public ObjectStore ObjectStore { get; }
public JSONSerializer(ObjectStore objectStore)
{
ObjectStore = objectStore;
Mapper = new JSONMapper() { DefaultBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, DefaultMappingFlags = JSONObjectMappingFlags.FIELDS };
Mapper.OnRequestCustomSerialization += Mapper_OnRequestCustomSerialization;
Mapper.AddMappingFactory(
typeof(IList<>),
(Type targetType, out JSONMapping mapping) =>
{
mapping = (JSONMapping)Activator.CreateInstance(typeof(LazyListMapping<>).MakeGenericType(targetType.GetGenericArguments()), objectStore);
return false;
});
}
private bool Mapper_OnRequestCustomSerialization(object o, out JSONValue json)
{
if (!ReferenceEquals(null, o) && !o.GetType().IsValueType && !o.GetType().IsInterface && Mapper.GetOrBuildMapping(o.GetType(), out JSONMapping mapping) && mapping is JSONObjectMapping)
{
if (TryLookupReference(o, out object reference))
{
json = new JSONString(Convert.ToBase64String(((Guid)reference).ToByteArray()));
return true;
}
}
json = null;
return false;
}
public override bool SerializeObject(object o, out byte[] serializedBytes)
{
if (ReferenceEquals(null, o))
{
serializedBytes = new byte[0];
return true;
}
if (Mapper.GetOrBuildMapping(o.GetType(), out JSONMapping mapping))
{
JSONValue json = mapping.ToJson(Mapper, o);
serializedBytes = Encoding.UTF8.GetBytes(json.ToString());
if (ObjectStore.DEBUG)
Logging.Log(LogLevel.DEBUG, "Serialized: {0}", json.ToString());
return true;
}
throw new NotSupportedException();
}
}
}