using System;
|
using System.Collections.Generic;
|
using System.Text;
|
|
namespace Json
|
{
|
public class JsonProperty
|
{
|
private bool _bool;
|
private List<JsonProperty> _list;
|
private double _number;
|
private JsonObject _object;
|
private JsonPropertyType _type;
|
private string _value;
|
|
public JsonProperty()
|
{
|
this._type = JsonPropertyType.Null;
|
this._value = (string)null;
|
this._object = (JsonObject)null;
|
this._list = (List<JsonProperty>)null;
|
}
|
|
public JsonProperty(object value)
|
{
|
this.SetValue(value);
|
}
|
|
public JsonProperty(string jsonString)
|
{
|
this.Parse(ref jsonString);
|
}
|
|
public JsonProperty Add(object value)
|
{
|
if (this._type != JsonPropertyType.Null && this._type != JsonPropertyType.Array)
|
throw new NotSupportedException("Json属性不是Array类型,无法添加元素!");
|
if (this._list == null)
|
this._list = new List<JsonProperty>();
|
JsonProperty jsonProperty = new JsonProperty(value);
|
this._list.Add(jsonProperty);
|
this._type = JsonPropertyType.Array;
|
return jsonProperty;
|
}
|
|
public void Clear()
|
{
|
this._type = JsonPropertyType.Null;
|
this._value = string.Empty;
|
this._object = (JsonObject)null;
|
if (this._list == null)
|
return;
|
this._list.Clear();
|
this._list = (List<JsonProperty>)null;
|
}
|
|
public virtual T GetValue<T>() where T : class
|
{
|
return this.GetValue() as T;
|
}
|
|
public object GetValue()
|
{
|
if (this._type == JsonPropertyType.String)
|
return (object)this._value;
|
if (this._type == JsonPropertyType.Object)
|
return (object)this._object;
|
if (this._type == JsonPropertyType.Array)
|
return (object)this._list;
|
if (this._type == JsonPropertyType.Bool)
|
return (object)this._bool;
|
if (this._type == JsonPropertyType.Number)
|
return (object)this._number;
|
return (object)null;
|
}
|
|
public void Parse(ref string jsonString)
|
{
|
if (string.IsNullOrEmpty(jsonString.Trim()))
|
{
|
this.SetValue((object)null);
|
}
|
else
|
{
|
jsonString = jsonString.Trim();
|
string str1 = jsonString.Substring(0, 1);
|
string str2 = jsonString.Substring(jsonString.Length - 1, 1);
|
if (str1 == "[" && str2 == "]")
|
this.SetValue((object)this.ParseArray(ref jsonString));
|
else if (str1 == "{" && str2 == "}")
|
this.SetValue((object)this.ParseObject(ref jsonString));
|
else if ((str1 == "'" || str1 == "\"") && str1 == str2)
|
this.SetValue((object)this.ParseString(ref jsonString));
|
else if (jsonString == "true" || jsonString == "false")
|
this.SetValue((object)(jsonString == "true"));
|
else if (jsonString == "null")
|
{
|
this.SetValue((object)null);
|
}
|
else
|
{
|
double result = 0.0;
|
if (double.TryParse(jsonString, out result))
|
this.SetValue((object)result);
|
else
|
this.SetValue((object)jsonString);
|
}
|
}
|
}
|
|
private List<JsonProperty> ParseArray(ref string jsonString)
|
{
|
List<JsonProperty> jsonPropertyList = new List<JsonProperty>();
|
int length = jsonString.Length;
|
StringBuilder stringBuilder = new StringBuilder();
|
Stack<char> charStack1 = new Stack<char>();
|
Stack<char> charStack2 = new Stack<char>();
|
bool flag = false;
|
for (int index = 1; index <= length - 2; ++index)
|
{
|
char c = jsonString[index];
|
if (char.IsWhiteSpace(c) && charStack1.Count == 0)
|
stringBuilder.Append(c);
|
else if (c == '\'' && charStack1.Count == 0 && (!flag && charStack2.Count == 0) || c == '"' && charStack1.Count == 0 && !flag && charStack2.Count == 0)
|
{
|
stringBuilder.Length = 0;
|
stringBuilder.Append(c);
|
charStack1.Push(c);
|
}
|
else if (c == '\\' && charStack1.Count > 0 && !flag)
|
{
|
stringBuilder.Append(c);
|
flag = true;
|
}
|
else if (flag)
|
{
|
flag = false;
|
if (c == 'u')
|
{
|
stringBuilder.Append(new char[4]
|
{
|
c,
|
jsonString[index + 1],
|
jsonString[index + 2],
|
jsonString[index + 3]
|
});
|
index += 4;
|
}
|
else
|
stringBuilder.Append(c);
|
}
|
else if ((c == '\'' || c == '"') && (!flag && charStack1.Count > 0) && (int)charStack1.Peek() == (int)c && charStack2.Count == 0)
|
{
|
stringBuilder.Append(c);
|
jsonPropertyList.Add(new JsonProperty(stringBuilder.ToString()));
|
int num = (int)charStack1.Pop();
|
}
|
else if ((c == '[' || c == '{') && charStack1.Count == 0)
|
{
|
if (charStack2.Count == 0)
|
stringBuilder.Length = 0;
|
stringBuilder.Append(c);
|
charStack2.Push(c == '[' ? ']' : '}');
|
}
|
else if ((c == ']' || c == '}') && (charStack1.Count == 0 && charStack2.Count > 0) && (int)charStack2.Peek() == (int)c)
|
{
|
stringBuilder.Append(c);
|
int num = (int)charStack2.Pop();
|
if (charStack2.Count == 0)
|
{
|
jsonPropertyList.Add(new JsonProperty(stringBuilder.ToString()));
|
stringBuilder.Length = 0;
|
}
|
}
|
else if (c == ',' && charStack1.Count == 0 && charStack2.Count == 0)
|
{
|
if (stringBuilder.Length > 0)
|
{
|
jsonPropertyList.Add(new JsonProperty(stringBuilder.ToString()));
|
stringBuilder.Length = 0;
|
}
|
}
|
else
|
stringBuilder.Append(c);
|
}
|
if (charStack1.Count > 0 || charStack2.Count > 0)
|
{
|
jsonPropertyList.Clear();
|
throw new ArgumentException("无法解析Json Array对象!");
|
}
|
if (stringBuilder.ToString().Trim().Length > 0)
|
jsonPropertyList.Add(new JsonProperty(stringBuilder.ToString()));
|
return jsonPropertyList;
|
}
|
|
private JsonObject ParseObject(ref string jsonString)
|
{
|
return new JsonObject(jsonString);
|
}
|
|
private string ParseString(ref string jsonString)
|
{
|
int length = jsonString.Length;
|
StringBuilder stringBuilder = new StringBuilder();
|
bool flag = false;
|
for (int index = 1; index <= length - 2; ++index)
|
{
|
char ch = jsonString[index];
|
if (ch == '\\' && !flag)
|
flag = true;
|
else if (flag)
|
{
|
flag = false;
|
if (ch == '\\' || ch == '"' || ch == '\'' || ch == '/')
|
stringBuilder.Append(ch);
|
else if (ch == 'u')
|
{
|
string str = new string(new char[4]
|
{
|
ch,
|
jsonString[index + 1],
|
jsonString[index + 2],
|
jsonString[index + 3]
|
});
|
stringBuilder.Append((char)Convert.ToInt32(str, 16));
|
index += 4;
|
}
|
else
|
{
|
switch (ch)
|
{
|
case 'b':
|
stringBuilder.Append('\b');
|
continue;
|
case 'f':
|
stringBuilder.Append('\f');
|
continue;
|
case 'n':
|
stringBuilder.Append('\n');
|
continue;
|
case 'r':
|
stringBuilder.Append('\r');
|
continue;
|
case 's':
|
continue;
|
case 't':
|
stringBuilder.Append('\t');
|
continue;
|
}
|
}
|
}
|
else
|
stringBuilder.Append(ch);
|
}
|
return stringBuilder.ToString();
|
}
|
|
public virtual void SetValue(object value)
|
{
|
if (value is string)
|
{
|
this._type = JsonPropertyType.String;
|
this._value = (string)value;
|
}
|
else if (value is List<JsonProperty>)
|
{
|
this._list = (List<JsonProperty>)value;
|
this._type = JsonPropertyType.Array;
|
}
|
else if (value is JsonObject)
|
{
|
this._object = (JsonObject)value;
|
this._type = JsonPropertyType.Object;
|
}
|
else if (value is bool)
|
{
|
this._bool = (bool)value;
|
this._type = JsonPropertyType.Bool;
|
}
|
else if (value == null)
|
{
|
this._type = JsonPropertyType.Null;
|
}
|
else
|
{
|
double result = 0.0;
|
if (!double.TryParse(value.ToString(), out result))
|
throw new ArgumentException("错误的参数类型!");
|
this._number = result;
|
this._type = JsonPropertyType.Number;
|
}
|
}
|
|
public override string ToString()
|
{
|
return this.ToString("");
|
}
|
|
public virtual string ToString(string format)
|
{
|
StringBuilder stringBuilder = new StringBuilder();
|
if (this._type == JsonPropertyType.String)
|
{
|
stringBuilder.Append("\"").Append(this._value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", "\\r")).Append("\"");
|
return stringBuilder.ToString();
|
}
|
if (this._type == JsonPropertyType.Bool)
|
return this._bool ? "true" : "false";
|
if (this._type == JsonPropertyType.Number)
|
return this._number.ToString();
|
if (this._type == JsonPropertyType.Null)
|
return "null";
|
if (this._type == JsonPropertyType.Object)
|
return this._object.ToString();
|
if (this._list == null || this._list.Count == 0)
|
{
|
stringBuilder.Append("[]");
|
}
|
else
|
{
|
stringBuilder.Append("[");
|
if (this._list.Count > 0)
|
{
|
foreach (JsonProperty jsonProperty in this._list)
|
{
|
stringBuilder.Append(jsonProperty.ToString());
|
stringBuilder.Append(", ");
|
}
|
stringBuilder.Length -= 2;
|
}
|
stringBuilder.Append("]");
|
}
|
return stringBuilder.ToString();
|
}
|
|
public virtual int Count
|
{
|
get
|
{
|
int num = 0;
|
if (this._type != JsonPropertyType.Array)
|
return 1;
|
if (this._list != null)
|
num = this._list.Count;
|
return num;
|
}
|
}
|
|
public JsonProperty this[int index]
|
{
|
get
|
{
|
JsonProperty jsonProperty = (JsonProperty)null;
|
if (this._type == JsonPropertyType.Array)
|
{
|
if (this._list != null && this._list.Count - 1 >= index)
|
jsonProperty = this._list[index];
|
return jsonProperty;
|
}
|
if (index == 0)
|
return this;
|
return jsonProperty;
|
}
|
}
|
|
public JsonProperty this[string PropertyName]
|
{
|
get
|
{
|
if (this._type == JsonPropertyType.Object)
|
return this._object[PropertyName];
|
return (JsonProperty)null;
|
}
|
set
|
{
|
if (this._type != JsonPropertyType.Object)
|
throw new NotSupportedException("Json属性不是对象类型!");
|
this._object[PropertyName] = value;
|
}
|
}
|
|
public List<JsonProperty> Items
|
{
|
get
|
{
|
if (this._type == JsonPropertyType.Array)
|
return this._list;
|
return new List<JsonProperty>() { this };
|
}
|
}
|
|
public double Number
|
{
|
get
|
{
|
if (this._type == JsonPropertyType.Number)
|
return this._number;
|
return double.NaN;
|
}
|
}
|
|
public JsonObject Object
|
{
|
get
|
{
|
if (this._type == JsonPropertyType.Object)
|
return this._object;
|
return (JsonObject)null;
|
}
|
}
|
|
public JsonPropertyType Type
|
{
|
get
|
{
|
return this._type;
|
}
|
}
|
|
public string Value
|
{
|
get
|
{
|
if (this._type == JsonPropertyType.String)
|
return this._value;
|
if (this._type == JsonPropertyType.Number)
|
return this._number.ToString();
|
if (this._type == JsonPropertyType.Bool)
|
return this._bool.ToString();
|
return (string)null;
|
}
|
}
|
}
|
}
|