Compare commits

...

18 Commits

Author SHA1 Message Date
Harald Wolff fa6b73cccd Add default mapping for IPAddress 2024-04-21 17:08:33 +02:00
Harald Wolff cf3952a9ba Add JSONObjectMapping.Assign() 2023-09-09 01:52:27 +02:00
Harald Wolff fb6d4fdede Fix boolean deserialization 2023-09-09 01:52:14 +02:00
Harald Wolff e8cd08cb4c Added implicit operators to JSONValue 2023-08-29 21:08:34 +02:00
Harald Wolff 12d75bbc64 Added implicit operators 2023-08-29 21:01:32 +02:00
Harald Wolff abd6a15bfa Add JSONArray.From(..) and JSONArray(JSONValue[]) 2023-08-29 20:49:38 +02:00
Harald Wolff f1aca689be Added Clone(), switched to .NET7 2023-08-17 11:46:46 +02:00
Harald Wolff ccd0a507bc Added one more critical section to JSONMapper.Serialize(..) 2022-12-20 13:33:46 +01:00
Harald Wolff 3677c6847b Add additional critical section to JSONMapper.GetOrBuildMapping(..) 2022-12-20 13:26:48 +01:00
Harald Wolff 3e2e2d717c Fixed multithreading safety on JsonMapper 2022-12-14 14:09:02 +01:00
Harald Wolff fdef5cc1a7 Add JSONNumber(byte), JSONNumber(sbyte) 2022-12-12 22:31:21 +01:00
Harald Wolff 04531d4382 Add JSONArray.GetValues<OT> 2022-12-12 22:31:00 +01:00
Harald Wolff 8d397ecbc6 Added dynamic Object support, added JSONObject.TryGetValue(..) 2022-06-14 11:07:22 +02:00
Harald Wolff fd9e11a182 added MapMethodParameters(..) method family to JSONMapper
ln.build - build0.waldrennach.l--n.de build job pending Details
2020-12-25 20:31:19 +01:00
Harald Wolff 02adec8cb8 added JSONMapper.Deserialize<T>(..), added JSONMapper.Deserialize(string..)
ln.build - build0.waldrennach.l--n.de build job pending Details
2020-12-18 21:17:59 +01:00
Harald Wolff 492e232fa7 Added mapping for System.SByte
ln.build - build0.waldrennach.l--n.de build job pending Details
2020-12-18 15:49:05 +01:00
Harald Wolff a6757e1b63 Release 1.0.4
ln.build - build0.waldrennach.l--n.de build job pending Details
2020-12-18 09:30:36 +01:00
Harald Wolff 2b807bcb73 Added JSONArray.Add(IEnumerable<JSONValue>..) 2020-12-18 09:30:24 +01:00
17 changed files with 434 additions and 55 deletions

