ptypes

ptypes Commit Details


Date:2013-05-12 21:16:00 (11 years 7 months ago)
Author:Natalie Adams
Branch:default
Commit:bd67c96aeb8b
Parents: 3005c9d543da
Message:Updating code

adding json parser
trying to fix test suite on windows
Changes:
Dsrc/ptparray.cpp (full)
Minclude/ptypes.h (3 diffs)
Msrc/pjson.cxx (1 diff)
Msrc/ppodlist.cxx (1 diff)
Msrc/ptypes_test.cxx (2 diffs)
Mwin32/PTypes.sdf
Mwin32/PTypes_DLL.vcxproj (1 diff)
Mwin32/PTypes_DLL.vcxproj.filters (1 diff)
Mwin32/PTypes_DLL.vcxproj.user (1 diff)
Mwin32/PTypes_Lib.vcxproj (2 diffs)
Mwin32/PTypes_Lib.vcxproj.filters (1 diff)
Mwin32/PTypes_Lib_ST.vcxproj (1 diff)
Mwin32/PTypes_Lib_ST.vcxproj.filters (1 diff)
Mwin32/PTypes_Lib_ST.vcxproj.user (1 diff)

File differences

include/ptypes.h
410410
411411
412412
413
413
414414
415415
416416
......
418418
419419
420420
421
421
422
423
424
422425
423426
424427
......
474477
475478
476479
480
477481
478482
479483
// as a basis for all list types in the library. this class is undocumented.
// tpodlist template must be used instead.
class ptpublic _podlist: public noncopyable
class _podlist: public noncopyable
{
protected:
void* list; // pointer to the array
int capacity; // allocated for the list
int itemsize; // list item size
static void idxerror();
/*#ifndef DEBUG
static
#endif*/
void idxerror() const { fatal(CRIT_FIRST + 30, "List index out of bounds"); }
_podlist& operator =(const _podlist& t);
tpodlist(): _podlist(sizeof(X)) {}
tpodlist<X, initzero>& operator =(const tpodlist<X, initzero>& t)
{ _podlist::operator =(t); return *this; }
~tpodlist() { }
void set_count(int newcount) { _podlist::set_count(newcount, initzero); }
X& ins(int index) { idxa(index); return doins(index); }
src/pjson.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "ptypes.h"
#include "pstreams.h"
PTYPES_BEGIN
pt::string json::JsonEncode(const pt::variant & v)
{
pt::string builder;
bool success = SerializeValue(v, builder);
if (success)
return builder;
else
return "";
}
bool json::SerializeValue(const pt::variant & value, pt::string & builder)
{
bool success = true;
if (pt::isstring(value))
{
success = SerializeString((pt::string)value, builder);
} else if (pt::isobject(value)) {
pt::tparray * arr = (pt::tparray *)(pt::component *)value;
if (pt::isassoc((*arr)))
{
success = SerializeObject(*arr, builder);
} else if (pt::islist((*arr))) {
success = SerializeArray(*arr, builder);
}
} else if (pt::isbool(value)) {
if ((bool)value)
builder += "true";
else
builder += "false";
} else if (pt::isint(value)) {
success = SerializeNumber(value, builder);
} else if (pt::isnull(value)) {
builder += "null";
} else {
success = false;
}
return success;
}
bool json::SerializeNumber(large number, string & builder)
{
builder += pt::itostring(number);
return true;
}
bool json::SerializeArray(const tparray & anArray, string & builder)
{
builder += "[";
bool first = true;
variant val;
for(int i = 0; anext(anArray, i, val);)
{
if (!first)
builder += ", ";
if (!SerializeValue(val, builder))
{
return false;
}
first = false;
}
builder += "]";
return true;
}
bool json::SerializeObject(const tparray & anObject, string & builder)
{
builder += "{";
bool first = true;
pt::variant key, val;
for(int i = 0; anext(anObject, i, val, key);)
{
if (!first)
{
builder += ", ";
}
SerializeString(key, builder);
builder += ":";
if (!SerializeValue(val, builder))
{
return false;
}
first = false;
}
builder += "}";
return true;
}
bool json::SerializeString(const string & aString, string & builder)
{
builder += '"';
for(int i = 0; i < length(aString); i++)
{
char c = aString[i];
if (c == '"') {
builder += "\\\"";
} else if (c == '\\') {
builder += "\\\\";
} else if (c == '\b') {
builder += "\\b";
} else if (c == '\f') {
builder += "\\f";
} else if (c == '\n') {
builder += "\\n";
} else if (c == '\r') {
builder += "\\r";
} else if (c == '\t') {
builder += "\\t";
} else {
int codepoint = (int)c;
if ((codepoint >= 32) && (codepoint <= 126)) {
builder += c;
} else {
builder += "\\u" + pt::itostring(codepoint, 16, 4, '0');
}
}
}
builder += '"';
return true;
}
#ifndef USE_VARIANT
pt::tparray * json::ParseArray(const string & json, int & index, bool & success)
#else
pt::variant json::ParseArray(const string & json, int & index, bool & success)
#endif
{
#ifndef USE_VARIANT
tparray * ret = new tparray();
#else
variant ret;
#endif
NextToken(json, index);
bool done = false;
while (!done) {
int token = LookAhead(json, index);
if (token == json::TOKEN_NONE)
{
success = false;
return ret;
} else if (token == json::TOKEN_COMMA) {
NextToken(json, index);
} else if (token == json::TOKEN_SQUARED_CLOSE) {
NextToken(json, index);
break;
} else {
variant v = ParseValue(json, index, success);
if (!success)
return ret; // NULL
#ifndef USE_VARIANT
add((*ret), v);
#else
add(ret, v);
#endif
}
}
return ret;
}
#ifndef USE_VARIANT
pt::tparray * json::ParseObject(const string & json, int & index, bool & success)
#else
pt::variant json::ParseObject(const string & json, int & index, bool & success)
#endif
{
#ifndef USE_VARIANT
tparray * ret = new tparray();
#else
pt::variant ret;
#endif
int token;
NextToken(json, index);
bool done = false;
while (!done) {
token = LookAhead(json, index);
if (token == json::TOKEN_NONE)
{
success = false;
return ret; // NULL
} else if (token == json::TOKEN_COMMA) {
NextToken(json, index);
} else if (token == json::TOKEN_CURLY_CLOSE) {
NextToken(json, index);
return ret; // NULL
} else {
// Missing support for numbers as keys
string name = ParseString(json, index, success);
if (!success) {
success = false;
return ret; //NULL
}
token = NextToken(json, index);
if (token != json::TOKEN_COLON)
{
success = false;
return ret; //NULL
}
variant obj = ParseValue(json, index, success);
if (!success) {
success = false;
return ret; //NULL
}
#ifndef USE_VARIANT
add((*ret), name, obj);
#else
put(ret, name, obj);
#endif
//put(ret, name, obj);
}
}
return ret;
}
pt::string json::ParseString(const pt::string & json, int & index, bool & success)
{
pt::string ret;
char c;
EatWhiteSpace(json, index);
c = json[index++];
bool complete = false;
while (!complete) {
if (index == length(json))
break;
c = json[index++];
if (c == '"') {
complete = true;
break;
} else if (c == '\\') {
if (index == length(json))
break;
c = json[index++];
//clever programming
bool brk = false;
int remainingLength;
switch(c)
{
case 'b':
ret += '\b';
break;
case 'f':
ret += '\f';
break;
case 'n':
ret += '\n';
break;
case 'r':
ret += '\r';
break;
case 't':
ret += '\t';
break;
case 'u':
remainingLength = length(json) - index;
if (remainingLength >= 4)
{
pt::large codePoint = pt::stringtoi(copy(json, index, 4));
ret += (char)codePoint;
index += 4;
} else {
brk = true;
}
break;
case '"':
case '\\':
case '/':
ret += c;
break;
}
if (brk)
break;
} else {
ret += c;
}
}
if (!complete) {
success = false;
return "";
}
return ret;
}
pt::large json::ParseNumber(const string & json, int & index, bool & success)
{
EatWhiteSpace(json, index);
int lastIndex = GetLastIndexOfNumber(json, index);
int charLength = (lastIndex - index) + 1;
pt::large number = stringtoi(copy(json, index, charLength));
index = lastIndex + 1;
return number;
}
int json::GetLastIndexOfNumber(const string & json, int index)
{
int lastIndex;
cset num = "0-9eE~43~45~46";
for(lastIndex = index; lastIndex < length(json); lastIndex++)
{
if (!(json[lastIndex] & num))
break;
}
return lastIndex - 1;
}
pt::variant json::JsonDecode(const pt::string & json, bool & success)
{
success = true;
if (!pt::isempty(json))
{
int index = 0;
pt::variant ret = ParseValue(json, index, success);
return ret;
} else {
return NULL;
}
}
pt::variant json::ParseValue(const pt::string & json, int & index, bool & success)
{
switch(LookAhead(json, index)) {
case json::TOKEN_STRING:
return ParseString(json, index, success);
case json::TOKEN_NUMBER:
return ParseNumber(json, index, success);
case json::TOKEN_CURLY_OPEN:
return ParseObject(json, index, success);
case json::TOKEN_SQUARED_OPEN:
return ParseArray(json, index, success);
case json::TOKEN_TRUE:
NextToken(json, index);
return true;
case json::TOKEN_FALSE:
NextToken(json, index);
return false;
case json::TOKEN_NULL:
NextToken(json, index);
return NULL;
case json::TOKEN_NONE:
break;
}
success = false;
return NULL;
}
int json::LookAhead(const pt::string & json, int index)
{
// why is this needed?
int saveIndex = index;
return NextToken(json, saveIndex);
}
int json::NextToken(const pt::string & json, int & index)
{
EatWhiteSpace(json, index);
if (index == length(json))
{
return json::TOKEN_NONE;
}
char c = json[index];
index++;
switch (c)
{
case '{':
return json::TOKEN_CURLY_OPEN;
case '}':
return json::TOKEN_CURLY_CLOSE;
case '[':
return json::TOKEN_SQUARED_OPEN;
case ']':
return json::TOKEN_SQUARED_CLOSE;
case ',':
return json::TOKEN_COMMA;
case '"':
return json::TOKEN_STRING;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-': //huh? - negative duh
return json::TOKEN_NUMBER;
case ':':
return json::TOKEN_COLON;
}
index--;
int remainingLength = length(json) - index;
// some clever shortcuts....
if (remainingLength >= 5)
{
if (copy(json, index, 5) == "false")
{
index += 5;
return json::TOKEN_FALSE;
}
}
if (remainingLength >= 4)
{
if (copy(json, index, 4) == "true")
{
index += 4;
return json::TOKEN_TRUE;
}
if (copy(json, index, 4) == "null")
{
index += 4;
return json::TOKEN_NULL;
}
}
return json::TOKEN_NONE;
}
void json::EatWhiteSpace(const pt::string & json, int & index)
{
pt::cset wspace = "~09~0d~0a ";
for(; index < pt::length(json); index++)
{
if (!(json[index] & wspace))
break;
}
}
PTYPES_END
src/ppodlist.cxx
1515
1616
1717
18
18
1919
2020
21
21
2222
2323
2424
PTYPES_BEGIN
void _podlist::idxerror()
/*void _podlist::idxerror() const
{
fatal(CRIT_FIRST + 30, "List index out of bounds");
}
}*/
_podlist::_podlist(int iitemsize)
src/ptparray.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "ptypes.h"
#include "pstreams.h"
PTYPES_BEGIN
bool ptdecl anext(const tparray& a, int& i, variant& val)
{
//if (a._vals.size() == i)
//if (a._vals.get_count() == i)
if (alength(a._vals) == i)
{
return false;
}
else
{
val = a._vals[(large)i];
i++;
return true;
}
}
bool ptdecl anext(const tparray& a, int& i, variant& val, variant & key)
{
//if (a._keys.size() == i)
//if (a._keys.get_count() == i)
if (alength(a._keys) == i)
{
return false;
}
else
{
val = a._vals[(large)i];
key = a._keys[(large)i];
i++;
return true;
}
}
void ptdecl add(tparray & t, const variant & val)
{
if (t.tag == ARR_NULL || t.tag == ARR_LIST)
{
t.tag = ARR_LIST;
//pout.put("here1");
//t._vals.push_back(val);
add(t._vals, val);
//t._vals.add(val);
//pout.put("here2");
}
//else drop it
}
void ptdecl add(tparray & t, const variant & key, const variant & val)
{
if (t.tag == ARR_NULL || t.tag == ARR_ASSOCIATIVE)
{
t.tag = ARR_ASSOCIATIVE;
add(t._vals, val);
add(t._keys, key);
//t._vals.add(val);
//t._keys.add(key);
//t._vals.push_back(val);
//t._keys.push_back(key);
}
}
variant ptdecl get(tparray & t, const variant & val)
{
//for(int i = 0; i < t._keys.size(); i++)
//for(int i = 0; i < t._keys.get_count(); i++)
for(int i = 0; i < alength(t._keys); i++)
{
if (t._keys[(large)i] == val)
{
return t._vals[(large)i];
}
}
return NULL;
}
variant ptdecl at(tparray & t, large index)
{
return t._vals[index];
}
variant ptdecl keyat(tparray & t, large index)
{
return t._keys[index];
}
PTYPES_END
src/ptypes_test.cxx
294294
295295
296296
297
298
297
298
299299
300300
301301
......
309309
310310
311311
312
312
313313
314314
315315
{
pout.put("\n--- PODLIST\n");
tpodlist<int, true> p;
p.add() = 6;
//tpodlist<int> p;
/*p.add() = 6;
p.add(8);
p.ins(1, 7);
showint(7, p[1]);
tpodlist<int, true> p1;
p1.add(p);
p1.pop();
p1.add(p);
p1.add(p);*/
}
win32/PTypes_DLL.vcxproj
248248
249249
250250
251
251252
252253
253254
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptparray.cxx" />
<ClCompile Include="..\src\punit.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
win32/PTypes_DLL.vcxproj.filters
181181
182182
183183
184
185
186
184187
185188
186189
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\ptparray.cxx">
<Filter>Types</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h">
win32/PTypes_DLL.vcxproj.user
11
22
3
4
5
36
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>
win32/PTypes_Lib.vcxproj
144144
145145
146146
147
147148
148149
149150
......
216217
217218
218219
219
220
220221
221222
222223
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\pjson.cxx" />
<ClCompile Include="..\src\pmem.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptparray.cpp" />
<ClCompile Include="..\src\ptparray.cxx" />
<ClCompile Include="..\src\punit.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
win32/PTypes_Lib.vcxproj.filters
182182
183183
184184
185
185
186
187
188
186189
187190
188191
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\ptparray.cpp">
<ClCompile Include="..\src\pjson.cxx">
<Filter>Types</Filter>
</ClCompile>
<ClCompile Include="..\src\ptparray.cxx">
<Filter>Types</Filter>
</ClCompile>
</ItemGroup>
win32/PTypes_Lib_ST.vcxproj
222222
223223
224224
225
225226
226227
227228
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\ptparray.cxx" />
<ClCompile Include="..\src\punknown.cxx">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
win32/PTypes_Lib_ST.vcxproj.filters
151151
152152
153153
154
155
156
154157
155158
156159
<ClCompile Include="..\src\pipsvbase.cxx">
<Filter>Inet</Filter>
</ClCompile>
<ClCompile Include="..\src\ptparray.cxx">
<Filter>Types</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pasync.h">
win32/PTypes_Lib_ST.vcxproj.user
11
22
3
4
5
36
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>

Archive Download the corresponding diff file

Branches

Tags

Page rendered in 1.64884s using 14 queries.