void Parse(string str, int maxDepth = -2, bool storeExcessLevels = false, bool strict = false)
{
if (!string.IsNullOrEmpty(str))
{
str = str.Trim(WHITESPACE);
if (strict)
{
if (str[0] != '[' && str[0] != '{')
{
type = Type.NULL;
Debug.LogWarning("Improper (strict) JSON formatting. First character must be [ or {");
return;
}
}
if (str.Length > 0)
{
if (string.Compare(str, "true", true) == 0)
{
type = Type.BOOL;
b = true;
}
else if (string.Compare(str, "false", true) == 0)
{
type = Type.BOOL;
b = false;
}
else if (string.Compare(str, "null", true) == 0)
{
type = Type.NULL;
#if USEFLOAT
} else if(str == INFINITY) {
type = Type.NUMBER;
n = float.PositiveInfinity;
} else if(str == NEGINFINITY) {
type = Type.NUMBER;
n = float.NegativeInfinity;
} else if(str == NaN) {
type = Type.NUMBER;
n = float.NaN;
#else
}
else if (str == INFINITY)
{
type = Type.NUMBER;
n = double.PositiveInfinity;
}
else if (str == NEGINFINITY)
{
type = Type.NUMBER;
n = double.NegativeInfinity;
}
else if (str == NaN)
{
type = Type.NUMBER;
n = double.NaN;
#endif
}
else if (str[0] == '"')
{
type = Type.STRING;
this.str = str.Substring(1, str.Length - 2);
}
else
{
int tokenTmp = 1;
/*
* Checking for the following formatting (www.json.org)
* object - {"field1":value,"field2":value}
* array - [value,value,value]
* value - string - "string"
* - number - 0.0
* - bool - true -or- false
* - null - null
*/
int offset = 0;
switch (str[offset])
{
case '{':
type = Type.OBJECT;
keys = new List<string>();
list = new List<JSONObject>();
break;
case '[':
type = Type.ARRAY;
list = new List<JSONObject>();
break;
default:
try
{
#if USEFLOAT
n = System.Convert.ToSingle(str);
#else
n = System.Convert.ToDouble(str);
#endif
type = Type.NUMBER;
}
catch (System.FormatException)
{
type = Type.NULL;
Debug.LogWarning("improper JSON formatting:" + str);
}
return;
}
string propName = "";
bool openQuote = false;
bool inProp = false;
int depth = 0;
while (++offset < str.Length)
{
if (System.Array.IndexOf(WHITESPACE, str[offset]) > -1)
continue;
if (str[offset] == '\\')
{
offset += 1;
continue;
}
if (str[offset] == '"')
{
if (openQuote)
{
if (!inProp && depth == 0 && type == Type.OBJECT)
propName = str.Substring(tokenTmp + 1, offset - tokenTmp - 1);
openQuote = false;
}
else
{
if (depth == 0 && type == Type.OBJECT)
tokenTmp = offset;
openQuote = true;
}
}
if (openQuote)
continue;
if (type == Type.OBJECT && depth == 0)
{
if (str[offset] == ':')
{
tokenTmp = offset + 1;
inProp = true;
}
}
if (str[offset] == '[' || str[offset] == '{')
{
depth++;
}
else if (str[offset] == ']' || str[offset] == '}')
{
depth--;
}
//if (encounter a ',' at top level) || a closing ]/}
if ((str[offset] == ',' && depth == 0) || depth < 0)
{
inProp = false;
string inner = str.Substring(tokenTmp, offset - tokenTmp).Trim(WHITESPACE);
if (inner.Length > 0)
{
if (type == Type.OBJECT)
keys.Add(propName);
if (maxDepth != -1) //maxDepth of -1 is the end of the line
list.Add(Create(inner, (maxDepth < -1) ? -2 : maxDepth - 1));
else if (storeExcessLevels)
list.Add(CreateBakedObject(inner));
}
tokenTmp = offset + 1;
}
}
}
}
else type = Type.NULL;
}
else type = Type.NULL; //If the string is missing, this is a null
//Profiler.EndSample();
}
#endregion