From 0cb031d0bad6fa7c3bb930231678ffd7b5a06112 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 6 Feb 2019 20:03:35 +0900 Subject: [PATCH] Separate GenericDeserializer.cs --- .../UniJSON/Scripts/GenericDeserializer.cs | 194 ++++++++++++++++++ .../Scripts/GenericDeserializer.cs.meta | 12 ++ .../ListTreeNodeDeserializerExtensions.cs | 186 ----------------- 3 files changed, 206 insertions(+), 186 deletions(-) create mode 100644 Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs create mode 100644 Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs.meta diff --git a/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs b/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs new file mode 100644 index 000000000..e61cdad61 --- /dev/null +++ b/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + + +namespace UniJSON +{ + public static class GenericDeserializer + where T : IListTreeItem, IValue + { + static V[] GenericArrayDeserializer(ListTreeNode s) + { + if (!s.IsArray()) + { + throw new ArgumentException("not array: " + s.Value.ValueType); + } + var u = new V[s.GetArrayCount()]; + int i = 0; + foreach (var x in s.ArrayItems()) + { + x.Deserialize(ref u[i++]); + } + return u; + } + + static List GenericListDeserializer(ListTreeNode s) + { + if (!s.IsArray()) + { + throw new ArgumentException("not array: " + s.Value.ValueType); + } + var u = new List(s.GetArrayCount()); + foreach (var x in s.ArrayItems()) + { + var e = default(V); + x.Deserialize(ref e); + u.Add(e); + } + return u; + } + + delegate void FieldSetter(ListTreeNode s, object o); + static FieldSetter GetFieldDeserializer(FieldInfo fi) + { + return (s, o) => + { + var u = default(V); + s.Deserialize(ref u); + fi.SetValue(o, u); + }; + } + + static Func, U> GetDeserializer() + { + // primitive + { + var mi = typeof(ListTreeNode).GetMethods().FirstOrDefault(x => + { + if (!x.Name.StartsWith("Get")) + { + return false; + } + + if (!x.Name.EndsWith(typeof(U).Name)) + { + return false; + } + + var parameters = x.GetParameters(); + if (parameters.Length != 0) + { + return false; + } + + if (x.ReturnType != typeof(U)) + { + return false; + } + + return true; + }); + + if (mi != null) + { + return GenericInvokeCallFactory.StaticFunc, U>(mi); + } + } + + var target = typeof(U); + + if (target.IsArray) + { + var mi = typeof(GenericDeserializer).GetMethod("GenericArrayDeserializer", + BindingFlags.Static | BindingFlags.NonPublic); + var g = mi.MakeGenericMethod(target.GetElementType()); + return GenericInvokeCallFactory.StaticFunc, U>(g); + } + + if (target.IsGenericType) + { + if (target.GetGenericTypeDefinition() == typeof(List<>)) + { + var mi = typeof(GenericDeserializer).GetMethod("GenericListDeserializer", + BindingFlags.Static | BindingFlags.NonPublic); + var g = mi.MakeGenericMethod(target.GetGenericArguments()); + return GenericInvokeCallFactory.StaticFunc, U>(g); + } + + if (target.GetGenericTypeDefinition() == typeof(Dictionary<,>) && + target.GetGenericArguments()[0] == typeof(string)) + { + var mi = typeof(ListTreeNodeDeserializerExtensions).GetMethod("DictionaryDeserializer", + BindingFlags.Static | BindingFlags.NonPublic); + var g = mi.MakeGenericMethod(typeof(T)); + return GenericInvokeCallFactory.StaticFunc, U>(g); + } + } + + { + var schema = JsonSchema.FromType(); + return s => + { + var t = default(U); + schema.Validator.Deserialize(s, ref t); + return t; + }; + } + +#if false + if (target.IsEnum) + { + var value = Expression.Parameter(typeof(int), "value"); + var cast = Expression.Convert(value, target); + var func = Expression.Lambda(cast, value); + var compiled = (Func)func.Compile(); + return s => + { + return compiled(s.GetInt32()); + }; + } + + { + var fields = target.GetFields(BindingFlags.Instance | BindingFlags.Public); + var fieldDeserializers = fields.ToDictionary(x => Utf8String.From(x.Name), x => + { + var mi = typeof(GenericDeserializer).GetMethod("GetFieldDeserializer", + BindingFlags.Static|BindingFlags.NonPublic); + var g = mi.MakeGenericMethod(x.FieldType); + return (FieldSetter)g.Invoke(null, new object[] { x }); + }); + + return (S s) => + { + if (!s.IsMap()) + { + throw new ArgumentException(s.ValueType.ToString()); + } + + var t = (object)default(GenericCreator).Create(s); + foreach(var kv in s.ObjectItems()) + { + FieldSetter setter; + if (fieldDeserializers.TryGetValue(kv.Key, out setter)) + { + setter(kv.Value, t); + } + } + return (T)t; + }; + } +#endif + } + + public delegate U Deserializer(ListTreeNode node); + + public static Deserializer s_deserializer; + + public static void Deserialize(ListTreeNode node, ref U value) + { + if (s_deserializer == null) + { + var d = GetDeserializer(); + s_deserializer = new Deserializer(d); + } + value = s_deserializer(node); + } + + public static void SetCustomDeserializer(Deserializer deserializer) + { + s_deserializer = deserializer; + } + } +} diff --git a/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs.meta b/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs.meta new file mode 100644 index 000000000..2efc295d6 --- /dev/null +++ b/Assets/VRM/UniJSON/Scripts/GenericDeserializer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 74625bf2a3d6bc64d9d92b08221a8a3d +timeCreated: 1549450914 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNodeDeserializerExtensions.cs b/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNodeDeserializerExtensions.cs index 9a55a7da3..b5fda3380 100644 --- a/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNodeDeserializerExtensions.cs +++ b/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNodeDeserializerExtensions.cs @@ -51,190 +51,4 @@ namespace UniJSON GenericDeserializer.Deserialize(self, ref value); } } - - public static class GenericDeserializer - where T : IListTreeItem, IValue - { - static V[] GenericArrayDeserializer(ListTreeNode s) - { - if (!s.IsArray()) - { - throw new ArgumentException("not array: " + s.Value.ValueType); - } - var u = new V[s.GetArrayCount()]; - int i = 0; - foreach (var x in s.ArrayItems()) - { - x.Deserialize(ref u[i++]); - } - return u; - } - - static List GenericListDeserializer(ListTreeNode s) - { - if (!s.IsArray()) - { - throw new ArgumentException("not array: " + s.Value.ValueType); - } - var u = new List(s.GetArrayCount()); - foreach (var x in s.ArrayItems()) - { - var e = default(V); - x.Deserialize(ref e); - u.Add(e); - } - return u; - } - - delegate void FieldSetter(ListTreeNode s, object o); - static FieldSetter GetFieldDeserializer(FieldInfo fi) - { - return (s, o) => - { - var u = default(V); - s.Deserialize(ref u); - fi.SetValue(o, u); - }; - } - - static Func, U> GetDeserializer() - { - // primitive - { - var mi = typeof(ListTreeNode).GetMethods().FirstOrDefault(x => - { - if (!x.Name.StartsWith("Get")) - { - return false; - } - - if (!x.Name.EndsWith(typeof(U).Name)) - { - return false; - } - - var parameters = x.GetParameters(); - if (parameters.Length != 0) - { - return false; - } - - if (x.ReturnType != typeof(U)) - { - return false; - } - - return true; - }); - - if (mi != null) - { - return GenericInvokeCallFactory.StaticFunc, U>(mi); - } - } - - var target = typeof(U); - - if (target.IsArray) - { - var mi = typeof(GenericDeserializer).GetMethod("GenericArrayDeserializer", - BindingFlags.Static | BindingFlags.NonPublic); - var g = mi.MakeGenericMethod(target.GetElementType()); - return GenericInvokeCallFactory.StaticFunc, U>(g); - } - - if (target.IsGenericType) - { - if (target.GetGenericTypeDefinition() == typeof(List<>)) - { - var mi = typeof(GenericDeserializer).GetMethod("GenericListDeserializer", - BindingFlags.Static | BindingFlags.NonPublic); - var g = mi.MakeGenericMethod(target.GetGenericArguments()); - return GenericInvokeCallFactory.StaticFunc, U>(g); - } - - if (target.GetGenericTypeDefinition() == typeof(Dictionary<,>) && - target.GetGenericArguments()[0] == typeof(string)) - { - var mi = typeof(ListTreeNodeDeserializerExtensions).GetMethod("DictionaryDeserializer", - BindingFlags.Static | BindingFlags.NonPublic); - var g = mi.MakeGenericMethod(typeof(T)); - return GenericInvokeCallFactory.StaticFunc, U>(g); - } - } - - { - var schema = JsonSchema.FromType(); - return s => - { - var t = default(U); - schema.Validator.Deserialize(s, ref t); - return t; - }; - } - -#if false - if (target.IsEnum) - { - var value = Expression.Parameter(typeof(int), "value"); - var cast = Expression.Convert(value, target); - var func = Expression.Lambda(cast, value); - var compiled = (Func)func.Compile(); - return s => - { - return compiled(s.GetInt32()); - }; - } - - { - var fields = target.GetFields(BindingFlags.Instance | BindingFlags.Public); - var fieldDeserializers = fields.ToDictionary(x => Utf8String.From(x.Name), x => - { - var mi = typeof(GenericDeserializer).GetMethod("GetFieldDeserializer", - BindingFlags.Static|BindingFlags.NonPublic); - var g = mi.MakeGenericMethod(x.FieldType); - return (FieldSetter)g.Invoke(null, new object[] { x }); - }); - - return (S s) => - { - if (!s.IsMap()) - { - throw new ArgumentException(s.ValueType.ToString()); - } - - var t = (object)default(GenericCreator).Create(s); - foreach(var kv in s.ObjectItems()) - { - FieldSetter setter; - if (fieldDeserializers.TryGetValue(kv.Key, out setter)) - { - setter(kv.Value, t); - } - } - return (T)t; - }; - } -#endif - } - - public delegate U Deserializer(ListTreeNode node); - - public static Deserializer s_deserializer; - - public static void Deserialize(ListTreeNode node, ref U value) - { - if (s_deserializer == null) - { - var d = GetDeserializer(); - s_deserializer = new Deserializer(d); - } - value = s_deserializer(node); - } - - public static void SetCustomDeserializer(Deserializer deserializer) - { - s_deserializer = deserializer; - } - } }