@@ -14,6 +14,8 @@ import nulib.string;
1414import nulib.math;
1515import numem;
1616
17+ import core.stdc.stdio : printf;
18+
1719@nogc :
1820
1921/**
@@ -32,6 +34,7 @@ Result!DataNode readJson(Stream stream) @nogc {
3234
3335 if (auto err = reader.readJsonImpl(result, reader.stream.tell, reader.stream.length))
3436 return error! DataNode(err);
37+ printf(" Read complete\n " );
3538
3639 return ok (result.move());
3740}
@@ -50,7 +53,7 @@ Result!DataNode readJson(Stream stream) @nogc {
5053
5154*/
5255string readJson (StreamReader reader, ref DataNode node, uint length = uint .max) @nogc {
53- return reader.readJsonImpl(node, reader.stream.tell, min(reader.stream.length- reader.stream.tell, length ));
56+ return reader.readJsonImpl(node, reader.stream.tell, min(length, reader.stream.length- reader.stream.tell));
5457}
5558
5659
@@ -67,6 +70,35 @@ char peekChar(StreamReader reader) {
6770 return c;
6871}
6972
73+ string peek (StreamReader reader, uint length) {
74+ auto s = reader.read(length);
75+ if (s.length > 0 ) {
76+ reader.stream.seek(- cast (ptrdiff_t )s.length, SeekOrigin.relative);
77+ }
78+ return s;
79+ }
80+
81+ bool peek (StreamReader reader, string key) {
82+ string read = reader.peek(cast (uint )key.length);
83+ bool same = key == read;
84+ nu_freea(read);
85+ return same;
86+ }
87+
88+ string read (StreamReader reader, uint length) {
89+ return reader.readUTF8(length).take();
90+ }
91+
92+ string popString (StreamReader reader, string key) {
93+ auto read = reader.readUTF8(cast (uint )key.length);
94+ if (read == key) {
95+ return key;
96+ }
97+
98+ reader.stream.seek(- cast (ptrdiff_t )read.length, SeekOrigin.relative);
99+ return null ;
100+ }
101+
70102string readJsonString (StreamReader reader) {
71103
72104 // Skip initial quote.
@@ -89,7 +121,7 @@ string readJsonString(StreamReader reader) {
89121 result ~= c;
90122 }
91123 } while (c != ' "' );
92- return result.take()[ 0 .. $ - 1 ] ;
124+ return result.take();
93125}
94126
95127string readJsonNumber (StreamReader reader) {
@@ -100,6 +132,8 @@ string readJsonNumber(StreamReader reader) {
100132 c = cast (char )reader.readU8();
101133 result ~= c;
102134 } while (isNumberChar(c));
135+
136+ reader.stream.seek(- 1 , SeekOrigin.relative);
103137 return result.take();
104138}
105139
@@ -108,48 +142,75 @@ bool isJsonSymbol(char c) {
108142 return isAlphaNumeric (c) ||
109143 c == ' "' || c == ' :' || c == ' ,' ||
110144 c == ' {' || c == ' }' ||
111- c == ' [' || c == ' ]' ;
145+ c == ' [' || c == ' ]' || c == ' . ' ;
112146}
113147
114148void skipWhitespace (StreamReader reader) {
115- do {} while (! isJsonSymbol(cast (char )reader.readU8()));
149+ do { } while (! isJsonSymbol(cast (char )reader.readU8()));
116150 reader.stream.seek(- 1 , SeekOrigin.relative);
117151}
118152
119153bool isNumberChar (char c) {
120- return (c >= ' 0' && c <= ' 9' ) || c == ' .' ;
154+ return (c >= ' 0' && c <= ' 9' ) || c == ' .' || c == ' - ' || c == ' + ' ;
121155}
122156
123157string readJsonImpl ()(StreamReader reader, ref DataNode node, size_t start, size_t length) {
124158 import nulib.conv : to_floating;
125- reader.skipWhitespace();
126159
127- if (reader.stream.tell() > start+ length)
160+ reader.skipWhitespace();
161+ if (reader.stream.tell() >= start+ length)
128162 return " Reached EOF" ;
129163
164+
130165 char c = cast (char )reader.readU8();
131166 switch (c) {
132167 default :
168+ reader.stream.seek(- 1 , SeekOrigin.relative);
133169 if (isNumberChar(c)) {
134- reader.stream.seek(- 1 , SeekOrigin.relative);
135170
136171 auto valueStr = reader.readJsonNumber();
137172 node = DataNode(to_floating! double (valueStr));
138173 nu_freea(valueStr);
174+ return null ;
175+ }
176+
177+ if (reader.peek(" true" )) {
178+ reader.stream.seek(4 , SeekOrigin.relative);
179+ node = DataNode(true );
180+ return null ;
181+ }
182+
183+ if (reader.peek(" false" )) {
184+ reader.stream.seek(5 , SeekOrigin.relative);
185+ node = DataNode(false );
186+ return null ;
187+ }
188+
189+ // Skip 'null'
190+ if (reader.peek(" null" )) {
191+ reader.stream.seek(4 , SeekOrigin.relative);
192+ return null ;
139193 }
140- return null ;
194+
195+ // Okay, no idea what this character is.
196+ return " Unexpected token" ;
141197
142198 case ' [' :
143199 node = DataNode.createArray();
200+
201+ // Empty array.
202+ if (reader.peekChar() == ' ]' ) {
203+ reader.stream.seek(1 , SeekOrigin.relative);
204+ return null ;
205+ }
206+
144207 do {
145208 DataNode value;
146209
147210 reader.skipWhitespace();
148-
149211 if (auto error = reader.readJsonImpl(value, start, length))
150212 return error;
151213 node ~= value.move();
152-
153214 reader.skipWhitespace();
154215
155216 c = cast (char )reader.readU8();
@@ -161,6 +222,13 @@ string readJsonImpl()(StreamReader reader, ref DataNode node, size_t start, size
161222
162223 case ' {' :
163224 node = DataNode.createObject();
225+
226+ // Empty object.
227+ if (reader.peekChar() == ' }' ) {
228+ reader.stream.seek(1 , SeekOrigin.relative);
229+ return null ;
230+ }
231+
164232 do {
165233 DataNode value;
166234
@@ -169,9 +237,6 @@ string readJsonImpl()(StreamReader reader, ref DataNode node, size_t start, size
169237 string key = reader.readJsonString();
170238 reader.skipWhitespace();
171239
172- import core.stdc.stdio : printf;
173- printf(" %s\n " , key.ptr);
174-
175240 c = cast (char )reader.readU8();
176241 if (c != ' :' )
177242 return " Invalid key-value pair!" ;
0 commit comments