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(); } } }