ln.json/mapping/JSONMapper.cs

189 lines
7.1 KiB
C#

// /**
// * File: JSONMapper.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics.Tracing;
namespace ln.json.mapping
{
public class JSONMapper
{
public static JSONMapper DefaultMapper { get; set; } = new JSONMapper(true);
Dictionary<Type, JSONMapping> mappings = new Dictionary<Type, JSONMapping>();
public JSONMapper()
{
}
private JSONMapper(bool defaultMapper)
{
/**
* Integer
**/
Add(new JSONMapping(
typeof(byte),
(JSONMapper arg1, object arg2) => new JSONNumber((int)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToByte(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(short),
(JSONMapper arg1, object arg2) => new JSONNumber((int)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToInt16(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(int),
(JSONMapper arg1, object arg2) => new JSONNumber((int)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToInt32(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(long),
(JSONMapper arg1, object arg2) => new JSONNumber((long)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToInt64(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(ushort),
(JSONMapper arg1, object arg2) => new JSONNumber((uint)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToUInt16(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(uint),
(JSONMapper arg1, object arg2) => new JSONNumber((uint)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToUInt32(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(ulong),
(JSONMapper arg1, object arg2) => new JSONNumber((ulong)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToUInt64(((JSONNumber)arg2).Decimal)
));
/**
* Float
**/
Add(new JSONMapping(
typeof(float),
(JSONMapper arg1, object arg2) => new JSONNumber((float)arg2),
(JSONMapper arg1, JSONValue arg2) => (float)Decimal.ToDouble(((JSONNumber)arg2).Decimal)
));
Add(new JSONMapping(
typeof(double),
(JSONMapper arg1, object arg2) => new JSONNumber((double)arg2),
(JSONMapper arg1, JSONValue arg2) => Decimal.ToDouble(((JSONNumber)arg2).Decimal)
));
/**
* Strings
**/
Add(new JSONMapping(
typeof(string),
(JSONMapper arg1, object arg2) => new JSONString((string)arg2),
(JSONMapper arg1, JSONValue arg2) => ((JSONString)arg2).Value
));
/**
* Others
**/
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()
));
Add(new JSONDateTimeMapping());
Add(new JSONDateTimeOffsetMapping());
Add(new JSONGuidMapping());
Add(new JSONIPv4Mapping());
Add(new JSONNetwork4Mapping());
Add(new JSONTimeSpanMapping());
Add(new JSONRPCCallMapping());
Add(new JSONRPCResultMapping());
}
public void Add(JSONMapping mapping)
{
mappings[mapping.TargetType] = mapping;
}
private JSONMapping FindMapping(Type targetType)
{
if (mappings.ContainsKey(targetType))
return mappings[targetType];
if (this != DefaultMapper)
return DefaultMapper.FindMapping(targetType);
if (!targetType.IsPrimitive)
{
if (targetType.IsArray)
{
Add(new JSONArrayMapping(targetType));
}
else if (targetType.IsEnum)
{
Add(new JSONEnumMapping(targetType));
}
else if (targetType.IsGenericType)
{
Type genericTypeDefinition = targetType.GetGenericTypeDefinition();
if (genericTypeDefinition.Equals(typeof(IEnumerable<>)))
{
Add((JSONMapping)Activator.CreateInstance(typeof(JSONEnumerableMapping<>).MakeGenericType(targetType.GetGenericArguments()[0])));
} else if (genericTypeDefinition.Equals(typeof(Dictionary<,>)))
{
Add((JSONMapping)Activator.CreateInstance(typeof(JSONDictionaryMapping<,>).MakeGenericType(targetType.GetGenericArguments())));
}
}
else
{
Add(new JSONObjectMapping(targetType));
}
return mappings[targetType];
}
throw new NotSupportedException(targetType.ToString());
}
public T FromJson<T>(string jsonString) => FromJson<T>((JSONObject)JSONParser.Parse(jsonString));
public T FromJson<T>(JSONValue json) => (T)FromJson(json, typeof(T));
public object FromJson(string jsonString, Type targetType) => FromJson((JSONObject)JSONParser.Parse(jsonString), targetType);
public object FromJson(JSONValue json, Type targetType)
{
if (json.ValueType == JSONValueType.NULL)
return null;
return FindMapping(targetType).FromJson(this, json);
}
public JSONValue ToJson(object value)
{
if (value == null)
return JSONNull.Instance;
Type sourceType = value.GetType();
return FindMapping(sourceType).ToJson(this, value);
}
public void Apply(string jsonString, object o) => Apply((JSONObject)JSONParser.Parse(jsonString), o);
public void Apply(JSONObject json,object o)
{
JSONMapping mapping = FindMapping(o.GetType());
if (!(mapping is JSONObjectMapping))
throw new NotSupportedException();
JSONObjectMapping objectMapping = mapping as JSONObjectMapping;
objectMapping.Apply(this, json, o);
}
}
}