diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 include/ptypes.h --- a/include/ptypes.h Sun May 12 16:17:02 2013 -0500 +++ b/include/ptypes.h Sun May 12 21:16:53 2013 -0500 @@ -410,7 +410,7 @@ // 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 @@ -418,7 +418,10 @@ 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); @@ -474,6 +477,7 @@ tpodlist(): _podlist(sizeof(X)) {} tpodlist& operator =(const tpodlist& 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); } diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 src/pjson.cxx --- a/src/pjson.cxx Sun May 12 16:17:02 2013 -0500 +++ b/src/pjson.cxx Sun May 12 21:16:53 2013 -0500 @@ -0,0 +1,483 @@ +#include +#include +#include + +#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 \ No newline at end of file diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 src/ppodlist.cxx --- a/src/ppodlist.cxx Sun May 12 16:17:02 2013 -0500 +++ b/src/ppodlist.cxx Sun May 12 21:16:53 2013 -0500 @@ -15,10 +15,10 @@ PTYPES_BEGIN -void _podlist::idxerror() +/*void _podlist::idxerror() const { fatal(CRIT_FIRST + 30, "List index out of bounds"); -} +}*/ _podlist::_podlist(int iitemsize) diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 src/ptparray.cpp --- a/src/ptparray.cpp Sun May 12 16:17:02 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -#include -#include -#include - -#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 \ No newline at end of file diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 src/ptypes_test.cxx --- a/src/ptypes_test.cxx Sun May 12 16:17:02 2013 -0500 +++ b/src/ptypes_test.cxx Sun May 12 21:16:53 2013 -0500 @@ -294,8 +294,8 @@ { pout.put("\n--- PODLIST\n"); - tpodlist p; - p.add() = 6; + //tpodlist p; + /*p.add() = 6; p.add(8); p.ins(1, 7); showint(7, p[1]); @@ -309,7 +309,7 @@ tpodlist p1; p1.add(p); p1.pop(); - p1.add(p); + p1.add(p);*/ } diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes.sdf Binary file win32/PTypes.sdf has changed diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_DLL.vcxproj --- a/win32/PTypes_DLL.vcxproj Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_DLL.vcxproj Sun May 12 21:16:53 2013 -0500 @@ -248,6 +248,7 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_DLL.vcxproj.filters --- a/win32/PTypes_DLL.vcxproj.filters Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_DLL.vcxproj.filters Sun May 12 21:16:53 2013 -0500 @@ -181,6 +181,9 @@ Inet + + Types + diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_DLL.vcxproj.user --- a/win32/PTypes_DLL.vcxproj.user Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_DLL.vcxproj.user Sun May 12 21:16:53 2013 -0500 @@ -1,3 +1,6 @@  + + false + \ No newline at end of file diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_Lib.vcxproj --- a/win32/PTypes_Lib.vcxproj Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_Lib.vcxproj Sun May 12 21:16:53 2013 -0500 @@ -144,6 +144,7 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) @@ -216,7 +217,7 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) - + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_Lib.vcxproj.filters --- a/win32/PTypes_Lib.vcxproj.filters Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_Lib.vcxproj.filters Sun May 12 21:16:53 2013 -0500 @@ -182,7 +182,10 @@ Inet - + + Types + + Types diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_Lib_ST.vcxproj --- a/win32/PTypes_Lib_ST.vcxproj Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_Lib_ST.vcxproj Sun May 12 21:16:53 2013 -0500 @@ -222,6 +222,7 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_Lib_ST.vcxproj.filters --- a/win32/PTypes_Lib_ST.vcxproj.filters Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_Lib_ST.vcxproj.filters Sun May 12 21:16:53 2013 -0500 @@ -151,6 +151,9 @@ Inet + + Types + diff -r 3005c9d543da92f1428adc00606f5f6f6d4cdf3f -r bd67c96aeb8b753fdfec559de7386ea901b2a141 win32/PTypes_Lib_ST.vcxproj.user --- a/win32/PTypes_Lib_ST.vcxproj.user Sun May 12 16:17:02 2013 -0500 +++ b/win32/PTypes_Lib_ST.vcxproj.user Sun May 12 21:16:53 2013 -0500 @@ -1,3 +1,6 @@  + + false + \ No newline at end of file