View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/.idea.ln.json.iml
/modules.xml
/projectSettingsUpdater.xml
/contentModel.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -3,7 +3,7 @@
"dotnet"
],
"env": {
"NUGET_SOURCE": "https://nexus.niclas-thobaben.de/repository/l--n.de/",
"NUGET_SOURCE": "https://nexus.l--n.de/repository/ln.net/",
"CONFIGURATION": "Release"
},
"stages": [

View File

@ -1,4 +1,5 @@
using System;
using System.Reflection;
using ln.json.mapping;
using NUnit.Framework;
@ -87,6 +88,7 @@ namespace ln.json.tests
TestEnumSerialization(testEnum3.C);
TestEnumSerialization(testEnum3.D);
TestEnumSerialization(testEnum3.E);
TestEnumSerialization((testEnum3)23);
}
bool TestEnumSerialization(object enumValue)
@ -125,6 +127,65 @@ namespace ln.json.tests
}
[Test]
public void TestDeserialize()
{
Assert.IsTrue(JSONMapper.DefaultMapper.Deserialize("[\"A\",\"B\",\"C\"]", out string[] texts));
Assert.AreEqual(3, texts.Length);
Assert.AreEqual("A", texts[0]);
Assert.AreEqual("B", texts[1]);
Assert.AreEqual("C", texts[2]);
}
[Test]
public void TestParameterMapping()
{
MethodInfo testMethodInfo = GetType().GetMethod("MappingTestMethod");
object[] methodArguments = null;
JSONArray jsonArguments = new JSONArray()
.Add(new JSONString("text parameter value"))
.Add(new JSONNumber(10))
.Add(new JSONNumber(-2))
.Add(new JSONNumber(-3))
;
Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonArguments, out object[] arguments));
Assert.AreEqual("text parameter value", arguments[0]);
Assert.AreEqual(10, arguments[1]);
Assert.AreEqual(-2, arguments[2]);
Assert.AreEqual(-3, arguments[3]);
jsonArguments.Remove(3);
Assert.IsFalse(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonArguments, out arguments));
JSONObject jsonNamedArguments = new JSONObject()
.Add("n", new JSONNumber(10))
.Add("m", new JSONNumber(-2))
.Add("a", new JSONNumber(-3))
.Add("t", new JSONString("text parameter value"))
;
Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments));
Assert.AreEqual("text parameter value", arguments[0]);
Assert.AreEqual(10, arguments[1]);
Assert.AreEqual(-2, arguments[2]);
Assert.AreEqual(-3, arguments[3]);
jsonNamedArguments.Remove("m");
Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments));
jsonNamedArguments.Remove("a");
Assert.IsTrue(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments));
jsonNamedArguments.Remove("n");
Assert.IsFalse(JSONMapper.DefaultMapper.MapMethodParameters(testMethodInfo, jsonNamedArguments, out arguments));
}
public void MappingTestMethod(string t, int n, short m = 2, long a = 3)
{}
void TestPrimitiveMapping(object primitiveValue)
{
Type primitiveType = primitiveValue.GetType();

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
@ -9,7 +9,7 @@
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>

View File

@ -32,14 +32,35 @@ namespace ln.json
public JSONArray()
: base(JSONValueType.ARRAY) { }
public JSONArray(IEnumerable<JSONValue> values)
: base(JSONValueType.ARRAY)
{
this.values.AddRange(values);
}
public static JSONArray From<T>(IEnumerable<T> values) where T:JSONValue
{
return new JSONArray(values);
}
public override JSONValue this[int index] {
get => values[index];
set => values[index] = value;
}
public JSONArray Add(IEnumerable<JSONValue> values){ foreach (JSONValue value in values) this.values.Add(value); return this; }
public JSONArray Add(JSONValue value){ values.Add(value); return this; }
public JSONArray Remove(int index) { values.RemoveAt(index); return this; }
public override JSONValue Clone()
{
JSONArray copy = new JSONArray();
foreach (var value in values)
copy.Add(value.Clone());
return copy;
}
public override string ToString()
{
@ -61,5 +82,14 @@ namespace ln.json
return sb.ToString();
}
public IEnumerable<OT> GetValues<OT>()
{
foreach (var value in values)
{
if (value is OT otValue)
yield return otValue;
}
}
}
}

View File

