少年修仙传客户端基础资源
lwb
2021-01-26 f6ab248e23fb6485f4121294ff4167e8a15a47a3
Assets/Plugins/LitJson/JsonMapper.cs
@@ -15,7 +15,10 @@
using System.Globalization;
using System.IO;
using System.Reflection;
using ILRuntime.Runtime.Intepreter;
using ILRuntime.Runtime.Stack;
using ILRuntime.CLR.Method;
using ILRuntime.CLR.Utils;
namespace LitJson
{
@@ -100,33 +103,33 @@
    public class JsonMapper
    {
        #region Fields
        private static readonly int max_nesting_depth;
        private static int max_nesting_depth;
        private static readonly IFormatProvider datetime_format;
        private static IFormatProvider datetime_format;
        private static readonly IDictionary<Type, ExporterFunc> base_exporters_table;
        private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table;
        private static IDictionary<Type, ExporterFunc> base_exporters_table;
        private static IDictionary<Type, ExporterFunc> custom_exporters_table;
        private static readonly IDictionary<Type,
        private static IDictionary<Type,
                IDictionary<Type, ImporterFunc>> base_importers_table;
        private static readonly IDictionary<Type,
        private static IDictionary<Type,
                IDictionary<Type, ImporterFunc>> custom_importers_table;
        private static readonly IDictionary<Type, ArrayMetadata> array_metadata;
        private static IDictionary<Type, ArrayMetadata> array_metadata;
        private static readonly object array_metadata_lock = new Object ();
        private static readonly IDictionary<Type,
        private static IDictionary<Type,
                IDictionary<Type, MethodInfo>> conv_ops;
        private static readonly object conv_ops_lock = new Object ();
        private static readonly IDictionary<Type, ObjectMetadata> object_metadata;
        private static IDictionary<Type, ObjectMetadata> object_metadata;
        private static readonly object object_metadata_lock = new Object ();
        private static readonly IDictionary<Type,
        private static IDictionary<Type,
                IList<PropertyMetadata>> type_properties;
        private static readonly object type_properties_lock = new Object ();
        private static readonly JsonWriter      static_writer;
        private static JsonWriter      static_writer;
        private static readonly object static_writer_lock = new Object ();
        #endregion
@@ -173,19 +176,34 @@
            if (type.GetInterface ("System.Collections.IList") != null)
                data.IsList = true;
            foreach (PropertyInfo p_info in type.GetProperties ()) {
                if (p_info.Name != "Item")
                    continue;
                ParameterInfo[] parameters = p_info.GetIndexParameters ();
                if (parameters.Length != 1)
                    continue;
                if (parameters[0].ParameterType == typeof (int))
                    data.ElementType = p_info.PropertyType;
            if (type is ILRuntime.Reflection.ILRuntimeWrapperType)
            {
                var wt = (ILRuntime.Reflection.ILRuntimeWrapperType)type;
                if (data.IsArray)
                {
                    data.ElementType = wt.CLRType.ElementType.ReflectionType;
                }
                else
                {
                    data.ElementType = wt.CLRType.GenericArguments[0].Value.ReflectionType;
                }
            }
            else
            {
                foreach (PropertyInfo p_info in type.GetProperties())
                {
                    if (p_info.Name != "Item")
                        continue;
                    ParameterInfo[] parameters = p_info.GetIndexParameters();
                    if (parameters.Length != 1)
                        continue;
                    if (parameters[0].ParameterType == typeof(int))
                        data.ElementType = p_info.PropertyType;
                }
            }
            lock (array_metadata_lock) {
                try {
                    array_metadata.Add (type, data);
@@ -206,7 +224,6 @@
                data.IsDictionary = true;
            data.Properties = new Dictionary<string, PropertyMetadata> ();
            foreach (PropertyInfo p_info in type.GetProperties ()) {
                if (p_info.Name == "Item") {
                    ParameterInfo[] parameters = p_info.GetIndexParameters ();
@@ -214,8 +231,15 @@
                    if (parameters.Length != 1)
                        continue;
                    if (parameters[0].ParameterType == typeof (string))
                        data.ElementType = p_info.PropertyType;
                    if (parameters[0].ParameterType == typeof(string))
                    {
                        if (type is ILRuntime.Reflection.ILRuntimeWrapperType)
                        {
                            data.ElementType = ((ILRuntime.Reflection.ILRuntimeWrapperType)type).CLRType.GenericArguments[1].Value.ReflectionType;
                        }
                        else
                            data.ElementType = p_info.PropertyType;
                    }
                    continue;
                }
@@ -310,19 +334,14 @@
            if (reader.Token == JsonToken.ArrayEnd)
                return null;
            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
            Type value_type = underlying_type ?? inst_type;
            //ILRuntime doesn't support nullable valuetype
            Type underlying_type = inst_type;//Nullable.GetUnderlyingType(inst_type);
            Type value_type = inst_type;
            if (reader.Token == JsonToken.Null) {
                #if NETSTANDARD1_5
                if (inst_type.IsClass() || underlying_type != null) {
                    return null;
                }
                #else
                if (inst_type.IsClass || underlying_type != null) {
                    return null;
                }
                #endif
                throw new JsonException (String.Format (
                            "Can't assign null to an instance of type {0}",
@@ -335,18 +354,23 @@
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean) {
                Type json_type = reader.Value.GetType ();
                Type json_type = reader.Value.GetType();
                var vt = value_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).CLRType.TypeForCLR : value_type;
                if (value_type.IsAssignableFrom (json_type))
                if (vt.IsAssignableFrom(json_type))
                    return reader.Value;
                if (vt is ILRuntime.Reflection.ILRuntimeType && ((ILRuntime.Reflection.ILRuntimeType)vt).ILType.IsEnum)
                {
                    if (json_type == typeof(int) || json_type == typeof(long) || json_type == typeof(short) || json_type == typeof(byte))
                        return reader.Value;
                }
                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey (json_type) &&
                    custom_importers_table[json_type].ContainsKey (
                        value_type)) {
                        vt)) {
                    ImporterFunc importer =
                        custom_importers_table[json_type][value_type];
                        custom_importers_table[json_type][vt];
                    return importer (reader.Value);
                }
@@ -354,24 +378,20 @@
                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey (json_type) &&
                    base_importers_table[json_type].ContainsKey (
                        value_type)) {
                        vt)) {
                    ImporterFunc importer =
                        base_importers_table[json_type][value_type];
                        base_importers_table[json_type][vt];
                    return importer (reader.Value);
                }
                // Maybe it's an enum
                #if NETSTANDARD1_5
                if (value_type.IsEnum())
                    return Enum.ToObject (value_type, reader.Value);
                #else
                if (value_type.IsEnum)
                    return Enum.ToObject (value_type, reader.Value);
                #endif
                if (vt.IsEnum)
                    return Enum.ToObject (vt, reader.Value);
                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp (value_type, json_type);
                MethodInfo conv_op = GetConvOp (vt, json_type);
                if (conv_op != null)
                    return conv_op.Invoke (null,
@@ -405,20 +425,22 @@
                    list = new ArrayList ();
                    elem_type = inst_type.GetElementType ();
                }
                list.Clear();
                while (true) {
                    object item = ReadValue (elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                        break;
                    var rt = elem_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)elem_type).RealType : elem_type;
                    rt = elem_type is ILRuntime.Reflection.ILRuntimeType ? ((ILRuntime.Reflection.ILRuntimeType)elem_type).ILType.TypeForCLR : elem_type;
                    item = rt.CheckCLRTypes(item);
                    list.Add (item);
                }
                if (t_data.IsArray) {
                    int n = list.Count;
                    instance = Array.CreateInstance (elem_type, n);
                    var rt = elem_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)elem_type).RealType : elem_type;
                    rt = elem_type is ILRuntime.Reflection.ILRuntimeType ? ((ILRuntime.Reflection.ILRuntimeType)elem_type).ILType.TypeForCLR : elem_type;
                    instance = Array.CreateInstance (rt, n);
                    for (int i = 0; i < n; i++)
                        ((Array) instance).SetValue (list[i], i);
@@ -428,9 +450,14 @@
            } else if (reader.Token == JsonToken.ObjectStart) {
                AddObjectMetadata (value_type);
                ObjectMetadata t_data = object_metadata[value_type];
                instance = Activator.CreateInstance (value_type);
                if (value_type is ILRuntime.Reflection.ILRuntimeType)
                    instance = ((ILRuntime.Reflection.ILRuntimeType)value_type).ILType.Instantiate();
                else
                {
                    if (value_type is ILRuntime.Reflection.ILRuntimeWrapperType)
                        value_type = ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).RealType;
                    instance = Activator.CreateInstance(value_type);
                }
                while (true) {
                    reader.Read ();
@@ -473,9 +500,10 @@
                            }
                        }
                        var rt = t_data.ElementType is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)t_data.ElementType).RealType : t_data.ElementType;
                        ((IDictionary) instance).Add (
                            property, ReadValue (
                                t_data.ElementType, reader));
                            property, rt.CheckCLRTypes(ReadValue (
                                t_data.ElementType, reader)));
                    }
                }
