From 7274c7561cdda14ef33e8254bd24ae48d010948c Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Mon, 23 Jan 2023 11:15:53 +1100 Subject: [PATCH] 1.0.4 - Update license - Update fastJSON to 2.4.0.5 - Add support for many tfms (including limited support for .NET Core 1.0 and Standard 1.5) - Binary compat fix: specify enum values for 'myPropInfoType' explicitly (wouldn't have affected any existing distribution of this library) --- LICENSE | 2 +- README.md | 11 ++ UnitTests/Tests.cs | 98 ++++++++++------ UnitTests/UnitTestsCore.csproj | 8 +- fastJSON.nuspec | 60 +++++++++- fastJSON/Helper.cs | 7 +- fastJSON/InternalHelpers.cs | 206 +++++++++++++++++++++++++++++++++ fastJSON/JSON.cs | 48 ++++---- fastJSON/JsonParser.cs | 24 ++-- fastJSON/JsonSerializer.cs | 16 +-- fastJSON/Reflection.cs | 126 +++++++++++--------- fastJSON/dynamic.cs | 4 +- fastJSONcore/fastJSON.csproj | 55 +++++++-- history_json5.txt | 6 + 14 files changed, 514 insertions(+), 157 deletions(-) create mode 100644 fastJSON/InternalHelpers.cs diff --git a/LICENSE b/LICENSE index 6ba117b..ff40947 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License Copyright (c) 2010-2021 Mehdi Gholam -Copyright (c) 2020-2021 Hamish Arblaster +Copyright (c) 2020-2023 Hamish Arblaster Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index de98b17..6d36cce 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,22 @@ The [fastJSON how to](https://github.com/mgholam/fastJSON/blob/master/Howto.md) Supported platforms: - .NET Framework 4.0 +- .NET Framework 4.5 +- .NET Standard 1.5 (limited support) - .NET Standard 2.0 - .NET Standard 2.1 +- .NET Core 1.0 (limited support) +- .NET Core 2.0 +- .NET Core 2.1 +- .NET Core 3.0 +- .NET Core 3.1 - .NET 5.0 +- .NET 6.0 +- .NET 7.0 - And any platforms compatible with the above tfms +Limited support: you should test that the code works on each specific runtime you plan to build for as required APIs may not be available at runtime. + When building the project for yourself, open the fastJSONCore.sln solution and build the fastJSON5Builder project to create the executables. Use the fastJSON project at fastJSONcore/fastJSON.csproj (fastJSON in the sln file) to modify the library files. The UnitTests/UnitTestsCore.csproj project (UnitTestsCore in the sln file) is used to do the testing, so use it for anything relating to tests. The UnitTests/UnitTests.csproj project (UnitTests in the sln file) is the test project for .NET Framework. You may encounter issues building if you have the fastJSON.csproj file open in Visual Studio, try closing it if you do. diff --git a/UnitTests/Tests.cs b/UnitTests/Tests.cs index b3ea305..2471ce2 100644 --- a/UnitTests/Tests.cs +++ b/UnitTests/Tests.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) +using System.Data; +#endif #if !SILVERLIGHT using NUnit.Framework; -using System.Data; #endif using System.Collections; using System.Threading; @@ -48,10 +50,10 @@ public static void IsInstanceOf(object o) #endif public class tests { - #region [ helpers ] +#region [ helpers ] static int thousandtimes = 1000; static int fivetimes = 5; -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) static DataSet ds = new DataSet(); #endif //static bool exotic = false; @@ -91,11 +93,13 @@ ahjksjkAHJKS سلام فارسی public bool isNew { get; set; } public string laststring { get; set; } public Gender gender { get; set; } +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + public DataSet dataset { get; set; } +#endif #if !SILVERLIGHT - public DataSet dataset { get; set; } public Hashtable hash { get; set; } #endif - public Dictionary stringDictionary { get; set; } + public Dictionary stringDictionary { get; set; } public Dictionary objectDictionary { get; set; } public Dictionary intDictionary { get; set; } public Guid? nullableGuid { get; set; } @@ -122,10 +126,12 @@ public static colclass CreateObject(bool exotic, bool dataset) c.hash = new Hashtable(); c.hash.Add(new class1("0", "hello", Guid.NewGuid()), new class2("1", "code", "desc")); c.hash.Add(new class2("0", "hello", "pppp"), new class1("1", "code", Guid.NewGuid())); - if (dataset) +#endif +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + if (dataset) c.dataset = CreateDataset(); #endif - c.bytes = new byte[1024]; + c.bytes = new byte[1024]; c.stringDictionary = new Dictionary(); c.objectDictionary = new Dictionary(); c.intDictionary = new Dictionary(); @@ -211,8 +217,8 @@ public class Retclass public object obj; public string ppp { get { return "sdfas df "; } } public DateTime date { get; set; } -#if !SILVERLIGHT - public DataTable ds { get; set; } +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + public DataTable ds { get; set; } #endif } @@ -224,8 +230,8 @@ public struct Retstruct public int Field2; public string ppp { get { return "sdfas df "; } } public DateTime date { get; set; } -#if !SILVERLIGHT - public DataTable ds { get; set; } +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + public DataTable ds { get; set; } #endif } @@ -249,8 +255,8 @@ private static long CreateLong(string s) return neg ? -num : num; } -#if !SILVERLIGHT - private static DataSet CreateDataset() +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + private static DataSet CreateDataset() { DataSet ds = new DataSet(); for (int j = 1; j < 3; j++) @@ -289,9 +295,9 @@ public class RetNestedclass public Retclass Nested { get; set; } } - #endregion +#endregion -#if NET4 +#if !CORE_TEST [TestFixtureSetUp] #else [OneTimeSetUp] @@ -318,8 +324,8 @@ public static void ClassTest() r.Field1 = "dsasdF"; r.Field2 = 2312; r.date = DateTime.Now; -#if !SILVERLIGHT - r.ds = CreateDataset().Tables[0]; +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + r.ds = CreateDataset().Tables[0]; #endif var s = JSON.ToJSON(r); @@ -338,8 +344,8 @@ public static void StructTest() r.Field1 = "dsasdF"; r.Field2 = 2312; r.date = DateTime.Now; -#if !SILVERLIGHT - r.ds = CreateDataset().Tables[0]; +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + r.ds = CreateDataset().Tables[0]; #endif var s = JSON.ToNiceJSON(r); @@ -357,8 +363,8 @@ public static void ParseTest() r.Field1 = "dsasdF"; r.Field2 = 2312; r.date = DateTime.Now; -#if !SILVERLIGHT - r.ds = CreateDataset().Tables[0]; +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) + r.ds = CreateDataset().Tables[0]; #endif var s = JSON.ToJSON(r); @@ -878,7 +884,8 @@ public static void SingleCharNumber() Assert.That(zero, Is.EqualTo(o)); } - +#endif +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET4) [Test] public static void Datasets() @@ -908,8 +915,10 @@ public static void Datasets() Assert.AreEqual(100, oo.Rows.Count); } +#endif +#if !SILVERLIGHT - [Test] + [Test] public static void DynamicTest() { string s = "{\"Name\":\"aaaaaa\",\"Age\":10,\"dob\":\"2000-01-01 00:00:00Z\",\"inner\":{\"prop\":30},\"arr\":[1,{\"a\":2},3,4,5,6]}"; @@ -950,7 +959,7 @@ public static void GetDynamicMemberNamesTests() } #endif - [Test] + [Test] public static void CommaTests() { var s = JSON.ToJSON(new commaclass(), new JSONParameters() { UseExtensions = true }); @@ -1882,7 +1891,7 @@ public static void comments() Assert.AreEqual(2, (o as IDictionary).Count); } -#if NET4 +#if !CORE_TEST || NETFRAMEWORK || !NETCOREAPP3_0_OR_GREATER public class ctype { public System.Net.IPAddress ip; @@ -2067,7 +2076,7 @@ public static void bytearrindic() var d = JSON.ToObject>(s); } - #region twitter +#region twitter public class Twitter { public Query query { get; set; } @@ -2119,11 +2128,11 @@ public class BoundingBox public string type { get; set; } } } - #endregion +#endregion [Test] public static void twitter() { - #region tw data +#region tw data string ss = @"{ ""query"": { ""params"": { @@ -2481,7 +2490,7 @@ public static void twitter() ] } }"; - #endregion +#endregion var o = JSON.ToObject(ss); } @@ -3516,7 +3525,8 @@ public static void UTCDateFalse() var dt = new DateTime(2021, 1, 10, 12, 0, 0, DateTimeKind.Utc); var js = JSON.ToJSON(dt); Console.WriteLine(js); - Assert.AreEqual(15, JSON.ToObject(js, new JSONParameters() { UseUTCDateTime = false }).Hour); + var dt2 = DateTime.SpecifyKind(dt.ToLocalTime(), DateTimeKind.Utc); + Assert.AreEqual(dt2.Hour, JSON.ToObject(js, new JSONParameters() { UseUTCDateTime = false }).Hour); } //[Test] //public static void ma() @@ -3915,7 +3925,7 @@ public static void json5_additional_tests_3() Console.WriteLine("Test for -0x0 --> -0"); Assert.AreEqual( -#if NET4 +#if NETFRAMEWORK || NET4 || NETCOREAPP && !NETCOREAPP3_0_OR_GREATER "9.0144042682896313E+28" #else "9.014404268289631E+28" @@ -3923,11 +3933,27 @@ public static void json5_additional_tests_3() , JSON.ToJSON(JSON.Parse("+0x0123456789abcdefABCDEF0000"))); Console.WriteLine("Test for long hex number"); - AssertException(typeof(FormatException), "Input string was not in a correct format.", () => JSON.Parse("..2")); - Console.WriteLine(".. is illegal"); - - AssertException(typeof(FormatException), "Input string was not in a correct format.", () => JSON.Parse("{a:..2}")); - Console.WriteLine(".. is illegal inside of an object"); + try + { + AssertException(typeof(FormatException), "Input string was not in a correct format.", () => JSON.Parse("..2")); + Console.WriteLine(".. is illegal"); + } + catch + { + AssertException(typeof(FormatException), "The input string '..2' was not in a correct format.", () => JSON.Parse("..2")); + Console.WriteLine(".. is illegal"); + } + + try + { + AssertException(typeof(FormatException), "Input string was not in a correct format.", () => JSON.Parse("{a:..2}")); + Console.WriteLine(".. is illegal inside of an object"); + } + catch + { + AssertException(typeof(FormatException), "The input string '..2' was not in a correct format.", () => JSON.Parse("{a:..2}")); + Console.WriteLine(".. is illegal inside of an object"); + } Assert.AreEqual(1e41, JSON.Parse("100000000000000000000000000000000000000000")); Console.WriteLine("Parses 100000000000000000000000000000000000000000"); diff --git a/UnitTests/UnitTestsCore.csproj b/UnitTests/UnitTestsCore.csproj index 025bef7..51048b9 100644 --- a/UnitTests/UnitTestsCore.csproj +++ b/UnitTests/UnitTestsCore.csproj @@ -1,10 +1,14 @@  - netcoreapp3.1 + net47;netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0 + false false false true + $(DefineConstants);CORE_TEST + $(NoWarn);CS8981 + 9 @@ -12,6 +16,8 @@ + + diff --git a/fastJSON.nuspec b/fastJSON.nuspec index 4361c34..34a62b4 100644 --- a/fastJSON.nuspec +++ b/fastJSON.nuspec @@ -3,33 +3,87 @@ xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> fastJSON5 - 1.0.3 + 1.0.4 fastJSON5 hamarb123, mgholam https://github.com/hamarb123/fastJSON5 true LICENSE - Very fast, conformant, and polymorphic JSON5 serializer. This build is based on mgholam/fastJSON 2.4.0.3. - mgholam © 2010-2021, hamarb123 © 2020-2021 + Very fast, conformant, and polymorphic JSON5 serializer. This build is based on mgholam/fastJSON 2.4.0.5. Support on .NET Core < 2.0 and .NET Standard < 2.0 can be quite limited; be sure to test thoroughly on these platorms since some required APIs may not be available at runtime. + mgholam © 2010-2021, hamarb123 © 2020-2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fastJSON/Helper.cs b/fastJSON/Helper.cs index 3f7f5e9..0031ff1 100644 --- a/fastJSON/Helper.cs +++ b/fastJSON/Helper.cs @@ -1,15 +1,16 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Reflection; namespace fastJSON { public class Helper { - public static bool IsNullable(Type t) + public static bool IsNullable(Type t) { - if (!t.IsGenericType) return false; - Type g = t.GetGenericTypeDefinition(); + if (!t.IsGenericType()) return false; + Type g = t.GetGenericTypeDefinition(); return (g.Equals(typeof(Nullable<>))); } diff --git a/fastJSON/InternalHelpers.cs b/fastJSON/InternalHelpers.cs new file mode 100644 index 0000000..0ae516b --- /dev/null +++ b/fastJSON/InternalHelpers.cs @@ -0,0 +1,206 @@ +using System; +using System.IO; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; + +namespace fastJSON +{ + //Helper methods for older runtime support (fastJSON5) + internal static class InternalHelpers + { + public static bool IsGenericType(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsGenericType; +#else + return t.GetTypeInfo().IsGenericType; +#endif + } + + public static bool IsEnum(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsEnum; +#else + return t.GetTypeInfo().IsEnum; +#endif + } + + public static bool IsPrimitive(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsPrimitive; +#else + return t.GetTypeInfo().IsPrimitive; +#endif + } + + public static bool IsValueType(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsValueType; +#else + return t.GetTypeInfo().IsValueType; +#endif + } + + public static bool IsClass(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsClass; +#else + return t.GetTypeInfo().IsClass; +#endif + } + + public static bool IsAbstract(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsAbstract; +#else + return t.GetTypeInfo().IsAbstract; +#endif + } + + public static bool IsInterface(this Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return t.IsInterface; +#else + return t.GetTypeInfo().IsInterface; +#endif + } + +#if !(NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + public static bool IsAssignableFrom(this Type t, Type t2) + { + return t.GetTypeInfo().IsAssignableFrom(t2); + } +#endif + +#if !(NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + public static Type LookupType(string name, params string[] hintAssembly) + { + //check in hint assemblies + for (int i = 0; i < hintAssembly.Length; i++) + { + try + { + Assembly a = Assembly.Load(new AssemblyName(hintAssembly[i])); + return a.GetType(name, true); + } + catch { } + } + //check in bcl + return Type.GetType(name, true); + } +#endif + +#if !(NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + private static class _GetUninitializedObjectHelper + { + public readonly static Func _GetUninitializedObject; + + //Attempt to use a real impl for GetUninitializedObject if available at runtime + static _GetUninitializedObjectHelper() + { + try + { + var t = LookupType("System.Runtime.Serialization.FormatterServices", "netstandard", "System.Runtime.Serialization.Formatters", "mscorlib"); + var mi = t.GetMethod("GetUninitializedObject", new Type[] { typeof(Type) }); + var d = (Func)mi.CreateDelegate(typeof(Func)); + _GetUninitializedObject = d; + } + catch { } + } + } +#endif + + public static object TryGetUninitializedObject(Type t) + { +#if NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER + return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(t); +#else + var getter = _GetUninitializedObjectHelper._GetUninitializedObject; + if (getter != null) return getter(t); + else return Reflection.Instance.FastCreateInstance(t); +#endif + } + +#if !(NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER) + //Attempt to dynamically load the following methods + private static class _TryGetMethodBodyILByteArrayHelper + { + public static readonly Func _GetMethodBody; + public static readonly Func _GetILAsByteArray; + + static _TryGetMethodBodyILByteArrayHelper() + { + try + { + var getMethodBody = typeof(MethodInfo).GetMethod("GetMethodBody", new Type[0]); + var methodBody = getMethodBody.ReturnType; + var getILAsByteArray = methodBody.GetMethod("GetILAsByteArray", new Type[0]); + _GetMethodBody = (Func)getMethodBody.CreateDelegate(typeof(Func)); + var getILAsByteArray2 = getILAsByteArray.CreateDelegate(typeof(Func<,>).MakeGenericType(methodBody, typeof(byte[]))); + var paramEx = Expression.Parameter(typeof(object)); + Expression e = Expression.Call(Expression.TypeAs(paramEx, methodBody), getILAsByteArray); + _GetILAsByteArray = Expression.Lambda>(e, paramEx).Compile(); + } + catch { } + } + } +#endif + + public unsafe static byte[] TryGetMethodBodyILByteArray(MethodInfo mi) + { +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER + return mi.GetMethodBody()?.GetILAsByteArray() ?? new byte[0]; +#else + if (_TryGetMethodBodyILByteArrayHelper._GetMethodBody == null || _TryGetMethodBodyILByteArrayHelper._GetILAsByteArray == null) return null; + var body = _TryGetMethodBodyILByteArrayHelper._GetMethodBody(mi); + if (body == null) return new byte[0]; + return _TryGetMethodBodyILByteArrayHelper._GetILAsByteArray(body) ?? new byte[0]; +#endif + } + +#if !(NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER) + private static class _ModuleResolveMemberHelper + { + public static readonly Func _ResolveMember; + + static _ModuleResolveMemberHelper() + { + try + { + var method = typeof(Module).GetMethod("ResolveMember", new Type[] { typeof(int), typeof(Type[]), typeof(Type[]) }); + _ResolveMember = (Func)method.CreateDelegate(typeof(Func)); + } + catch { } + } + } +#endif + + public static bool HasModuleResolveMember + { + get + { +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER + return true; +#else + return _ModuleResolveMemberHelper._ResolveMember != null; +#endif + } + } + + public static MemberInfo ModuleResolveMember(Module m, int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER + return m.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments); +#else + return _ModuleResolveMemberHelper._ResolveMember(m, metadataToken, genericTypeArguments, genericMethodArguments); +#endif + } + } +} diff --git a/fastJSON/JSON.cs b/fastJSON/JSON.cs index 78b13bb..a9d7e6d 100644 --- a/fastJSON/JSON.cs +++ b/fastJSON/JSON.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) using System.Data; #endif using System.Globalization; @@ -219,7 +219,7 @@ public static string ToJSON(object obj, JSONParameters param) if (obj == null) return "null"; - if (obj.GetType().IsGenericType) + if (obj.GetType().IsGenericType()) t = Reflection.Instance.GetGenericTypeDefinition(obj.GetType()); if (typeof(IDictionary).IsAssignableFrom(t) || typeof(List<>).IsAssignableFrom(t)) param.UsingGlobalTypes = false; @@ -243,7 +243,6 @@ public static object Parse(string json, IList warnings) /// /// public static object Parse(string json) => Parse(json, null); -#if NET4 /// /// Create a .net4 dynamic object from the json string /// @@ -253,7 +252,6 @@ public static dynamic ToDynamic(string json) { return new DynamicJson(json); } -#endif /// /// Create a typed generic object from the json /// @@ -262,7 +260,7 @@ public static dynamic ToDynamic(string json) /// public static T ToObject(string json) { - return new deserializer(Parameters).ToObject(json); + return new @deserializer(Parameters).ToObject(json); } /// /// Create a typed generic object from the json with parameter override on this call @@ -273,7 +271,7 @@ public static T ToObject(string json) /// public static T ToObject(string json, JSONParameters param) { - return new deserializer(param).ToObject(json); + return new @deserializer(param).ToObject(json); } /// /// Create an object from the json @@ -282,7 +280,7 @@ public static T ToObject(string json, JSONParameters param) /// public static object ToObject(string json) { - return new deserializer(Parameters).ToObject(json, null); + return new @deserializer(Parameters).ToObject(json, null); } /// /// Create an object from the json with parameter override on this call @@ -292,7 +290,7 @@ public static object ToObject(string json) /// public static object ToObject(string json, JSONParameters param) { - return new deserializer(param).ToObject(json, null); + return new @deserializer(param).ToObject(json, null); } /// /// Create an object of type from the json @@ -302,7 +300,7 @@ public static object ToObject(string json, JSONParameters param) /// public static object ToObject(string json, Type type) { - return new deserializer(Parameters).ToObject(json, type); + return new @deserializer(Parameters).ToObject(json, type); } /// /// Create an object of type from the json with parameter override on this call @@ -313,7 +311,7 @@ public static object ToObject(string json, Type type) /// public static object ToObject(string json, Type type, JSONParameters par) { - return new deserializer(par).ToObject(json, type); + return new @deserializer(par).ToObject(json, type); } /// /// Fill a given object with the json represenation @@ -325,7 +323,7 @@ public static object FillObject(object input, string json, IList warning { Dictionary ht = new JsonParser(json, true, warnings).Decode(input.GetType()) as Dictionary; if (ht == null) return null; - return new deserializer(Parameters).ParseDictionary(ht, null, input.GetType(), input); + return new @deserializer(Parameters).ParseDictionary(ht, null, input.GetType(), input); } /// /// Fill a given object with the json represenation @@ -341,7 +339,7 @@ public static object FillObject(object input, string json, IList warning /// public static object DeepCopy(object obj) { - return new deserializer(Parameters).ToObject(ToJSON(obj)); + return new @deserializer(Parameters).ToObject(ToJSON(obj)); } /// /// @@ -351,7 +349,7 @@ public static object DeepCopy(object obj) /// public static T DeepCopy(T obj) { - return new deserializer(Parameters).ToObject(ToJSON(obj)); + return new @deserializer(Parameters).ToObject(ToJSON(obj)); } /// @@ -394,9 +392,9 @@ public static void ClearReflectionCache() } } - internal class deserializer + internal class @deserializer { - public deserializer(JSONParameters param) + public @deserializer(JSONParameters param) { if (param.OverrideObjectHashCodeChecking) _circobj = new Dictionary(10, ReferenceEqualityComparer.Default); @@ -442,7 +440,7 @@ public object ToObject(string json, Type type, IList warnings) { //_params.FixValues(); Type t = null; - if (type != null && type.IsGenericType) + if (type != null && type.IsGenericType()) t = Reflection.Instance.GetGenericTypeDefinition(type); _usingglobals = _params.UsingGlobalTypes; if (typeof(IDictionary).IsAssignableFrom(t) || typeof(List<>).IsAssignableFrom(t)) @@ -451,7 +449,7 @@ public object ToObject(string json, Type type, IList warnings) object o = new JsonParser(json, true, warnings).Decode(type); if (o == null) return null; -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) if (type != null) { if (type == typeof(DataSet)) @@ -550,7 +548,7 @@ private object ChangeType(object value, Type conversionType) else if (conversionType == typeof(string)) return (string)value; - else if (conversionType.IsEnum) + else if (conversionType.IsEnum()) return Helper.CreateEnum(conversionType, value); else if (conversionType == typeof(DateTime)) @@ -724,7 +722,7 @@ internal object ParseDictionary(Dictionary d, Dictionary d, Dictionary)v, globaltypes); break; case myPropInfoType.DataTable: oset = CreateDataTable((Dictionary)v, globaltypes); break; - case myPropInfoType.Hashtable: // same case as Dictionary +#endif +#if !SILVERLIGHT + case myPropInfoType.Hashtable: // same case as Dictionary #endif case myPropInfoType.Dictionary: oset = CreateDictionary((List)v, pi.pt, pi.GenericTypes, globaltypes); break; case myPropInfoType.StringKeyDictionary: oset = CreateStringKeyDictionary((Dictionary)v, pi.pt, pi.GenericTypes, globaltypes); break; @@ -811,7 +811,7 @@ internal object ParseDictionary(Dictionary d, Dictionary props, Dictionary dic) + private static void ProcessMap(object obj, Dictionary props, Dictionary dic) { foreach (KeyValuePair kv in dic) { @@ -865,7 +865,7 @@ private object CreateGenericList(List data, Type pt, Type bt, Dictionary else if (ob is List) { - if (bt.IsGenericType) + if (bt.IsGenericType()) col.Add((List)ob);//).ToArray()); else col.Add(((List)ob).ToArray()); @@ -971,7 +971,7 @@ private object CreateDictionary(List reader, Type pt, Type[] types, Dict return col; } -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) private DataSet CreateDataset(Dictionary reader, Dictionary globalTypes) { DataSet ds = new DataSet(); diff --git a/fastJSON/JsonParser.cs b/fastJSON/JsonParser.cs index 1a3ea12..dab98eb 100644 --- a/fastJSON/JsonParser.cs +++ b/fastJSON/JsonParser.cs @@ -150,12 +150,12 @@ private void BuildGenericTypeLookup(Type t) foreach (var e in t.GetGenericArguments()) { - if (e.IsPrimitive) + if (e.IsPrimitive()) continue; - bool isstruct = e.IsValueType && !e.IsEnum; + bool isstruct = e.IsValueType() && !e.IsEnum(); - if ((e.IsClass || isstruct || e.IsAbstract) && e != typeof(string) && e != typeof(DateTime) && e != typeof(Guid)) + if ((e.IsClass() || isstruct || e.IsAbstract()) && e != typeof(string) && e != typeof(DateTime) && e != typeof(Guid)) { BuildLookup(e); } @@ -167,9 +167,9 @@ private void BuildArrayTypeLookup(Type t) if (_seen.TryGetValue(t, out bool _)) return; - bool isstruct = t.IsValueType && !t.IsEnum; + bool isstruct = t.IsValueType() && !t.IsEnum(); - if ((t.IsClass || isstruct) && t != typeof(string) && t != typeof(DateTime) && t != typeof(Guid)) + if ((t.IsClass() || isstruct) && t != typeof(string) && t != typeof(DateTime) && t != typeof(Guid)) { BuildLookup(t.GetElementType()); } @@ -193,7 +193,7 @@ private void BuildLookup(Type objtype) if (_seen.TryGetValue(objtype, out bool _)) return; - if (objtype.IsGenericType) + if (objtype.IsGenericType()) BuildGenericTypeLookup(objtype); else if (objtype.IsArray) @@ -214,7 +214,7 @@ private void BuildLookup(Type objtype) if (t.IsArray) BuildArrayTypeLookup(t); - if (t.IsGenericType) + if (t.IsGenericType()) { // skip if dictionary if (typeof(IDictionary).IsAssignableFrom(t)) @@ -506,10 +506,10 @@ private unsafe string ParseKey(char* p) private unsafe string ParseIdentifierNameWithoutQuoteString(char* p) { - bool IsUnicodeLetter(char c) => char.GetUnicodeCategory(c) is UnicodeCategory.UppercaseLetter or UnicodeCategory.LowercaseLetter or UnicodeCategory.TitlecaseLetter or UnicodeCategory.ModifierLetter or UnicodeCategory.OtherLetter or UnicodeCategory.LetterNumber; - bool IsUnicodeCombiningMark(char c) => char.GetUnicodeCategory(c) is UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark; - bool IsUnicodeDigit(char c) => char.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber; - bool IsUnicodeConnectorPunctuation(char c) => char.GetUnicodeCategory(c) == UnicodeCategory.ConnectorPunctuation; + bool IsUnicodeLetter(char c) => CharUnicodeInfo.GetUnicodeCategory(c) is UnicodeCategory.UppercaseLetter or UnicodeCategory.LowercaseLetter or UnicodeCategory.TitlecaseLetter or UnicodeCategory.ModifierLetter or UnicodeCategory.OtherLetter or UnicodeCategory.LetterNumber; + bool IsUnicodeCombiningMark(char c) => CharUnicodeInfo.GetUnicodeCategory(c) is UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark; + bool IsUnicodeDigit(char c) => CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber; + bool IsUnicodeConnectorPunctuation(char c) => CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.ConnectorPunctuation; ConsumeToken(); @@ -1026,7 +1026,7 @@ private unsafe void SkipWhitespace(char* p) if (c == '/') throw new Exception("Illegal comment declaration at index " + index); - if (c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != '\v' && c != '\f' && c != '\u00A0' && c != '\u2028' && c != '\u2029' && c != '\uFEFF' && char.GetUnicodeCategory(c) != UnicodeCategory.SpaceSeparator) + if (c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != '\v' && c != '\f' && c != '\u00A0' && c != '\u2028' && c != '\u2029' && c != '\uFEFF' && CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.SpaceSeparator) break; } while (++index < _len); } diff --git a/fastJSON/JsonSerializer.cs b/fastJSON/JsonSerializer.cs index 8e54305..6109c57 100644 --- a/fastJSON/JsonSerializer.cs +++ b/fastJSON/JsonSerializer.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) using System.Data; #endif using System.Globalization; @@ -129,12 +129,12 @@ obj is uint || obj is ulong //#endif else if (_params.KVStyleStringDictionary == false && obj is IDictionary && - obj.GetType().IsGenericType && Reflection.Instance.GetGenericArguments(obj.GetType())[0] == typeof(string)) + obj.GetType().IsGenericType() && Reflection.Instance.GetGenericArguments(obj.GetType())[0] == typeof(string)) WriteStringDictionary((IDictionary)obj); else if (obj is IDictionary) WriteDictionary((IDictionary)obj); -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) else if (obj is DataSet) WriteDataset((DataSet)obj); @@ -268,10 +268,10 @@ private void WriteGuid(Guid g) private void WriteBytes(byte[] bytes) { -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER) WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None)); #else - WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length)); + WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length)); #endif } @@ -312,7 +312,7 @@ private void write_date_value(DateTime dt) _output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo)); } -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) private DatasetSchema GetSchema(DataTable ds) { if (ds == null) return null; @@ -678,7 +678,7 @@ private void WriteString(string s) if (_useEscapedUnicode) { if ((c >= ' ' && c < 128 && c != '\"' && c != '\\') - || (char.GetUnicodeCategory(c) is UnicodeCategory.UppercaseLetter or UnicodeCategory.LowercaseLetter or UnicodeCategory.TitlecaseLetter or UnicodeCategory.ModifierLetter or UnicodeCategory.OtherLetter or UnicodeCategory.LetterNumber or UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark or UnicodeCategory.DecimalDigitNumber or UnicodeCategory.ConnectorPunctuation) + || (CharUnicodeInfo.GetUnicodeCategory(c) is UnicodeCategory.UppercaseLetter or UnicodeCategory.LowercaseLetter or UnicodeCategory.TitlecaseLetter or UnicodeCategory.ModifierLetter or UnicodeCategory.OtherLetter or UnicodeCategory.LetterNumber or UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark or UnicodeCategory.DecimalDigitNumber or UnicodeCategory.ConnectorPunctuation) || (c is '$' or '_' or '\u200C' or '\u200D')) { if (runIndex == -1) @@ -718,7 +718,7 @@ private void WriteString(string s) case '\a': _output.Append('\\').Append('a'); break; default: if (_useEscapedUnicode - && (char.GetUnicodeCategory(c) is not UnicodeCategory.UppercaseLetter and not UnicodeCategory.LowercaseLetter and not UnicodeCategory.TitlecaseLetter and not UnicodeCategory.ModifierLetter and not UnicodeCategory.OtherLetter and not UnicodeCategory.LetterNumber and not UnicodeCategory.NonSpacingMark and not UnicodeCategory.SpacingCombiningMark and not UnicodeCategory.DecimalDigitNumber and not UnicodeCategory.ConnectorPunctuation) + && (CharUnicodeInfo.GetUnicodeCategory(c) is not UnicodeCategory.UppercaseLetter and not UnicodeCategory.LowercaseLetter and not UnicodeCategory.TitlecaseLetter and not UnicodeCategory.ModifierLetter and not UnicodeCategory.OtherLetter and not UnicodeCategory.LetterNumber and not UnicodeCategory.NonSpacingMark and not UnicodeCategory.SpacingCombiningMark and not UnicodeCategory.DecimalDigitNumber and not UnicodeCategory.ConnectorPunctuation) && (c is not '$' and not '_' and not '\u200C' and not '\u200D')) { _output.Append("\\u"); diff --git a/fastJSON/Reflection.cs b/fastJSON/Reflection.cs index 63982ef..d1ac115 100644 --- a/fastJSON/Reflection.cs +++ b/fastJSON/Reflection.cs @@ -5,10 +5,8 @@ using System.Collections; using System.Text; using System.Runtime.Serialization; -#if NET4 using System.Linq; -#endif -#if !SILVERLIGHT +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) using System.Data; #endif using System.Collections.Specialized; @@ -26,27 +24,29 @@ public struct Getters public enum myPropInfoType { - Int, - Long, - String, - Bool, - DateTime, - Enum, - Guid, - - Array, - ByteArray, - Dictionary, - StringKeyDictionary, - NameValue, - StringDictionary, + Int = 0, + Long = 1, + String = 2, + Bool = 3, + DateTime = 4, + Enum = 5, + Guid = 6, + + Array = 7, + ByteArray = 8, + Dictionary = 9, + StringKeyDictionary = 10, + NameValue = 11, + StringDictionary = 12, #if !SILVERLIGHT - Hashtable, - DataSet, - DataTable, + Hashtable = 13, +#endif +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) + DataSet = 14, + DataTable = 15, #endif - Custom, - Unknown, + Custom = 16, + Unknown = 17, } public class myPropInfo @@ -85,7 +85,9 @@ private Reflection() } public static Reflection Instance { get { return instance; } } +#if NET40_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER public static bool RDBMode = false; +#endif public delegate string Serialize(object data); public delegate object Deserialize(string data); @@ -256,14 +258,12 @@ public Dictionary Getproperties(Type type, string typename, var att = p.GetCustomAttributes(true); foreach (var at in att) { -#if NET4 if (at is System.Runtime.Serialization.DataMemberAttribute) { var dm = (System.Runtime.Serialization.DataMemberAttribute)at; if (dm.Name != "") d.memberName = dm.Name; } -#endif if (at is fastJSON.DataMemberAttribute) { var dm = (fastJSON.DataMemberAttribute)at; @@ -290,14 +290,12 @@ public Dictionary Getproperties(Type type, string typename, var att = f.GetCustomAttributes(true); foreach (var at in att) { -#if NET4 if (at is System.Runtime.Serialization.DataMemberAttribute) { var dm = (System.Runtime.Serialization.DataMemberAttribute)at; if (dm.Name != "") d.memberName = dm.Name; } -#endif if (at is fastJSON.DataMemberAttribute) { var dm = (fastJSON.DataMemberAttribute)at; @@ -327,7 +325,7 @@ private myPropInfo CreateMyProp(Type t, string name) else if (t == typeof(string)) d_type = myPropInfoType.String; else if (t == typeof(bool) || t == typeof(bool?)) d_type = myPropInfoType.Bool; else if (t == typeof(DateTime) || t == typeof(DateTime?)) d_type = myPropInfoType.DateTime; - else if (t.IsEnum) d_type = myPropInfoType.Enum; + else if (t.IsEnum()) d_type = myPropInfoType.Enum; else if (t == typeof(Guid) || t == typeof(Guid?)) d_type = myPropInfoType.Guid; else if (t == typeof(StringDictionary)) d_type = myPropInfoType.StringDictionary; else if (t == typeof(NameValueCollection)) d_type = myPropInfoType.NameValue; @@ -349,19 +347,21 @@ private myPropInfo CreateMyProp(Type t, string name) } #if !SILVERLIGHT else if (t == typeof(Hashtable)) d_type = myPropInfoType.Hashtable; +#endif +#if !SILVERLIGHT && (NETFRAMEWORK || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER) else if (t == typeof(DataSet)) d_type = myPropInfoType.DataSet; else if (t == typeof(DataTable)) d_type = myPropInfoType.DataTable; #endif else if (IsTypeRegistered(t)) d_type = myPropInfoType.Custom; - if (t.IsValueType && !t.IsPrimitive && !t.IsEnum && t != typeof(decimal)) + if (t.IsValueType() && !t.IsPrimitive() && !t.IsEnum() && t != typeof(decimal)) d.IsStruct = true; - d.IsInterface = t.IsInterface; - d.IsClass = t.IsClass; - d.IsValueType = t.IsValueType; - if (t.IsGenericType) + d.IsInterface = t.IsInterface(); + d.IsClass = t.IsClass(); + d.IsValueType = t.IsValueType(); + if (t.IsGenericType()) { d.IsGenericType = true; d.bt = Reflection.Instance.GetGenericArguments(t)[0]; @@ -377,7 +377,7 @@ private myPropInfo CreateMyProp(Type t, string name) private Type GetChangeType(Type conversionType) { - if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) + if (conversionType.IsGenericType() && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) return Reflection.Instance.GetGenericArguments(conversionType)[0]; return conversionType; @@ -415,7 +415,7 @@ internal Type GetTypeFromCache(string typename, bool badlistChecking) } Type t = Type.GetType(typename); -#if NET4 +#if NET40_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER if (RDBMode) { if (t == null) // RaptorDB : loading runtime assemblies @@ -486,7 +486,7 @@ internal object FastCreateInstance(Type objtype) } else { - if (objtype.IsClass) + if (objtype.IsClass()) { DynamicMethod dynMethod = new DynamicMethod("_fcic", objtype, null, true); ILGenerator ilGen = dynMethod.GetILGenerator(); @@ -527,7 +527,7 @@ internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo) ILGenerator il = dynamicSet.GetILGenerator(); - if (!type.IsClass) // structs + if (!type.IsClass()) // structs { var lv = il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); @@ -535,7 +535,7 @@ internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo) il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lv); il.Emit(OpCodes.Ldarg_1); - if (fieldInfo.FieldType.IsClass) + if (fieldInfo.FieldType.IsClass()) il.Emit(OpCodes.Castclass, fieldInfo.FieldType); else il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); @@ -548,7 +548,7 @@ internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); - if (fieldInfo.FieldType.IsValueType) + if (fieldInfo.FieldType.IsValueType()) il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); il.Emit(OpCodes.Stfld, fieldInfo); il.Emit(OpCodes.Ldarg_0); @@ -563,7 +563,9 @@ internal static FieldInfo GetGetterBackingField(PropertyInfo autoProperty) // Restrict operation to auto properties to avoid risking errors if a getter does not contain exactly one field read instruction (such as with calculated properties). if (!getMethod.IsDefined(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false)) return null; - var byteCode = getMethod.GetMethodBody()?.GetILAsByteArray() ?? new byte[0]; + if (!InternalHelpers.HasModuleResolveMember) goto tryAlternative; + var byteCode = InternalHelpers.TryGetMethodBodyILByteArray(getMethod); + if (byteCode == null) goto tryAlternative; //var byteCode = getMethod.GetMethodBody().GetILAsByteArray(); int pos = 0; // Find the first LdFld instruction and parse its operand to a FieldInfo object. @@ -576,7 +578,7 @@ internal static FieldInfo GetGetterBackingField(PropertyInfo autoProperty) // If it is a LdFld, read its operand, parse it to a FieldInfo and return it. if (opCode == OpCodes.Ldfld && opCode.OperandType == OperandType.InlineField && pos + sizeof(int) <= byteCode.Length) { - return getMethod.Module.ResolveMember(BitConverter.ToInt32(byteCode, pos), getMethod.DeclaringType?.GetGenericArguments(), null) as FieldInfo; + return InternalHelpers.ModuleResolveMember(getMethod.Module, BitConverter.ToInt32(byteCode, pos), getMethod.DeclaringType?.GetGenericArguments(), null) as FieldInfo; } // Otherwise, set the current position to the start of the next instruction, if any (we need to know how much bytes are used by operands). pos += opCode.OperandType == OperandType.InlineNone @@ -595,6 +597,22 @@ internal static FieldInfo GetGetterBackingField(PropertyInfo autoProperty) : 4; } return null; + tryAlternative:; +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP2_0_OR_GREATER + //Should never get here + return null; +#else + //Just try to look up the default named backing field + if (autoProperty.GetIndexParameters().Length != 0) return null; + try + { + return autoProperty.DeclaringType.GetField("<" + autoProperty.Name + ">k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); + } + catch + { + return null; + } +#endif } internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo, bool ShowReadOnlyProperties) @@ -614,7 +632,7 @@ internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyIn DynamicMethod setter = new DynamicMethod("_csm", typeof(object), arguments, true);// !setMethod.IsPublic); // fix: skipverify ILGenerator il = setter.GetILGenerator(); - if (!type.IsClass) // structs + if (!type.IsClass()) // structs { var lv = il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); @@ -622,7 +640,7 @@ internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyIn il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lv); il.Emit(OpCodes.Ldarg_1); - if (propertyInfo.PropertyType.IsClass) + if (propertyInfo.PropertyType.IsClass()) il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); else il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); @@ -637,7 +655,7 @@ internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyIn il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); il.Emit(OpCodes.Ldarg_1); - if (propertyInfo.PropertyType.IsClass) + if (propertyInfo.PropertyType.IsClass()) il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); else il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); @@ -648,7 +666,7 @@ internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyIn { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); - if (propertyInfo.PropertyType.IsClass) + if (propertyInfo.PropertyType.IsClass()) il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); else il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); @@ -667,7 +685,7 @@ internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo) ILGenerator il = dynamicGet.GetILGenerator(); - if (!type.IsClass) // structs + if (!type.IsClass()) // structs { var lv = il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); @@ -675,14 +693,14 @@ internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo) il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lv); il.Emit(OpCodes.Ldfld, fieldInfo); - if (fieldInfo.FieldType.IsValueType) + if (fieldInfo.FieldType.IsValueType()) il.Emit(OpCodes.Box, fieldInfo.FieldType); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fieldInfo); - if (fieldInfo.FieldType.IsValueType) + if (fieldInfo.FieldType.IsValueType()) il.Emit(OpCodes.Box, fieldInfo.FieldType); } @@ -701,7 +719,7 @@ internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyIn ILGenerator il = getter.GetILGenerator(); - if (!type.IsClass) // structs + if (!type.IsClass()) // structs { var lv = il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); @@ -709,7 +727,7 @@ internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyIn il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lv); il.EmitCall(OpCodes.Call, getMethod, null); - if (propertyInfo.PropertyType.IsValueType) + if (propertyInfo.PropertyType.IsValueType()) il.Emit(OpCodes.Box, propertyInfo.PropertyType); } else @@ -723,7 +741,7 @@ internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyIn else il.Emit(OpCodes.Call, getMethod); - if (propertyInfo.PropertyType.IsValueType) + if (propertyInfo.PropertyType.IsValueType()) il.Emit(OpCodes.Box, propertyInfo.PropertyType); } @@ -739,7 +757,7 @@ public Getters[] GetGetters(Type type, /*bool ShowReadOnlyProperties,*/ List - net4;netstandard2.0;netstandard2.1;net5.0 + net4;net45;netstandard1.5;netstandard2.0;netstandard2.1;netcoreapp1.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0 + false false Hamish Arblaster, M. Gholam https://github.com/hamarb123/fastJSON5 fastJSON5 Very fast, conformant, and polymorphic JSON5 serializer fastJSON5 - mgholam © 2010-2021, hamarb123 © 2020-2021 + mgholam © 2010-2021, hamarb123 © 2020-2023 hamarb123, mgholam - 1.0.3-2.4.0.3 + 1.0.4-2.4.0.5 fastJSON5 false 9 true $(NoWarn);1591;1573 - - - TRACE;DEBUG;NETSTANDARD2_0;NET4; - true + true + + + TRACE;DEBUG; false - NETSTANDARD2_0;NET4; - true true @@ -33,17 +32,53 @@ + - + 4.3.0 + + + 4.3.0 + + + + + 4.3.0 + + + + + 4.3.0 + + + + + 4.3.0 + + + + + 4.7.0 + + + + + 4.3.0 + + + + + 4.3.0 + + diff --git a/history_json5.txt b/history_json5.txt index 4fc849d..8cd04ff 100644 --- a/history_json5.txt +++ b/history_json5.txt @@ -1,3 +1,9 @@ +1.0.4-2.4.0.5 +- Update license +- Update fastJSON to 2.4.0.5 +- Add support for many tfms (including limited support for .NET Core 1.0 and Standard 1.5) +- Binary compat fix: specify enum values for 'myPropInfoType' explicitly (wouldn't have affected any existing distribution of this library) + 1.0.3-2.4.0.3 - Update license - Small fix to do with serialising doubles and floats on .NET Framework