source: binary-improvements2/7dtd-server-fixes/src/JSON/JSONNumber.cs@ 391

Last change on this file since 391 was 391, checked in by alloc, 2 years ago

Major refactoring/cleanup

File size: 3.2 KB
Line 
1using System;
2using System.Text;
3
4namespace AllocsFixes.JSON {
5 public class JsonNumber : JsonValue {
6 private readonly double value;
7
8 public JsonNumber (double _value) {
9 value = _value;
10 }
11
12 public double GetDouble () {
13 return value;
14 }
15
16 public int GetInt () {
17 return (int) Math.Round (value);
18 }
19
20 public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
21 _stringBuilder.Append (value.ToCultureInvariantString ());
22 }
23
24 public static JsonNumber Parse (string _json, ref int _offset) {
25 //Log.Out ("ParseNumber enter (" + offset + ")");
26 StringBuilder sbNum = new StringBuilder ();
27 StringBuilder sbExp = null;
28 bool hasDec = false;
29 bool hasExp = false;
30 while (_offset < _json.Length) {
31 if (_json [_offset] >= '0' && _json [_offset] <= '9') {
32 if (hasExp) {
33 sbExp.Append (_json [_offset]);
34 } else {
35 sbNum.Append (_json [_offset]);
36 }
37 } else if (_json [_offset] == '.') {
38 if (hasExp) {
39 throw new MalformedJsonException ("Decimal separator in exponent");
40 }
41
42 if (hasDec) {
43 throw new MalformedJsonException ("Multiple decimal separators in number found");
44 }
45
46 if (sbNum.Length == 0) {
47 throw new MalformedJsonException ("No leading digits before decimal separator found");
48 }
49
50 sbNum.Append ('.');
51 hasDec = true;
52 } else if (_json [_offset] == '-') {
53 if (hasExp) {
54 if (sbExp.Length > 0) {
55 throw new MalformedJsonException ("Negative sign in exponent after digits");
56 }
57
58 sbExp.Append (_json [_offset]);
59 } else {
60 if (sbNum.Length > 0) {
61 throw new MalformedJsonException ("Negative sign in mantissa after digits");
62 }
63
64 sbNum.Append (_json [_offset]);
65 }
66 } else if (_json [_offset] == 'e' || _json [_offset] == 'E') {
67 if (hasExp) {
68 throw new MalformedJsonException ("Multiple exponential markers in number found");
69 }
70
71 if (sbNum.Length == 0) {
72 throw new MalformedJsonException ("No leading digits before exponential marker found");
73 }
74
75 sbExp = new StringBuilder ();
76 hasExp = true;
77 } else if (_json [_offset] == '+') {
78 if (hasExp) {
79 if (sbExp.Length > 0) {
80 throw new MalformedJsonException ("Positive sign in exponent after digits");
81 }
82
83 sbExp.Append (_json [_offset]);
84 } else {
85 throw new MalformedJsonException ("Positive sign in mantissa found");
86 }
87 } else {
88 if (!StringParsers.TryParseDouble (sbNum.ToString (), out double number)) {
89 throw new MalformedJsonException ("Mantissa is not a valid decimal (\"" + sbNum + "\")");
90 }
91
92 if (hasExp) {
93 if (!int.TryParse (sbExp.ToString (), out int exp)) {
94 throw new MalformedJsonException ("Exponent is not a valid integer (\"" + sbExp + "\")");
95 }
96
97 number *= Math.Pow (10, exp);
98 }
99
100 //Log.Out ("JSON:Parsed Number: " + number.ToString ());
101 return new JsonNumber (number);
102 }
103
104 _offset++;
105 }
106
107 throw new MalformedJsonException ("End of JSON reached before parsing number finished");
108 }
109
110 public override string AsString => value.ToCultureInvariantString ();
111 public override int AsInt => GetInt ();
112 public override double AsDouble => value;
113 }
114}
Note: See TracBrowser for help on using the repository browser.