Benoit Blanchon 11 лет назад
Родитель
Сommit
ee520d1ff5
1 измененных файлов с 60 добавлено и 48 удалено
  1. 60 48
      src/Internals/JsonParser.cpp

+ 60 - 48
src/Internals/JsonParser.cpp

@@ -49,6 +49,10 @@ void JsonParser::parseAnythingTo(JsonVariant &destination) {
       destination = parseArray();
       break;
 
+    case '{':
+      destination = parseObject();
+      break;
+
     case 't':
     case 'f':
       parseBooleanTo(destination);
@@ -73,10 +77,6 @@ void JsonParser::parseAnythingTo(JsonVariant &destination) {
       parseNullTo(destination);
       break;
 
-    case '{':
-      destination = parseObject();
-      break;
-
     case '\'':
     case '\"':
       destination = parseString();
@@ -87,60 +87,41 @@ void JsonParser::parseAnythingTo(JsonVariant &destination) {
 }
 
 JsonArray &JsonParser::parseArray() {
-  if (!skip('[')) return JsonArray::invalid();  // missing opening bracket
-
-  if (isEnd()) return JsonArray::invalid();  // end of stream
-
+  // Create an empty array
   JsonArray &array = _buffer->createArray();
-  if (skip(']')) return array;  // empty array
 
-  for (;;) {
-    JsonVariant &child = array.add();
-
-    parseAnythingTo(child);
-    if (!child.success()) return JsonArray::invalid();  // child parsing failed
+  // Check opening braket
+  if (!skip('[')) goto ERROR_MISSING_BRACKET;
+  if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
 
-    if (skip(']')) return array;  // end of the array
+  // Read each value
+  for (;;) {
+    // 1 - Parse value
+    JsonVariant &value = array.add();
+    parseAnythingTo(value);
+    if (!value.success()) goto ERROR_INVALID_VALUE;
 
-    if (!skip(',')) return JsonArray::invalid();  // comma is missing
+    // 2 - More values?
+    if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
+    if (!skip(',')) goto ERROR_MISSING_COMMA;
   }
-}
-
-void JsonParser::parseBooleanTo(JsonVariant &destination) {
-  bool value = *_ptr == 't';
 
-  if (skip(value ? "true" : "false"))
-    destination = value;
-  else
-    destination = JsonVariant::invalid();
-}
-
-void JsonParser::parseNumberTo(JsonVariant &destination) {
-  char *endOfLong;
-  long longValue = strtol(_ptr, &endOfLong, 10);
-
-  if (*endOfLong == '.') {
-    // stopped on a decimal separator
-    double doubleValue = strtod(_ptr, &_ptr);
-    uint8_t decimals = static_cast<uint8_t>(_ptr - endOfLong - 1);
-    destination.set(doubleValue, decimals);
-  } else {
-    _ptr = endOfLong;
-    destination = longValue;
-  }
-}
+SUCCESS_EMPTY_ARRAY:
+SUCCES_NON_EMPTY_ARRAY:
+  return array;
 
-void JsonParser::parseNullTo(JsonVariant &destination) {
-  if (skip("null"))
-    destination = static_cast<const char *>(NULL);
-  else
-    destination = JsonVariant::invalid();
+ERROR_INVALID_VALUE:
+ERROR_MISSING_BRACKET:
+ERROR_MISSING_COMMA:
+  return JsonArray::invalid();
 }
 
 JsonObject &JsonParser::parseObject() {
+  // Create an empty object
   JsonObject &object = _buffer->createObject();
 
-  if (!skip('{')) goto ERROR_MISSING_OPENING_BRACE;
+  // Check opening brace
+  if (!skip('{')) goto ERROR_MISSING_BRACE;
   if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
 
   // Read each key value pair
@@ -155,7 +136,7 @@ JsonObject &JsonParser::parseObject() {
     parseAnythingTo(value);
     if (!value.success()) goto ERROR_INVALID_VALUE;
 
-    // 3 - More elements?
+    // 3 - More keys/values?
     if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
     if (!skip(',')) goto ERROR_MISSING_COMMA;
   }
@@ -166,12 +147,43 @@ SUCCESS_NON_EMPTY_OBJECT:
 
 ERROR_INVALID_KEY:
 ERROR_INVALID_VALUE:
+ERROR_MISSING_BRACE:
 ERROR_MISSING_COLON:
 ERROR_MISSING_COMMA:
-ERROR_MISSING_OPENING_BRACE:
   return JsonObject::invalid();
 }
 
+void JsonParser::parseBooleanTo(JsonVariant &destination) {
+  bool value = *_ptr == 't';
+
+  if (skip(value ? "true" : "false"))
+    destination = value;
+  else
+    destination = JsonVariant::invalid();
+}
+
+void JsonParser::parseNumberTo(JsonVariant &destination) {
+  char *endOfLong;
+  long longValue = strtol(_ptr, &endOfLong, 10);
+
+  if (*endOfLong == '.') {
+    // stopped on a decimal separator
+    double doubleValue = strtod(_ptr, &_ptr);
+    uint8_t decimals = static_cast<uint8_t>(_ptr - endOfLong - 1);
+    destination.set(doubleValue, decimals);
+  } else {
+    _ptr = endOfLong;
+    destination = longValue;
+  }
+}
+
+void JsonParser::parseNullTo(JsonVariant &destination) {
+  if (skip("null"))
+    destination = static_cast<const char *>(NULL);
+  else
+    destination = JsonVariant::invalid();
+}
+
 const char *JsonParser::parseString() {
   return QuotedString::extractFrom(_ptr, &_ptr);
 }