@ -20,6 +20,10 @@ namespace ln.json
return (double)decValue;
}
public JSONNumber(byte i)
: this((long)i) { }
public JSONNumber(sbyte i)
: this((long)i) { }
public JSONNumber(short i)
: this((long)i) { }
public JSONNumber(ushort i)
@ -45,6 +49,7 @@ namespace ln.json
public JSONNumber(double doubleValue)
: base(JSONValueType.NUMBER)
{
decValue = doubleValue.ToDecimal();
}
public JSONNumber(decimal decValue)
@ -52,10 +57,21 @@ namespace ln.json
{
this.decValue = decValue;
}
public override JSONValue Clone() => new JSONNumber(this.decValue);
public override string ToString()
{
return decValue.ToString(CultureInfo.InvariantCulture);
}
public static implicit operator Decimal(JSONNumber j) => j.decValue;
public static implicit operator float(JSONNumber j) => (float)j.decValue;
public static implicit operator double(JSONNumber j) => (double)j.decValue;
public static implicit operator int(JSONNumber j) => (int)j.decValue;
public static implicit operator long(JSONNumber j) => (long)j.decValue;
public static implicit operator uint(JSONNumber j) => (uint)j.decValue;
public static implicit operator ulong(JSONNumber j) => (ulong)j.decValue;
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Dynamic;
using ln.collections;
using ln.json.mapping;
@ -40,11 +41,27 @@ namespace ln.json
return this;
}
public void Remove(string propertyName) => values.Remove(propertyName);
public bool ContainsKey(string key)
{
return values.ContainsKey(key);
}
public bool TryGetValue(string key, out JSONValue jsonValue) => values.TryGet(key, out jsonValue);
public bool TryGetValue<OT>(string key, out OT value) where OT : JSONValue
{
if (TryGetValue(key, out JSONValue jsonValue) && (jsonValue is OT otValue))
{
value = otValue;
return true;
}
value = default;
return false;
}
public T ToObject<T>()
{
if (JSONMapper.DefaultMapper.Deserialize(this, typeof(T), out object o))
@ -54,6 +71,14 @@ namespace ln.json
throw new NotSupportedException();
}
public override JSONValue Clone()
{
JSONObject copy = new JSONObject();
foreach (var key in Keys)
copy[key] = this[key].Clone();
return copy;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
@ -78,6 +103,28 @@ namespace ln.json
return sb.ToString();
}
public override bool TryGetMember(GetMemberBinder binder, out object? result)
{
if (values.TryGet(binder.Name, out JSONValue jsonValue))
{
result = jsonValue;
return true;
}
result = null;
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object? value)
{
if (value is JSONValue jsonValue)
values[binder.Name] = jsonValue;
else
values[binder.Name] = JSONMapper.DefaultMapper.ToJson(value);
return true;
}
public static JSONObject From(object value)
{
if (JSONMapper.DefaultMapper.Serialize(value, out JSONValue json))

View File

@ -5,6 +5,8 @@ namespace ln.json
{
public static JSONTrue Instance { get; } = new JSONTrue();
private JSONTrue() : base(JSONValueType.TRUE) { }
public override JSONValue Clone() => this;
public override string ToString() => "true";
public override object ToNative() => true;
}
@ -12,6 +14,8 @@ namespace ln.json
{
public static JSONFalse Instance { get; } = new JSONFalse();
private JSONFalse() : base(JSONValueType.FALSE) { }
public override JSONValue Clone() => this;
public override string ToString() => "false";
public override object ToNative() => false;
}
@ -19,6 +23,8 @@ namespace ln.json
{
public static JSONNull Instance { get; } = new JSONNull();
private JSONNull() : base(JSONValueType.NULL) { }
public override JSONValue Clone() => this;
public override string ToString() => "null";
public override object ToNative() => null;
}

View File

@ -29,6 +29,8 @@ namespace ln.json
Value = value;
}
public override JSONValue Clone() => new JSONString(Value);
public override string ToString()
{
return String.Format("\"{0}\"", Escape(Value));
@ -95,5 +97,7 @@ namespace ln.json
}
return sb.ToString();
}
public static implicit operator String(JSONString j) => j.Value;
}
}

View File

@ -9,13 +9,19 @@
// **/
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Text;
using System.Text.Json;
using ln.type;
namespace ln.json
{
public enum JSONValueType
{
NULL, OBJECT, ARRAY, STRING, NUMBER, TRUE, FALSE
}
public abstract class JSONValue
public abstract class JSONValue : DynamicObject
{
public JSONValueType ValueType { get; private set; }
@ -24,6 +30,8 @@ namespace ln.json
public virtual object ToNative() => throw new NotImplementedException();
public T As<T>() where T : JSONValue => this as T;
public JSONValue(JSONValueType valueType)
{
ValueType = valueType;
@ -40,6 +48,30 @@ namespace ln.json
set => throw new NotSupportedException();
}
public abstract JSONValue Clone();
public override string ToString() => throw new NotImplementedException();
public virtual void WriteTo(string filename)
{
using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
WriteTo(fs);
}
}
public virtual void WriteTo(Stream stream)
{
stream.Write(Encoding.UTF8.GetBytes(this.ToString()!));
}
public static implicit operator JSONValue(string v) => new JSONString(v);
public static implicit operator JSONValue(float v) => new JSONNumber(v);
public static implicit operator JSONValue(double v) => new JSONNumber(v);
public static implicit operator JSONValue(decimal v) => new JSONNumber(v);
public static implicit operator JSONValue(int v) => new JSONNumber(v);
public static implicit operator JSONValue(long v) => new JSONNumber(v);
public static implicit operator JSONValue(uint v) => new JSONNumber(v);
public static implicit operator JSONValue(ulong v) => new JSONNumber(v);
}
}

