Parse key value pairs

This commit is contained in:
Benoit Blanchon
2014-10-21 23:37:17 +02:00
parent cfbe50057a
commit 04330a7a47
7 changed files with 103 additions and 31 deletions

View File

@ -41,7 +41,7 @@ namespace ArduinoJson
{ {
const char* key; const char* key;
JsonNode* value; JsonNode* value;
} asKey; } asKeyValue;
struct struct
{ {
@ -106,8 +106,8 @@ namespace ArduinoJson
void setAsObjectKeyValue(const char* key, JsonNode* value) void setAsObjectKeyValue(const char* key, JsonNode* value)
{ {
type = JSON_KEY_VALUE; type = JSON_KEY_VALUE;
content.asKey.key = key; content.asKeyValue.key = key;
content.asKey.value = value; content.asKeyValue.value = value;
} }
bool getAsBoolean() bool getAsBoolean()
@ -144,12 +144,12 @@ namespace ArduinoJson
const char* getAsObjectKey() const char* getAsObjectKey()
{ {
return type == JSON_KEY_VALUE ? content.asKey.key : 0; return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0;
} }
JsonNode* getAsObjectValue() JsonNode* getAsObjectValue()
{ {
return type == JSON_KEY_VALUE ? content.asKey.value : 0; return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0;
} }
JsonNode* getProxyTarget() JsonNode* getProxyTarget()

View File

@ -29,6 +29,7 @@ namespace ArduinoJson
inline bool isArrayStop(); inline bool isArrayStop();
inline bool isBoolean(); inline bool isBoolean();
inline bool isComma(); inline bool isComma();
inline bool isColon();
inline bool isDouble(); inline bool isDouble();
inline bool isEnd(); inline bool isEnd();
inline bool isLong(); inline bool isLong();
@ -42,12 +43,12 @@ namespace ArduinoJson
inline JsonNode* parseArray(); inline JsonNode* parseArray();
inline JsonNode* parseBoolean(); inline JsonNode* parseBoolean();
inline JsonNode *parseDouble();
inline JsonNode* parseObjectKeyValue();
inline JsonNode* parseLong(); inline JsonNode* parseLong();
inline JsonNode* parseNull(); inline JsonNode* parseNull();
inline JsonNode* parseObject(); inline JsonNode* parseObject();
inline JsonNode* parseString(); inline JsonNode* parseString();
JsonNode *parseDouble();
}; };
} }
} }

View File

@ -46,6 +46,7 @@ namespace ArduinoJson
Internals::JsonNode* createDoubleNode(double value, int decimals); Internals::JsonNode* createDoubleNode(double value, int decimals);
Internals::JsonNode* createLongNode(long value); Internals::JsonNode* createLongNode(long value);
Internals::JsonNode* createObjectNode(); Internals::JsonNode* createObjectNode();
Internals::JsonNode* createObjectKeyValueNode(const char* key, Internals::JsonNode* value);
Internals::JsonNode* createStringNode(const char* value); Internals::JsonNode* createStringNode(const char* value);
}; };
} }

View File

@ -119,9 +119,9 @@ void JsonNode::writeObjectTo(JsonWriter& writer)
for (;;) for (;;)
{ {
writer.writeString(child->content.asKey.key); writer.writeString(child->content.asKeyValue.key);
writer.writeColon(); writer.writeColon();
child->content.asKey.value->writeTo(writer); child->content.asKeyValue.value->writeTo(writer);
child = child->next; child = child->next;
if (!child) break; if (!child) break;

View File

@ -18,16 +18,6 @@ bool JsonParser::isArrayStop()
return *_ptr == ']'; return *_ptr == ']';
} }
bool JsonParser::isObjectStart()
{
return *_ptr == '{';
}
bool JsonParser::isObjectStop()
{
return *_ptr == '}';
}
bool JsonParser::isBoolean() bool JsonParser::isBoolean()
{ {
return *_ptr == 't' || *_ptr == 'f'; return *_ptr == 't' || *_ptr == 'f';
@ -38,6 +28,11 @@ bool JsonParser::isComma()
return *_ptr == ','; return *_ptr == ',';
} }
bool JsonParser::isColon()
{
return *_ptr == ':';
}
bool JsonParser::isDouble() bool JsonParser::isDouble()
{ {
char* ptr = _ptr; char* ptr = _ptr;
@ -80,6 +75,16 @@ bool JsonParser::isNull()
return *_ptr == 'n'; return *_ptr == 'n';
} }
bool JsonParser::isObjectStart()
{
return *_ptr == '{';
}
bool JsonParser::isObjectStop()
{
return *_ptr == '}';
}
bool JsonParser::isSpace() bool JsonParser::isSpace()
{ {
return *_ptr == ' ' || *_ptr == '\t' || *_ptr == '\n' || *_ptr == '\r'; return *_ptr == ' ' || *_ptr == '\t' || *_ptr == '\n' || *_ptr == '\r';
@ -131,7 +136,10 @@ JsonNode* JsonParser::parseArray()
return 0; return 0;
if (isArrayStop()) if (isArrayStop())
{
skipOneChar(); // skip the ']'
return node; return node;
}
for(;;) 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() JsonNode *JsonParser::parseBoolean()
{ {
bool value = *_ptr == 't'; bool value = *_ptr == 't';
@ -196,6 +193,55 @@ JsonNode* JsonParser::parseNull()
return _buffer->createStringNode(0); 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() JsonNode* JsonParser::parseString()
{ {
const char* s = QuotedString::extractFrom(_ptr, &_ptr); const char* s = QuotedString::extractFrom(_ptr, &_ptr);

View File

@ -90,6 +90,16 @@ JsonNode* JsonBuffer::createObjectNode()
return node; 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* JsonBuffer::createStringNode(const char* value)
{ {
JsonNode* node = createNode(); JsonNode* node = createNode();

View File

@ -1,5 +1,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <ArduinoJson/StaticJsonBuffer.hpp> #include <ArduinoJson/StaticJsonBuffer.hpp>
#include <ArduinoJson/JsonValue.hpp>
using namespace ArduinoJson; using namespace ArduinoJson;
@ -28,6 +29,11 @@ protected:
EXPECT_EQ(expected, _object.size()); EXPECT_EQ(expected, _object.size());
} }
void keyMustHaveValue(const char* key, const char* expected)
{
EXPECT_STREQ(expected, static_cast<const char*>(_object[key]));
}
private: private:
StaticJsonBuffer<10> _jsonBuffer; StaticJsonBuffer<10> _jsonBuffer;
JsonObject _object; JsonObject _object;
@ -47,3 +53,11 @@ TEST_F(JsonParser_Object_Test, MissingClosingBrace)
parseMustFail(); parseMustFail();
sizeMustBe(0); sizeMustBe(0);
} }
TEST_F(JsonParser_Object_Test, OneString)
{
whenInputIs("{\"key\":\"value\"}");
parseMustSucceed();
sizeMustBe(1);
keyMustHaveValue("key", "value");
}