/// <summary> /// Gets the value of the element as a <see cref="bool"/>. /// </summary> /// <remarks> /// This method does not parse the contents of a JSON string value. /// </remarks> /// <returns>The value of the element as a <see cref="bool"/>.</returns> /// <exception cref="InvalidOperationException"> /// This value's <see cref="Type"/> is neither <see cref="JsonValueType.True"/> or /// <see cref="JsonValueType.False"/>. /// </exception> /// <exception cref="ObjectDisposedException"> /// The parent <see cref="JsonDocument"/> has been disposed. /// </exception> public bool GetBoolean() { // CheckValidInstance is redundant. Asking for the type will // return None, which then throws the same exception in the return statement. JsonTokenType type = TokenType; return (type == JsonTokenType.True ? true : type == JsonTokenType.False ? false : throw ThrowHelper.GetJsonElementWrongTypeException(nameof(Boolean), type)); }
/// <summary> /// Get an enumerator to enumerate the properties in the JSON object represented by this JsonElement. /// </summary> /// <returns> /// An enumerator to enumerate the properties in the JSON object represented by this JsonElement. /// </returns> /// <exception cref="InvalidOperationException"> /// This value's <see cref="Type"/> is not <see cref="JsonValueType.Object"/>. /// </exception> /// <exception cref="ObjectDisposedException"> /// The parent <see cref="JsonDocument"/> has been disposed. /// </exception> public ObjectEnumerator EnumerateObject() { CheckValidInstance(); JsonTokenType tokenType = TokenType; if (tokenType != JsonTokenType.StartObject) { throw ThrowHelper.GetJsonElementWrongTypeException(JsonTokenType.StartObject, tokenType); } return(new ObjectEnumerator(this)); }
/// <summary> /// Get an enumerator to enumerate the values in the JSON array represented by this JsonElement. /// </summary> /// <returns> /// An enumerator to enumerate the values in the JSON array represented by this JsonElement. /// </returns> /// <exception cref="InvalidOperationException"> /// This value's <see cref="Type"/> is not <see cref="JsonValueType.Array"/>. /// </exception> /// <exception cref="ObjectDisposedException"> /// The parent <see cref="JsonDocument"/> has been disposed. /// </exception> public ArrayEnumerator EnumerateArray() { CheckValidInstance(); JsonTokenType tokenType = TokenType; if (tokenType != JsonTokenType.StartArray) { throw ThrowHelper.GetJsonElementWrongTypeException(JsonTokenType.StartArray, tokenType); } return(new ArrayEnumerator(this)); }
/// <summary> /// Performs a deep copy operation on <paramref name="jsonElement"/> returning corresponding modifiable tree structure of JSON nodes. /// Operations performed on returned <see cref="JsonNode"/> does not modify <paramref name="jsonElement"/>. /// </summary> /// <param name="jsonElement"><see cref="JsonElement"/> to copy.</param> /// <returns><see cref="JsonNode"/> representing <paramref name="jsonElement"/>.</returns> public static JsonNode DeepCopy(JsonElement jsonElement) { if (!jsonElement.IsImmutable) { return(GetNode(jsonElement).Clone()); } switch (jsonElement.ValueKind) { case JsonValueKind.Object: JsonObject jsonObject = new JsonObject(); foreach (JsonProperty property in jsonElement.EnumerateObject()) { jsonObject.Add(property.Name, DeepCopy(property.Value)); } return(jsonObject); case JsonValueKind.Array: JsonArray jsonArray = new JsonArray(); foreach (JsonElement element in jsonElement.EnumerateArray()) { jsonArray.Add(DeepCopy(element)); } return(jsonArray); case JsonValueKind.Number: return(new JsonNumber(jsonElement.GetRawText())); case JsonValueKind.String: return(new JsonString(jsonElement.GetString())); case JsonValueKind.True: return(new JsonBoolean(true)); case JsonValueKind.False: return(new JsonBoolean(false)); case JsonValueKind.Null: return(null); default: Debug.Assert(jsonElement.ValueKind == JsonValueKind.Undefined, "No handler for JsonValueKind.{jsonElement.ValueKind}"); throw ThrowHelper.GetJsonElementWrongTypeException(JsonValueKind.Undefined, jsonElement.ValueKind); } }
/// <summary> /// Performs a deep copy operation on <paramref name="jsonElement"/> returning corresponding modifiable tree structure of JSON nodes. /// Operations performed on returned <see cref="JsonNode"/> does not modify <paramref name="jsonElement"/>. /// </summary> /// <param name="jsonElement"><see cref="JsonElement"/> to copy.</param> /// <returns><see cref="JsonNode"/> representing <paramref name="jsonElement"/>.</returns> public static JsonNode DeepCopy(JsonElement jsonElement) { if (!jsonElement.IsImmutable) { return(GetNode(jsonElement).Clone()); } // Iterative DFS: var currentNodes = new Stack <KeyValuePair <string, JsonNode> >(); // objects/arrays currently being created var recursionStack = new Stack <KeyValuePair <string, JsonElement?> >(); // null JsonElement represents end of current object/array JsonNode toReturn = null; recursionStack.Push(new KeyValuePair <string, JsonElement?>(null, jsonElement)); while (recursionStack.Any()) { KeyValuePair <string, JsonElement?> currentPair = recursionStack.Peek(); JsonElement?currentJsonElement = currentPair.Value; recursionStack.Pop(); if (!currentJsonElement.HasValue) { // Current object/array is finished and can be added to its parent: KeyValuePair <string, JsonNode> nodePair = currentNodes.Peek(); currentNodes.Pop(); Debug.Assert(nodePair.Value is JsonArray || nodePair.Value is JsonObject); AddToParent(nodePair, ref currentNodes, ref toReturn); continue; } switch (currentJsonElement.Value.ValueKind) { case JsonValueKind.Object: var jsonObject = new JsonObject(); // Add jsonObject to current nodes: currentNodes.Push(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonObject)); // Add end of object marker: recursionStack.Push(new KeyValuePair <string, JsonElement?>(null, null)); // Add properties to recursion stack. Reverse enumerator to keep properties order: foreach (JsonProperty property in currentJsonElement.Value.EnumerateObject().Reverse()) { recursionStack.Push(new KeyValuePair <string, JsonElement?>(property.Name, property.Value)); } break; case JsonValueKind.Array: var jsonArray = new JsonArray(); // Add jsonArray to current nodes: currentNodes.Push(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonArray)); // Add end of array marker: recursionStack.Push(new KeyValuePair <string, JsonElement?>(null, null)); // Add elements to recursion stack. Reverse enumerator to keep items order: foreach (JsonElement element in currentJsonElement.Value.EnumerateArray().Reverse()) { recursionStack.Push(new KeyValuePair <string, JsonElement?>(null, element)); } break; case JsonValueKind.Number: var jsonNumber = new JsonNumber(currentJsonElement.Value.GetRawText()); AddToParent(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonNumber), ref currentNodes, ref toReturn); break; case JsonValueKind.String: var jsonString = new JsonString(currentJsonElement.Value.GetString()); AddToParent(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonString), ref currentNodes, ref toReturn); break; case JsonValueKind.True: var jsonBooleanTrue = new JsonBoolean(true); AddToParent(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonBooleanTrue), ref currentNodes, ref toReturn); break; case JsonValueKind.False: var jsonBooleanFalse = new JsonBoolean(false); AddToParent(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonBooleanFalse), ref currentNodes, ref toReturn); break; case JsonValueKind.Null: var jsonNull = new JsonNull(); AddToParent(new KeyValuePair <string, JsonNode>(currentPair.Key, jsonNull), ref currentNodes, ref toReturn); break; default: Debug.Assert(jsonElement.ValueKind == JsonValueKind.Undefined, "No handler for JsonValueKind.{jsonElement.ValueKind}"); throw ThrowHelper.GetJsonElementWrongTypeException(JsonValueKind.Undefined, jsonElement.ValueKind); } } Debug.Assert(toReturn != null); return(toReturn); }