void Check( string json, bool isNull, bool isArray, bool isObject, bool isValue, SLJsonNodeType valueType, bool valueBoolean, int valueInt32, long valueInt64, double valueNumber, string valueString) { SLJsonNode parsed = SLJsonParser.Parse(json); SLJsonNode n = parsed["value"]; Test.Assert(() => n.IsArray == isArray); Test.Assert(() => n.IsNull == isNull); Test.Assert(() => n.IsObject == isObject); Test.Assert(() => n.IsValue == isValue); Test.Assert(() => n.NodeType == valueType); Test.Assert(() => n.IsValue == (n.IsBoolean || n.IsNumber || n.IsString)); Test.Assert(() => n.IsBoolean == (valueType == SLJsonNodeType.Boolean)); Test.Assert(() => n.IsNumber == (valueType == SLJsonNodeType.Number)); Test.Assert(() => n.IsString == (valueType == SLJsonNodeType.String)); Test.Assert(() => n.AsBoolean == valueBoolean); Test.Assert(() => n.AsInt32 == valueInt32); Test.Assert(() => n.AsInt64 == valueInt64); Test.Assert(() => Math.Abs(n.AsDouble - valueNumber) <= 1e-7); Test.Assert(() => n.AsString == valueString); }
public static void RunExample1() { Console.WriteLine("Example 1"); Console.WriteLine("========="); Console.WriteLine(); string jsonExpression = @" { addressBook: [ {lastName: 'Average', firstName: 'Joe'}, {lastName: 'Doe', firstName: 'Jane'}, {lastName: 'Smith', firstName: 'John'} ] }"; SLJsonNode root = SLJsonParser.Parse(jsonExpression); SLJsonNode book = root["addressBook"]; if (book.IsArray) { int c = book.Count; for (int i = 0; i < c; i++) { SLJsonNode entry = book[i]; string ln = entry["lastName"]; string fn = entry["firstName"]; Console.WriteLine(fn + " " + ln); } } Console.WriteLine(); }
void ParseAndSerialize(string jsonExpression, bool allowArraysAndValues, SLJsonNodeType nodeType) { SLJsonNode n = SLJsonParser.Parse(jsonExpression, allowArraysAndValues); Test.Assert(() => n.NodeType == nodeType); string s = RemoveWhitespace(jsonExpression); Test.Assert(() => n.AsJsonCompact == s); }
public static void RunExample2() { Console.WriteLine("Example 2"); Console.WriteLine("========="); Console.WriteLine(); string jsonExpression = RetrieveJsonExample(); PrintNode(SLJsonNode.Parse(jsonExpression), "demo = ", 0); Console.WriteLine(); }
public static void RunExample3() { Console.WriteLine("Example 3"); Console.WriteLine("========="); Console.WriteLine(); var root = new SLJsonNode(); root["addressBook"] = CreateAddressBook(); Console.WriteLine(root.AsJson); Console.WriteLine(); }
void MakeObjectSetItem(string name, SLJsonNode value) { MakeObject(); SLJsonNode n = TryGetObjectProperty(name); if (n != null) { n.ClearParent(); } m_Object[name] = value; }
static SLJsonNode CreateAddressBook() { var book = new SLJsonNode(); book[0]["LastName"] = "Average"; book[0]["firstName"] = "Joe"; book[1]["LastName"] = "Doe"; book[1]["firstName"] = "Jane"; book[2]["LastName"] = "Smith"; book[2]["firstName"] = "John"; return(book); }
public T Deserialize <T>(SLJsonNode node) where T : new() { if (node == null) { throw new ArgumentNullException("node"); } if (node.IsObject) { return((T)DeserializeObject(typeof(T), node)); } return(new T()); //return Activator.CreateInstance<T>(); }
void TestReadWrite() { string s = RetrieveJsonExpression(); SLJsonNode n = SLJsonParser.Parse(s); SLJsonMonitor m = n.CreateMonitor(); // Try to read some properties Test.Assert(() => n["person"]["firstName"].AsString == "Jane"); Test.Assert(() => n["person"]["lastName"].AsString == "Doe"); Test.Assert(() => n["person"]["zipCode"].AsString == "12345"); Test.Assert(() => !m.IsModified); try { m.IsReadOnly = true; n["abc"]["def"][100] = 0; Test.Assert(() => false); } catch (InvalidOperationException) { m.IsReadOnly = false; Test.Assert(() => true); } Test.Assert(() => !m.IsModified); // Try to change an existing property n["person"]["firstName"].AsString = "John"; Test.Assert(() => n["person"]["firstName"].AsString == "John"); Test.Assert(() => m.IsModified); // Try to add a new property int c = n["person"].Count; Test.Assert(() => n["person"]["newProperty"].NodeType == SLJsonNodeType.Missing); n["person"]["newProperty"].AsInt32 = 333; Test.Assert(() => n["person"].Count == c + 1); Test.Assert(() => n["person"]["newProperty"].NodeType == SLJsonNodeType.Number); Test.Assert(() => n["person"]["newProperty"].AsString == "333"); // Try to delete a property c = n["person"].Count; Test.Assert(() => n["person"]["lastName"].NodeType == SLJsonNodeType.String); n["person"]["lastName"].Remove(); Test.Assert(() => n["person"].Count == c - 1); Test.Assert(() => n["person"]["lastName"].NodeType == SLJsonNodeType.Missing); Test.Assert(() => n["person"]["lastName"].AsString == null); }
SLJsonNode Clone(SLJsonNode parent) { var res = new SLJsonNode(parent); res.m_NodeType = m_NodeType; res.m_Value = m_Value; res.m_Index = m_Index; res.m_Name = m_Name; // Do not copy m_Monitor here! if (m_Array != null) { res.m_Array = CreateArray(); foreach (SLJsonNode n in m_Array) { #if DEBUG if (n.m_Parent != this) { throw new InvalidOperationException(); } #endif res.m_Array.Add(n.Clone(res)); } } if (m_Object != null) { res.m_Object = CreateObject(); foreach (string k in m_Object.Keys) { SLJsonNode n = TryGetObjectProperty(k); #if DEBUG if (n.m_Parent != this) { throw new InvalidOperationException(); } #endif res.m_Object.Add(k, n.Clone(res)); } } return(res); }
public SLJsonNode this[string name] { get { if (name == null) { throw new ArgumentNullException("name"); } if (m_Object != null) { SLJsonNode n = TryGetObjectProperty(name); if (n != null) { return(n); } } return(new SLJsonNode(this, name)); } set { if (name == null) { throw new ArgumentNullException("name"); } if (value == null) { value = new SLJsonNode(); } else { if (value.m_Parent != null) { throw new ArgumentException("Node already in use", "value"); } } BeforeChange(); MakeObjectSetItem(name, value); value.AssignParent(this); Activate(); } }
object DeserializeArray(Type type, SLJsonNode array, bool asObject) { if (!type.IsArray) { throw new NotSupportedException("Type " + type.FullName + " is not an array"); } Type t = type.GetElementType(); object defaultValue = null; if (!asObject && !t.GetTypeInfo().IsClass) { defaultValue = Activator.CreateInstance(t); } int c = array.Count; var res = Array.CreateInstance(t, c); for (int i = 0; i < c; i++) { object v = defaultValue; SLJsonNode n = array[i]; if (n != null) { if (asObject) { if (n.IsObject) { v = DeserializeObject(t, n); } } else { if (n.IsValue) { v = DeserializeValue(t, n); } } } res.SetValue(v, i); } return(res); }
void MakeArraySetItem(int index, SLJsonNode value) { MakeArray(); while (m_Array.Count < index) { m_Array.Add(new SLJsonNode(this)); } if (index == m_Array.Count) { m_Array.Add(value); } else { GetArrayItem(index).ClearParent(); m_Array[index] = value; } }
public void Run() { Test = new UnitTestHelper(); Test.PrintHeadline("UnitTest3 - Reflection-based Serialization"); var o1 = new ExampleOuter() { ValueString = "Test", ValueStringArray = new string[] { "A", "B,", "C" }, ValueDoubleArray = new double[] { 2, 3.14, 10000 }, PropertyInteger = 27, PropertyDateTime = new DateTime(2017, 12, 27, 14, 30, 0), }; o1.ValueObject = new ExampleInner(2); o1.ValueObjectArray = new ExampleInner[] { new ExampleInner(4), new ExampleInner(6) }; o1.ChangePrivateValue(2.345f); string s1 = Serialize(o1); //Console.WriteLine(s1); var d = new SLJsonDeserializer(); ExampleOuter o2 = d.Deserialize <ExampleOuter>(s1); string s2 = Serialize(o1); Test.Assert(() => s1 == s2); SLJsonNode n1 = SLJsonParser.Parse(s1); SLJsonNode n2 = n1.Clone(); SLJsonNode n3 = SLJsonParser.Parse(n2.AsJson); SLJsonNode n4 = SLJsonParser.Parse(n3.AsJsonCompact); Test.Assert(() => n1 != n2); CompareNodes(n1, n1); CompareNodes(n1, n2); CompareNodes(n1, n3); CompareNodes(n1, n4); //Console.WriteLine(); Test.PrintSummary(); Test = null; }
void TestCreateNew() { var n = new SLJsonNode(); n["person"]["firstName"].AsString = "John"; n["person"]["lastName"].AsString = "Doe"; Test.Assert(() => n.Count == 1); Test.Assert(() => n["person"].Count == 2); Test.Assert(() => n["person"]["firstName"].AsString == "John"); Test.Assert(() => n["person"]["lastName"].AsString == "Doe"); n["intValue"].AsInt32 = 27; Test.Assert(() => n["intValue"].IsNumber); Test.Assert(() => n["intValue"].AsString == "27"); Test.Assert(() => n["intValue"].Remove()); Test.Assert(() => !n["intValue"].Remove()); Test.Assert(() => n["intValue"].IsMissing); Test.Assert(() => n["intValue"].AsString == null); Test.Assert(() => n["testArray"].IsMissing); n["testArray"][0].AsInt32 = 11; Test.Assert(() => n["testArray"].IsArray); Test.Assert(() => n["testArray"].Count == 1); n["testArray"][0].AsInt32 = 77; Test.Assert(() => n["testArray"].Count == 1); Test.Assert(() => n["testArray"][0].AsInt32 == 77); Test.Assert(() => n["testArray"][1].IsMissing); n["testArray"][2].AsInt32 = 200; Test.Assert(() => n["testArray"][1].IsNull); Test.Assert(() => n["testArray"][2].IsNumber); Test.Assert(() => n["testArray"][3].IsMissing); n["testArray"][3].AsInt32 = 300; Test.Assert(() => n["testArray"][3].IsNumber); Test.Assert(() => n["testArray"].Count == 4); Test.Assert(() => !n["testArray"][100].Remove()); Test.Assert(() => !n["testArray"][100].Remove()); Test.Assert(() => n["testArray"].Count == 4); Test.Assert(() => n["testArray"][1].Remove()); Test.Assert(() => n["testArray"].Count == 3); }
object DeserializeObjectInternal(SLJsonNode node, SLJsonMemberType memberType, Type type, object value) { if (node != null) { switch (memberType) { case SLJsonMemberType.Value: if (node.IsValue) { return(DeserializeValue(type, node)); } break; case SLJsonMemberType.ValueArray: if (node.IsArray) { return(DeserializeArray(type, node, false)); } break; case SLJsonMemberType.Object: if (node.IsObject) { return(DeserializeObject(type, node)); } break; case SLJsonMemberType.ObjectArray: if (node.IsArray) { return(DeserializeArray(type, node, true)); } break; default: throw new NotImplementedException(); } } return(value); }
public static void RunExample4() { Console.WriteLine("Example 4"); Console.WriteLine("========="); Console.WriteLine(); string s = @" { ""options"": { ""logging"": true }, ""sensors"": [ { ""name"": ""Button"", ""value"": 1 }, { ""name"": ""Temperature"", ""value"": 17.5 } ], ""actors"": [ { ""name"": ""Lamp"", ""value"": 0 } ] }"; /* * Console.WriteLine(s.Trim()); * Console.WriteLine(); * //*/ var n = SLJsonNode.Parse(s); Console.WriteLine("n.AsJsonCompact => " + n.AsJsonCompact); Console.WriteLine(); Console.WriteLine("n[\"options\"].NodeType => " + n["options"].NodeType); Console.WriteLine("n[\"options\"][\"logging\"] => " + n["options"]["logging"]); Console.WriteLine("n[\"sensors\"].NodeType => " + n["sensors"].NodeType); Console.WriteLine("n[\"sensors\"].Count => " + n["sensors"].Count); Console.WriteLine("n[\"sensors\"][0][\"name\"] => " + n["sensors"][0]["name"]); Console.WriteLine("n[\"sensors\"][1][\"value\"] => " + n["sensors"][1]["value"]); Console.WriteLine("n[\"missing\"][33][\"foo\"] => " + n["missing"][33]["foo"]); Console.WriteLine(); }
//------------------------------------------------------------------------ public static void RunExample4() { Console.WriteLine("Example 4"); Console.WriteLine("========="); Console.WriteLine(); string s = @" { options: { logging: true }, sensors: [ { name: 'Button', value: 1 }, { name: 'Temperature', value: 17.5 } ], actors: [ { name: 'Lamp', value: 0 } ] }"; /* * Console.WriteLine(s.Trim()); * Console.WriteLine(); * //*/ SLJsonNode n = SLJsonParser.Parse(s); Console.WriteLine("n.AsJsonCompact => " + n.AsJsonCompact); Console.WriteLine(); Console.WriteLine("n[\"options\"].NodeType => " + n["options"].NodeType); Console.WriteLine("n[\"options\"][\"logging\"] => " + n["options"]["logging"]); Console.WriteLine("n[\"sensors\"].NodeType => " + n["sensors"].NodeType); Console.WriteLine("n[\"sensors\"].Count => " + n["sensors"].Count); Console.WriteLine("n[\"sensors\"][0][\"name\"] => " + n["sensors"][0]["name"]); Console.WriteLine("n[\"sensors\"][1][\"value\"] => " + n["sensors"][1]["value"]); Console.WriteLine("n[\"missing\"][33][\"foo\"] => " + n["missing"][33]["foo"]); Console.WriteLine(); }
static void PrintNode(SLJsonNode node, int level) { if (level <= 0) { level = 1; } switch (node.NodeType) { case SLJsonNodeType.Array: Console.WriteLine("(Array)"); foreach (SLJsonNode item in node) { Indent(level); PrintNode(item, level + 1); } break; case SLJsonNodeType.Object: Console.WriteLine("(Object)"); foreach (string name in node.Names) { Indent(level); Console.Write(name + " = "); PrintNode(node[name], level + 1); } break; case SLJsonNodeType.Boolean: case SLJsonNodeType.Number: case SLJsonNodeType.String: Console.WriteLine(node.AsString + " (" + node.NodeType.ToString() + ")"); break; default: Console.WriteLine("(" + node.NodeType.ToString() + ")"); break; } }
public SLJsonNode this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException("index"); } if (m_Array != null && index < m_Array.Count) { return(GetArrayItem(index)); } return(new SLJsonNode(this, index)); } set { if (value == null) { value = new SLJsonNode(); } else { if (value.m_Parent != null) { throw new ArgumentException("Node already in use", "value"); } } BeforeChange(); MakeArraySetItem(index, value); value.AssignParent(this); Activate(); } }
//------------------------------------------------------------------------ SLJsonMonitor RetrieveMonitor() { SLJsonNode n = this; do { if (n.m_Parent == null) { return(n.m_Monitor ?? m_DefaultMonitor); } #if DEBUG if (n.m_Monitor != null) { throw new InvalidOperationException(); } #endif n = n.m_Parent; }while(n != null); return(m_DefaultMonitor); }
void TestSerialization() { string s = RetrieveJsonExpression(); SLJsonNode n = SLJsonParser.Parse(s); n["newProperty"]["value"].AsInt32 = 27; Test.Assert(() => n["newProperty"]["value"].NodeType == SLJsonNodeType.Number); Test.Assert(() => n["newProperty"]["value"].AsJson == "27"); Test.Assert(() => RemoveWhitespace(n["newProperty"].AsJson) == "{\"value\":27}"); n["newProperty"]["value"][0].AsInt32 = 100; n["newProperty"]["value"][3].AsInt32 = 333; Test.Assert(() => n["newProperty"]["value"].NodeType == SLJsonNodeType.Array); Test.Assert(() => n["newProperty"].AsJsonCompact == "{\"value\":[100,null,null,333]}"); n["newProperty"]["value"].AsString = "Text"; Test.Assert(() => n["newProperty"]["value"].NodeType == SLJsonNodeType.String); n["newProperty"]["value"].AsString = null; Test.Assert(() => n["newProperty"]["value"].NodeType == SLJsonNodeType.Null); Test.Assert(() => n["newProperty"]["value"].Remove()); Test.Assert(() => n["newProperty"]["value"].NodeType == SLJsonNodeType.Missing); }
//------------------------------------------------------------------------ void TestReadOnly() { string s = RetrieveJsonExpression(); SLJsonNode n = SLJsonParser.Parse(s); Test.Assert(() => n["person"]["firstName"].AsString == "Jane"); Test.Assert(() => n["person"]["lastName"].AsString == "Doe"); Test.Assert(() => n["person"]["zipCode"].AsString == "12345"); Test.Assert(() => !n["person"]["street"].IsReadOnly); SLJsonMonitor m = n.CreateMonitor(); Test.Assert(() => !m.IsModified); Test.Assert(() => !m.IsReadOnly); m.IsReadOnly = true; Test.Assert(() => n["person"]["street"].IsReadOnly); Test.Assert(() => n["test"]["emptyArray"].IsArray); Test.Assert(() => n["test"]["emptyArray"].Count == 0); Test.Assert(() => n["test"]["emptyObject"].IsObject); Test.Assert(() => n["test"]["emptyObject"].Count == 0); Test.Assert(() => n["test"]["testArray"].IsArray); Test.Assert(() => n["test"]["testArray"].Count == 4); Test.Assert(() => n["test"]["testArray"][0].AsInt32 == 10); Test.Assert(() => n["test"]["testArray"][1].AsInt32 == 20); Test.Assert(() => n["test"]["testArray"][2].AsInt32 == 30); Test.Assert(() => n["test"]["testArray"][3].AsInt32 == 40); Test.Assert(() => n["test"]["testArray"][4].AsInt32 == 0); // Access to missing entry Test.Assert(() => !n["test"]["testArray"][4].IsValue); // Check missing entry Test.Assert(() => n["test"]["testArray"].Count == 4); // Check count again Test.Assert(() => n["test"]["testObject"].NodeType == SLJsonNodeType.Object); Test.Assert(() => n["test"]["testObject"].Count == 2); Test.Assert(() => n["test"]["testObject"].AsString == null); Test.Assert(() => n["test"]["testValueMissing__"].NodeType == SLJsonNodeType.Missing); Test.Assert(() => !n["test"]["testValueMissing__"].AsBoolean); Test.Assert(() => n["test"]["testValueMissing__"].AsInt32 == 0); Test.Assert(() => n["test"]["testValueMissing__"].AsString == null); Test.Assert(() => n["test"]["testValueNull"].NodeType == SLJsonNodeType.Null); Test.Assert(() => !n["test"]["testValueNull"].AsBoolean); Test.Assert(() => n["test"]["testValueNull"].AsInt32 == 0); Test.Assert(() => n["test"]["testValueNull"].AsString == null); Test.Assert(() => n["test"]["testValueTrue"].NodeType == SLJsonNodeType.Boolean); Test.Assert(() => n["test"]["testValueTrue"].AsBoolean); Test.Assert(() => n["test"]["testValueTrue"].AsInt32 == 0); Test.Assert(() => n["test"]["testValueTrue"].AsString == "true"); Test.Assert(() => n["test"]["testValue32"].NodeType == SLJsonNodeType.Number); Test.Assert(() => n["test"]["testValue32"].AsInt32 == 256); Test.Assert(() => n["test"]["testValue32"].AsString == "+256"); Test.Assert(() => n["test"]["testValueString1"].NodeType == SLJsonNodeType.String); Test.Assert(() => n["test"]["testValueString1"].AsString == "abc 'def' ghi"); Test.Assert(() => n["test"]["testValueString2"].NodeType == SLJsonNodeType.String); Test.Assert(() => n["test"]["testValueString2"].AsString == "ABC 'DEF' GHI"); Test.Assert(() => n["test"]["testValueString3"].NodeType == SLJsonNodeType.String); Test.Assert(() => n["test"]["testValueString3"].AsString == "First Line\r\nSecond Line\r\nThird Line\0"); // .NET MF seems to work internally with zero-terminated strings. As a result the test case fails. if ("123\0".Length == 4) { Test.Assert(() => n["test"]["testValueString3"].AsJsonCompact == @"""First Line\r\nSecond Line\r\nThird Line\u0000"""); } Test.Assert(() => !m.IsModified); Test.Assert(() => m.IsReadOnly); }
object DeserializeArray(Type type, SLJsonNode array, bool asObject) { int c = array.Count; Type elemType; Array resArray; IList resList; if (type.IsArray) { if (type.GetArrayRank() != 1) { throw new NotSupportedException("Multi-dimensional arrays are not supported"); } elemType = type.GetElementType(); resArray = Array.CreateInstance(elemType, c); resList = null; } else { Type[] args = type.GetGenericArguments(); elemType = args.Length == 1 ? args[0] : null; if (elemType == null || !typeof(List <>).MakeGenericType(elemType).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) { throw new NotSupportedException("Type " + type.FullName + " is neither an array nor a List<>"); } resList = (IList)Activator.CreateInstance(type); resArray = null; } object defaultValue = null; if (!asObject && !elemType.GetTypeInfo().IsClass) { defaultValue = Activator.CreateInstance(elemType); } for (int i = 0; i < c; i++) { object v = defaultValue; SLJsonNode n = array[i]; if (n != null) { if (asObject) { if (n.IsObject) { v = DeserializeObject(elemType, n); } } else { if (n.IsValue) { v = DeserializeValue(elemType, n); } } } if (resArray != null) { resArray.SetValue(v, i); } else { resList.Add(v); } } return(resArray ?? resList); }
SLJsonNode(SLJsonNode parent) { m_NodeType = SLJsonNodeType.Null; m_Parent = parent; }
SLJsonNode(SLJsonNode parent, string name) { m_NodeType = SLJsonNodeType.Missing; m_Parent = parent; m_Name = name; }
} // Used by the parser SLJsonNode(SLJsonNode parent, int index) { m_NodeType = SLJsonNodeType.Missing; m_Parent = parent; m_Index = index; }
internal void AssignParent(SLJsonNode parent) { m_Parent = parent; } // Used by the parser and by the setters of the indexer properties
object DeserializeValue(Type type, SLJsonNode value) { return(ParseValue(type, value.AsString)); }
public T Deserialize <T>(string jsonExpression) where T : new() { SLJsonNode n = SLJsonParser.Parse(jsonExpression); return(Deserialize <T>(n)); }