JToken.cs :  » Development » Json.NET » Newtonsoft » Json » Linq » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » Json.NET 
Json.NET » Newtonsoft » Json » Linq » JToken.cs
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json.Utilities;
using System.Diagnostics;
using System.Globalization;
using System.Collections;
using System.ComponentModel;

namespace Newtonsoft.Json.Linq{
  /// <summary>
  /// Represents an abstract JSON token.
  /// </summary>
  public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
  {
    private JContainer _parent;
    internal JToken _next;
    private static JTokenEqualityComparer _equalityComparer;

    private int? _lineNumber;
    private int? _linePosition;

    /// <summary>
    /// Gets a comparer that can compare two tokens for value equality.
    /// </summary>
    /// <value>A <see cref="JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
    public static JTokenEqualityComparer EqualityComparer
    {
      get
      {
        if (_equalityComparer == null)
          _equalityComparer = new JTokenEqualityComparer();

        return _equalityComparer;
      }
    }

    /// <summary>
    /// Gets or sets the parent.
    /// </summary>
    /// <value>The parent.</value>
    public JContainer Parent
    {
      [DebuggerStepThrough]
      get { return _parent; }
      internal set { _parent = value; }
    }

    /// <summary>
    /// Gets the root <see cref="JToken"/> of this <see cref="JToken"/>.
    /// </summary>
    /// <value>The root <see cref="JToken"/> of this <see cref="JToken"/>.</value>
    public JToken Root
    {
      get
      {
        JContainer parent = Parent;
        if (parent == null)
          return this;

        while (parent.Parent != null)
        {
          parent = parent.Parent;
        }

        return parent;
      }
    }

    internal abstract JToken CloneToken();
    internal abstract bool DeepEquals(JToken node);

    /// <summary>
    /// Gets the node type for this <see cref="JToken"/>.
    /// </summary>
    /// <value>The type.</value>
    public abstract JTokenType Type { get; }

    /// <summary>
    /// Gets a value indicating whether this token has childen tokens.
    /// </summary>
    /// <value>
    ///   <c>true</c> if this token has child values; otherwise, <c>false</c>.
    /// </value>
    public abstract bool HasValues { get; }

    /// <summary>
    /// Compares the values of two tokens, including the values of all descendant tokens.
    /// </summary>
    /// <param name="t1">The first <see cref="JToken"/> to compare.</param>
    /// <param name="t2">The second <see cref="JToken"/> to compare.</param>
    /// <returns>true if the tokens are equal; otherwise false.</returns>
    public static bool DeepEquals(JToken t1, JToken t2)
    {
      return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
    }

    /// <summary>
    /// Gets the next sibling token of this node.
    /// </summary>
    /// <value>The <see cref="JToken"/> that contains the next sibling token.</value>
    public JToken Next
    {
      get
      {
        if (_parent != null && _next != _parent.First)
          return _next;

        return null;
      }
      internal set { _next = value; }
    }

    /// <summary>
    /// Gets the previous sibling token of this node.
    /// </summary>
    /// <value>The <see cref="JToken"/> that contains the previous sibling token.</value>
    public JToken Previous
    {
      get
      {
        if (_parent == null)
          return null;

        JToken parentNext = _parent.Content._next;
        JToken parentNextBefore = null;
        while (parentNext != this)
        {
          parentNextBefore = parentNext;
          parentNext = parentNext.Next;
        }
        return parentNextBefore;
      }
    }

    internal JToken()
    {
    }

    /// <summary>
    /// Adds the specified content immediately after this token.
    /// </summary>
    /// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
    public void AddAfterSelf(object content)
    {
      if (_parent == null)
        throw new InvalidOperationException("The parent is missing.");

      _parent.AddInternal((Next == null), this, content);
    }

    /// <summary>
    /// Adds the specified content immediately before this token.
    /// </summary>
    /// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
    public void AddBeforeSelf(object content)
    {
      if (_parent == null)
        throw new InvalidOperationException("The parent is missing.");

      JToken previous = Previous;
      if (previous == null)
        previous = _parent.Last;

      _parent.AddInternal(false, previous, content);
    }

    /// <summary>
    /// Returns a collection of the ancestor tokens of this token.
    /// </summary>
    /// <returns>A collection of the ancestor tokens of this token.</returns>
    public IEnumerable<JToken> Ancestors()
    {
      for (JToken parent = Parent; parent != null; parent = parent.Parent)
      {
        yield return parent;
      }
    }

    /// <summary>
    /// Returns a collection of the sibling tokens after this token, in document order.
    /// </summary>
    /// <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
    public IEnumerable<JToken> AfterSelf()
    {
      if (Parent == null)
        yield break;

      for (JToken o = Next; o != null; o = o.Next)
        yield return o;
    }

    /// <summary>
    /// Returns a collection of the sibling tokens before this token, in document order.
    /// </summary>
    /// <returns>A collection of the sibling tokens before this token, in document order.</returns>
    public IEnumerable<JToken> BeforeSelf()
    {
      for (JToken o = Parent.First; o != this; o = o.Next)
        yield return o;
    }

    /// <summary>
    /// Gets the <see cref="JToken"/> with the specified key.
    /// </summary>
    /// <value>The <see cref="JToken"/> with the specified key.</value>
    public virtual JToken this[object key]
    {
      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
      set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
    }

    /// <summary>
    /// Gets the <see cref="JToken"/> with the specified key converted to the specified type.
    /// </summary>
    /// <typeparam name="T">The type to convert the token to.</typeparam>
    /// <param name="key">The token key.</param>
    /// <returns>The converted token value.</returns>
    public virtual T Value<T>(object key)
    {
      JToken token = this[key];

      return Extensions.Convert<JToken, T>(token);
    }

    /// <summary>
    /// Get the first child token of this token.
    /// </summary>
    /// <value>A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.</value>
    public virtual JToken First
    {
      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
    }

    /// <summary>
    /// Get the last child token of this token.
    /// </summary>
    /// <value>A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.</value>
    public virtual JToken Last
    {
      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
    }

    /// <summary>
    /// Returns a collection of the child tokens of this token, in document order.
    /// </summary>
    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
    public virtual JEnumerable<JToken> Children()
    {
      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
    }

    /// <summary>
    /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
    /// </summary>
    /// <typeparam name="T">The type to filter the child tokens on.</typeparam>
    /// <returns>A <see cref="JEnumerable{T}"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
    public JEnumerable<T> Children<T>() where T : JToken
    {
      return new JEnumerable<T>(Children().OfType<T>());
    }

    /// <summary>
    /// Returns a collection of the child values of this token, in document order.
    /// </summary>
    /// <typeparam name="T">The type to convert the values to.</typeparam>
    /// <returns>A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.</returns>
    public virtual IEnumerable<T> Values<T>()
    {
      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
    }

    /// <summary>
    /// Removes this token from its parent.
    /// </summary>
    public void Remove()
    {
      if (_parent == null)
        throw new InvalidOperationException("The parent is missing.");

      _parent.RemoveItem(this);
    }

    /// <summary>
    /// Replaces this token with the specified token.
    /// </summary>
    /// <param name="value">The value.</param>
    public void Replace(JToken value)
    {
      if (_parent == null)
        throw new InvalidOperationException("The parent is missing.");

      _parent.ReplaceItem(this, value);
    }

    /// <summary>
    /// Writes this token to a <see cref="JsonWriter"/>.
    /// </summary>
    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
    public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);

