mirror of https://github.com/icsharpcode/ILSpy.git
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							769 lines
						
					
					
						
							19 KiB
						
					
					
				
			
		
		
	
	
							769 lines
						
					
					
						
							19 KiB
						
					
					
				// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | 
						|
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. | 
						|
 | 
						|
namespace LightJson | 
						|
{ | 
						|
	using System; | 
						|
	using System.Collections.Generic; | 
						|
	using System.Diagnostics; | 
						|
	using System.Diagnostics.CodeAnalysis; | 
						|
	using System.Globalization; | 
						|
	using LightJson.Serialization; | 
						|
 | 
						|
	/// <summary> | 
						|
	/// A wrapper object that contains a valid JSON value. | 
						|
	/// </summary> | 
						|
	[DebuggerDisplay("{ToString(),nq}", Type = "JsonValue({Type})")] | 
						|
	[DebuggerTypeProxy(typeof(JsonValueDebugView))] | 
						|
	internal struct JsonValue | 
						|
	{ | 
						|
		/// <summary> | 
						|
		/// Represents a null JsonValue. | 
						|
		/// </summary> | 
						|
		public static readonly JsonValue Null = new JsonValue(JsonValueType.Null, default(double), null); | 
						|
 | 
						|
		private readonly JsonValueType type; | 
						|
		private readonly object reference; | 
						|
		private readonly double value; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct, representing a Boolean value. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be wrapped.</param> | 
						|
		public JsonValue(bool? value) | 
						|
		{ | 
						|
			if (value.HasValue) { | 
						|
				this.reference = null; | 
						|
 | 
						|
				this.type = JsonValueType.Boolean; | 
						|
 | 
						|
				this.value = value.Value ? 1 : 0; | 
						|
			} else { | 
						|
				this = JsonValue.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct, representing a Number value. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be wrapped.</param> | 
						|
		public JsonValue(double? value) | 
						|
		{ | 
						|
			if (value.HasValue) { | 
						|
				this.reference = null; | 
						|
 | 
						|
				this.type = JsonValueType.Number; | 
						|
 | 
						|
				this.value = value.Value; | 
						|
			} else { | 
						|
				this = JsonValue.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct, representing a String value. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be wrapped.</param> | 
						|
		public JsonValue(string value) | 
						|
		{ | 
						|
			if (value != null) { | 
						|
				this.value = default(double); | 
						|
 | 
						|
				this.type = JsonValueType.String; | 
						|
 | 
						|
				this.reference = value; | 
						|
			} else { | 
						|
				this = JsonValue.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct, representing a JsonObject. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be wrapped.</param> | 
						|
		public JsonValue(JsonObject value) | 
						|
		{ | 
						|
			if (value != null) { | 
						|
				this.value = default(double); | 
						|
 | 
						|
				this.type = JsonValueType.Object; | 
						|
 | 
						|
				this.reference = value; | 
						|
			} else { | 
						|
				this = JsonValue.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct, representing a Array reference value. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be wrapped.</param> | 
						|
		public JsonValue(JsonArray value) | 
						|
		{ | 
						|
			if (value != null) { | 
						|
				this.value = default(double); | 
						|
 | 
						|
				this.type = JsonValueType.Array; | 
						|
 | 
						|
				this.reference = value; | 
						|
			} else { | 
						|
				this = JsonValue.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Initializes a new instance of the <see cref="JsonValue"/> struct. | 
						|
		/// </summary> | 
						|
		/// <param name="type">The Json type of the JsonValue.</param> | 
						|
		/// <param name="value"> | 
						|
		/// The internal value of the JsonValue. | 
						|
		/// This is used when the Json type is Number or Boolean. | 
						|
		/// </param> | 
						|
		/// <param name="reference"> | 
						|
		/// The internal value reference of the JsonValue. | 
						|
		/// This value is used when the Json type is String, JsonObject, or JsonArray. | 
						|
		/// </param> | 
						|
		private JsonValue(JsonValueType type, double value, object reference) | 
						|
		{ | 
						|
			this.type = type; | 
						|
			this.value = value; | 
						|
			this.reference = reference; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets the type of this JsonValue. | 
						|
		/// </summary> | 
						|
		/// <value>The type of this JsonValue.</value> | 
						|
		public JsonValueType Type { | 
						|
			get { | 
						|
				return this.type; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is Null. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is Null.</value> | 
						|
		public bool IsNull { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.Null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is a Boolean. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is a Boolean.</value> | 
						|
		public bool IsBoolean { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.Boolean; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is an Integer. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is an Integer.</value> | 
						|
		public bool IsInteger { | 
						|
			get { | 
						|
				if (!this.IsNumber) { | 
						|
					return false; | 
						|
				} | 
						|
 | 
						|
				var value = this.value; | 
						|
				return unchecked((int)value) == value; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is a Number. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is a Number.</value> | 
						|
		public bool IsNumber { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.Number; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is a String. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is a String.</value> | 
						|
		public bool IsString { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.String; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is a JsonObject. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is a JsonObject.</value> | 
						|
		public bool IsJsonObject { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.Object; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue is a JsonArray. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue is a JsonArray.</value> | 
						|
		public bool IsJsonArray { | 
						|
			get { | 
						|
				return this.Type == JsonValueType.Array; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this JsonValue represents a DateTime. | 
						|
		/// </summary> | 
						|
		/// <value>A value indicating whether this JsonValue represents a DateTime.</value> | 
						|
		public bool IsDateTime { | 
						|
			get { | 
						|
				return this.AsDateTime != null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets a value indicating whether this value is true or false. | 
						|
		/// </summary> | 
						|
		/// <value>This value as a Boolean type.</value> | 
						|
		public bool AsBoolean { | 
						|
			get { | 
						|
				switch (this.Type) { | 
						|
					case JsonValueType.Boolean: | 
						|
						return this.value == 1; | 
						|
 | 
						|
					case JsonValueType.Number: | 
						|
						return this.value != 0; | 
						|
 | 
						|
					case JsonValueType.String: | 
						|
						return (string)this.reference != string.Empty; | 
						|
 | 
						|
					case JsonValueType.Object: | 
						|
					case JsonValueType.Array: | 
						|
						return true; | 
						|
 | 
						|
					default: | 
						|
						return false; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as an Integer type. | 
						|
		/// </summary> | 
						|
		/// <value>This value as an Integer type.</value> | 
						|
		public int AsInteger { | 
						|
			get { | 
						|
				var value = this.AsNumber; | 
						|
 | 
						|
				// Prevent overflow if the value doesn't fit. | 
						|
				if (value >= int.MaxValue) { | 
						|
					return int.MaxValue; | 
						|
				} | 
						|
 | 
						|
				if (value <= int.MinValue) { | 
						|
					return int.MinValue; | 
						|
				} | 
						|
 | 
						|
				return (int)value; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as a Number type. | 
						|
		/// </summary> | 
						|
		/// <value>This value as a Number type.</value> | 
						|
		public double AsNumber { | 
						|
			get { | 
						|
				switch (this.Type) { | 
						|
					case JsonValueType.Boolean: | 
						|
						return (this.value == 1) | 
						|
							? 1 | 
						|
							: 0; | 
						|
 | 
						|
					case JsonValueType.Number: | 
						|
						return this.value; | 
						|
 | 
						|
					case JsonValueType.String: | 
						|
						double number; | 
						|
						if (double.TryParse((string)this.reference, NumberStyles.Float, CultureInfo.InvariantCulture, out number)) { | 
						|
							return number; | 
						|
						} else { | 
						|
							goto default; | 
						|
						} | 
						|
 | 
						|
					default: | 
						|
						return 0; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as a String type. | 
						|
		/// </summary> | 
						|
		/// <value>This value as a String type.</value> | 
						|
		public string AsString { | 
						|
			get { | 
						|
				switch (this.Type) { | 
						|
					case JsonValueType.Boolean: | 
						|
						return (this.value == 1) | 
						|
							? "true" | 
						|
							: "false"; | 
						|
 | 
						|
					case JsonValueType.Number: | 
						|
						return this.value.ToString(CultureInfo.InvariantCulture); | 
						|
 | 
						|
					case JsonValueType.String: | 
						|
						return (string)this.reference; | 
						|
 | 
						|
					default: | 
						|
						return null; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as an JsonObject. | 
						|
		/// </summary> | 
						|
		/// <value>This value as an JsonObject.</value> | 
						|
		public JsonObject AsJsonObject { | 
						|
			get { | 
						|
				return this.IsJsonObject | 
						|
					? (JsonObject)this.reference | 
						|
					: null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as an JsonArray. | 
						|
		/// </summary> | 
						|
		/// <value>This value as an JsonArray.</value> | 
						|
		public JsonArray AsJsonArray { | 
						|
			get { | 
						|
				return this.IsJsonArray | 
						|
					? (JsonArray)this.reference | 
						|
					: null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this value as a system.DateTime. | 
						|
		/// </summary> | 
						|
		/// <value>This value as a system.DateTime.</value> | 
						|
		public DateTime? AsDateTime { | 
						|
			get { | 
						|
				DateTime value; | 
						|
 | 
						|
				if (this.IsString && DateTime.TryParse((string)this.reference, out value)) { | 
						|
					return value; | 
						|
				} else { | 
						|
					return null; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets this (inner) value as a System.object. | 
						|
		/// </summary> | 
						|
		/// <value>This (inner) value as a System.object.</value> | 
						|
		public object AsObject { | 
						|
			get { | 
						|
				switch (this.Type) { | 
						|
					case JsonValueType.Boolean: | 
						|
					case JsonValueType.Number: | 
						|
						return this.value; | 
						|
 | 
						|
					case JsonValueType.String: | 
						|
					case JsonValueType.Object: | 
						|
					case JsonValueType.Array: | 
						|
						return this.reference; | 
						|
 | 
						|
					default: | 
						|
						return null; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets or sets the value associated with the specified key. | 
						|
		/// </summary> | 
						|
		/// <param name="key">The key of the value to get or set.</param> | 
						|
		/// <exception cref="System.InvalidOperationException"> | 
						|
		/// Thrown when this JsonValue is not a JsonObject. | 
						|
		/// </exception> | 
						|
		public JsonValue this[string key] { | 
						|
			get { | 
						|
				if (this.IsJsonObject) { | 
						|
					return ((JsonObject)this.reference)[key]; | 
						|
				} else { | 
						|
					throw new InvalidOperationException("This value does not represent a JsonObject."); | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			set { | 
						|
				if (this.IsJsonObject) { | 
						|
					((JsonObject)this.reference)[key] = value; | 
						|
				} else { | 
						|
					throw new InvalidOperationException("This value does not represent a JsonObject."); | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets or sets the value at the specified index. | 
						|
		/// </summary> | 
						|
		/// <param name="index">The zero-based index of the value to get or set.</param> | 
						|
		/// <exception cref="System.InvalidOperationException"> | 
						|
		/// Thrown when this JsonValue is not a JsonArray | 
						|
		/// </exception> | 
						|
		public JsonValue this[int index] { | 
						|
			get { | 
						|
				if (this.IsJsonArray) { | 
						|
					return ((JsonArray)this.reference)[index]; | 
						|
				} else { | 
						|
					throw new InvalidOperationException("This value does not represent a JsonArray."); | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			set { | 
						|
				if (this.IsJsonArray) { | 
						|
					((JsonArray)this.reference)[index] = value; | 
						|
				} else { | 
						|
					throw new InvalidOperationException("This value does not represent a JsonArray."); | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given nullable boolean into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(bool? value) | 
						|
		{ | 
						|
			return new JsonValue(value); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given nullable double into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(double? value) | 
						|
		{ | 
						|
			return new JsonValue(value); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given string into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(string value) | 
						|
		{ | 
						|
			return new JsonValue(value); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonObject into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(JsonObject value) | 
						|
		{ | 
						|
			return new JsonValue(value); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonArray into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(JsonArray value) | 
						|
		{ | 
						|
			return new JsonValue(value); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given DateTime? into a JsonValue. | 
						|
		/// </summary> | 
						|
		/// <remarks> | 
						|
		/// The DateTime value will be stored as a string using ISO 8601 format, | 
						|
		/// since JSON does not define a DateTime type. | 
						|
		/// </remarks> | 
						|
		/// <param name="value">The value to be converted.</param> | 
						|
		public static implicit operator JsonValue(DateTime? value) | 
						|
		{ | 
						|
			if (value == null) { | 
						|
				return JsonValue.Null; | 
						|
			} | 
						|
 | 
						|
			return new JsonValue(value.Value.ToString("o")); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into an Int. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator int(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsInteger) { | 
						|
				return jsonValue.AsInteger; | 
						|
			} else { | 
						|
				return 0; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a nullable Int. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		/// <exception cref="System.InvalidCastException"> | 
						|
		/// Throws System.InvalidCastException when the inner value type of the | 
						|
		/// JsonValue is not the desired type of the conversion. | 
						|
		/// </exception> | 
						|
		public static explicit operator int? (JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsNull) { | 
						|
				return null; | 
						|
			} else { | 
						|
				return (int)jsonValue; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a Bool. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator bool(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsBoolean) { | 
						|
				return jsonValue.value == 1; | 
						|
			} else { | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a nullable Bool. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		/// <exception cref="System.InvalidCastException"> | 
						|
		/// Throws System.InvalidCastException when the inner value type of the | 
						|
		/// JsonValue is not the desired type of the conversion. | 
						|
		/// </exception> | 
						|
		public static explicit operator bool? (JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsNull) { | 
						|
				return null; | 
						|
			} else { | 
						|
				return (bool)jsonValue; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a Double. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator double(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsNumber) { | 
						|
				return jsonValue.value; | 
						|
			} else { | 
						|
				return double.NaN; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a nullable Double. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		/// <exception cref="System.InvalidCastException"> | 
						|
		/// Throws System.InvalidCastException when the inner value type of the | 
						|
		/// JsonValue is not the desired type of the conversion. | 
						|
		/// </exception> | 
						|
		public static explicit operator double? (JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsNull) { | 
						|
				return null; | 
						|
			} else { | 
						|
				return (double)jsonValue; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a String. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator string(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsString || jsonValue.IsNull) { | 
						|
				return jsonValue.reference as string; | 
						|
			} else { | 
						|
				return null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a JsonObject. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator JsonObject(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsJsonObject || jsonValue.IsNull) { | 
						|
				return jsonValue.reference as JsonObject; | 
						|
			} else { | 
						|
				return null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a JsonArray. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator JsonArray(JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsJsonArray || jsonValue.IsNull) { | 
						|
				return jsonValue.reference as JsonArray; | 
						|
			} else { | 
						|
				return null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a DateTime. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator DateTime(JsonValue jsonValue) | 
						|
		{ | 
						|
			var dateTime = jsonValue.AsDateTime; | 
						|
 | 
						|
			if (dateTime.HasValue) { | 
						|
				return dateTime.Value; | 
						|
			} else { | 
						|
				return DateTime.MinValue; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Converts the given JsonValue into a nullable DateTime. | 
						|
		/// </summary> | 
						|
		/// <param name="jsonValue">The JsonValue to be converted.</param> | 
						|
		public static explicit operator DateTime? (JsonValue jsonValue) | 
						|
		{ | 
						|
			if (jsonValue.IsDateTime || jsonValue.IsNull) { | 
						|
				return jsonValue.AsDateTime; | 
						|
			} else { | 
						|
				return null; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Returns a value indicating whether the two given JsonValues are equal. | 
						|
		/// </summary> | 
						|
		/// <param name="a">First JsonValue to compare.</param> | 
						|
		/// <param name="b">Second JsonValue to compare.</param> | 
						|
		public static bool operator ==(JsonValue a, JsonValue b) | 
						|
		{ | 
						|
			return (a.Type == b.Type) | 
						|
				&& (a.value == b.value) | 
						|
				&& Equals(a.reference, b.reference); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Returns a value indicating whether the two given JsonValues are unequal. | 
						|
		/// </summary> | 
						|
		/// <param name="a">First JsonValue to compare.</param> | 
						|
		/// <param name="b">Second JsonValue to compare.</param> | 
						|
		public static bool operator !=(JsonValue a, JsonValue b) | 
						|
		{ | 
						|
			return !(a == b); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Returns a JsonValue by parsing the given string. | 
						|
		/// </summary> | 
						|
		/// <param name="text">The JSON-formatted string to be parsed.</param> | 
						|
		/// <returns>The <see cref="JsonValue"/> representing the parsed text.</returns> | 
						|
		public static JsonValue Parse(string text) | 
						|
		{ | 
						|
			return JsonReader.Parse(text); | 
						|
		} | 
						|
 | 
						|
		/// <inheritdoc/> | 
						|
		public override bool Equals(object obj) | 
						|
		{ | 
						|
			if (obj == null) { | 
						|
				return this.IsNull; | 
						|
			} | 
						|
 | 
						|
			var jsonValue = obj as JsonValue?; | 
						|
			if (jsonValue == null) { | 
						|
				return false; | 
						|
			} else { | 
						|
				return this == jsonValue.Value; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <inheritdoc/> | 
						|
		public override int GetHashCode() | 
						|
		{ | 
						|
			if (this.IsNull) { | 
						|
				return this.Type.GetHashCode(); | 
						|
			} else { | 
						|
				return this.Type.GetHashCode() | 
						|
					^ this.value.GetHashCode() | 
						|
					^ EqualityComparer<object>.Default.GetHashCode(this.reference); | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		[ExcludeFromCodeCoverage] | 
						|
		private class JsonValueDebugView | 
						|
		{ | 
						|
			private JsonValue jsonValue; | 
						|
 | 
						|
			public JsonValueDebugView(JsonValue jsonValue) | 
						|
			{ | 
						|
				this.jsonValue = jsonValue; | 
						|
			} | 
						|
 | 
						|
			[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | 
						|
			public JsonObject ObjectView { | 
						|
				get { | 
						|
					if (this.jsonValue.IsJsonObject) { | 
						|
						return (JsonObject)this.jsonValue.reference; | 
						|
					} else { | 
						|
						return null; | 
						|
					} | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] | 
						|
			public JsonArray ArrayView { | 
						|
				get { | 
						|
					if (this.jsonValue.IsJsonArray) { | 
						|
						return (JsonArray)this.jsonValue.reference; | 
						|
					} else { | 
						|
						return null; | 
						|
					} | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			public JsonValueType Type { | 
						|
				get { | 
						|
					return this.jsonValue.Type; | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			public object Value { | 
						|
				get { | 
						|
					if (this.jsonValue.IsJsonObject) { | 
						|
						return (JsonObject)this.jsonValue.reference; | 
						|
					} else if (this.jsonValue.IsJsonArray) { | 
						|
						return (JsonArray)this.jsonValue.reference; | 
						|
					} else { | 
						|
						return this.jsonValue; | 
						|
					} | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
	} | 
						|
}
 | 
						|
 |