|
|
@@ -33,449 +33,411 @@ namespace crown
|
|
|
{
|
|
|
namespace json
|
|
|
{
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* next(const char* str, const char c = 0)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(str);
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* next(const char* str, const char c = 0)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(str);
|
|
|
+ if (c && c != (*str))
|
|
|
+ {
|
|
|
+ CE_ASSERT(false, "Expected '%c' got '%c'", c, (*str));
|
|
|
+ }
|
|
|
|
|
|
- if (c && c != (*str))
|
|
|
- {
|
|
|
- CE_ASSERT(false, "Expected '%c' got '%c'", c, (*str));
|
|
|
+ return str + 1;
|
|
|
}
|
|
|
|
|
|
- return str + 1;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_whites(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_whites(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- while ((*ch) && (*ch) <= ' ') ch = next(ch);
|
|
|
+ while ((*ch) && (*ch) <= ' ') ch = next(ch);
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
+ return ch;
|
|
|
+ }
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_string(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_string(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- bool escaped = false;
|
|
|
+ bool escaped = false;
|
|
|
|
|
|
- if ((*ch) == '"')
|
|
|
- {
|
|
|
- while ((*(ch = next(ch))) != 0)
|
|
|
+ if ((*ch) == '"')
|
|
|
{
|
|
|
- if ((*ch) == '"' && !escaped)
|
|
|
+ while ((*(ch = next(ch))) != 0)
|
|
|
{
|
|
|
- ch = next(ch);
|
|
|
- return ch;
|
|
|
+ if ((*ch) == '"' && !escaped)
|
|
|
+ {
|
|
|
+ ch = next(ch);
|
|
|
+ return ch;
|
|
|
+ }
|
|
|
+ else if ((*ch) == '\\') escaped = true;
|
|
|
+ else escaped = false;
|
|
|
}
|
|
|
- else if ((*ch) == '\\') escaped = true;
|
|
|
- else escaped = false;
|
|
|
}
|
|
|
+
|
|
|
+ return ch;
|
|
|
}
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_number(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_number(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ while ((*ch) && (((*ch) >= '0' && (*ch) <= '9') ||
|
|
|
+ (*ch) == '-' || (*ch) == '.' || (*ch) == '+' ||
|
|
|
+ (*ch) == 'e' || (*ch) == 'E'))
|
|
|
+ {
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
|
|
|
- while ((*ch) && (((*ch) >= '0' && (*ch) <= '9') ||
|
|
|
- (*ch) == '-' || (*ch) == '.' || (*ch) == '+' ||
|
|
|
- (*ch) == 'e' || (*ch) == 'E'))
|
|
|
- {
|
|
|
- ch = next(ch);
|
|
|
+ return ch;
|
|
|
}
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_object(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
-
|
|
|
- const char* ch = s;
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_object(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- uint32_t brackets = 1;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- if ((*ch) == '{')
|
|
|
- {
|
|
|
- brackets++;
|
|
|
- ch = next(ch, '{');
|
|
|
+ uint32_t brackets = 1;
|
|
|
|
|
|
- while ((*ch) && brackets != 1)
|
|
|
+ if ((*ch) == '{')
|
|
|
{
|
|
|
- if ((*ch) == '}') brackets--;
|
|
|
- else if ((*ch) == '{') brackets++;
|
|
|
- ch = next(ch);
|
|
|
- }
|
|
|
- }
|
|
|
+ brackets++;
|
|
|
+ ch = next(ch, '{');
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
+ while ((*ch) && brackets != 1)
|
|
|
+ {
|
|
|
+ if ((*ch) == '}') brackets--;
|
|
|
+ else if ((*ch) == '{') brackets++;
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_array(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ return ch;
|
|
|
+ }
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_array(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- uint32_t brackets = 1;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- if ((*ch) == '[')
|
|
|
- {
|
|
|
- brackets++;
|
|
|
- ch = next(ch, '[');
|
|
|
+ uint32_t brackets = 1;
|
|
|
|
|
|
- while ((*ch) && brackets != 1)
|
|
|
+ if ((*ch) == '[')
|
|
|
{
|
|
|
- if ((*ch) == ']') brackets--;
|
|
|
- else if ((*ch) == '[') brackets++;
|
|
|
- ch = next(ch);
|
|
|
+ brackets++;
|
|
|
+ ch = next(ch, '[');
|
|
|
+
|
|
|
+ while ((*ch) && brackets != 1)
|
|
|
+ {
|
|
|
+ if ((*ch) == ']') brackets--;
|
|
|
+ else if ((*ch) == '[') brackets++;
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ return ch;
|
|
|
}
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_bool(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
+
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_bool(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ switch ((*ch))
|
|
|
+ {
|
|
|
+ case 't':
|
|
|
+ {
|
|
|
+ ch = next(ch, 't');
|
|
|
+ ch = next(ch, 'r');
|
|
|
+ ch = next(ch, 'u');
|
|
|
+ ch = next(ch, 'e');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 'f':
|
|
|
+ {
|
|
|
+ ch = next(ch, 'f');
|
|
|
+ ch = next(ch, 'a');
|
|
|
+ ch = next(ch, 'l');
|
|
|
+ ch = next(ch, 's');
|
|
|
+ ch = next(ch, 'e');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ return ch;
|
|
|
+ }
|
|
|
|
|
|
- switch ((*ch))
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static const char* skip_null(const char* s)
|
|
|
{
|
|
|
- case 't':
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
+
|
|
|
+ const char* ch = s;
|
|
|
+ if ((*ch) == 'n')
|
|
|
{
|
|
|
- ch = next(ch, 't');
|
|
|
- ch = next(ch, 'r');
|
|
|
+ ch = next(ch, 'n');
|
|
|
ch = next(ch, 'u');
|
|
|
- ch = next(ch, 'e');
|
|
|
- break;
|
|
|
- }
|
|
|
- case 'f':
|
|
|
- {
|
|
|
- ch = next(ch, 'f');
|
|
|
- ch = next(ch, 'a');
|
|
|
ch = next(ch, 'l');
|
|
|
- ch = next(ch, 's');
|
|
|
- ch = next(ch, 'e');
|
|
|
- break;
|
|
|
- }
|
|
|
- default:
|
|
|
- {
|
|
|
- break;
|
|
|
+ ch = next(ch, 'l');
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static const char* skip_null(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ return ch;
|
|
|
+ }
|
|
|
|
|
|
- const char* ch = s;
|
|
|
- if ((*ch) == 'n')
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ static bool is_escapee(char c)
|
|
|
{
|
|
|
- ch = next(ch, 'n');
|
|
|
- ch = next(ch, 'u');
|
|
|
- ch = next(ch, 'l');
|
|
|
- ch = next(ch, 'l');
|
|
|
+ return c == '"' || c == '\\' || c == '/' || c == '\b' || c == '\f' || c == '\n' ||
|
|
|
+ c == '\r' || c == '\t';
|
|
|
}
|
|
|
|
|
|
- return ch;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-static bool is_escapee(char c)
|
|
|
-{
|
|
|
- return c == '"' || c == '\\' || c == '/' || c == '\b' || c == '\f' || c == '\n' ||
|
|
|
- c == '\r' || c == '\t';
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-JSONType::Enum type(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ JSONType::Enum type(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char c = s[0];
|
|
|
+ const char c = s[0];
|
|
|
|
|
|
- switch (c)
|
|
|
- {
|
|
|
- case '{': return JSONType::OBJECT;
|
|
|
- case '[': return JSONType::ARRAY;
|
|
|
- case '"': return JSONType::STRING;
|
|
|
- case '-': return JSONType::NUMBER;
|
|
|
- default: return (c >= '0' && c <= '9') ? JSONType::NUMBER : (c == 'n' ? JSONType::NIL : JSONType::BOOL);
|
|
|
+ switch (c)
|
|
|
+ {
|
|
|
+ case '{': return JSONType::OBJECT;
|
|
|
+ case '[': return JSONType::ARRAY;
|
|
|
+ case '"': return JSONType::STRING;
|
|
|
+ case '-': return JSONType::NUMBER;
|
|
|
+ default: return (c >= '0' && c <= '9') ? JSONType::NUMBER : (c == 'n' ? JSONType::NIL : JSONType::BOOL);
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-void parse_string(const char* s, DynamicString& str)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ void parse_string(const char* s, DynamicString& str)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- if ((*ch) == '"')
|
|
|
- {
|
|
|
- while ((*(ch = next(ch))))
|
|
|
+ if ((*ch) == '"')
|
|
|
{
|
|
|
- // Empty string
|
|
|
- if ((*ch) == '"')
|
|
|
- {
|
|
|
- ch = next(ch);
|
|
|
- return;
|
|
|
- }
|
|
|
- else if ((*ch) == '\\')
|
|
|
+ while ((*(ch = next(ch))))
|
|
|
{
|
|
|
- ch = next(ch);
|
|
|
-
|
|
|
- if ((*ch) == 'u')
|
|
|
+ // Empty string
|
|
|
+ if ((*ch) == '"')
|
|
|
{
|
|
|
- CE_FATAL("Not supported at the moment");
|
|
|
+ ch = next(ch);
|
|
|
+ return;
|
|
|
}
|
|
|
- else if (is_escapee(*ch))
|
|
|
+ else if ((*ch) == '\\')
|
|
|
{
|
|
|
- str += (*ch);
|
|
|
+ ch = next(ch);
|
|
|
+
|
|
|
+ if ((*ch) == 'u')
|
|
|
+ {
|
|
|
+ CE_FATAL("Not supported at the moment");
|
|
|
+ }
|
|
|
+ else if (is_escapee(*ch))
|
|
|
+ {
|
|
|
+ str += (*ch);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Go to invalid string
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // Go to invalid string
|
|
|
- break;
|
|
|
+ str += (*ch);
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- str += (*ch);
|
|
|
- }
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- CE_FATAL("Bad string");
|
|
|
-}
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-double parse_number(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ CE_FATAL("Bad string");
|
|
|
+ }
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ double parse_number(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- Array<char> str(default_allocator());
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- if ((*ch) == '-')
|
|
|
- {
|
|
|
- array::push_back(str, '-');
|
|
|
- ch = next(ch, '-');
|
|
|
- }
|
|
|
- while ((*ch) >= '0' && (*ch) <= '9')
|
|
|
- {
|
|
|
- array::push_back(str, (*ch));
|
|
|
- ch = next(ch);
|
|
|
- }
|
|
|
+ Array<char> str(default_allocator());
|
|
|
|
|
|
- if ((*ch) == '.')
|
|
|
- {
|
|
|
- array::push_back(str, '.');
|
|
|
- while ((*(ch = next(ch))) && (*ch) >= '0' && (*ch) <= '9')
|
|
|
+ if ((*ch) == '-')
|
|
|
{
|
|
|
- array::push_back(str, *ch);
|
|
|
+ array::push_back(str, '-');
|
|
|
+ ch = next(ch, '-');
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- if ((*ch) == 'e' || (*ch) == 'E')
|
|
|
- {
|
|
|
- array::push_back(str, *ch);
|
|
|
- ch = next(ch);
|
|
|
-
|
|
|
- if ((*ch) == '-' || (*ch) == '+')
|
|
|
+ while ((*ch) >= '0' && (*ch) <= '9')
|
|
|
{
|
|
|
- array::push_back(str, *ch);
|
|
|
+ array::push_back(str, (*ch));
|
|
|
ch = next(ch);
|
|
|
}
|
|
|
- while ((*ch) >= '0' && (*ch) <= '9')
|
|
|
+
|
|
|
+ if ((*ch) == '.')
|
|
|
+ {
|
|
|
+ array::push_back(str, '.');
|
|
|
+ while ((*(ch = next(ch))) && (*ch) >= '0' && (*ch) <= '9')
|
|
|
+ {
|
|
|
+ array::push_back(str, *ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((*ch) == 'e' || (*ch) == 'E')
|
|
|
{
|
|
|
array::push_back(str, *ch);
|
|
|
ch = next(ch);
|
|
|
+
|
|
|
+ if ((*ch) == '-' || (*ch) == '+')
|
|
|
+ {
|
|
|
+ array::push_back(str, *ch);
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
+ while ((*ch) >= '0' && (*ch) <= '9')
|
|
|
+ {
|
|
|
+ array::push_back(str, *ch);
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // Ensure null terminated
|
|
|
- array::push_back(str, '\0');
|
|
|
+ // Ensure null terminated
|
|
|
+ array::push_back(str, '\0');
|
|
|
|
|
|
- return string::parse_double(array::begin(str));
|
|
|
-}
|
|
|
+ return string::parse_double(array::begin(str));
|
|
|
+ }
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-bool parse_bool(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ bool parse_bool(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- switch(*ch)
|
|
|
- {
|
|
|
- case 't':
|
|
|
- {
|
|
|
- ch = next(ch, 't');
|
|
|
- ch = next(ch, 'r');
|
|
|
- ch = next(ch, 'u');
|
|
|
- ch = next(ch, 'e');
|
|
|
- return true;
|
|
|
- }
|
|
|
- case 'f':
|
|
|
+ switch(*ch)
|
|
|
{
|
|
|
- ch = next(ch, 'f');
|
|
|
- ch = next(ch, 'a');
|
|
|
- ch = next(ch, 'l');
|
|
|
- ch = next(ch, 's');
|
|
|
- ch = next(ch, 'e');
|
|
|
- return false;
|
|
|
- }
|
|
|
- default:
|
|
|
- {
|
|
|
- CE_FATAL("Bad boolean");
|
|
|
- return false;
|
|
|
+ case 't':
|
|
|
+ {
|
|
|
+ ch = next(ch, 't');
|
|
|
+ ch = next(ch, 'r');
|
|
|
+ ch = next(ch, 'u');
|
|
|
+ ch = next(ch, 'e');
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ case 'f':
|
|
|
+ {
|
|
|
+ ch = next(ch, 'f');
|
|
|
+ ch = next(ch, 'a');
|
|
|
+ ch = next(ch, 'l');
|
|
|
+ ch = next(ch, 's');
|
|
|
+ ch = next(ch, 'e');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ CE_FATAL("Bad boolean");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-int32_t parse_int(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
-
|
|
|
- return (int32_t) parse_number(s);
|
|
|
-}
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-float parse_float(const char* s)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ int32_t parse_int(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- return (float) parse_number(s);
|
|
|
-}
|
|
|
+ return (int32_t) parse_number(s);
|
|
|
+ }
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-void parse_array(const char* s, Array<const char*>& array)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ float parse_float(const char* s)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ return (float) parse_number(s);
|
|
|
+ }
|
|
|
|
|
|
- if ((*ch) == '[')
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ void parse_array(const char* s, Array<const char*>& array)
|
|
|
{
|
|
|
- ch = next(ch, '[');
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- // Skip whitespaces
|
|
|
- while ((*ch) && (*ch) <= ' ')
|
|
|
- {
|
|
|
- ch = next(ch);
|
|
|
- }
|
|
|
-
|
|
|
- if ((*ch) == ']')
|
|
|
- {
|
|
|
- ch = next(ch, ']');
|
|
|
- return;
|
|
|
- }
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- while (*ch)
|
|
|
+ if ((*ch) == '[')
|
|
|
{
|
|
|
- array::push_back(array, ch);
|
|
|
+ ch = next(ch, '[');
|
|
|
|
|
|
- ch = skip_array(ch);
|
|
|
- ch = skip_object(ch);
|
|
|
- ch = skip_number(ch);
|
|
|
- ch = skip_string(ch);
|
|
|
- ch = skip_bool(ch);
|
|
|
- ch = skip_null(ch);
|
|
|
-
|
|
|
- ch = skip_whites(ch);
|
|
|
+ // Skip whitespaces
|
|
|
+ while ((*ch) && (*ch) <= ' ')
|
|
|
+ {
|
|
|
+ ch = next(ch);
|
|
|
+ }
|
|
|
|
|
|
- // Closing bracket (top-most array)
|
|
|
if ((*ch) == ']')
|
|
|
{
|
|
|
ch = next(ch, ']');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // Skip until next ','
|
|
|
- ch = next(ch, ',');
|
|
|
-
|
|
|
- // Skip whites, eventually
|
|
|
- ch = skip_whites(ch);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- CE_FATAL("Bad array");
|
|
|
-}
|
|
|
+ while (*ch)
|
|
|
+ {
|
|
|
+ array::push_back(array, ch);
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-void parse_object(const char* s, Array<JSONPair>& object)
|
|
|
-{
|
|
|
- CE_ASSERT_NOT_NULL(s);
|
|
|
+ ch = skip_array(ch);
|
|
|
+ ch = skip_object(ch);
|
|
|
+ ch = skip_number(ch);
|
|
|
+ ch = skip_string(ch);
|
|
|
+ ch = skip_bool(ch);
|
|
|
+ ch = skip_null(ch);
|
|
|
|
|
|
- const char* ch = s;
|
|
|
+ ch = skip_whites(ch);
|
|
|
|
|
|
- if ((*ch) == '{')
|
|
|
- {
|
|
|
- ch = next(ch, '{');
|
|
|
+ // Closing bracket (top-most array)
|
|
|
+ if ((*ch) == ']')
|
|
|
+ {
|
|
|
+ ch = next(ch, ']');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- ch = skip_whites(ch);
|
|
|
+ // Skip until next ','
|
|
|
+ ch = next(ch, ',');
|
|
|
|
|
|
- if ((*ch) == '}')
|
|
|
- {
|
|
|
- next(ch, '}');
|
|
|
- return;
|
|
|
+ // Skip whites, eventually
|
|
|
+ ch = skip_whites(ch);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- while (*ch)
|
|
|
- {
|
|
|
- JSONPair pair;
|
|
|
-
|
|
|
- pair.key = ch;
|
|
|
-
|
|
|
- // Skip any value
|
|
|
- ch = skip_array(ch);
|
|
|
- ch = skip_object(ch);
|
|
|
- ch = skip_number(ch);
|
|
|
- ch = skip_string(ch);
|
|
|
- ch = skip_bool(ch);
|
|
|
- ch = skip_null(ch);
|
|
|
+ CE_FATAL("Bad array");
|
|
|
+ }
|
|
|
|
|
|
- ch = skip_whites(ch);
|
|
|
- ch = next(ch, ':');
|
|
|
- ch = skip_whites(ch);
|
|
|
+ //-----------------------------------------------------------------------------
|
|
|
+ void parse_object(const char* s, Array<JSONPair>& object)
|
|
|
+ {
|
|
|
+ CE_ASSERT_NOT_NULL(s);
|
|
|
|
|
|
- pair.val = ch;
|
|
|
- array::push_back(object, pair);
|
|
|
+ const char* ch = s;
|
|
|
|
|
|
- // Skip any value
|
|
|
- ch = skip_array(ch);
|
|
|
- ch = skip_object(ch);
|
|
|
- ch = skip_number(ch);
|
|
|
- ch = skip_string(ch);
|
|
|
- ch = skip_bool(ch);
|
|
|
- ch = skip_null(ch);
|
|
|
+ if ((*ch) == '{')
|
|
|
+ {
|
|
|
+ ch = next(ch, '{');
|
|
|
|
|
|
ch = skip_whites(ch);
|
|
|
|
|
|
@@ -485,13 +447,49 @@ void parse_object(const char* s, Array<JSONPair>& object)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- ch = next(ch, ',');
|
|
|
- ch = skip_whites(ch);
|
|
|
- }
|
|
|
- }
|
|
|
+ while (*ch)
|
|
|
+ {
|
|
|
+ JSONPair pair;
|
|
|
+
|
|
|
+ pair.key = ch;
|
|
|
|
|
|
- CE_FATAL("Bad object");
|
|
|
-}
|
|
|
+ // Skip any value
|
|
|
+ ch = skip_array(ch);
|
|
|
+ ch = skip_object(ch);
|
|
|
+ ch = skip_number(ch);
|
|
|
+ ch = skip_string(ch);
|
|
|
+ ch = skip_bool(ch);
|
|
|
+ ch = skip_null(ch);
|
|
|
|
|
|
+ ch = skip_whites(ch);
|
|
|
+ ch = next(ch, ':');
|
|
|
+ ch = skip_whites(ch);
|
|
|
+
|
|
|
+ pair.val = ch;
|
|
|
+ array::push_back(object, pair);
|
|
|
+
|
|
|
+ // Skip any value
|
|
|
+ ch = skip_array(ch);
|
|
|
+ ch = skip_object(ch);
|
|
|
+ ch = skip_number(ch);
|
|
|
+ ch = skip_string(ch);
|
|
|
+ ch = skip_bool(ch);
|
|
|
+ ch = skip_null(ch);
|
|
|
+
|
|
|
+ ch = skip_whites(ch);
|
|
|
+
|
|
|
+ if ((*ch) == '}')
|
|
|
+ {
|
|
|
+ next(ch, '}');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ ch = next(ch, ',');
|
|
|
+ ch = skip_whites(ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CE_FATAL("Bad object");
|
|
|
+ }
|
|
|
} // namespace json
|
|
|
} // namespace crown
|