View File

@ -0,0 +1,7 @@
using System;
namespace ln.json.attributes;
public class DontAssign : Attribute
{
}

View File

@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Version>1.0.3</Version>
<Version>1.0.8-ci</Version>
<Authors>Harald Wolff-Thobaben</Authors>
<Company>l--n.de</Company>
<Product>ln.json</Product>
@ -10,11 +9,13 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>0.1.0.0</AssemblyVersion>
<FileVersion>0.1.0.0</FileVersion>
<PackageVersion>1.3.0-preview8</PackageVersion>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="ln.type" Version="0.1.3" />
<PackageReference Include="ln.collections" Version="0.1.2" />
<PackageReference Include="ln.type" Version="0.1.9" />
<PackageReference Include="ln.collections" Version="0.2.2" />
</ItemGroup>
</Project>

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
namespace ln.json.mapping
@ -54,21 +55,38 @@ namespace ln.json.mapping
Dictionary<Type, JSONMapping> mappings = new Dictionary<Type, JSONMapping>();
public virtual void Add(JSONMapping mapping) => mappings[mapping.TargetType] = mapping;
public virtual void Add(JSONMapping mapping)
{
lock (mappings)
{
mappings[mapping.TargetType] = mapping;
}
}
Dictionary<Type, MappingFactory> mappingFactories = new Dictionary<Type, MappingFactory>();
public virtual void AddMappingFactory(Type targetType, MappingFactory mappingFactory) => mappingFactories.Add(targetType, mappingFactory);
public virtual bool GetOrBuildMapping(Type nativeType, out JSONMapping mapping) => TryGetMapping(nativeType, out mapping) || TryBuildRememberedMapping(nativeType, out mapping);
public virtual bool GetOrBuildMapping(Type nativeType, out JSONMapping mapping)
{
lock (mappings)
{
return TryGetMapping(nativeType, out mapping) || TryBuildRememberedMapping(nativeType, out mapping);
}
}
public virtual bool TryBuildRememberedMapping(Type nativeType,out JSONMapping mapping)
{
if (TryBuildMapping(nativeType, out mapping))
lock (mappings)
{
mappings.Add(nativeType, mapping);
return true;
if (TryBuildMapping(nativeType, out mapping))
{
mappings.Add(nativeType, mapping);
return true;
}
return false;
}
return false;
}
public virtual bool TryBuildMapping(Type nativeType,out JSONMapping mapping)
{
@ -119,73 +137,107 @@ namespace ln.json.mapping
public virtual bool TryGetMapping(Type nativeType,out JSONMapping mapping)
{
if (mappings.TryGetValue(nativeType, out mapping))
return true;
lock (mappings)
{
if (mappings.TryGetValue(nativeType, out mapping))
return true;
if (RequestCustomMapping(nativeType, out mapping))
return true;
if (RequestCustomMapping(nativeType, out mapping))
return true;
if ((this != DefaultMapper) && DefaultMapper.TryGetMapping(nativeType, out mapping))
return true;
if ((this != DefaultMapper) && DefaultMapper.TryGetMapping(nativeType, out mapping))
return true;
return false;
return false;
}
}
public virtual bool Serialize(object o, out JSONValue json)
{
if (object.ReferenceEquals(null, o))
if (o is JSONValue jValue)
{
json = JSONNull.Instance;
json = jValue.Clone();
return true;
}
Type type = o.GetType();
if (RequestCustomSerialization(o, out json))
return true;
if (TryGetMapping(type, out JSONMapping mapping))
lock (mappings)
{
json = mapping.ToJson(this, o);
return true;
}
if (type.IsEnum)
{
if (type.GetCustomAttribute<FlagsAttribute>() != null)
if (object.ReferenceEquals(null, o))
{
Type enumBaseType = type.GetEnumUnderlyingType();
o = Convert.ChangeType(o, enumBaseType);
ConstructorInfo constructor = typeof(JSONNumber).GetConstructor(new Type[]{ enumBaseType });
json = (JSONNumber)constructor.Invoke(new object[]{ o });
json = JSONNull.Instance;
return true;
}
else
Type type = o.GetType();
if (RequestCustomSerialization(o, out json))
return true;
if (TryGetMapping(type, out JSONMapping mapping))
{
json = new JSONString(Enum.GetName(type, o));
json = mapping.ToJson(this, o);
return true;
}
if (type.IsEnum)
{
if (type.GetCustomAttribute<FlagsAttribute>() != null)
{
Type enumBaseType = type.GetEnumUnderlyingType();
o = Convert.ChangeType(o, enumBaseType);
ConstructorInfo constructor = typeof(JSONNumber).GetConstructor(new Type[] { enumBaseType });
json = (JSONNumber)constructor.Invoke(new object[] { o });
}
else
{
json = new JSONString(Enum.GetName(type, o));
}
return true;
}
if (type.IsPrimitive)
{
throw new NotSupportedException(
String.Format("JSONMapperBase: Unsupported primitive type found: {0}", type));
}
if (TryBuildRememberedMapping(type, out mapping))
{
json = mapping.ToJson(this, o);
return true;
}
return false;
}
}
public virtual bool Deserialize<T>(string jsonSource, out T v) => Deserialize(JSONParser.Parse(jsonSource), out v);
public virtual bool Deserialize<T>(JSONValue json, out T v)
{
if (Deserialize(json, typeof(T), out object o))
{
v = (T)o;
return true;
}
if (type.IsPrimitive)
{
throw new NotSupportedException(String.Format("JSONMapperBase: Unsupported primitive type found: {0}", type));
}
if (TryBuildRememberedMapping(type,out mapping))
{
json = mapping.ToJson(this, o);
return true;
}
v = default;
return false;
}
public virtual bool Deserialize(string jsonSource, Type nativeType, out object o) => Deserialize(JSONParser.Parse(jsonSource), nativeType, out o);
public virtual bool Deserialize(JSONValue json, Type nativeType, out object o)
{
o = null;
if (nativeType.IsSubclassOf(typeof(JSONValue)))
{
o = json.Clone();
return true;
}
if (JSONNull.Instance.Equals(json))
return true;
@ -254,6 +306,67 @@ namespace ln.json.mapping
}
public bool MapMethodParameters(MethodInfo methodInfo, JSONValue jsonArguments, out object[] methodArguments)
{
if (jsonArguments is JSONArray jsonArrayArguments)
return MapMethodParameters(methodInfo.GetParameters(), jsonArrayArguments, out methodArguments);
if (jsonArguments is JSONObject jsonNamedArguments)
return MapMethodParameters(methodInfo.GetParameters(), jsonNamedArguments, out methodArguments);
throw new ArgumentException(nameof(jsonArguments));
}
public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONValue jsonArguments, out object[] methodArguments)
{
if (jsonArguments is JSONArray jsonArrayArguments)
return MapMethodParameters(parameterInfos, jsonArrayArguments, out methodArguments);
if (jsonArguments is JSONObject jsonNamedArguments)
return MapMethodParameters(parameterInfos, jsonNamedArguments, out methodArguments);
throw new ArgumentException(nameof(jsonArguments));
}
public bool MapMethodParameters(MethodInfo methodInfo, JSONObject namedArguments, out object[] methodArguments) => MapMethodParameters(methodInfo.GetParameters(), namedArguments, out methodArguments);
public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONObject namedArguments, out object[] methodArguments)
{
methodArguments = new object[parameterInfos.Length];
for (int n=0; n < methodArguments.Length; n++)
{
if (namedArguments.ContainsKey(parameterInfos[n].Name))
{
if (!JSONMapper.DefaultMapper.Deserialize(namedArguments[parameterInfos[n].Name], parameterInfos[n].ParameterType, out methodArguments[n]))
return false;
} else if (parameterInfos[n].IsOptional)
{
methodArguments[n] = parameterInfos[n].DefaultValue;
} else
return false;
}
return true;
}
public bool MapMethodParameters(MethodInfo methodInfo, JSONArray jsonArguments, out object[] methodArguments) => MapMethodParameters(methodInfo.GetParameters(), jsonArguments, out methodArguments);
public bool MapMethodParameters(ParameterInfo[] parameterInfos, JSONArray jsonArguments, out object[] methodArguments)
{
methodArguments = new object[parameterInfos.Length];
if (jsonArguments.Count != methodArguments.Length)
return false;
for (int n=0; n < methodArguments.Length; n++)
{
if (!JSONMapper.DefaultMapper.Deserialize(jsonArguments[n], parameterInfos[n].ParameterType, out methodArguments[n]))
return false;
}
return true;
}
static JSONMapper()
{
DefaultMapper.Add(new JSONMapping(
@ -261,6 +374,11 @@ namespace ln.json.mapping
(JSONMapper arg1, object arg2) => new JSONNumber((int)(byte)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToByte(((JSONNumber)arg2).Decimal)
));
DefaultMapper.Add(new JSONMapping(
typeof(sbyte),
(JSONMapper arg1, object arg2) => new JSONNumber((int)(sbyte)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToSByte(((JSONNumber)arg2).Decimal)
));
DefaultMapper.Add(new JSONMapping(
typeof(short),
(JSONMapper arg1, object arg2) => new JSONNumber((int)(short)arg2),
@ -329,7 +447,7 @@ namespace ln.json.mapping
DefaultMapper.Add(new JSONMapping(
typeof(bool),
(JSONMapper arg1, object arg2) => ((bool)arg2) ? (JSONValue)JSONTrue.Instance : (JSONValue)JSONFalse.Instance,
(JSONMapper arg1, JSONValue arg2) => (arg2.ValueType == JSONValueType.TRUE) || (arg2.ValueType == JSONValueType.FALSE) ? false : throw new NotSupportedException()
(JSONMapper arg1, JSONValue arg2) => (arg2.ValueType == JSONValueType.TRUE) ? true : false
));
DefaultMapper.Add(new JSONByteArrayMapping());
@ -343,6 +461,12 @@ namespace ln.json.mapping
DefaultMapper.Add(new JSONRPCCallMapping());
DefaultMapper.Add(new JSONRPCResultMapping());
DefaultMapper.Add(new JSONMapping(
typeof(IPAddress),
((mapper, o) => ((IPAddress)o).ToString()),
(mapper, value) => IPAddress.Parse((value as JSONString).Value))
);
}
}
}

View File

@ -25,6 +25,7 @@ namespace ln.json.mapping
Dictionary<string, Action<object,object>> setters = new Dictionary<string, Action<object,object>>();
Dictionary<string, Func<object, object>> getters = new Dictionary<string, Func<object, object>>();
Dictionary<string, Type> types = new Dictionary<string, Type>();
private HashSet<string> _dontAssign = new HashSet<string>();
public JSONObjectMapping(Type type)
: this(type, JSONObjectMappingFlags.FIELDS | JSONObjectMappingFlags.PROPERTIES, BindingFlags.Instance | BindingFlags.Public)
@ -44,6 +45,8 @@ namespace ln.json.mapping
setters.Add(fieldInfo.Name, (object arg1, object arg2) => fieldInfo.SetValue(arg1, arg2));
getters.Add(fieldInfo.Name, (object arg) => fieldInfo.GetValue(arg));
types.Add(fieldInfo.Name, fieldInfo.FieldType);
if (fieldInfo.GetCustomAttribute<DontAssign>() != null)
_dontAssign.Add(fieldInfo.Name);
}
}
if ((mappingFlags & JSONObjectMappingFlags.PROPERTIES) == JSONObjectMappingFlags.PROPERTIES)
@ -55,6 +58,8 @@ namespace ln.json.mapping
setters.Add(propertyInfo.Name, (object arg1, object arg2) => { if (propertyInfo.CanWrite) propertyInfo.SetValue(arg1, arg2); });
getters.Add(propertyInfo.Name, (object arg) => propertyInfo.GetValue(arg));
types.Add(propertyInfo.Name, propertyInfo.PropertyType);
if (propertyInfo.GetCustomAttribute<DontAssign>() != null)
_dontAssign.Add(propertyInfo.Name);
}
}
}
@ -102,5 +107,20 @@ namespace ln.json.mapping
}
}
}
public bool Assign(JSONMapper mapper, object o, JSONObject json)
{
bool applied = false;
foreach (string name in setters.Keys)
{
if (json.ContainsKey(name) && !_dontAssign.Contains(name))
{
setters[name](o, mapper.FromJson(json[name], types[name]));
applied = true;
}
}
return applied;
}
}
}