    /// <summary>
    /// Returns the indented JSON for this token.
    /// </summary>
    /// <returns>
    /// The indented JSON for this token.
    /// </returns>
    public override string ToString()
    {
      return ToString(Formatting.Indented);
    }

    /// <summary>
    /// Returns the JSON for this token using the given formatting and converters.
    /// </summary>
    /// <param name="formatting">Indicates how the output is formatted.</param>
    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
    /// <returns>The JSON for this token using the given formatting and converters.</returns>
    public string ToString(Formatting formatting, params JsonConverter[] converters)
    {
      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
      {
        JsonTextWriter jw = new JsonTextWriter(sw);
        jw.Formatting = formatting;

        WriteTo(jw, converters);

        return sw.ToString();
      }
    }

    private static JValue EnsureValue(JToken value)
    {
      if (value == null)
        throw new ArgumentNullException("value");

      if (value is JProperty)
        value = ((JProperty)value).Value;

      JValue v = value as JValue;

      return v;
    }

    private static string GetType(JToken token)
    {
      ValidationUtils.ArgumentNotNull(token, "token");

      if (token is JProperty)
        token = ((JProperty)token).Value;

      return token.Type.ToString();
    }

    private static bool IsNullable(JToken o)
    {
      return (o.Type == JTokenType.Undefined || o.Type == JTokenType.Null);
    }

