/// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
        }
예제 #6
0
        /// <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&lt;string, YourType&gt;></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.");
            }
        }