final class · System.Text
JsonValue
public final class JsonValue
- Kind
- final class
- Namespace
- System.Text
- Assembly
- System.Core
- Access
- public, final
- Source file
Json.ant
Inheritance
- Base classes
-
AnyJsonValue
Constructors
Properties
Methods
An array's item.
Appends to an array (returns this, to chain).
The key of the i-th member of an obj.
The i-th member's value.
An obj's member, or null when there is none.
Sets an obj's member (replacing one with that key; returns this, to chain).
override ToString() : str
#
The value as JSON text (compact).
Private and internal members (15)
Objects up to this many members find a key by looking at each one; bigger ones keep an index.
str text
#
Dictionary<str, i32>? index
#
Where an object's member key is, or -1.
static WriteText(StringBuilder sb, str value)
#
value in quotes, escaped: the units that need no escape go in as runs.
Write(StringBuilder sb)
#
Inherited members (4)
GetTypemethod from AnyUndescribedmethod from AnyHashmethod from Anydestroymethod from Any
Source
JsonValue as Antril, decompiled from its Larva HIR.
// System.Text.JsonValue — System.Core (decompiled from Larva HIR)
import System;
into namespace System.Text
{
public final class JsonValue
{
/// Objects up to this many members find a key by looking at each one; bigger ones keep an index.
const i32 IndexFrom = 8;
JsonKind kind;
bool boolean;
f64 number;
str text;
List<JsonValue>? items;
List<str>? keys;
Dictionary<str, i32>? index;
Expect(JsonKind wanted, str what)
{
if (kind != wanted)
throw new FormatError("the JSON value is not " + what);
}
Items() : List<JsonValue>
{
if (items is List<JsonValue> list)
return list;
List<JsonValue> made = new List<JsonValue>();
items = made;
return made;
}
Keys() : List<str>
{
if (keys is List<str> list)
return list;
List<str> made = new List<str>();
keys = made;
return made;
}
/// Where an object's member `key` is, or -1.
Find(str key) : i32
{
if (index is Dictionary<str, i32> map)
return map.TryGet(key, -1);
if (keys is List<str> list)
{
i32 count = list.Count;
if (count < 8)
{
loop (i32 i = 0..count)
{
if (list[i] == key)
return i;
}
return -1;
}
Dictionary<str, i32> made = new Dictionary<str, i32>();
loop (i32 i = 0..count)
made.Set(list[i], i);
index = made;
return made.TryGet(key, -1);
}
return -1;
}
/// `value` in quotes, escaped: the units that need no escape go in as runs.
static WriteText(StringBuilder sb, str value)
{
sb.Append(34);
i32 n = value.Length;
i32 run = 0;
loop (i32 i = 0..n)
{
u32 c = value[i];
if (c >= 32 && c != 34 && c != 92)
continue;
if (i > run)
sb.Append(value, run, i - run);
run = i + 1;
if (c == 34)
sb.Append("\\\"");
else if (c == 92)
sb.Append("\\\\");
else if (c == 10)
sb.Append("\\n");
else if (c == 13)
sb.Append("\\r");
else if (c == 9)
sb.Append("\\t");
else if (c == 8)
sb.Append("\\b");
else if (c == 12)
sb.Append("\\f");
else
{
sb.Append("\\u00");
sb.Append(Hex(c >> 4));
sb.Append(Hex(c & 15));
}
}
if (n > run)
sb.Append(value, run, n - run);
sb.Append(34);
}
static Hex(u32 digit) : u16 => (u16)(digit < 10 ? 48 + digit : 97 + digit - 10);
Write(StringBuilder sb)
{
if (kind == JsonKind.Null)
sb.Append("null");
else if (kind == JsonKind.Bool)
sb.Append(boolean ? "true" : "false");
else if (kind == JsonKind.Number)
{
if (number - number != 0.0)
throw new FormatError("JSON has no value for " + number);
i64 whole = (i64)number;
if (whole == number && number > -9007199254740992.0 && number < 9007199254740992.0)
sb.Append(whole);
else
sb.Append(number.ToString());
}
else if (kind == JsonKind.String)
WriteText(sb, text);
else if (kind == JsonKind.Array)
{
sb.Append(91);
if (items is List<JsonValue> list)
{
loop (i32 i = 0..list.Count)
{
if (i > 0)
sb.Append(44);
list[i].Write(sb);
}
}
sb.Append(93);
}
else
{
sb.Append(123);
if (keys is List<str> names && items is List<JsonValue> values)
{
loop (i32 i = 0..names.Count)
{
if (i > 0)
sb.Append(44);
WriteText(sb, names[i]);
sb.Append(58);
values[i].Write(sb);
}
}
sb.Append(125);
}
}
public:
new(JsonKind kind)
{
this.kind = kind;
text = "";
}
static Null() : JsonValue => new JsonValue(JsonKind.Null);
static Of(bool value) : JsonValue
{
JsonValue v = new JsonValue(JsonKind.Bool);
v.boolean = value;
return v;
}
static Of(f64 value) : JsonValue
{
JsonValue v = new JsonValue(JsonKind.Number);
v.number = value;
return v;
}
static Of(i32 value) : JsonValue => Of(value);
static Of(str value) : JsonValue
{
JsonValue v = new JsonValue(JsonKind.String);
v.text = value;
return v;
}
static NewArray() : JsonValue => new JsonValue(JsonKind.Array);
static NewObject() : JsonValue => new JsonValue(JsonKind.Object);
/// An array's item.
At(i32 index) : JsonValue
{
Expect(JsonKind.Array, "an array");
return Items()[index];
}
/// Appends to an array (returns this, to chain).
Add(JsonValue item) : JsonValue
{
Expect(JsonKind.Array, "an array");
Items().Add(item);
return this;
}
/// The key of the i-th member of an obj.
KeyAt(i32 index) : str
{
Expect(JsonKind.Object, "an obj");
return Keys()[index];
}
/// The i-th member's value.
ValueAt(i32 index) : JsonValue
{
Expect(JsonKind.Object, "an obj");
return Items()[index];
}
Has(str key) : bool => kind == JsonKind.Object && Find(key) >= 0;
/// An obj's member, or null when there is none.
Get(str key) : JsonValue?
{
if (kind != JsonKind.Object)
return null;
i32 at = Find(key);
if (at < 0)
return null;
return Items()[at];
}
/// Sets an obj's member (replacing one with that key; returns this, to chain).
Set(str key, JsonValue value) : JsonValue
{
Expect(JsonKind.Object, "an obj");
i32 at = Find(key);
List<JsonValue> values = Items();
if (at >= 0)
{
values[at] = value;
return this;
}
List<str> names = Keys();
names.Add(key);
values.Add(value);
if (index is Dictionary<str, i32> map)
map.Set(key, names.Count - 1);
return this;
}
/// The value as JSON text (compact).
override ToString() : str
{
StringBuilder sb = new StringBuilder();
Write(sb);
return sb.ToString();
}
static Parse(str json) : JsonValue
{
JsonReader reader = new JsonReader(json.Units());
JsonValue value = reader.ReadValue();
reader.SkipSpace();
if (!reader.AtEnd)
reader.Fail("text after the value");
return value;
}
JsonKind Kind
{
get => kind;
}
bool IsNull
{
get => kind == JsonKind.Null;
}
bool AsBool
{
get
{
Expect(JsonKind.Bool, "a bool");
return boolean;
}
}
f64 AsNumber
{
get
{
Expect(JsonKind.Number, "a number");
return number;
}
}
str AsString
{
get
{
Expect(JsonKind.String, "a string");
return text;
}
}
/// Items of an array, or members of an obj.
i32 Count
{
get
{
if (kind == JsonKind.Array || kind == JsonKind.Object)
{
if (items is List<JsonValue> list)
return list.Count;
}
return 0;
}
}
}
}