Skip to content

Commit

Permalink
Improve JSON (neo-project#1315)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored and Tommo-L committed Jun 22, 2020
1 parent 5b03551 commit 5e1333b
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 414 deletions.
59 changes: 13 additions & 46 deletions src/neo/IO/Json/JArray.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;

namespace Neo.IO.Json
{
Expand Down Expand Up @@ -55,7 +53,7 @@ public void Add(JObject item)

public override string AsString()
{
return string.Join(VALUE_SEPARATOR.ToString(), items.Select(p => p?.AsString()));
return string.Join(",", items.Select(p => p?.AsString()));
}

public void Clear()
Expand Down Expand Up @@ -93,32 +91,6 @@ public void Insert(int index, JObject item)
items.Insert(index, item);
}

internal new static JArray Parse(TextReader reader, int max_nest)
{
SkipSpace(reader);
if (reader.Read() != BEGIN_ARRAY) throw new FormatException();
JArray array = new JArray();
SkipSpace(reader);
if (reader.Peek() != END_ARRAY)
{
while (true)
{
JObject obj = JObject.Parse(reader, max_nest - 1);
array.items.Add(obj);
SkipSpace(reader);
char nextchar = (char)reader.Read();
if (nextchar == VALUE_SEPARATOR) continue;
if (nextchar == END_ARRAY) break;
throw new FormatException();
}
}
else
{
reader.Read();
}
return array;
}

public bool Remove(JObject item)
{
return items.Remove(item);
Expand All @@ -129,27 +101,22 @@ public void RemoveAt(int index)
items.RemoveAt(index);
}

public override string ToString()
internal override void Write(Utf8JsonWriter writer)
{
StringBuilder sb = new StringBuilder();
sb.Append(BEGIN_ARRAY);
writer.WriteStartArray();
foreach (JObject item in items)
{
if (item == null)
sb.Append(LITERAL_NULL);
if (item is null)
writer.WriteNullValue();
else
sb.Append(item);
sb.Append(VALUE_SEPARATOR);
item.Write(writer);
}
if (items.Count == 0)
{
sb.Append(END_ARRAY);
}
else
{
sb[sb.Length - 1] = END_ARRAY;
}
return sb.ToString();
writer.WriteEndArray();
}

public static implicit operator JArray(JObject[] value)
{
return new JArray(value);
}
}
}
34 changes: 7 additions & 27 deletions src/neo/IO/Json/JBoolean.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Text.Json;

namespace Neo.IO.Json
{
Expand Down Expand Up @@ -27,38 +26,19 @@ public override string AsString()
return Value.ToString().ToLowerInvariant();
}

internal static JBoolean Parse(TextReader reader)
{
SkipSpace(reader);
char firstChar = (char)reader.Peek();
if (firstChar == LITERAL_FALSE[0])
return ParseFalse(reader);
else if (firstChar == LITERAL_TRUE[0])
return ParseTrue(reader);
throw new FormatException();
}

internal static JBoolean ParseFalse(TextReader reader)
public override string ToString()
{
SkipSpace(reader);
for (int i = 0; i < LITERAL_FALSE.Length; i++)
if ((char)reader.Read() != LITERAL_FALSE[i])
throw new FormatException();
return new JBoolean(false);
return AsString();
}

internal static JBoolean ParseTrue(TextReader reader)
internal override void Write(Utf8JsonWriter writer)
{
SkipSpace(reader);
for (int i = 0; i < LITERAL_TRUE.Length; i++)
if ((char)reader.Read() != LITERAL_TRUE[i])
throw new FormatException();
return new JBoolean(true);
writer.WriteBooleanValue(Value);
}

public override string ToString()
public static implicit operator JBoolean(bool value)
{
return AsString();
return new JBoolean(value);
}
}
}
80 changes: 13 additions & 67 deletions src/neo/IO/Json/JNumber.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.Json;

namespace Neo.IO.Json
{
Expand All @@ -14,12 +13,13 @@ public class JNumber : JObject

public JNumber(double value = 0)
{
if (!double.IsFinite(value)) throw new FormatException();
this.Value = value;
}

public override bool AsBoolean()
{
return Value != 0 && !double.IsNaN(Value);
return Value != 0;
}

public override double AsNumber()
Expand All @@ -29,73 +29,9 @@ public override double AsNumber()

public override string AsString()
{
if (double.IsPositiveInfinity(Value)) throw new FormatException("Positive infinity number");
if (double.IsNegativeInfinity(Value)) throw new FormatException("Negative infinity number");
return Value.ToString(CultureInfo.InvariantCulture);
}

internal static JNumber Parse(TextReader reader)
{
SkipSpace(reader);
StringBuilder sb = new StringBuilder();
char nextchar = (char)reader.Read();
if (nextchar == '-')
{
sb.Append(nextchar);
nextchar = (char)reader.Read();
}
if (nextchar < '0' || nextchar > '9') throw new FormatException();
sb.Append(nextchar);
if (nextchar > '0')
{
while (true)
{
char c = (char)reader.Peek();
if (c < '0' || c > '9') break;
sb.Append((char)reader.Read());
}
}
nextchar = (char)reader.Peek();
if (nextchar == '.')
{
sb.Append((char)reader.Read());
nextchar = (char)reader.Read();
if (nextchar < '0' || nextchar > '9') throw new FormatException();
sb.Append(nextchar);
while (true)
{
nextchar = (char)reader.Peek();
if (nextchar < '0' || nextchar > '9') break;
sb.Append((char)reader.Read());
}
}
if (nextchar == 'e' || nextchar == 'E')
{
sb.Append((char)reader.Read());
nextchar = (char)reader.Read();
if (nextchar == '-' || nextchar == '+')
{
sb.Append(nextchar);
nextchar = (char)reader.Read();
}
if (nextchar < '0' || nextchar > '9') throw new FormatException();
sb.Append(nextchar);
while (true)
{
nextchar = (char)reader.Peek();
if (nextchar < '0' || nextchar > '9') break;
sb.Append((char)reader.Read());
}
}

var value = double.Parse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture);

if (value > MAX_SAFE_INTEGER || value < MIN_SAFE_INTEGER)
throw new FormatException();

return new JNumber(value);
}

public override string ToString()
{
return AsString();
Expand All @@ -116,5 +52,15 @@ public override T TryGetEnum<T>(T defaultValue = default, bool ignoreCase = fals
object result = Enum.ToObject(enumType, value);
return Enum.IsDefined(enumType, result) ? (T)result : defaultValue;
}

internal override void Write(Utf8JsonWriter writer)
{
writer.WriteNumberValue(Value);
}

public static implicit operator JNumber(double value)
{
return new JNumber(value);
}
}
}
Loading

0 comments on commit 5e1333b

Please sign in to comment.