/// <summary> /// Attempt to create object node from a .NET object. /// </summary> /// <param name="instance">Input object.</param> /// <returns> /// The new <see cref="JsonObjectNode"/> instance; otherwise a value of <c>null</c> /// if input was <c>null</c>. /// </returns> /// <exception cref="System.Exception"> /// If error is encountered whilst creating object node. Errors are likely to /// occur when unable to convert property values into JSON nodes. /// </exception> internal static JsonObjectNode FromInstance(object instance) { if (instance == null) { return(null); } var node = new JsonObjectNode(); var metaType = MetaType.FromType(instance.GetType()); metaType.InvokeOnSerializing(instance, default(StreamingContext)); foreach (var member in metaType.SerializableMembers) { object value; if (member.Info.MemberType == MemberTypes.Field) { var mi = (FieldInfo)member.Info; value = mi.GetValue(instance); } else { var pi = (PropertyInfo)member.Info; value = pi.GetValue(instance, null); } node[member.ResolvedName] = ConvertFrom(value); } metaType.InvokeOnSerialized(instance, default(StreamingContext)); return(node); }
/// <inheritdoc/> public override JsonNode Clone() { var node = new JsonObjectNode(); foreach (var property in this.properties) { node[property.Key] = property.Value != null ? property.Value.Clone() : null; } return(node); }
private static JsonObjectNode FromDictionaryStyleCollection(ICollection collection, MetaType metaType) { var node = new JsonObjectNode(); if (collection.Count > 0) { foreach (var pair in collection) { string key = (string)metaType.KeyPropertyInfo.GetValue(pair, null); node[key] = ConvertFrom(metaType.ValuePropertyInfo.GetValue(pair, null)); } } return(node); }
/// <summary> /// Reads a JSON object which comprises of zero-or-more named properties. /// </summary> /// <returns> /// The new <see cref="JsonNode"/> instance. /// </returns> /// <exception cref="JsonParserException"> /// If a syntax error was encountered whilst attempting to parse input content. /// Exception contains identifies the source of the error by providing the line /// number and position. /// </exception> private JsonNode ReadObject() { this.Accept(); this.SkipWhitespace(); var node = new JsonObjectNode(); while (!this.HasReachedEnd) { if (this.Peek() == '}') { this.Accept(); return(node); } else if (this.Peek() == ',' && node.Count != 0) { this.Accept(); this.SkipWhitespace(); if (this.HasReachedEnd) { break; } } string key = this.ReadStringLiteral("Key"); this.SkipWhitespace(); if (this.HasReachedEnd) { break; } if (this.Peek() != ':') { throw new JsonParserException("Found '" + this.Peek() + "' but expected ':'", this.lineNumber, this.linePosition); } this.Accept(); this.SkipWhitespace(); if (this.HasReachedEnd) { break; } node[key] = this.ReadValue(); this.SkipWhitespace(); } throw new JsonParserException("Expected '}' but reached end of input.", this.lineNumber, this.linePosition); }
/// <summary> /// Create object node from a generic dictionary. /// </summary> /// <remarks> /// <para>Property values are cloned if they are already <see cref="JsonNode"/> /// instances.</para> /// </remarks> /// <typeparam name="TValue">Type of property value.</typeparam> /// <param name="dictionary">Input dictionary.</param> /// <returns> /// The new <see cref="JsonObjectNode"/> instance. /// </returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="dictionary"/> is <c>null</c>. /// </exception> /// <exception cref="System.Exception"> /// If error is encountered whilst creating object node. Errors are likely to /// occur when unable to convert property values into JSON nodes. /// </exception> public static JsonObjectNode FromDictionary <TValue>(IDictionary <string, TValue> dictionary) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } var node = new JsonObjectNode(); foreach (var property in dictionary) { node[property.Key] = ConvertFrom(property.Value); } return(node); }
/// <summary> /// Attempt to create JSON node representation from given input. /// </summary> /// <remarks> /// <para>This method uses type information from input to determine which type of /// nodes seem best suited. Common basic data types are supported along with /// objects, structures, lists, native arrays and even dictionaries. Dictionary /// support is limited to those with string type keys (<c>Dictionary<string, YourType>></c>).</para> /// <para>Input value is simply cloned if it is already a <see cref="JsonNode"/>.</para> /// </remarks> /// <example> /// <para>Create JSON object from a generic dictionary:</para> /// <code language="csharp"><![CDATA[ /// // Prepare an example data structure. /// var lookupTable = new Dictionary<string, int>(); /// lookupTable["Player"] = 42; /// lookupTable["Boss1"] = 72; /// lookupTable["Whale"] = 128; /// /// // Convert example data structure into a JSON object. /// var jsonObject = JsonNode.FromObject(lookupTable); /// /// // Read node from JSON object. /// var playerNode = jsonObject["Player"] as JsonLongNode; /// Debug.Log(playerNode.Value); // 42 /// ]]></code> /// <para>Once you have a node representation of your data you can then proceed /// to output this to a JSON encoded text file:</para> /// <code language="csharp"><![CDATA[ /// File.WriteAllText(outputPath, jsonObject.ToString()); /// ]]></code> /// <para>The resulting text file would then look something like this:</para> /// <code language="json"><![CDATA[ /// { /// "Player": 42, /// "Boss1": 72, /// "Whale": 128 /// } /// ]]></code> /// </example> /// <param name="value">Input value, array, collection, object instance, etc.</param> /// <returns> /// The new <see cref="JsonNode"/> instance; or a value of <c>null</c> if input /// was itself a value of <c>null</c>. /// </returns> /// <exception cref="System.Exception"> /// If a problem was encountered whilst attempting to create node representation /// from input value. /// </exception> /// <seealso cref="ConvertTo{T}()"/> /// <seealso cref="ConvertTo(Type)"/> public static JsonNode ConvertFrom(object value) { if (value == null) { return(null); } var valueNode = value as JsonNode; if (valueNode != null) { return(valueNode.Clone()); } var type = value.GetType(); var metaType = MetaType.FromType(type); switch (metaType.TargetNodeType) { case MetaType.NodeType.Integer: if (Type.GetTypeCode(type) == TypeCode.UInt64) { return(new JsonIntegerNode((long)Convert.ToUInt64(value, CultureInfo.InvariantCulture))); } else { return(new JsonIntegerNode(Convert.ToInt64(value, CultureInfo.InvariantCulture))); } case MetaType.NodeType.Double: return(new JsonDoubleNode(Convert.ToDouble(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.Boolean: return(new JsonBooleanNode(Convert.ToBoolean(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.String: return(new JsonStringNode(Convert.ToString(value, CultureInfo.InvariantCulture))); case MetaType.NodeType.Array: if (type.IsArray) { return(JsonArrayNode.FromArray((object[])value)); } else { return(JsonArrayNode.FromCollection((IEnumerable)value)); } case MetaType.NodeType.Object: if (metaType.IsDictionaryStyleCollection) { return(FromDictionaryStyleCollection((ICollection)value, metaType)); } else { return(JsonObjectNode.FromInstance(value)); } default: throw new InvalidOperationException("Was unable to convert input value."); } }