JsonStep
using AngleSharp.Extensions;
using System.Collections.Generic;
namespace AngleSharp.Html.Submitters.Json
{
internal abstract class JsonStep
{
private sealed class ObjectStep : JsonStep
{
public string Key { get; set; }
public ObjectStep(string key)
{
Key = key;
}
protected override JsonElement GetValue(JsonElement context)
{
return context[Key];
}
protected override JsonElement SetValue(JsonElement context, JsonElement value)
{
context[Key] = value;
return value;
}
protected override JsonElement CreateElement()
{
return new JsonObject();
}
protected override JsonElement ConvertArray(JsonArray values)
{
JsonObject jsonObject = new JsonObject();
for (int i = 0; i < values.Length; i++) {
JsonElement jsonElement = values[i];
if (jsonElement != null)
jsonObject[i.ToString()] = jsonElement;
}
return jsonObject;
}
}
private sealed class ArrayStep : JsonStep
{
public int Key { get; set; }
public ArrayStep(int key)
{
Key = key;
}
protected override JsonElement GetValue(JsonElement context)
{
JsonArray jsonArray = context as JsonArray;
if (jsonArray == null)
return context[Key.ToString()];
return jsonArray[Key];
}
protected override JsonElement SetValue(JsonElement context, JsonElement value)
{
JsonArray jsonArray = context as JsonArray;
if (jsonArray != null)
jsonArray[Key] = value;
else
context[Key.ToString()] = value;
return value;
}
protected override JsonElement CreateElement()
{
return new JsonArray();
}
protected override JsonElement ConvertArray(JsonArray value)
{
return value;
}
}
public bool Append { get; set; }
public JsonStep Next { get; set; }
public static IEnumerable<JsonStep> Parse(string path)
{
List<JsonStep> list = new List<JsonStep>();
int i;
for (i = 0; i < path.Length && path[i] != '['; i++) {
}
if (i == 0)
return FailedJsonSteps(path);
list.Add(new ObjectStep(path.Substring(0, i)));
while (i < path.Length) {
if (i + 1 >= path.Length || path[i] != '[')
return FailedJsonSteps(path);
if (path[i + 1] == ']') {
list[list.Count - 1].Append = true;
i += 2;
if (i < path.Length)
return FailedJsonSteps(path);
} else if (path[i + 1].IsDigit()) {
int num = ++i;
for (; i < path.Length && path[i] != ']'; i++) {
if (!path[i].IsDigit())
return FailedJsonSteps(path);
}
if (i == path.Length)
return FailedJsonSteps(path);
list.Add(new ArrayStep(path.Substring(num, i - num).ToInteger(0)));
i++;
} else {
int num2 = ++i;
for (; i < path.Length && path[i] != ']'; i++) {
}
if (i == path.Length)
return FailedJsonSteps(path);
list.Add(new ObjectStep(path.Substring(num2, i - num2)));
i++;
}
}
int j = 0;
for (int num3 = list.Count - 1; j < num3; j++) {
list[j].Next = list[j + 1];
}
return list;
}
private static IEnumerable<JsonStep> FailedJsonSteps(string original)
{
return new ObjectStep[1] {
new ObjectStep(original)
};
}
protected abstract JsonElement CreateElement();
protected abstract JsonElement SetValue(JsonElement context, JsonElement value);
protected abstract JsonElement GetValue(JsonElement context);
protected abstract JsonElement ConvertArray(JsonArray value);
public JsonElement Run(JsonElement context, JsonElement value, bool file = false)
{
if (Next == null)
return JsonEncodeLastValue(context, value, file);
return JsonEncodeValue(context, value, file);
}
private JsonElement JsonEncodeValue(JsonElement context, JsonElement value, bool file)
{
JsonElement value2 = GetValue(context);
if (value2 == null) {
JsonElement value3 = Next.CreateElement();
return SetValue(context, value3);
}
if (value2 is JsonObject)
return value2;
if (value2 is JsonArray)
return SetValue(context, Next.ConvertArray((JsonArray)value2));
JsonObject value4 = new JsonObject {
[string.Empty] = value2
};
return SetValue(context, value4);
}
private JsonElement JsonEncodeLastValue(JsonElement context, JsonElement value, bool file)
{
JsonElement value2 = GetValue(context);
if (value2 == null) {
if (Append) {
JsonArray jsonArray = new JsonArray();
jsonArray.Push(value);
value = jsonArray;
}
SetValue(context, value);
} else if (value2 is JsonArray) {
((JsonArray)value2).Push(value);
} else {
if (value2 is JsonObject && !file)
return new ObjectStep(string.Empty).JsonEncodeLastValue(value2, value, true);
JsonArray jsonArray2 = new JsonArray();
jsonArray2.Push(value2);
jsonArray2.Push(value);
SetValue(context, jsonArray2);
}
return context;
}
}
}