    private static bool ValidateFloat(JToken o, bool nullable)
    {
      return (o.Type == JTokenType.Float || o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
    }

    private static bool ValidateInteger(JToken o, bool nullable)
    {
      return (o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
    }

    private static bool ValidateDate(JToken o, bool nullable)
    {
      return (o.Type == JTokenType.Date || (nullable && IsNullable(o)));
    }

    private static bool ValidateBoolean(JToken o, bool nullable)
    {
      return (o.Type == JTokenType.Boolean || (nullable && IsNullable(o)));
    }

    private static bool ValidateString(JToken o)
    {
      return (o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o));
    }

    private static bool ValidateBytes(JToken o)
    {
      return (o.Type == JTokenType.Bytes || IsNullable(o));
    }

    #region Cast from operators
    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Boolean"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator bool(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateBoolean(v, false))
        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (bool)v.Value;
    }

#if !PocketPC && !NET20
    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator DateTimeOffset(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateDate(v, false))
        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (DateTimeOffset)v.Value;
    }
#endif

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator bool?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateBoolean(v, true))
        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (bool?)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int64"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator long(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, false))
        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (long)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTime}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator DateTime?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateDate(v, true))
        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (DateTime?)v.Value;
    }

#if !PocketPC && !NET20
    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator DateTimeOffset?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateDate(v, true))
        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (DateTimeOffset?)v.Value;
    }
#endif

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator decimal?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, true))
        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Double}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator double?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, true))
        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (double?)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int32"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator int(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, false))
        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator int?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, true))
        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator DateTime(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateDate(v, false))
        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (DateTime)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int64}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator long?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, true))
        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (long?)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Single}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator float?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, true))
        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Decimal"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator decimal(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, false))
        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt32}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    [CLSCompliant(false)]
    public static explicit operator uint?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, true))
        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (uint?)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt64}"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    [CLSCompliant(false)]
    public static explicit operator ulong?(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, true))
        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (ulong?)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Double"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator double(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, false))
        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (double)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Single"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator float(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateFloat(v, false))
        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.String"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator string(JToken value)
    {
      if (value == null)
        return null;

      JValue v = EnsureValue(value);
      if (v == null || !ValidateString(v))
        throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (string)v.Value;
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt32"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    [CLSCompliant(false)]
    public static explicit operator uint(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, false))
        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt64"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    [CLSCompliant(false)]
    public static explicit operator ulong(JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateInteger(v, false))
        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The result of the conversion.</returns>
    public static explicit operator byte[](JToken value)
    {
      JValue v = EnsureValue(value);
      if (v == null || !ValidateBytes(v))
        throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));

      return (byte[])v.Value;
    }
    #endregion

    #region Cast to operators
    /// <summary>
    /// Performs an implicit conversion from <see cref="Boolean"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(bool value)
    {
      return new JValue(value);
    }

#if !PocketPC && !NET20
    /// <summary>
    /// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(DateTimeOffset value)
    {
      return new JValue(value);
    }
