diff --git a/.vs/sharp.json/xs/UserPrefs.xml b/.vs/sharp.json/xs/UserPrefs.xml index 4917db8..6d0c64c 100644 --- a/.vs/sharp.json/xs/UserPrefs.xml +++ b/.vs/sharp.json/xs/UserPrefs.xml @@ -1,15 +1,17 @@  - + + + + - - - + + - - + + diff --git a/JSONArray.cs b/JSONArray.cs index 22c3620..6298b80 100644 --- a/JSONArray.cs +++ b/JSONArray.cs @@ -9,6 +9,8 @@ namespace ln.json public override IEnumerable Children => Values; public override bool HasChildren => true; + public int Count => values.Count; + JSONValue[] Values { get => values.ToArray(); diff --git a/JSONNumber.cs b/JSONNumber.cs index 24d2a77..147e107 100644 --- a/JSONNumber.cs +++ b/JSONNumber.cs @@ -5,6 +5,7 @@ namespace ln.json { public class JSONNumber : JSONValue { + public Decimal Decimal => decValue; readonly decimal decValue; public JSONNumber(int i) @@ -16,6 +17,15 @@ namespace ln.json decValue = new decimal(integer); } + public JSONNumber(uint i) + : this((ulong)i) { } + + public JSONNumber(ulong integer) + : base(JSONValueType.NUMBER) + { + decValue = new decimal(integer); + } + public JSONNumber(double doubleValue) : base(JSONValueType.NUMBER) { diff --git a/JSONObject.cs b/JSONObject.cs index a0824da..ddbd796 100644 --- a/JSONObject.cs +++ b/JSONObject.cs @@ -15,6 +15,8 @@ namespace ln.json public override IEnumerable Children => values.Values; public override bool HasChildren => true; + public int Count => values.Count; + BTree values = new BTree(); public JSONObject() @@ -32,6 +34,11 @@ namespace ln.json return this; } + public bool ContainsKey(string key) + { + return values.ContainsKey(key); + } + public override string ToString() { StringBuilder sb = new StringBuilder(); diff --git a/json.test/Program.cs b/json.test/Program.cs index aceca7a..1230bc8 100644 --- a/json.test/Program.cs +++ b/json.test/Program.cs @@ -2,6 +2,7 @@ using System.IO; using ln.json; +using ln.json.mapping; namespace json.test { @@ -37,6 +38,26 @@ namespace json.test Console.WriteLine(""); Console.WriteLine("test.json file:"); Console.WriteLine("PARSED: {0}",value.ToString()); + + Person person = new Person() + { + firstname = "Harald", + lastname = "Wolff-Thobaben", + age = 39 + }; + + JSONValue jsonPerson = JSONMapper.DefaultMapper.ToJson(person); + Console.WriteLine(jsonPerson.ToString()); + + Person p2 = JSONMapper.DefaultMapper.FromJson(jsonPerson); } - } + + class Person + { + public string firstname; + public string lastname; + + public int age; + } + } } diff --git a/ln.json.csproj b/ln.json.csproj index deb6716..0eedf27 100644 --- a/ln.json.csproj +++ b/ln.json.csproj @@ -38,6 +38,11 @@ + + + + + @@ -45,6 +50,9 @@ ln.types + + + diff --git a/mapping/JSONArrayMapping.cs b/mapping/JSONArrayMapping.cs new file mode 100644 index 0000000..27933b8 --- /dev/null +++ b/mapping/JSONArrayMapping.cs @@ -0,0 +1,45 @@ +// /** +// * File: JSONArrayMapping.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; +namespace ln.json.mapping +{ + public class JSONArrayMapping : JSONMapping + { + Type elementType; + + public JSONArrayMapping(Type type) + :base(type) + { + elementType = type.GetElementType(); + } + + public override object FromJson(JSONMapper mapper, JSONValue json) + { + JSONArray jsonArray = (JSONArray)json; + Array array = Array.CreateInstance(elementType,jsonArray.Count); + + for (int n = 0; n < array.Length; n++) + array.SetValue(mapper.FromJson(jsonArray[n],elementType),n); + + return array; + } + public override JSONValue ToJson(JSONMapper mapper, object value) + { + Array array = (Array)value; + JSONArray jsonArray = new JSONArray(); + + foreach (object element in array) + jsonArray.Add(mapper.ToJson(element)); + + return jsonArray; + } + + } +} diff --git a/mapping/JSONEnumerableMapping.cs b/mapping/JSONEnumerableMapping.cs new file mode 100644 index 0000000..e03b4ad --- /dev/null +++ b/mapping/JSONEnumerableMapping.cs @@ -0,0 +1,41 @@ +// /** +// * File: JSONArrayMapping.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.Collections; +using System.Collections.Generic; +namespace ln.json.mapping +{ + public class JSONEnumerableMapping : JSONMapping + { + Type elementType; + + public JSONEnumerableMapping() + :base(typeof(T)) + { + elementType = typeof(T).GetGenericArguments()[0]; + } + + public override object FromJson(JSONMapper mapper, JSONValue json) + { + throw new NotSupportedException("IEnumerable<> can not be set from JSON"); + } + public override JSONValue ToJson(JSONMapper mapper, object value) + { + IEnumerable ie = (IEnumerable)value; + JSONArray jsonArray = new JSONArray(); + + foreach (object element in ie) + jsonArray.Add(mapper.ToJson(element)); + + return jsonArray; + } + + } +} diff --git a/mapping/JSONMapper.cs b/mapping/JSONMapper.cs new file mode 100644 index 0000000..2fad2a9 --- /dev/null +++ b/mapping/JSONMapper.cs @@ -0,0 +1,151 @@ +// /** +// * 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() + )); + + } + + 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 && !targetType.IsValueType) + { + if (targetType.IsArray) + { + Add(new JSONArrayMapping(targetType)); + } else if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(IEnumerable<>))) + { + Add((JSONMapping)Activator.CreateInstance(typeof(JSONEnumerableMapping<>).MakeGenericType(targetType.GetGenericArguments()[0]))); + } else + { + Add(new JSONObjectMapping(targetType)); + } + return mappings[targetType]; + } + + throw new NotSupportedException(); + } + + public T FromJson(JSONValue json) => (T)FromJson(json, typeof(T)); + 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); + } + + } +} diff --git a/mapping/JSONMapping.cs b/mapping/JSONMapping.cs new file mode 100644 index 0000000..5c706d0 --- /dev/null +++ b/mapping/JSONMapping.cs @@ -0,0 +1,43 @@ +// /** +// * File: JSONMapping.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; +namespace ln.json.mapping +{ + public class JSONMapping + { + public Type TargetType { get; } + + Func tojson; + Func fromjson; + + public JSONMapping(Type targetType,Func tojson, Func fromjson) + { + TargetType = targetType; + this.fromjson = fromjson; + this.tojson = tojson; + } + protected JSONMapping(Type targetType) + { + TargetType = targetType; + } + + public virtual object FromJson(JSONMapper mapper,JSONValue json) + { + return fromjson(mapper, json); + } + public virtual JSONValue ToJson(JSONMapper mapper,object value) + { + return tojson(mapper, value); + } + + + + } +} diff --git a/mapping/JSONObjectMapping.cs b/mapping/JSONObjectMapping.cs new file mode 100644 index 0000000..47539a9 --- /dev/null +++ b/mapping/JSONObjectMapping.cs @@ -0,0 +1,62 @@ +// /** +// * File: JSONObjectMapping.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.Collections.Generic; +using System.Reflection; +namespace ln.json.mapping +{ + public class JSONObjectMapping : JSONMapping + { + Dictionary> setters = new Dictionary>(); + Dictionary> getters = new Dictionary>(); + Dictionary types = new Dictionary(); + + public JSONObjectMapping(Type type) + :base(type) + { + foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public)) + { + 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); + } + foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + setters.Add(propertyInfo.Name, (object arg1, object arg2) => propertyInfo.SetValue(arg1, arg2)); + getters.Add(propertyInfo.Name, (object arg) => propertyInfo.GetValue(arg)); + types.Add(propertyInfo.Name, propertyInfo.PropertyType); + } + } + + public override object FromJson(JSONMapper mapper, JSONValue json) + { + JSONObject jObject = (JSONObject)json; + object o = Activator.CreateInstance(TargetType); + + foreach (string name in setters.Keys) + { + if (jObject.ContainsKey(name)) + setters[name](o, mapper.FromJson(jObject[name], types[name])); + } + + return o; + } + + public override JSONValue ToJson(JSONMapper mapper, object value) + { + JSONObject json = new JSONObject(); + foreach (string name in getters.Keys) + { + json[name] = mapper.ToJson(getters[name](value)); + } + return json; + } + } +}