Skip to content

Commit 8f86d8b

Browse files
authored
add jute (#376)
1 parent ba2c8ee commit 8f86d8b

File tree

5 files changed

+408
-17
lines changed

5 files changed

+408
-17
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
*.gcda
2+
*.gcno
3+
*.gcov
14
*.ilk
25
*.log
36
*.o
47
*.obj
58
*.pdb
69
/src/loda
710
/src/loda.exe
8-
/src/sys/jute.*
911
/tests/programs/local/
1012
/loda
1113
/loda.exe

src/Makefile

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,10 @@ OBJS = cmd/benchmark.o cmd/boinc.o cmd/commands.o cmd/main.o cmd/test.o \
1717
oeis/oeis_list.o oeis/oeis_manager.o oeis/oeis_program.o oeis/oeis_sequence.o \
1818
sys/file.o sys/git.o sys/jute.o sys/log.o sys/metrics.o sys/process.o sys/setup.o sys/util.o sys/web_client.o
1919

20-
loda: sys/jute.h sys/jute.cpp $(OBJS)
20+
loda: $(OBJS)
2121
$(CXX) $(LDFLAGS) -o loda $(OBJS)
2222
[ -L ../loda ] || ( cd .. && ln -s src/loda loda )
2323
du -sh loda
2424

25-
sys/jute.h:
26-
curl -sS -o sys/jute.h https://raw.githubusercontent.com/ckrause/jute/master/jute.h
27-
28-
sys/jute.cpp:
29-
curl -sS -o sys/jute.cpp https://raw.githubusercontent.com/ckrause/jute/master/jute.cpp
30-
3125
clean:
32-
rm -R -f $(OBJS) loda ../loda sys/jute.h sys/jute.cpp
26+
rm -R -f $(OBJS) loda ../loda

src/Makefile.windows.mk

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,9 @@ SRCS = cmd/benchmark.cpp cmd/boinc.cpp cmd/commands.cpp cmd/main.cpp cmd/test.cp
1919
oeis/oeis_list.cpp oeis/oeis_manager.cpp oeis/oeis_program.cpp oeis/oeis_sequence.cpp \
2020
sys/file.cpp sys/git.cpp sys/jute.cpp sys/log.cpp sys/metrics.cpp sys/process.cpp sys/setup.cpp sys/util.cpp sys/web_client.cpp
2121

22-
loda: sys/jute.h sys/jute.cpp $(SRCS)
22+
loda: $(SRCS)
2323
cl /EHsc /Feloda.exe $(CXXFLAGS) $(SRCS)
2424
copy loda.exe ..
2525

26-
sys/jute.h:
27-
curl -sS -o sys/jute.h https://raw.githubusercontent.com/amir-s/jute/master/jute.h
28-
29-
sys/jute.cpp:
30-
curl -sS -o sys/jute.cpp https://raw.githubusercontent.com/amir-s/jute/master/jute.cpp
31-
3226
clean:
33-
del /f $(OBJS) loda ../loda sys/jute.h sys/jute.cpp
27+
del /f $(OBJS) loda.exe ../loda.exe

src/sys/jute.cpp

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <map>
4+
#include <string>
5+
#include <sstream>
6+
#include <fstream>
7+
#include <cstring>
8+
#include "jute.h"
9+
using namespace std;
10+
using namespace jute;
11+
12+
string deserialize(const string& ref) {
13+
string out = "";
14+
for (size_t i=0;i<ref.length();i++) {
15+
if (ref[i] == '\\' && i+1 < ref.length()) {
16+
int plus = 2;
17+
if (ref[i+1] == '\"') {
18+
out += '"';
19+
}else if (ref[i+1] == '\\') {
20+
out += '\\';
21+
}else if (ref[i+1] == '/') {
22+
out += '/';
23+
}else if (ref[i+1] == 'b') {
24+
out += '\b';
25+
}else if (ref[i+1] == 'f') {
26+
out += '\f';
27+
}else if (ref[i+1] == 'n') {
28+
out += '\n';
29+
}else if (ref[i+1] == 'r') {
30+
out += '\r';
31+
}else if (ref[i+1] == 't') {
32+
out += '\t';
33+
}else if(ref[i+1] == 'u' && i+5 < ref.length()) {
34+
unsigned long long v = 0;
35+
for (int j=0;j<4;j++) {
36+
v *= 16;
37+
if (ref[i+2+j] <= '9' && ref[i+2+j] >= '0') v += ref[i+2+j]-'0';
38+
if (ref[i+2+j] <= 'f' && ref[i+2+j] >= 'a') v += ref[i+2+j]-'a'+10;
39+
}
40+
out += (char)v;
41+
plus = 6;
42+
}
43+
i += plus-1;
44+
continue;
45+
}
46+
out += ref[i];
47+
}
48+
return out;
49+
}
50+
51+
string jValue::makesp(int d) {
52+
string s = "";
53+
while (d--) s += " ";
54+
return s;
55+
}
56+
string jValue::to_string_d(int d) {
57+
if (type == JSTRING) return string("\"") + svalue + string("\"");
58+
if (type == JNUMBER) return svalue;
59+
if (type == JBOOLEAN) return svalue;
60+
if (type == JNULL) return "null";
61+
if (type == JOBJECT) {
62+
string s = string("{\n");
63+
for (size_t i=0;i<properties.size();i++) {
64+
s += makesp(d) + string("\"") + properties[i].first + string("\": ") + properties[i].second.to_string_d(d+1) + string(i==properties.size()-1?"":",") + string("\n");
65+
}
66+
s += makesp(d-1) + string("}");
67+
return s;
68+
}
69+
if (type == JARRAY) {
70+
string s = "[";
71+
for (size_t i=0;i<arr.size();i++) {
72+
if (i) s += ", ";
73+
s += arr[i].to_string_d(d+1);
74+
}
75+
s += "]";
76+
return s;
77+
}
78+
return "##";
79+
}
80+
jValue::jValue() {
81+
this->type = JUNKNOWN;
82+
}
83+
jValue::jValue(jType tp) {
84+
this->type = tp;
85+
}
86+
87+
string jValue::to_string() {
88+
return to_string_d(1);
89+
}
90+
jType jValue::get_type() {
91+
return type;
92+
}
93+
void jValue::set_type(jType tp) {
94+
type = tp;
95+
}
96+
void jValue::add_property(string key, jValue v) {
97+
mpindex[key] = properties.size();
98+
properties.push_back(make_pair(key, v));
99+
}
100+
void jValue::add_element(jValue v) {
101+
arr.push_back(v);
102+
}
103+
void jValue::set_string(string s) {
104+
svalue = s;
105+
}
106+
int jValue::as_int() {
107+
stringstream ss;
108+
ss << svalue;
109+
int k;
110+
ss >> k;
111+
return k;
112+
}
113+
double jValue::as_double() {
114+
stringstream ss;
115+
ss << svalue;
116+
double k;
117+
ss >> k;
118+
return k;
119+
}
120+
bool jValue::as_bool() {
121+
if (svalue == "true") return true;
122+
return false;
123+
}
124+
void* jValue::as_null() {
125+
return NULL;
126+
}
127+
string jValue::as_string() {
128+
return deserialize(svalue);
129+
}
130+
int jValue::size() {
131+
if (type == JARRAY) {
132+
return (int)arr.size();
133+
}
134+
if (type == JOBJECT) {
135+
return (int)properties.size();;
136+
}
137+
return 0;
138+
}
139+
jValue jValue::operator[](int i) {
140+
if (type == JARRAY) {
141+
return arr[i];
142+
}
143+
if (type == JOBJECT) {
144+
return properties[i].second;
145+
}
146+
return jValue();
147+
}
148+
jValue jValue::operator[](string s) {
149+
if (mpindex.find(s) == mpindex.end()) return jValue();
150+
return properties[mpindex[s]].second;
151+
}
152+
153+
struct parser::token {
154+
string value;
155+
token_type type;
156+
token(string value="",token_type type=UNKNOWN): value(value), type(type) {}
157+
};
158+
bool parser::is_whitespace(const char c) {
159+
return isspace(c);
160+
}
161+
int parser::next_whitespace(const string& source, int i) {
162+
while (i < (int)source.length()) {
163+
if (source[i] == '"') {
164+
i++;
165+
while (i < (int)source.length() && (source[i] != '"' || source[i-1] == '\\')) i++;
166+
}
167+
if (source[i] == '\'') {
168+
i++;
169+
while (i < (int)source.length() && (source[i] != '\'' || source[i-1] == '\\')) i++;
170+
}
171+
if (is_whitespace(source[i])) return i;
172+
i++;
173+
}
174+
return (int)source.length();
175+
}
176+
int parser::skip_whitespaces(const string& source, int i) {
177+
while (i < (int)source.length()) {
178+
if (!is_whitespace(source[i])) return i;
179+
i++;
180+
}
181+
return -1;
182+
}
183+
184+
vector<parser::token> parser::tokenize(string source) {
185+
source += " ";
186+
vector<token> tokens;
187+
int index = skip_whitespaces(source, 0);
188+
while (index >= 0) {
189+
int next = next_whitespace(source, index);
190+
string str = source.substr(index, next-index);
191+
192+
size_t k = 0;
193+
while (k < str.length()) {
194+
if (str[k] == '"') {
195+
size_t tmp_k = k+1;
196+
while (tmp_k < str.length() && (str[tmp_k] != '"' || str[tmp_k-1] == '\\')) tmp_k++;
197+
tokens.push_back(token(str.substr(k+1, tmp_k-k-1), STRING));
198+
k = tmp_k+1;
199+
continue;
200+
}
201+
if (str[k] == '\'') {
202+
size_t tmp_k = k+1;
203+
while (tmp_k < str.length() && (str[tmp_k] != '\'' || str[tmp_k-1] == '\\')) tmp_k++;
204+
tokens.push_back(token(str.substr(k+1, tmp_k-k-1), STRING));
205+
k = tmp_k+1;
206+
continue;
207+
}
208+
if (str[k] == ',') {
209+
tokens.push_back(token(",", COMMA));
210+
k++;
211+
continue;
212+
}
213+
if (str[k] == 't' && k+3 < str.length() && str.substr(k, 4) == "true") {
214+
tokens.push_back(token("true", BOOLEAN));
215+
k += 4;
216+
continue;
217+
}
218+
if (str[k] == 'f' && k+4 < str.length() && str.substr(k, 5) == "false") {
219+
tokens.push_back(token("false", BOOLEAN));
220+
k += 5;
221+
continue;
222+
}
223+
if (str[k] == 'n' && k+3 < str.length() && str.substr(k, 4) == "null") {
224+
tokens.push_back(token("null", NUL));
225+
k += 4;
226+
continue;
227+
}
228+
if (str[k] == '}') {
229+
tokens.push_back(token("}", CROUSH_CLOSE));
230+
k++;
231+
continue;
232+
}
233+
if (str[k] == '{') {
234+
tokens.push_back(token("{", CROUSH_OPEN));
235+
k++;
236+
continue;
237+
}
238+
if (str[k] == ']') {
239+
tokens.push_back(token("]", BRACKET_CLOSE));
240+
k++;
241+
continue;
242+
}
243+
if (str[k] == '[') {
244+
tokens.push_back(token("[", BRACKET_OPEN));
245+
k++;
246+
continue;
247+
}
248+
if (str[k] == ':') {
249+
tokens.push_back(token(":", COLON));
250+
k++;
251+
continue;
252+
}
253+
if (str[k] == '-' || (str[k] <= '9' && str[k] >= '0')) {
254+
size_t tmp_k = k;
255+
if (str[tmp_k] == '-') tmp_k++;
256+
while (tmp_k < str.size() && ((str[tmp_k] <= '9' && str[tmp_k] >= '0') || str[tmp_k] == '.')) tmp_k++;
257+
tokens.push_back(token(str.substr(k, tmp_k-k), NUMBER));
258+
k = tmp_k;
259+
continue;
260+
}
261+
tokens.push_back(token(str.substr(k), UNKNOWN));
262+
k = str.length();
263+
}
264+
265+
index = skip_whitespaces(source, next);
266+
}
267+
// for (int i=0;i<tokens.size();i++) {
268+
// cout << i << " " << tokens[i].value << endl;
269+
// }
270+
return tokens;
271+
}
272+
273+
274+
jValue parser::json_parse(vector<token> v, int i, int& r) {
275+
jValue current;
276+
if (v[i].type == CROUSH_OPEN) {
277+
current.set_type(JOBJECT);
278+
int k = i+1;
279+
while (v[k].type != CROUSH_CLOSE) {
280+
string key = v[k].value;
281+
k+=2; // k+1 should be ':'
282+
int j = k;
283+
jValue vv = json_parse(v, k, j);
284+
current.add_property(key, vv);
285+
k = j;
286+
if (v[k].type == COMMA) k++;
287+
}
288+
r = k+1;
289+
return current;
290+
}
291+
if (v[i].type == BRACKET_OPEN) {
292+
current.set_type(JARRAY);
293+
int k = i+1;
294+
while (v[k].type != BRACKET_CLOSE) {
295+
int j = k;
296+
jValue vv = json_parse(v, k, j);
297+
current.add_element(vv);
298+
k = j;
299+
if (v[k].type == COMMA) k++;
300+
}
301+
r = k+1;
302+
return current;
303+
}
304+
if (v[i].type == NUMBER) {
305+
current.set_type(JNUMBER);
306+
current.set_string(v[i].value);
307+
r = i+1;
308+
return current;
309+
}
310+
if (v[i].type == STRING) {
311+
current.set_type(JSTRING);
312+
current.set_string(v[i].value);
313+
r = i+1;
314+
return current;
315+
}
316+
if (v[i].type == BOOLEAN) {
317+
current.set_type(JBOOLEAN);
318+
current.set_string(v[i].value);
319+
r = i+1;
320+
return current;
321+
}
322+
if (v[i].type == NUL) {
323+
current.set_type(JNULL);
324+
current.set_string("null");
325+
r = i+1;
326+
return current;
327+
}
328+
return current;
329+
}
330+
331+
jValue parser::parse(const string& str) {
332+
int k;
333+
return json_parse(tokenize(str), 0, k);
334+
}
335+
jValue parser::parse_file(const string& filename) {
336+
ifstream in(filename.c_str());
337+
string str = "";
338+
string tmp;
339+
while (getline(in, tmp)) str += tmp;
340+
in.close();
341+
return parser::parse(str);
342+
}
343+

0 commit comments

Comments
 (0)