#endif

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(bool? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(long value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{DateTime}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(DateTime? value)
    {
      return new JValue(value);
    }

#if !PocketPC && !NET20
    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(DateTimeOffset? value)
    {
      return new JValue(value);
    }
#endif

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(decimal? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Double}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(double? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(ushort value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Int32"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(int value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Int32}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(int? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="DateTime"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(DateTime value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(long? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{Single}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(float? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Decimal"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(decimal value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(ushort? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{UInt32}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(uint? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Nullable{UInt64}"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(ulong? value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Double"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(double value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="Single"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(float value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="String"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(string value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="UInt32"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(uint value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="UInt64"/> to <see cref="JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    [CLSCompliant(false)]
    public static implicit operator JToken(ulong value)
    {
      return new JValue(value);
    }

    /// <summary>
    /// Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
    /// </summary>
    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
    public static implicit operator JToken(byte[] value)
    {
      return new JValue(value);
    }
    #endregion

    IEnumerator IEnumerable.GetEnumerator()
    {
      return ((IEnumerable<JToken>)this).GetEnumerator();
    }

    IEnumerator<JToken> IEnumerable<JToken>.GetEnumerator()
    {
      return Children().GetEnumerator();
    }

    internal abstract int GetDeepHashCode();

    IJEnumerable<JToken> IJEnumerable<JToken>.this[object key]
    {
      get { return this[key]; }
    }

    /// <summary>
    /// Creates an <see cref="JsonReader"/> for this token.
    /// </summary>
    /// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
    public JsonReader CreateReader()
    {
      return new JTokenReader(this);
    }

    internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
    {
      ValidationUtils.ArgumentNotNull(o, "o");
      ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");

      JToken token;
      using (JTokenWriter jsonWriter = new JTokenWriter())
      {
        jsonSerializer.Serialize(jsonWriter, o);
        token = jsonWriter.Token;
      }

      return token;
    }

    /// <summary>
    /// Creates a <see cref="JToken"/> from an object.
    /// </summary>
    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
    public static JToken FromObject(object o)
    {
      return FromObjectInternal(o, new JsonSerializer());
    }

    /// <summary>
    /// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
    /// </summary>
    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
    public static JToken FromObject(object o, JsonSerializer jsonSerializer)
    {
      return FromObjectInternal(o, jsonSerializer);
    }

    /// <summary>
    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
    /// </summary>
    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
    /// <returns>
    /// An <see cref="JToken"/> that contains the token and its descendant tokens
    /// that were read from the reader. The runtime type of the token is determined
    /// by the token type of the first token encountered in the reader.
    /// </returns>
    public static JToken ReadFrom(JsonReader reader)
    {
      ValidationUtils.ArgumentNotNull(reader, "reader");

      if (reader.TokenType == JsonToken.None)
      {
        if (!reader.Read())
          throw new Exception("Error reading JToken from JsonReader.");
      }

      if (reader.TokenType == JsonToken.StartObject)
        return JObject.Load(reader);

      if (reader.TokenType == JsonToken.StartArray)
        return JArray.Load(reader);

      if (reader.TokenType == JsonToken.PropertyName)
        return JProperty.Load(reader);

      if (reader.TokenType == JsonToken.StartConstructor)
        return JConstructor.Load(reader);

      // hack. change to look at TokenType rather than using value
      if (!JsonReader.IsStartToken(reader.TokenType))
        return new JValue(reader.Value);

      // TODO: loading constructor and parameters?
      throw new Exception("Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
    }

    internal void SetLineInfo(IJsonLineInfo lineInfo)
    {
      if (lineInfo == null || !lineInfo.HasLineInfo())
        return;

      SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
    }

    internal void SetLineInfo(int lineNumber, int linePosition)
    {
      _lineNumber = lineNumber;
      _linePosition = linePosition;
    }

    bool IJsonLineInfo.HasLineInfo()
    {
      return (_lineNumber != null && _linePosition != null);
    }

    int IJsonLineInfo.LineNumber
    {
      get { return _lineNumber ?? 0; }
    }

    int IJsonLineInfo.LinePosition
    {
      get { return _linePosition ?? 0; }
    }

    /// <summary>
    /// Selects the token that matches the object path.
    /// </summary>
    /// <param name="path">
    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
    /// to be returned. This must be a string of property names or array indexes separated
    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
    /// </param>
    /// <returns>The <see cref="JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
    public JToken SelectToken(string path)
    {
      return SelectToken(path, false);
    }

    /// <summary>
    /// Selects the token that matches the object path.
    /// </summary>
    /// <param name="path">
    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
    /// to be returned. This must be a string of property names or array indexes separated
    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
    /// </param>
    /// <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
    /// <returns>The <see cref="JToken"/> that matches the object path.</returns>
    public JToken SelectToken(string path, bool errorWhenNoMatch)
    {
      JPath p = new JPath(path);
      return p.Evaluate(this, errorWhenNoMatch);
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.