#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.ComponentModel; using System.Linq; using System.Text; using Newtonsoft.Json.Utilities; using System.Diagnostics; using System.Globalization; namespace Newtonsoft.Json.Linq { /// /// Represents a JSON property. /// public class JProperty : JContainer { private readonly string _name; /// /// Gets the property name. /// /// The property name. public string Name { [DebuggerStepThrough] get { return _name; } } /// /// Gets or sets the property value. /// /// The property value. public JToken Value { [DebuggerStepThrough] get { return Content; } set { CheckReentrancy(); JToken newValue = value ?? new JValue((object) null); if (Content == null) { newValue = EnsureParentToken(newValue); Content = newValue; Content.Parent = this; Content.Next = Content; } else { Content.Replace(newValue); } } } internal override void ReplaceItem(JToken existing, JToken replacement) { if (IsTokenUnchanged(existing, replacement)) return; if (Parent != null) ((JObject)Parent).InternalPropertyChanging(this); base.ReplaceItem(existing, replacement); if (Parent != null) ((JObject)Parent).InternalPropertyChanged(this); } /// /// Initializes a new instance of the class from another object. /// /// A object to copy from. public JProperty(JProperty other) : base(other) { _name = other.Name; } internal override void AddItem(bool isLast, JToken previous, JToken item) { if (Value != null) throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); Value = item; } internal override JToken GetItem(int index) { if (index != 0) throw new ArgumentOutOfRangeException(); return Value; } internal override void SetItem(int index, JToken item) { if (index != 0) throw new ArgumentOutOfRangeException(); Value = item; } internal override bool RemoveItem(JToken item) { throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); } internal override void RemoveItemAt(int index) { throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); } internal override void InsertItem(int index, JToken item) { throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); } internal override bool ContainsItem(JToken item) { return (Value == item); } internal override void ClearItems() { throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); } /// /// Returns a collection of the child tokens of this token, in document order. /// /// /// An of containing the child tokens of this , in document order. /// public override JEnumerable Children() { return new JEnumerable(ChildrenInternal()); } private IEnumerable ChildrenInternal() { yield return Value; } internal override bool DeepEquals(JToken node) { JProperty t = node as JProperty; return (t != null && _name == t.Name && ContentsEqual(t)); } internal override JToken CloneToken() { return new JProperty(this); } /// /// Gets the node type for this . /// /// The type. public override JTokenType Type { [DebuggerStepThrough] get { return JTokenType.Property; } } internal JProperty(string name) { // called from JTokenWriter ValidationUtils.ArgumentNotNull(name, "name"); _name = name; } /// /// Initializes a new instance of the class. /// /// The property name. /// The property content. public JProperty(string name, params object[] content) : this(name, (object)content) { } /// /// Initializes a new instance of the class. /// /// The property name. /// The property content. public JProperty(string name, object content) { ValidationUtils.ArgumentNotNull(name, "name"); _name = name; Value = IsMultiContent(content) ? new JArray(content) : CreateFromContent(content); } /// /// Writes this token to a . /// /// A into which this method will write. /// A collection of which will be used when writing the token. public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) { writer.WritePropertyName(_name); Value.WriteTo(writer, converters); } internal override int GetDeepHashCode() { return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0); } /// /// Loads an from a . /// /// A that will be read for the content of the . /// A that contains the JSON that was read from the specified . public static JProperty Load(JsonReader reader) { if (reader.TokenType == JsonToken.None) { if (!reader.Read()) throw new Exception("Error reading JProperty from JsonReader."); } if (reader.TokenType != JsonToken.PropertyName) throw new Exception( "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith( CultureInfo.InvariantCulture, reader.TokenType)); JProperty p = new JProperty((string)reader.Value); p.SetLineInfo(reader as IJsonLineInfo); if (!reader.Read()) throw new Exception("Error reading JProperty from JsonReader."); p.ReadContentFrom(reader); return p; } } }