From 852256c1af65f725be1e0fcc7d4c0a7fb8b8c2cb Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 27 Oct 2014 22:50:50 +0100 Subject: [PATCH] Epic refactoring int progress... --- include/ArduinoJson/ForwardDeclarations.hpp | 1 + .../ArduinoJson/Internals/JsonArrayImpl.hpp | 9 +- .../Internals/JsonArrayIterator.hpp | 12 +- .../Internals/JsonObjectConstIterator.hpp | 15 +-- .../ArduinoJson/Internals/JsonObjectImpl.hpp | 20 ++-- .../Internals/JsonObjectIterator.hpp | 14 +-- .../ArduinoJson/Internals/JsonObjectNode.hpp | 9 +- include/ArduinoJson/Internals/JsonParser.hpp | 1 + .../ArduinoJson/Internals/JsonValueImpl.hpp | 32 ++--- include/ArduinoJson/JsonArray.hpp | 16 ++- include/ArduinoJson/JsonObject.hpp | 22 +++- include/ArduinoJson/JsonPair.hpp | 15 ++- .../{JsonContainer.hpp => JsonPrintable.hpp} | 8 +- include/ArduinoJson/JsonValue.hpp | 52 +++++--- include/ArduinoJson/StaticJsonBuffer.hpp | 11 +- src/Internals/JsonArrayImpl.cpp | 10 +- src/Internals/JsonObjectImpl.cpp | 111 ++++++++---------- src/Internals/JsonParser.cpp | 14 ++- src/Internals/JsonValueImpl.cpp | 13 +- src/JsonArray.cpp | 11 +- src/JsonBuffer.cpp | 35 +++++- src/JsonContainer.cpp | 80 ------------- src/JsonObject.cpp | 2 + src/JsonPrintable.cpp | 42 +++++++ src/JsonValue.cpp | 15 ++- test/Issue10.cpp | 2 +- test/JsonArray_Container_Tests.cpp | 2 + test/JsonObject_Container_Tests.cpp | 4 +- test/JsonObject_PrettyPrintTo_Tests.cpp | 1 + test/JsonParser_Array_Tests.cpp | 3 +- test/JsonParser_Nested_Tests.cpp | 2 + test/JsonParser_Object_Tests.cpp | 1 + test/JsonValueTests.cpp | 2 + test/StaticJsonBufferTests.cpp | 3 +- 34 files changed, 334 insertions(+), 256 deletions(-) rename include/ArduinoJson/{JsonContainer.hpp => JsonPrintable.hpp} (76%) delete mode 100644 src/JsonContainer.cpp create mode 100644 src/JsonPrintable.cpp diff --git a/include/ArduinoJson/ForwardDeclarations.hpp b/include/ArduinoJson/ForwardDeclarations.hpp index 629654e3..7c91b707 100644 --- a/include/ArduinoJson/ForwardDeclarations.hpp +++ b/include/ArduinoJson/ForwardDeclarations.hpp @@ -22,6 +22,7 @@ class JsonArrayImpl; class JsonArrayIterator; class JsonObjectImpl; class JsonObjectIterator; +class JsonObjectConstIterator; class JsonParser; class JsonValueImpl; class JsonWriter; diff --git a/include/ArduinoJson/Internals/JsonArrayImpl.hpp b/include/ArduinoJson/Internals/JsonArrayImpl.hpp index d3cb91c8..8069e537 100644 --- a/include/ArduinoJson/Internals/JsonArrayImpl.hpp +++ b/include/ArduinoJson/Internals/JsonArrayImpl.hpp @@ -20,8 +20,9 @@ class JsonArrayImpl { JsonArrayImpl(JsonBuffer *buffer) : _buffer(buffer) {} - value_type operator[](int index) const; + int size() const; + value_type operator[](int index) const; value_type add(); JsonArrayImpl *createNestedArray(); @@ -29,15 +30,15 @@ class JsonArrayImpl { void writeTo(JsonWriter &writer) const; - iterator begin() { return iterator(_firstChild); } + iterator begin() { return iterator(_firstNode); } iterator end() { return iterator(0); } - const_iterator begin() const { return const_iterator(_firstChild); } + const_iterator begin() const { return const_iterator(_firstNode); } const_iterator end() const { return const_iterator(0); } private: JsonBuffer *_buffer; - Internals::JsonArrayNode *_firstChild; + Internals::JsonArrayNode *_firstNode; }; } } diff --git a/include/ArduinoJson/Internals/JsonArrayIterator.hpp b/include/ArduinoJson/Internals/JsonArrayIterator.hpp index c7e111df..0cfd041c 100644 --- a/include/ArduinoJson/Internals/JsonArrayIterator.hpp +++ b/include/ArduinoJson/Internals/JsonArrayIterator.hpp @@ -13,10 +13,12 @@ namespace Internals { class JsonArrayIterator { public: - explicit JsonArrayIterator(Internals::JsonArrayNode *node) : _node(node) {} + explicit JsonArrayIterator(Internals::JsonArrayNode *node) : _node(node) { + updateValue(); + } - JsonValueImpl &operator*() const { return _node->value; } - JsonValueImpl *operator->() { return &_node->value; } + JsonValue operator*() const { return _value; } + JsonValue *operator->() { return &_value; } bool operator==(const JsonArrayIterator &other) const { return _node == other._node; @@ -28,11 +30,15 @@ class JsonArrayIterator { JsonArrayIterator &operator++() { _node = _node->next; + updateValue(); return *this; } private: + void updateValue() { _value = JsonValue(_node ? &_node->value : NULL); } + JsonArrayNode *_node; + JsonValue _value; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp b/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp index 347d8e6e..baa6f291 100644 --- a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp +++ b/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp @@ -6,6 +6,7 @@ #pragma once +#include "../JsonPair.hpp" #include "JsonObjectNode.hpp" namespace ArduinoJson { @@ -14,26 +15,26 @@ namespace Internals { class JsonObjectConstIterator { public: explicit JsonObjectConstIterator(Internals::JsonObjectNode *node) - : _node(node) {} + : _pair(node) {} - JsonPair operator*() const { return _node->pair; } - JsonPair *operator->() { return &_node->pair; } + const JsonPair operator*() const { return _pair; } + const JsonPair *operator->() { return &_pair; } bool operator==(const JsonObjectConstIterator &other) const { - return _node == other._node; + return _pair._node == other._pair._node; } bool operator!=(const JsonObjectConstIterator &other) const { - return _node != other._node; + return _pair._node != other._pair._node; } JsonObjectConstIterator &operator++() { - _node = _node->next; + _pair._node = _pair._node->next; return *this; } private: - JsonObjectNode *_node; + JsonPair _pair; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectImpl.hpp b/include/ArduinoJson/Internals/JsonObjectImpl.hpp index 9a4fd254..e935de59 100644 --- a/include/ArduinoJson/Internals/JsonObjectImpl.hpp +++ b/include/ArduinoJson/Internals/JsonObjectImpl.hpp @@ -19,27 +19,33 @@ class JsonObjectImpl { typedef JsonObjectIterator iterator; typedef JsonObjectConstIterator const_iterator; - JsonObjectImpl(JsonBuffer *buffer) : _buffer(buffer) {} + JsonObjectImpl(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} - JsonValueImpl *operator[](const char *key) { return getOrCreateValueAt(key); } + int size() const; + + JsonValueImpl *operator[](const char *key); void remove(key_type key); JsonArrayImpl *createNestedArray(key_type key); JsonObjectImpl *createNestedObject(key_type key); - iterator begin() { return iterator(_firstChild); } + iterator begin() { return iterator(_firstNode); } iterator end() { return iterator(0); } - const_iterator begin() const { return const_iterator(_firstChild); } + const_iterator begin() const { return const_iterator(_firstNode); } const_iterator end() const { return const_iterator(0); } + void writeTo(JsonWriter &writer) const; + private: - JsonObjectNode *getNodeAt(key_type key); + void addNode(JsonObjectNode *nodeToAdd); void removeNode(JsonObjectNode *nodeToRemove); - JsonValueImpl *getOrCreateValueAt(key_type key); + + JsonObjectNode *getNodeAt(key_type key); + JsonObjectNode *getOrCreateNodeAt(key_type key); JsonBuffer *_buffer; - JsonObjectNode *_firstChild; + JsonObjectNode *_firstNode; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectIterator.hpp b/include/ArduinoJson/Internals/JsonObjectIterator.hpp index f28946df..926ad9f2 100644 --- a/include/ArduinoJson/Internals/JsonObjectIterator.hpp +++ b/include/ArduinoJson/Internals/JsonObjectIterator.hpp @@ -11,26 +11,26 @@ namespace Internals { class JsonObjectIterator { public: - explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _node(node) {} + explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _pair(node) {} - JsonPair &operator*() const { return _node->pair; } - JsonPair *operator->() { return &_node->pair; } + JsonPair &operator*() { return _pair; } + JsonPair *operator->() { return &_pair; } bool operator==(const JsonObjectIterator &other) const { - return _node == other._node; + return _pair._node == other._pair._node; } bool operator!=(const JsonObjectIterator &other) const { - return _node != other._node; + return _pair._node != other._pair._node; } JsonObjectIterator &operator++() { - _node = _node->next; + _pair._node = _pair._node->next; return *this; } private: - JsonObjectNode *_node; + JsonPair _pair; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectNode.hpp b/include/ArduinoJson/Internals/JsonObjectNode.hpp index 1ccd29f0..ec202cf4 100644 --- a/include/ArduinoJson/Internals/JsonObjectNode.hpp +++ b/include/ArduinoJson/Internals/JsonObjectNode.hpp @@ -6,14 +6,17 @@ #pragma once -#include "../JsonPair.hpp" +#include "JsonValueImpl.hpp" namespace ArduinoJson { namespace Internals { struct JsonObjectNode { - JsonObjectNode *next; - JsonPair pair; + JsonObjectNode(const char* k) : key(k) {} + + const char* const key; + JsonValueImpl value; + JsonObjectNode* next; }; } } diff --git a/include/ArduinoJson/Internals/JsonParser.hpp b/include/ArduinoJson/Internals/JsonParser.hpp index 735b3726..342bb1ad 100644 --- a/include/ArduinoJson/Internals/JsonParser.hpp +++ b/include/ArduinoJson/Internals/JsonParser.hpp @@ -18,6 +18,7 @@ class JsonParser { JsonArray parseArray(); JsonObject parseObject(); + JsonValue parseValue(); private: bool isEnd() { return *_ptr == 0; } diff --git a/include/ArduinoJson/Internals/JsonValueImpl.hpp b/include/ArduinoJson/Internals/JsonValueImpl.hpp index 4703fadb..d22a5e8b 100644 --- a/include/ArduinoJson/Internals/JsonValueImpl.hpp +++ b/include/ArduinoJson/Internals/JsonValueImpl.hpp @@ -49,28 +49,28 @@ class JsonValueImpl { _content.asObject = object; } - operator bool() const { - return _type == JSON_BOOLEAN ? _content.asBoolean : false; - } - - operator char const *() const { - return _type == JSON_STRING ? _content.asString : NULL; - } - - operator double() const { - return _type >= JSON_DOUBLE_0_DECIMALS ? _content.asDouble : 0; - } - - operator long() const { return _type == JSON_LONG ? _content.asInteger : 0; } - - operator JsonArrayImpl *() const { + JsonArrayImpl *asArray() { return _type == JSON_ARRAY ? _content.asArray : NULL; } - operator JsonObjectImpl *() const { + JsonObjectImpl *asObject() { return _type == JSON_OBJECT ? _content.asObject : NULL; } + bool asBool() const { + return _type == JSON_BOOLEAN ? _content.asBoolean : false; + } + + const char *asString() const { + return _type == JSON_STRING ? _content.asString : NULL; + } + + double asDouble() const { + return _type >= JSON_DOUBLE_0_DECIMALS ? _content.asDouble : 0; + } + + long asLong() const { return _type == JSON_LONG ? _content.asInteger : 0; } + void writeTo(JsonWriter &writer) const; private: diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index 2492f21a..dc13b64a 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -6,11 +6,11 @@ #pragma once -#include "JsonContainer.hpp" +#include "JsonPrintable.hpp" #include "Internals/JsonArrayImpl.hpp" namespace ArduinoJson { -class JsonArray : public JsonContainer { +class JsonArray : public JsonPrintable { friend class JsonValue; public: @@ -21,8 +21,11 @@ class JsonArray : public JsonContainer { JsonArray() {} JsonArray(Internals::JsonArrayImpl* impl) : _impl(impl) {} - value_type operator[](int index) const; + bool success() const { return _impl; } + int size() const { return _impl ? _impl->size() : 0; } + + value_type operator[](int index) const; value_type add(); template @@ -47,7 +50,12 @@ class JsonArray : public JsonContainer { } const_iterator end() const { return const_iterator(0); } - static JsonArray null() { return JsonArray(NULL); } + bool operator==(const JsonArray& other) const { return _impl == other._impl; } + + protected: + virtual void writeTo(Internals::JsonWriter& writer) const { + if (_impl) _impl->writeTo(writer); + } private: Internals::JsonArrayImpl* _impl; diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index 9301a139..3daf36a4 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -6,11 +6,11 @@ #pragma once -#include "JsonContainer.hpp" +#include "JsonPrintable.hpp" #include "Internals/JsonObjectImpl.hpp" namespace ArduinoJson { -class JsonObject : public JsonContainer { +class JsonObject : public JsonPrintable { friend class JsonValue; public: @@ -19,10 +19,17 @@ class JsonObject : public JsonContainer { typedef Internals::JsonObjectIterator iterator; typedef Internals::JsonObjectConstIterator const_iterator; + JsonObject() : _impl(NULL) {} JsonObject(Internals::JsonObjectImpl* impl) : _impl(impl) {} + bool success() const { return _impl; } + + int size() const { return _impl ? _impl->size() : 0; } + JsonValue operator[](key_type key); - void remove(key_type key); + void remove(key_type key) { + if (_impl) _impl->remove(key); + } JsonArray createNestedArray(key_type key); JsonObject createNestedObject(key_type key); @@ -39,6 +46,15 @@ class JsonObject : public JsonContainer { } const_iterator end() const { return const_iterator(0); } + bool operator==(const JsonObject& other) const { + return _impl == other._impl; + } + + protected: + virtual void writeTo(Internals::JsonWriter& writer) const { + if (_impl) _impl->writeTo(writer); + } + private: Internals::JsonObjectImpl* _impl; }; diff --git a/include/ArduinoJson/JsonPair.hpp b/include/ArduinoJson/JsonPair.hpp index d8d3084c..40b4097e 100644 --- a/include/ArduinoJson/JsonPair.hpp +++ b/include/ArduinoJson/JsonPair.hpp @@ -7,17 +7,20 @@ #pragma once #include "JsonValue.hpp" +#include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { class JsonPair { - public: - JsonPair(const char *k) : _key(k) {} + friend class Internals::JsonObjectIterator; + friend class Internals::JsonObjectConstIterator; - const char *key() const { return _key; } - JsonValue &value() { return _value; } + public: + JsonPair(Internals::JsonObjectNode *node) : _node(node) {} + + const char *key() const { return _node->key; } + JsonValue value() { return JsonValue(&_node->value); } private: - const char *_key; - JsonValue _value; + Internals::JsonObjectNode *_node; }; } diff --git a/include/ArduinoJson/JsonContainer.hpp b/include/ArduinoJson/JsonPrintable.hpp similarity index 76% rename from include/ArduinoJson/JsonContainer.hpp rename to include/ArduinoJson/JsonPrintable.hpp index 9df3307e..8e6d2714 100644 --- a/include/ArduinoJson/JsonContainer.hpp +++ b/include/ArduinoJson/JsonPrintable.hpp @@ -6,13 +6,12 @@ #pragma once +#include "ForwardDeclarations.hpp" #include "Arduino/Printable.hpp" -#include "Internals/IndentedPrint.hpp" namespace ArduinoJson { -// TODO: renale to JsonPrintable -class JsonContainer : public Printable { +class JsonPrintable : public Printable { public: size_t printTo(char *buffer, size_t bufferSize) const; virtual size_t printTo(Print &print) const; @@ -20,5 +19,8 @@ class JsonContainer : public Printable { size_t prettyPrintTo(char *buffer, size_t bufferSize) const; size_t prettyPrintTo(Internals::IndentedPrint &print) const; size_t prettyPrintTo(Print &print) const; + + protected: + virtual void writeTo(Internals::JsonWriter &) const = 0; }; } diff --git a/include/ArduinoJson/JsonValue.hpp b/include/ArduinoJson/JsonValue.hpp index b3fe06b1..7144a576 100644 --- a/include/ArduinoJson/JsonValue.hpp +++ b/include/ArduinoJson/JsonValue.hpp @@ -18,35 +18,51 @@ class JsonValue { JsonValue() : _impl(NULL) {} JsonValue(Internals::JsonValueImpl *impl) : _impl(impl) {} - template - void operator=(T value) { + void set(const char *value) { if (_impl) _impl->set(value); } - - void operator=(JsonArray array); - void operator=(JsonObject object); - - void set(double value, int decimals) { + void set(bool value) { + if (_impl) _impl->set(value); + } + void set(double value, int decimals = 2) { if (_impl) _impl->set(value, decimals); } + void set(int value) { + if (_impl) _impl->set(static_cast(value)); + } + void set(long value) { + if (_impl) _impl->set(value); + } + void set(JsonObject object); + void set(JsonArray array); + + operator bool() const { return _impl ? _impl->asBool() : false; } + operator int() const { return _impl ? _impl->asLong() : 0; } + operator long() const { return _impl ? _impl->asLong() : 0; } + operator double() const { return _impl ? _impl->asDouble() : 0.0; } + operator const char *() const { + return _impl ? _impl->asString() : static_cast(NULL); + } + operator JsonArray(); + operator JsonObject(); + + bool success() { return _impl; } + + template + JsonValue operator=(T value) { + set(value); + return *this; + } template T as() { return static_cast(*this); } - operator bool() const { return _impl ? *_impl : false; } - operator int() const { return _impl ? *_impl : 0; } - operator long() const { return _impl ? *_impl : 0; } - operator double() const { return _impl ? *_impl : 0.0; } - operator const char *() const { - return _impl ? *_impl : static_cast(NULL); + protected: + virtual void writeTo(Internals::JsonWriter &writer) const { + if (_impl) _impl->writeTo(writer); } - operator JsonArray() const; - - bool success() { return _impl; } - - static JsonValue null() { return JsonValue(NULL); } private: Internals::JsonValueImpl *_impl; diff --git a/include/ArduinoJson/StaticJsonBuffer.hpp b/include/ArduinoJson/StaticJsonBuffer.hpp index e9897925..a6428e92 100644 --- a/include/ArduinoJson/StaticJsonBuffer.hpp +++ b/include/ArduinoJson/StaticJsonBuffer.hpp @@ -22,14 +22,15 @@ class StaticJsonBuffer : public JsonBuffer { int size() { return _size; } protected: - virtual void *allocateNode() { - if (_size >= CAPACITY) return 0; - - return &_buffer[_size++]; + virtual void* alloc(size_t size) { + if (_size + size > CAPACITY) return NULL; + void* p = &_buffer[_size]; + _size += size; + return p; } private: - Internals::JsonNode _buffer[CAPACITY]; + char _buffer[CAPACITY]; int _size; }; } diff --git a/src/Internals/JsonArrayImpl.cpp b/src/Internals/JsonArrayImpl.cpp index 7e9fbe75..3a85d11b 100644 --- a/src/Internals/JsonArrayImpl.cpp +++ b/src/Internals/JsonArrayImpl.cpp @@ -13,8 +13,14 @@ using namespace ArduinoJson; using namespace ArduinoJson::Internals; +int JsonArrayImpl::size() const { + int nodeCount = 0; + for (JsonArrayNode *node = _firstNode; node; node = node->next) nodeCount++; + return nodeCount; +} + JsonValueImpl *JsonArrayImpl::operator[](int index) const { - JsonArrayNode *node = _firstChild; + JsonArrayNode *node = _firstNode; while (node && index--) node = node->next; return NULL; @@ -50,7 +56,7 @@ JsonObjectImpl *JsonArrayImpl::createNestedObject() { } void JsonArrayImpl::writeTo(JsonWriter &writer) const { - JsonArrayNode *child = _firstChild; + JsonArrayNode *child = _firstNode; if (child) { writer.beginArray(); diff --git a/src/Internals/JsonObjectImpl.cpp b/src/Internals/JsonObjectImpl.cpp index 956701c3..97177c44 100644 --- a/src/Internals/JsonObjectImpl.cpp +++ b/src/Internals/JsonObjectImpl.cpp @@ -11,102 +11,95 @@ #include "ArduinoJson/JsonBuffer.hpp" #include "ArduinoJson/Internals/JsonArrayImpl.hpp" #include "ArduinoJson/Internals/JsonValueImpl.hpp" +#include "ArduinoJson/Internals/JsonWriter.hpp" #include "ArduinoJson/Internals/StringBuilder.hpp" using namespace ArduinoJson; using namespace ArduinoJson::Internals; +int JsonObjectImpl::size() const { + int nodeCount = 0; + for (JsonObjectNode *node = _firstNode; node; node = node->next) nodeCount++; + return nodeCount; +} + +JsonValueImpl *JsonObjectImpl::operator[](const char *key) { + JsonObjectNode *node = getOrCreateNodeAt(key); + return node ? &node->value : NULL; +} + void JsonObjectImpl::remove(char const *key) { removeNode(getNodeAt(key)); } JsonArrayImpl *JsonObjectImpl::createNestedArray(char const *key) { - JsonValueImpl *node = getOrCreateValueAt(key); + JsonObjectNode *node = getOrCreateNodeAt(key); if (!node) return NULL; JsonArrayImpl *array = new (_buffer) JsonArrayImpl(_buffer); - node->set(array); + node->value.set(array); return array; } -JsonObject JsonObject::createNestedObject(char const *key) { - JsonNode *node = getOrCreateValueAt(key); +JsonObjectImpl *JsonObjectImpl::createNestedObject(const char *key) { + JsonObjectNode *node = getOrCreateNodeAt(key); + if (!node) return NULL; - if (node) node->setAsObject(_node->getContainerBuffer()); + JsonObjectImpl *object = new (_buffer) JsonObjectImpl(_buffer); + node->value.set(object); - return JsonObject(node); + return object; } -JsonNode *JsonObject::getPairAt(const char *key) { - for (JsonNode *node = firstChild(); node; node = node->next) { - if (!strcmp(node->getAsObjectKey(), key)) return node; +JsonObjectNode *JsonObjectImpl::getNodeAt(const char *key) { + for (JsonObjectNode *node = _firstNode; node; node = node->next) { + if (!strcmp(node->key, key)) return node; } return NULL; } -JsonNode *JsonObject::getOrCreateValueAt(const char *key) { - JsonNode *existingNode = getPairAt(key); - if (existingNode) return existingNode->getAsObjectValue(); +JsonObjectNode *JsonObjectImpl::getOrCreateNodeAt(const char *key) { + JsonObjectNode *existingNode = getNodeAt(key); + if (existingNode) return existingNode; - JsonNode *newValueNode = createNode(); - if (!newValueNode) return 0; + JsonObjectNode *newNode = new (_buffer) JsonObjectNode(key); - JsonNode *newKeyNode = createNode(); - if (!newKeyNode) return 0; + if (newNode) addNode(newNode); - newKeyNode->setAsObjectKeyValue(key, newValueNode); - - addChild(newKeyNode); - - return newValueNode; + return newNode; } -void JsonNode::addChild(JsonNode *childToAdd) { - if (type == JSON_PROXY) return content.asProxy.target->addChild(childToAdd); - - if (type != JSON_ARRAY && type != JSON_OBJECT) return; - - JsonNode *lastChild = content.asContainer.child; - - if (!lastChild) { - content.asContainer.child = childToAdd; - return; - } - - while (lastChild->next) lastChild = lastChild->next; - - lastChild->next = childToAdd; -} - -void JsonNode::removeChild(JsonNode *childToRemove) { - if (type == JSON_PROXY) - return content.asProxy.target->removeChild(childToRemove); - - if (type != JSON_ARRAY && type != JSON_OBJECT) return; - - if (content.asContainer.child == childToRemove) { - content.asContainer.child = childToRemove->next; - return; - } - - for (JsonNode *child = content.asContainer.child; child; - child = child->next) { - if (child->next == childToRemove) child->next = childToRemove->next; +void JsonObjectImpl::addNode(JsonObjectNode *nodeToAdd) { + if (!_firstNode) { + _firstNode = nodeToAdd; + } else { + JsonObjectNode *lastNode = _firstNode; + while (lastNode->next) lastNode = lastNode->next; + lastNode->next = nodeToAdd; } } -void JsonObjectImpl::writeObjectTo(JsonWriter &writer) { - JsonObjectNode *child = _firstChild; +void JsonObjectImpl::removeNode(JsonObjectNode *nodeToRemove) { + if (nodeToRemove == _firstNode) { + _firstNode = nodeToRemove->next; + } else { + for (JsonObjectNode *node = _firstNode; node; node = node->next) + if (node->next == nodeToRemove) node->next = nodeToRemove->next; + } +} - if (child) { +void JsonObjectImpl::writeTo(JsonWriter &writer) const { + JsonObjectNode *node = _firstNode; + + if (node) { writer.beginObject(); for (;;) { - writer.writeString(child->content.asKeyValue.key); + writer.writeString(node->key); writer.writeColon(); - child->value->writeTo(writer); + node->value.writeTo(writer); - child = child->next; - if (!child) break; + node = node->next; + if (!node) break; writer.writeComma(); } diff --git a/src/Internals/JsonParser.cpp b/src/Internals/JsonParser.cpp index 95a66564..764b13d3 100644 --- a/src/Internals/JsonParser.cpp +++ b/src/Internals/JsonParser.cpp @@ -70,9 +70,6 @@ void JsonParser::parseValueTo(JsonValue destination) { case '\"': destination = parseString(); break; - - default: - destination = NULL; // invalid JSON } } @@ -142,10 +139,9 @@ JsonObject JsonParser::parseObject() { const char *key = parseString(); if (!key) return NULL; - if (!skip(':')) - return NULL; + if (!skip(':')) return NULL; - JsonValue value = object[key]; + JsonValue value = object[key]; parseValueTo(value); if (!value.success()) return NULL; @@ -159,3 +155,9 @@ JsonObject JsonParser::parseObject() { const char *JsonParser::parseString() { return QuotedString::extractFrom(_ptr, &_ptr); } + +JsonValue JsonParser::parseValue() { + JsonValue value = _buffer->createValue(); + parseValueTo(value); + return value; +} diff --git a/src/Internals/JsonValueImpl.cpp b/src/Internals/JsonValueImpl.cpp index 3d256db3..dcdb4a05 100644 --- a/src/Internals/JsonValueImpl.cpp +++ b/src/Internals/JsonValueImpl.cpp @@ -5,6 +5,11 @@ // https://github.com/bblanchon/ArduinoJson #include "ArduinoJson/Internals/JsonValueImpl.hpp" +#include "ArduinoJson/Internals/JsonArrayImpl.hpp" +#include "ArduinoJson/Internals/JsonObjectImpl.hpp" +#include "ArduinoJson/Internals/JsonWriter.hpp" + +using namespace ArduinoJson::Internals; void JsonValueImpl::writeTo(JsonWriter &writer) const { switch (_type) { @@ -17,19 +22,19 @@ void JsonValueImpl::writeTo(JsonWriter &writer) const { break; case JSON_STRING: - writer.writeString(content.asString); + writer.writeString(_content.asString); break; case JSON_LONG: - writer.writeInteger(content.asInteger); + writer.writeInteger(_content.asInteger); break; case JSON_BOOLEAN: - writer.writeBoolean(content.asBoolean); + writer.writeBoolean(_content.asBoolean); break; default: // >= JSON_DOUBLE_0_DECIMALS - writer.writeDouble(content.asDouble, type - JSON_DOUBLE_0_DECIMALS); + writer.writeDouble(_content.asDouble, _type - JSON_DOUBLE_0_DECIMALS); break; } } \ No newline at end of file diff --git a/src/JsonArray.cpp b/src/JsonArray.cpp index 1428b4a3..cca79d1f 100644 --- a/src/JsonArray.cpp +++ b/src/JsonArray.cpp @@ -11,17 +11,16 @@ using namespace ArduinoJson; using namespace ArduinoJson::Internals; +JsonValue JsonArray::add() { return JsonValue(_impl ? _impl->add() : NULL); } + JsonValue JsonArray::operator[](int index) const { - if (!_impl) return JsonValue::null(); - return JsonValue((*_impl)[index]); + return JsonValue(_impl ? (*_impl)[index] : NULL); } JsonArray JsonArray::createNestedArray() { - if (!_impl) return JsonArray::null(); - return JsonArray(_impl->createNestedArray()); + return JsonArray(_impl ? _impl->createNestedArray() : NULL); } JsonObject JsonArray::createNestedObject() { - if (!_impl) return JsonObject::null(); - return JsonObject(_impl->createNestedObject())); + return JsonObject(_impl ? _impl->createNestedObject() : NULL); } \ No newline at end of file diff --git a/src/JsonBuffer.cpp b/src/JsonBuffer.cpp index c4d7cf54..cde321a0 100644 --- a/src/JsonBuffer.cpp +++ b/src/JsonBuffer.cpp @@ -6,6 +6,12 @@ #include "ArduinoJson/JsonBuffer.hpp" +#include "ArduinoJson/JsonArray.hpp" +#include "ArduinoJson/Internals/JsonArrayImpl.hpp" +#include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/Internals/JsonObjectImpl.hpp" +#include "ArduinoJson/JsonValue.hpp" +#include "ArduinoJson/Internals/JsonValueImpl.hpp" #include "ArduinoJson/Internals/JsonParser.hpp" using namespace ArduinoJson; @@ -13,5 +19,32 @@ using namespace ArduinoJson::Internals; // TODO: what happens if alloc returns NULL void* operator new(size_t size, ArduinoJson::JsonBuffer* buffer) { - return _buffer->alloc(size); + return buffer->alloc(size); } + +JsonArray JsonBuffer::createArray() { + return JsonArray(new (this) JsonArrayImpl(this)); +} + +JsonObject JsonBuffer::createObject() { + return JsonObject(new (this) JsonObjectImpl(this)); +} + +JsonValue JsonBuffer::createValue() { + return JsonValue(new (this) JsonValueImpl()); +} + +JsonArray JsonBuffer::parseArray(char* json) { + JsonParser parser(this, json); + return JsonArray(parser.parseArray()); +} + +JsonObject JsonBuffer::parseObject(char* json) { + JsonParser parser(this, json); + return JsonObject(parser.parseObject()); +} + +JsonValue JsonBuffer::parseValue(char* json) { + JsonParser parser(this, json); + return JsonValue(parser.parseValue()); +} \ No newline at end of file diff --git a/src/JsonContainer.cpp b/src/JsonContainer.cpp deleted file mode 100644 index 440c7a07..00000000 --- a/src/JsonContainer.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#include "ArduinoJson/JsonContainer.hpp" - -#include "ArduinoJson/JsonBuffer.hpp" -#include "ArduinoJson/Internals/StringBuilder.hpp" -#include "ArduinoJson/Internals/CompactJsonWriter.hpp" -#include "ArduinoJson/Internals/PrettyJsonWriter.hpp" - -using namespace ArduinoJson; -using namespace ArduinoJson::Internals; - -size_t JsonContainer::printTo(char *buffer, size_t bufferSize) const { - StringBuilder sb(buffer, bufferSize); - return printTo(sb); -} - -size_t JsonContainer::printTo(Print &p) const { - CompactJsonWriter writer(&p); - _node->writeTo(writer); - return writer.bytesWritten(); -} - -size_t JsonContainer::prettyPrintTo(char *buffer, size_t bufferSize) const { - StringBuilder sb(buffer, bufferSize); - return prettyPrintTo(sb); -} - -size_t JsonContainer::prettyPrintTo(IndentedPrint &p) const { - PrettyJsonWriter writer(&p); - _node->writeTo(writer); - return writer.bytesWritten(); -} - -size_t JsonContainer::prettyPrintTo(Print &print) const { - IndentedPrint indentedPrint = IndentedPrint(print); - return prettyPrintTo(indentedPrint); -} - -JsonNode *JsonContainer::createNode() { - if (!_node) return 0; - - JsonBuffer *buffer = _node->getContainerBuffer(); - if (!buffer) return 0; - - return buffer->createNode(); -} - -bool JsonContainer::operator==(const JsonContainer &other) const { - if (_node == other._node) return true; - if (!_node || !other._node) return false; - return _node->getProxyTarget() == other._node->getProxyTarget(); -} - -void JsonContainer::addChild(JsonNode *childToAdd) { - if (_node) _node->addChild(childToAdd); -} - -void JsonContainer::removeChild(JsonNode *childToRemove) { - if (_node) _node->removeChild(childToRemove); -} - -size_t JsonContainer::size() const { - int n = 0; - - for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it) { - n++; - } - - return n; -} - -JsonNode* JsonContainer::firstChild() const -{ - return _node ? _node->getContainerChild() : 0; -} diff --git a/src/JsonObject.cpp b/src/JsonObject.cpp index 2b816f44..96a700ad 100644 --- a/src/JsonObject.cpp +++ b/src/JsonObject.cpp @@ -4,7 +4,9 @@ // Arduino JSON library // https://github.com/bblanchon/ArduinoJson +#include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/JsonValue.hpp" using namespace ArduinoJson; diff --git a/src/JsonPrintable.cpp b/src/JsonPrintable.cpp new file mode 100644 index 00000000..0948faf1 --- /dev/null +++ b/src/JsonPrintable.cpp @@ -0,0 +1,42 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#include "ArduinoJson/JsonPrintable.hpp" + +#include "ArduinoJson/JsonBuffer.hpp" +#include "ArduinoJson/Internals/StringBuilder.hpp" +#include "ArduinoJson/Internals/CompactJsonWriter.hpp" +#include "ArduinoJson/Internals/PrettyJsonWriter.hpp" + +using namespace ArduinoJson; +using namespace ArduinoJson::Internals; + +size_t JsonPrintable::printTo(char *buffer, size_t bufferSize) const { + StringBuilder sb(buffer, bufferSize); + return printTo(sb); +} + +size_t JsonPrintable::printTo(Print &p) const { + CompactJsonWriter writer(&p); + writeTo(writer); + return writer.bytesWritten(); +} + +size_t JsonPrintable::prettyPrintTo(char *buffer, size_t bufferSize) const { + StringBuilder sb(buffer, bufferSize); + return prettyPrintTo(sb); +} + +size_t JsonPrintable::prettyPrintTo(IndentedPrint &p) const { + PrettyJsonWriter writer(&p); + writeTo(writer); + return writer.bytesWritten(); +} + +size_t JsonPrintable::prettyPrintTo(Print &print) const { + IndentedPrint indentedPrint = IndentedPrint(print); + return prettyPrintTo(indentedPrint); +} diff --git a/src/JsonValue.cpp b/src/JsonValue.cpp index 1e2123ec..fd3e26ff 100644 --- a/src/JsonValue.cpp +++ b/src/JsonValue.cpp @@ -4,25 +4,24 @@ // Arduino JSON library // https://github.com/bblanchon/ArduinoJson -#include "ArduinoJson/JsonValue.hpp" - #include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/JsonValue.hpp" using namespace ArduinoJson; -JsonValue::operator JsonArray() const { - return _impl ? JsonArray(*_impl) : JsonArray(); +JsonValue::operator JsonArray() { + return JsonArray(_impl ? _impl->asArray() : NULL); } -JsonValue::operator JsonObject() const { - return _impl ? JsonObject(*_impl) : JsonObject(); +JsonValue::operator JsonObject() { + return JsonObject(_impl ? _impl->asObject() : NULL); } -void JsonValue::operator=(JsonArray array) { +void JsonValue::set(JsonArray array) { if (_impl) _impl->set(array._impl); } -void JsonValue::operator=(JsonObject object) { +void JsonValue::set(JsonObject object) { if (_impl) _impl->set(object._impl); } \ No newline at end of file diff --git a/test/Issue10.cpp b/test/Issue10.cpp index aae0e301..71616e2e 100644 --- a/test/Issue10.cpp +++ b/test/Issue10.cpp @@ -30,7 +30,7 @@ class Issue10 : public testing::Test { persons[1] = employee; } - void checkJsonString(JsonContainer &p) { + void checkJsonString(JsonPrintable &p) { char buffer[256]; p.printTo(buffer, sizeof(buffer)); diff --git a/test/JsonArray_Container_Tests.cpp b/test/JsonArray_Container_Tests.cpp index 1c2cd37d..c885c64b 100644 --- a/test/JsonArray_Container_Tests.cpp +++ b/test/JsonArray_Container_Tests.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "Printers.hpp" using namespace ArduinoJson; diff --git a/test/JsonObject_Container_Tests.cpp b/test/JsonObject_Container_Tests.cpp index 3fdf4dc4..399edbe1 100644 --- a/test/JsonObject_Container_Tests.cpp +++ b/test/JsonObject_Container_Tests.cpp @@ -5,8 +5,10 @@ // https://github.com/bblanchon/ArduinoJson #include -#include +#include +#include #include +#include #include "Printers.hpp" using namespace ArduinoJson; diff --git a/test/JsonObject_PrettyPrintTo_Tests.cpp b/test/JsonObject_PrettyPrintTo_Tests.cpp index 3e96884d..d356f36c 100644 --- a/test/JsonObject_PrettyPrintTo_Tests.cpp +++ b/test/JsonObject_PrettyPrintTo_Tests.cpp @@ -5,6 +5,7 @@ // https://github.com/bblanchon/ArduinoJson #include +#include #include #include #include diff --git a/test/JsonParser_Array_Tests.cpp b/test/JsonParser_Array_Tests.cpp index 6a38d817..c5891211 100644 --- a/test/JsonParser_Array_Tests.cpp +++ b/test/JsonParser_Array_Tests.cpp @@ -5,8 +5,9 @@ // https://github.com/bblanchon/ArduinoJson #include -#include +#include #include +#include using namespace ArduinoJson; diff --git a/test/JsonParser_Nested_Tests.cpp b/test/JsonParser_Nested_Tests.cpp index 394009bf..cb5c8ca0 100644 --- a/test/JsonParser_Nested_Tests.cpp +++ b/test/JsonParser_Nested_Tests.cpp @@ -5,6 +5,8 @@ // https://github.com/bblanchon/ArduinoJson #include +#include +#include #include using namespace ArduinoJson; diff --git a/test/JsonParser_Object_Tests.cpp b/test/JsonParser_Object_Tests.cpp index 8f60937e..6f3ad588 100644 --- a/test/JsonParser_Object_Tests.cpp +++ b/test/JsonParser_Object_Tests.cpp @@ -6,6 +6,7 @@ #include #include +#include #include using namespace ArduinoJson; diff --git a/test/JsonValueTests.cpp b/test/JsonValueTests.cpp index 2e890ed6..78c46875 100644 --- a/test/JsonValueTests.cpp +++ b/test/JsonValueTests.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include "Printers.hpp" diff --git a/test/StaticJsonBufferTests.cpp b/test/StaticJsonBufferTests.cpp index 5ade1f64..b3d92271 100644 --- a/test/StaticJsonBufferTests.cpp +++ b/test/StaticJsonBufferTests.cpp @@ -5,8 +5,9 @@ // https://github.com/bblanchon/ArduinoJson #include -#include +#include #include +#include using namespace ArduinoJson;