using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace LeanCloud.Storage.Internal
{
///
/// A simple recursive-descent JSON Parser based on the grammar defined at http://www.json.org
/// and http://tools.ietf.org/html/rfc4627
///
public class Json
{
///
/// Place at the start of a regex to force the match to begin wherever the search starts (i.e.
/// anchored at the index of the first character of the search, even when that search starts
/// in the middle of the string).
///
private static readonly string startOfString = "\\G";
private static readonly char startObject = '{';
private static readonly char endObject = '}';
private static readonly char startArray = '[';
private static readonly char endArray = ']';
private static readonly char valueSeparator = ',';
private static readonly char nameSeparator = ':';
private static readonly char[] falseValue = "false".ToCharArray();
private static readonly char[] trueValue = "true".ToCharArray();
private static readonly char[] nullValue = "null".ToCharArray();
private static readonly Regex numberValue = new Regex(startOfString +
@"-?(?:0|[1-9]\d*)(?\.\d+)?(?(?:e|E)(?:-|\+)?\d+)?");
private static readonly Regex stringValue = new Regex(startOfString +
"\"(?(?:[^\\\\\"]|(?\\\\(?:[\\\\\"/bfnrt]|u[0-9a-fA-F]{4})))*)\"",
RegexOptions.Multiline);
private static readonly Regex escapePattern = new Regex("\\\\|\"|[\u0000-\u001F]");
private class JsonStringParser
{
public string Input { get; private set; }
public char[] InputAsArray { get; private set; }
private int currentIndex;
public int CurrentIndex
{
get
{
return currentIndex;
}
}
public void Skip(int skip)
{
currentIndex += skip;
}
public JsonStringParser(string input)
{
Input = input;
InputAsArray = input.ToCharArray();
}
///
/// Parses JSON object syntax (e.g. '{}')
///
internal bool AVObject(out object output)
{
output = null;
int initialCurrentIndex = CurrentIndex;
if (!Accept(startObject))
{
return false;
}
var dict = new Dictionary();
while (true)
{
object pairValue;
if (!ParseMember(out pairValue))
{
break;
}
var pair = pairValue as Tuple;
dict[pair.Item1] = pair.Item2;
if (!Accept(valueSeparator))
{
break;
}
}
if (!Accept(endObject))
{
return false;
}
output = dict;
return true;
}
///
/// Parses JSON member syntax (e.g. '"keyname" : null')
///
private bool ParseMember(out object output)
{
output = null;
object key;
if (!ParseString(out key))
{
return false;
}
if (!Accept(nameSeparator))
{
return false;
}
object value;
if (!ParseValue(out value))
{
return false;
}
output = new Tuple((string)key, value);
return true;
}
///
/// Parses JSON array syntax (e.g. '[]')
///
internal bool ParseArray(out object output)
{
output = null;
if (!Accept(startArray))
{
return false;
}
var list = new List