// /** // * 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 mappings = new Dictionary(); 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(string jsonString) => FromJson((JSONObject)JSONParser.Parse(jsonString)); public T FromJson(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); } } }