#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; using System.Collections.Generic; using LC.Newtonsoft.Json.Utilities; using System.IO; using System.Globalization; namespace LC.Newtonsoft.Json.Linq { /// /// Represents a JSON array. /// /// /// /// public partial class JArray : JContainer, IList { private readonly List _values = new List(); /// /// Gets the container's children tokens. /// /// The container's children tokens. protected override IList ChildrenTokens => _values; /// /// Gets the node type for this . /// /// The type. public override JTokenType Type => JTokenType.Array; /// /// Initializes a new instance of the class. /// public JArray() { } /// /// Initializes a new instance of the class from another object. /// /// A object to copy from. public JArray(JArray other) : base(other) { } /// /// Initializes a new instance of the class with the specified content. /// /// The contents of the array. public JArray(params object[] content) : this((object)content) { } /// /// Initializes a new instance of the class with the specified content. /// /// The contents of the array. public JArray(object content) { Add(content); } internal override bool DeepEquals(JToken node) { return (node is JArray t && ContentsEqual(t)); } internal override JToken CloneToken() { return new JArray(this); } /// /// 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 new static JArray Load(JsonReader reader) { return Load(reader, null); } /// /// Loads an from a . /// /// A that will be read for the content of the . /// The used to load the JSON. /// If this is null, default load settings will be used. /// A that contains the JSON that was read from the specified . public new static JArray Load(JsonReader reader, JsonLoadSettings settings) { if (reader.TokenType == JsonToken.None) { if (!reader.Read()) { throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader."); } } reader.MoveToContent(); if (reader.TokenType != JsonToken.StartArray) { throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } JArray a = new JArray(); a.SetLineInfo(reader as IJsonLineInfo, settings); a.ReadTokenFrom(reader, settings); return a; } /// /// Load a from a string that contains JSON. /// /// A that contains JSON. /// A populated from the string that contains JSON. /// /// /// public new static JArray Parse(string json) { return Parse(json, null); } /// /// Load a from a string that contains JSON. /// /// A that contains JSON. /// The used to load the JSON. /// If this is null, default load settings will be used. /// A populated from the string that contains JSON. /// /// /// public new static JArray Parse(string json, JsonLoadSettings settings) { using (JsonReader reader = new JsonTextReader(new StringReader(json))) { JArray a = Load(reader, settings); while (reader.Read()) { // Any content encountered here other than a comment will throw in the reader. } return a; } } /// /// Creates a from an object. /// /// The object that will be used to create . /// A with the values of the specified object. public new static JArray FromObject(object o) { return FromObject(o, JsonSerializer.CreateDefault()); } /// /// Creates a from an object. /// /// The object that will be used to create . /// The that will be used to read the object. /// A with the values of the specified object. public new static JArray FromObject(object o, JsonSerializer jsonSerializer) { JToken token = FromObjectInternal(o, jsonSerializer); if (token.Type != JTokenType.Array) { throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type)); } return (JArray)token; } /// /// 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.WriteStartArray(); for (int i = 0; i < _values.Count; i++) { _values[i].WriteTo(writer, converters); } writer.WriteEndArray(); } /// /// Gets the with the specified key. /// /// The with the specified key. public override JToken this[object key] { get { ValidationUtils.ArgumentNotNull(key, nameof(key)); if (!(key is int)) { throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Int32 array index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); } return GetItem((int)key); } set { ValidationUtils.ArgumentNotNull(key, nameof(key)); if (!(key is int)) { throw new ArgumentException("Set JArray values with invalid key value: {0}. Int32 array index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); } SetItem((int)key, value); } } /// /// Gets or sets the at the specified index. /// /// public JToken this[int index] { get => GetItem(index); set => SetItem(index, value); } internal override int IndexOfItem(JToken item) { return _values.IndexOfReference(item); } internal override void MergeItem(object content, JsonMergeSettings settings) { IEnumerable a = (IsMultiContent(content) || content is JArray) ? (IEnumerable)content : null; if (a == null) { return; } MergeEnumerableContent(this, a, settings); } #region IList Members /// /// Determines the index of a specific item in the . /// /// The object to locate in the . /// /// The index of if found in the list; otherwise, -1. /// public int IndexOf(JToken item) { return IndexOfItem(item); } /// /// Inserts an item to the at the specified index. /// /// The zero-based index at which should be inserted. /// The object to insert into the . /// /// is not a valid index in the . /// public void Insert(int index, JToken item) { InsertItem(index, item, false); } /// /// Removes the item at the specified index. /// /// The zero-based index of the item to remove. /// /// is not a valid index in the . /// public void RemoveAt(int index) { RemoveItemAt(index); } /// /// Returns an enumerator that iterates through the collection. /// /// /// A of that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { return Children().GetEnumerator(); } #endregion #region ICollection Members /// /// Adds an item to the . /// /// The object to add to the . public void Add(JToken item) { Add((object)item); } /// /// Removes all items from the . /// public void Clear() { ClearItems(); } /// /// Determines whether the contains a specific value. /// /// The object to locate in the . /// /// true if is found in the ; otherwise, false. /// public bool Contains(JToken item) { return ContainsItem(item); } /// /// Copies the elements of the to an array, starting at a particular array index. /// /// The array. /// Index of the array. public void CopyTo(JToken[] array, int arrayIndex) { CopyItemsTo(array, arrayIndex); } /// /// Gets a value indicating whether the is read-only. /// /// true if the is read-only; otherwise, false. public bool IsReadOnly => false; /// /// Removes the first occurrence of a specific object from the . /// /// The object to remove from the . /// /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// public bool Remove(JToken item) { return RemoveItem(item); } #endregion internal override int GetDeepHashCode() { return ContentsHashCode(); } } }