@@ -605,11 +633,6 @@
                delegate (object obj, JsonWriter writer) {
                    writer.Write ((ulong) obj);
                };
            base_exporters_table[typeof(DateTimeOffset)] =
                delegate (object obj, JsonWriter writer) {
                    writer.Write(((DateTimeOffset)obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format));
                };
        }
        private static void RegisterBaseImporters ()
@@ -629,12 +652,6 @@
                              typeof (ulong), importer);
            importer = delegate (object input) {
                return Convert.ToInt64((int)input);
            };
            RegisterImporter(base_importers_table, typeof(int),
                              typeof(long), importer);
            importer = delegate (object input) {
                return Convert.ToSByte ((int) input);
            };
            RegisterImporter (base_importers_table, typeof (int),
@@ -645,6 +662,12 @@
            };
            RegisterImporter (base_importers_table, typeof (int),
                              typeof (short), importer);
            importer = delegate (object input) {
                return Convert.ToInt64((int)input);
            };
            RegisterImporter(base_importers_table, typeof(int),
                              typeof(long), importer);
            importer = delegate (object input) {
                return Convert.ToUInt16 ((int) input);
@@ -694,12 +717,6 @@
            };
            RegisterImporter (base_importers_table, typeof (string),
                              typeof (DateTime), importer);
            importer = delegate (object input) {
                return DateTimeOffset.Parse((string)input, datetime_format);
            };
            RegisterImporter(base_importers_table, typeof(string),
                typeof(DateTimeOffset), importer);
        }
        private static void RegisterImporter (
@@ -781,13 +798,10 @@
                return;
            }
            if (obj is IDictionary dictionary) {
            if (obj is IDictionary) {
                writer.WriteObjectStart ();
                foreach (DictionaryEntry entry in dictionary) {
                    var propertyName = entry.Key is string key ?
                        key
                        : Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
                    writer.WritePropertyName (propertyName);
                foreach (DictionaryEntry entry in (IDictionary) obj) {
                    writer.WritePropertyName ((string) entry.Key);
                    WriteValue (entry.Value, writer, writer_is_private,
                                depth + 1);
                }
@@ -796,7 +810,17 @@
                return;
            }
            Type obj_type = obj.GetType ();
            Type obj_type;
            if (obj is ILRuntime.Runtime.Intepreter.ILTypeInstance)
            {
                obj_type = ((ILRuntime.Runtime.Intepreter.ILTypeInstance)obj).Type.ReflectionType;
            }
            else if(obj is ILRuntime.Runtime.Enviorment.CrossBindingAdaptorType)
            {
                obj_type = ((ILRuntime.Runtime.Enviorment.CrossBindingAdaptorType)obj).ILInstance.Type.ReflectionType;
            }
            else
                obj_type = obj.GetType();
            // See if there's a custom exporter for the object
            if (custom_exporters_table.ContainsKey (obj_type)) {
@@ -909,13 +933,6 @@
            return (T) ReadValue (typeof (T), reader);
        }
        public static object ToObject(string json, Type ConvertType )
        {
            JsonReader reader = new JsonReader(json);
            return ReadValue(ConvertType, reader);
        }
        public static IJsonWrapper ToWrapper (WrapperFactory factory,
                                              JsonReader reader)
@@ -962,5 +979,70 @@
        {
            custom_importers_table.Clear ();
        }
        public unsafe static void RegisterILRuntimeCLRRedirection(ILRuntime.Runtime.Enviorment.AppDomain appdomain)
        {
            foreach(var i in typeof(JsonMapper).GetMethods())
            {
                if(i.Name == "ToObject" && i.IsGenericMethodDefinition)
                {
                    var param = i.GetParameters();
                    if(param[0].ParameterType == typeof(string))
                    {
                        appdomain.RegisterCLRMethodRedirection(i, JsonToObject);
                    }
                    else if(param[0].ParameterType == typeof(JsonReader))
                    {
                        appdomain.RegisterCLRMethodRedirection(i, JsonToObject2);
                    }
                    else if (param[0].ParameterType == typeof(TextReader))
                    {
                        appdomain.RegisterCLRMethodRedirection(i, JsonToObject3);
                    }
                }
            }
        }
        public unsafe static StackObject* JsonToObject(ILIntepreter intp, StackObject* esp, IList<object> mStack, CLRMethod method, bool isNewObj)
        {
            ILRuntime.Runtime.Enviorment.AppDomain __domain = intp.AppDomain;
            StackObject* ptr_of_this_method;
            StackObject* __ret = ILIntepreter.Minus(esp, 1);
            ptr_of_this_method = ILIntepreter.Minus(esp, 1);
            System.String json = (System.String)typeof(System.String).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, mStack));
            intp.Free(ptr_of_this_method);
            var type = method.GenericArguments[0].ReflectionType;
            var result_of_this_method = ReadValue(type, new JsonReader(json));
            return ILIntepreter.PushObject(__ret, mStack, result_of_this_method);
        }
        public unsafe static StackObject* JsonToObject2(ILIntepreter intp, StackObject* esp, IList<object> mStack, CLRMethod method, bool isNewObj)
        {
            ILRuntime.Runtime.Enviorment.AppDomain __domain = intp.AppDomain;
            StackObject* ptr_of_this_method;
            StackObject* __ret = ILIntepreter.Minus(esp, 1);
            ptr_of_this_method = ILIntepreter.Minus(esp, 1);
            JsonReader json = (JsonReader)typeof(JsonReader).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, mStack));
            intp.Free(ptr_of_this_method);
            var type = method.GenericArguments[0].ReflectionType;
            var result_of_this_method = ReadValue(type, json);
            return ILIntepreter.PushObject(__ret, mStack, result_of_this_method);
        }
        public unsafe static StackObject* JsonToObject3(ILIntepreter intp, StackObject* esp, IList<object> mStack, CLRMethod method, bool isNewObj)
        {
            ILRuntime.Runtime.Enviorment.AppDomain __domain = intp.AppDomain;
            StackObject* ptr_of_this_method;
            StackObject* __ret = ILIntepreter.Minus(esp, 1);
            ptr_of_this_method = ILIntepreter.Minus(esp, 1);
            TextReader json = (TextReader)typeof(TextReader).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, mStack));
            intp.Free(ptr_of_this_method);
            var type = method.GenericArguments[0].ReflectionType;
            var result_of_this_method = ReadValue(type, new JsonReader(json));
            return ILIntepreter.PushObject(__ret, mStack, result_of_this_method);
        }
    }
}