/// <summary> /// Reads a JSON array containing zero-or-more values. /// </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 ReadArray() { this.Accept(); this.SkipWhitespace(); var node = new JsonArrayNode(); 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; } } node.Add(this.ReadValue()); this.SkipWhitespace(); } throw new JsonParserException("Expected ']' but reached end of input.", this.lineNumber, this.linePosition); }
/// <summary> /// Create array node and populate from a native array of values. /// </summary> /// <remarks> /// <para>Array elements are cloned if they are already <see cref="JsonNode"/> /// instances.</para> /// </remarks> /// <typeparam name="T">Type of array elements.</typeparam> /// <param name="array">Native array of objects.</param> /// <returns> /// New <see cref="JsonArrayNode"/> instance containing zero or more nodes. /// </returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="array"/> is <c>null</c>. /// </exception> public static JsonArrayNode FromArray <T>(T[] array) { if (array == null) { throw new ArgumentNullException("array"); } var node = new JsonArrayNode(); foreach (T element in array) { node.Add(ConvertFrom(element)); } return(node); }
/// <summary> /// Create array node and populate from a collection of values. /// </summary> /// <remarks> /// <para>Collection entries are cloned if they are already <see cref="JsonNode"/> /// instances.</para> /// </remarks> /// <param name="collection">The collection.</param> /// <returns> /// New <see cref="JsonArrayNode"/> instance containing zero or more nodes. /// </returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="collection"/> is <c>null</c>. /// </exception> public static JsonArrayNode FromCollection(IEnumerable collection) { if (collection == null) { throw new ArgumentNullException("collection"); } var node = new JsonArrayNode(); foreach (var element in collection) { node.Add(ConvertFrom(element)); } return(node); }
/// <inheritdoc/> public override JsonNode Clone() { var clone = new JsonArrayNode(); foreach (var node in this.nodes) { if (node != null) { clone.Add(node.Clone()); } else { clone.Add(null); } } return(clone); }
/// <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."); } }