diff --git a/include/ArduinoJson/Internals/JsonNode.hpp b/include/ArduinoJson/Internals/JsonNode.hpp index a7aef7a0..147ed122 100644 --- a/include/ArduinoJson/Internals/JsonNode.hpp +++ b/include/ArduinoJson/Internals/JsonNode.hpp @@ -41,7 +41,7 @@ namespace ArduinoJson { const char* key; JsonNode* value; - } asKey; + } asKeyValue; struct { @@ -106,8 +106,8 @@ namespace ArduinoJson void setAsObjectKeyValue(const char* key, JsonNode* value) { type = JSON_KEY_VALUE; - content.asKey.key = key; - content.asKey.value = value; + content.asKeyValue.key = key; + content.asKeyValue.value = value; } bool getAsBoolean() @@ -144,12 +144,12 @@ namespace ArduinoJson const char* getAsObjectKey() { - return type == JSON_KEY_VALUE ? content.asKey.key : 0; + return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0; } JsonNode* getAsObjectValue() { - return type == JSON_KEY_VALUE ? content.asKey.value : 0; + return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0; } JsonNode* getProxyTarget() diff --git a/include/ArduinoJson/Internals/JsonParser.hpp b/include/ArduinoJson/Internals/JsonParser.hpp index 14872670..498717d1 100644 --- a/include/ArduinoJson/Internals/JsonParser.hpp +++ b/include/ArduinoJson/Internals/JsonParser.hpp @@ -29,6 +29,7 @@ namespace ArduinoJson inline bool isArrayStop(); inline bool isBoolean(); inline bool isComma(); + inline bool isColon(); inline bool isDouble(); inline bool isEnd(); inline bool isLong(); @@ -41,13 +42,13 @@ namespace ArduinoJson inline void skipSpaces(); inline JsonNode* parseArray(); - inline JsonNode* parseBoolean(); + inline JsonNode* parseBoolean(); + inline JsonNode *parseDouble(); + inline JsonNode* parseObjectKeyValue(); inline JsonNode* parseLong(); inline JsonNode* parseNull(); inline JsonNode* parseObject(); inline JsonNode* parseString(); - - JsonNode *parseDouble(); }; } } \ No newline at end of file diff --git a/include/ArduinoJson/JsonBuffer.hpp b/include/ArduinoJson/JsonBuffer.hpp index c592145c..aaa4253a 100644 --- a/include/ArduinoJson/JsonBuffer.hpp +++ b/include/ArduinoJson/JsonBuffer.hpp @@ -46,6 +46,7 @@ namespace ArduinoJson Internals::JsonNode* createDoubleNode(double value, int decimals); Internals::JsonNode* createLongNode(long value); Internals::JsonNode* createObjectNode(); + Internals::JsonNode* createObjectKeyValueNode(const char* key, Internals::JsonNode* value); Internals::JsonNode* createStringNode(const char* value); }; } \ No newline at end of file diff --git a/src/Internals/JsonNode.cpp b/src/Internals/JsonNode.cpp index 84451b1c..1d95f4fd 100644 --- a/src/Internals/JsonNode.cpp +++ b/src/Internals/JsonNode.cpp @@ -119,9 +119,9 @@ void JsonNode::writeObjectTo(JsonWriter& writer) for (;;) { - writer.writeString(child->content.asKey.key); + writer.writeString(child->content.asKeyValue.key); writer.writeColon(); - child->content.asKey.value->writeTo(writer); + child->content.asKeyValue.value->writeTo(writer); child = child->next; if (!child) break; diff --git a/src/Internals/JsonParser.cpp b/src/Internals/JsonParser.cpp index 083f3304..df064475 100644 --- a/src/Internals/JsonParser.cpp +++ b/src/Internals/JsonParser.cpp @@ -18,16 +18,6 @@ bool JsonParser::isArrayStop() return *_ptr == ']'; } -bool JsonParser::isObjectStart() -{ - return *_ptr == '{'; -} - -bool JsonParser::isObjectStop() -{ - return *_ptr == '}'; -} - bool JsonParser::isBoolean() { return *_ptr == 't' || *_ptr == 'f'; @@ -38,6 +28,11 @@ bool JsonParser::isComma() return *_ptr == ','; } +bool JsonParser::isColon() +{ + return *_ptr == ':'; +} + bool JsonParser::isDouble() { char* ptr = _ptr; @@ -80,6 +75,16 @@ bool JsonParser::isNull() return *_ptr == 'n'; } +bool JsonParser::isObjectStart() +{ + return *_ptr == '{'; +} + +bool JsonParser::isObjectStop() +{ + return *_ptr == '}'; +} + bool JsonParser::isSpace() { return *_ptr == ' ' || *_ptr == '\t' || *_ptr == '\n' || *_ptr == '\r'; @@ -131,7 +136,10 @@ JsonNode* JsonParser::parseArray() return 0; if (isArrayStop()) + { + skipOneChar(); // skip the ']' return node; + } for(;;) { @@ -149,17 +157,6 @@ JsonNode* JsonParser::parseArray() } } -JsonNode* JsonParser::parseObject() -{ - JsonNode* node = _buffer->createObjectNode(); - - skipOneChar(); // skip the '[' - skipSpaces(); - - if (isObjectStop()) - return node; -} - JsonNode *JsonParser::parseBoolean() { bool value = *_ptr == 't'; @@ -196,6 +193,55 @@ JsonNode* JsonParser::parseNull() return _buffer->createStringNode(0); } +JsonNode* JsonParser::parseObject() +{ + JsonNode* node = _buffer->createObjectNode(); + + skipOneChar(); // skip the '{' + skipSpaces(); + + if (isEnd()) + return 0; + + if (isObjectStop()) + { + skipOneChar(); // skip the '}' + return node; + } + + for(;;) + { + node->addChild(parseObjectKeyValue()); + + skipSpaces(); + + if (isObjectStop()) + return node; + + if (!isComma()) + return 0; + + skipOneChar(); // skip the ',' + } +} + +JsonNode* JsonParser::parseObjectKeyValue() +{ + const char* key = QuotedString::extractFrom(_ptr, &_ptr); + + skipSpaces(); + + if (!isColon()) + return 0; + + skipOneChar(); // skip the : + skipSpaces(); + + JsonNode* value = parseAnything(); + + return _buffer->createObjectKeyValueNode(key, value); +} + JsonNode* JsonParser::parseString() { const char* s = QuotedString::extractFrom(_ptr, &_ptr); diff --git a/src/JsonBuffer.cpp b/src/JsonBuffer.cpp index 9ff742ac..73e03bcd 100644 --- a/src/JsonBuffer.cpp +++ b/src/JsonBuffer.cpp @@ -90,6 +90,16 @@ JsonNode* JsonBuffer::createObjectNode() return node; } +Internals::JsonNode* JsonBuffer::createObjectKeyValueNode(const char* key, JsonNode* value) +{ + JsonNode* node = createNode(); + + if (node) + node->setAsObjectKeyValue(key, value); + + return node; +} + JsonNode* JsonBuffer::createStringNode(const char* value) { JsonNode* node = createNode(); diff --git a/test/JsonParser_Object_Tests.cpp b/test/JsonParser_Object_Tests.cpp index 482995b5..e3c98e58 100644 --- a/test/JsonParser_Object_Tests.cpp +++ b/test/JsonParser_Object_Tests.cpp @@ -1,5 +1,6 @@ #include #include +#include using namespace ArduinoJson; @@ -28,6 +29,11 @@ protected: EXPECT_EQ(expected, _object.size()); } + void keyMustHaveValue(const char* key, const char* expected) + { + EXPECT_STREQ(expected, static_cast(_object[key])); + } + private: StaticJsonBuffer<10> _jsonBuffer; JsonObject _object; @@ -46,4 +52,12 @@ TEST_F(JsonParser_Object_Test, MissingClosingBrace) whenInputIs("{"); parseMustFail(); sizeMustBe(0); +} + +TEST_F(JsonParser_Object_Test, OneString) +{ + whenInputIs("{\"key\":\"value\"}"); + parseMustSucceed(); + sizeMustBe(1); + keyMustHaveValue("key", "value"); } \ No newline at end of file