mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			190 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright Benoit Blanchon 2014-2016
 | |
| // MIT License
 | |
| //
 | |
| // Arduino JSON library
 | |
| // https://github.com/bblanchon/ArduinoJson
 | |
| // If you like this project, please add a star!
 | |
| 
 | |
| #include "JsonParser.hpp"
 | |
| #include "Comments.hpp"
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::skip(char charToSkip) {
 | |
|   const char *ptr = skipSpacesAndComments(_readPtr);
 | |
|   if (*ptr != charToSkip) return false;
 | |
|   ptr++;
 | |
|   _readPtr = skipSpacesAndComments(ptr);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo(
 | |
|     JsonVariant *destination) {
 | |
|   if (_nestingLimit == 0) return false;
 | |
|   _nestingLimit--;
 | |
|   bool success = parseAnythingToUnsafe(destination);
 | |
|   _nestingLimit++;
 | |
|   return success;
 | |
| }
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe(
 | |
|     JsonVariant *destination) {
 | |
|   _readPtr = skipSpacesAndComments(_readPtr);
 | |
| 
 | |
|   switch (*_readPtr) {
 | |
|     case '[':
 | |
|       return parseArrayTo(destination);
 | |
| 
 | |
|     case '{':
 | |
|       return parseObjectTo(destination);
 | |
| 
 | |
|     default:
 | |
|       return parseStringTo(destination);
 | |
|   }
 | |
| }
 | |
| 
 | |
| inline ArduinoJson::JsonArray &
 | |
| ArduinoJson::Internals::JsonParser::parseArray() {
 | |
|   // Create an empty array
 | |
|   JsonArray &array = _buffer->createArray();
 | |
| 
 | |
|   // Check opening braket
 | |
|   if (!skip('[')) goto ERROR_MISSING_BRACKET;
 | |
|   if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
 | |
| 
 | |
|   // Read each value
 | |
|   for (;;) {
 | |
|     // 1 - Parse value
 | |
|     JsonVariant value;
 | |
|     if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
 | |
|     if (!array.add(value)) goto ERROR_NO_MEMORY;
 | |
| 
 | |
|     // 2 - More values?
 | |
|     if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
 | |
|     if (!skip(',')) goto ERROR_MISSING_COMMA;
 | |
|   }
 | |
| 
 | |
| SUCCESS_EMPTY_ARRAY:
 | |
| SUCCES_NON_EMPTY_ARRAY:
 | |
|   return array;
 | |
| 
 | |
| ERROR_INVALID_VALUE:
 | |
| ERROR_MISSING_BRACKET:
 | |
| ERROR_MISSING_COMMA:
 | |
| ERROR_NO_MEMORY:
 | |
|   return JsonArray::invalid();
 | |
| }
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::parseArrayTo(
 | |
|     JsonVariant *destination) {
 | |
|   JsonArray &array = parseArray();
 | |
|   if (!array.success()) return false;
 | |
| 
 | |
|   *destination = array;
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| inline ArduinoJson::JsonObject &
 | |
| ArduinoJson::Internals::JsonParser::parseObject() {
 | |
|   // Create an empty object
 | |
|   JsonObject &object = _buffer->createObject();
 | |
| 
 | |
|   // Check opening brace
 | |
|   if (!skip('{')) goto ERROR_MISSING_BRACE;
 | |
|   if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
 | |
| 
 | |
|   // Read each key value pair
 | |
|   for (;;) {
 | |
|     // 1 - Parse key
 | |
|     const char *key = parseString();
 | |
|     if (!key) goto ERROR_INVALID_KEY;
 | |
|     if (!skip(':')) goto ERROR_MISSING_COLON;
 | |
| 
 | |
|     // 2 - Parse value
 | |
|     JsonVariant value;
 | |
|     if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
 | |
|     if (!object.set(key, value)) goto ERROR_NO_MEMORY;
 | |
| 
 | |
|     // 3 - More keys/values?
 | |
|     if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
 | |
|     if (!skip(',')) goto ERROR_MISSING_COMMA;
 | |
|   }
 | |
| 
 | |
| SUCCESS_EMPTY_OBJECT:
 | |
| SUCCESS_NON_EMPTY_OBJECT:
 | |
|   return object;
 | |
| 
 | |
| ERROR_INVALID_KEY:
 | |
| ERROR_INVALID_VALUE:
 | |
| ERROR_MISSING_BRACE:
 | |
| ERROR_MISSING_COLON:
 | |
| ERROR_MISSING_COMMA:
 | |
| ERROR_NO_MEMORY:
 | |
|   return JsonObject::invalid();
 | |
| }
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::parseObjectTo(
 | |
|     JsonVariant *destination) {
 | |
|   JsonObject &object = parseObject();
 | |
|   if (!object.success()) return false;
 | |
| 
 | |
|   *destination = object;
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| inline const char *ArduinoJson::Internals::JsonParser::parseString() {
 | |
|   const char *readPtr = _readPtr;
 | |
|   char *writePtr = _writePtr;
 | |
| 
 | |
|   char c = *readPtr;
 | |
| 
 | |
|   if (isQuote(c)) {  // quotes
 | |
|     char stopChar = c;
 | |
|     for (;;) {
 | |
|       c = *++readPtr;
 | |
|       if (c == '\0') break;
 | |
| 
 | |
|       if (c == stopChar) {
 | |
|         readPtr++;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       if (c == '\\') {
 | |
|         // replace char
 | |
|         c = Encoding::unescapeChar(*++readPtr);
 | |
|         if (c == '\0') break;
 | |
|       }
 | |
| 
 | |
|       *writePtr++ = c;
 | |
|     }
 | |
|   } else {  // no quotes
 | |
|     for (;;) {
 | |
|       if (!isLetterOrNumber(c)) break;
 | |
|       *writePtr++ = c;
 | |
|       c = *++readPtr;
 | |
|     }
 | |
|   }
 | |
|   // end the string here
 | |
|   *writePtr++ = '\0';
 | |
| 
 | |
|   const char *startPtr = _writePtr;
 | |
| 
 | |
|   // update end ptr
 | |
|   _readPtr = readPtr;
 | |
|   _writePtr = writePtr;
 | |
| 
 | |
|   // return pointer to unquoted string
 | |
|   return startPtr;
 | |
| }
 | |
| 
 | |
| inline bool ArduinoJson::Internals::JsonParser::parseStringTo(
 | |
|     JsonVariant *destination) {
 | |
|   bool hasQuotes = isQuote(_readPtr[0]);
 | |
|   const char *value = parseString();
 | |
|   if (value == NULL) return false;
 | |
|   if (hasQuotes) {
 | |
|     *destination = value;
 | |
|   } else {
 | |
|     *destination = RawJson(value);
 | |
|   }
 | |
|   return true;
 | |
| }
 |