From e0980292ef8c8a13567e5f538cf2f5528b26becc Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 26 Oct 2014 21:18:09 +0100 Subject: [PATCH] Epic refactoring in progress --- include/ArduinoJson/ForwardDeclarations.hpp | 18 +- .../Internals/JsonArrayConstIterator.hpp | 16 +- .../ArduinoJson/Internals/JsonArrayImpl.hpp | 41 +++++ .../Internals/JsonArrayIterator.hpp | 16 +- .../ArduinoJson/Internals/JsonArrayNode.hpp | 19 ++ include/ArduinoJson/Internals/JsonNode.hpp | 163 ------------------ .../Internals/JsonNodeIterator.hpp | 32 ---- .../ArduinoJson/Internals/JsonNodeWrapper.hpp | 31 ---- .../Internals/JsonObjectConstIterator.hpp | 17 +- .../Internals/JsonObjectIterator.hpp | 16 +- .../ArduinoJson/Internals/JsonObjectNode.hpp | 19 ++ .../Internals/JsonPairInternal.hpp | 22 --- include/ArduinoJson/Internals/JsonParser.hpp | 23 ++- .../ArduinoJson/Internals/JsonSerializer.hpp | 23 +++ .../Internals/JsonValueContent.hpp | 23 +++ .../ArduinoJson/Internals/JsonValueImpl.hpp | 79 +++++++++ .../Internals/JsonValueInternal.hpp | 25 --- .../ArduinoJson/Internals/JsonValueType.hpp | 25 +++ include/ArduinoJson/JsonArray.hpp | 33 ++-- include/ArduinoJson/JsonBuffer.hpp | 46 +++-- include/ArduinoJson/JsonContainer.hpp | 26 +-- include/ArduinoJson/JsonObject.hpp | 14 +- include/ArduinoJson/JsonPair.hpp | 16 +- include/ArduinoJson/JsonValue.hpp | 48 +++--- src/Internals/JsonArrayImpl.cpp | 52 ++++++ src/Internals/JsonParser.cpp | 105 ++++++----- .../{JsonNode.cpp => JsonSerializer.cpp} | 0 src/JsonArray.cpp | 36 +--- src/JsonValue.cpp | 34 +--- 29 files changed, 477 insertions(+), 541 deletions(-) create mode 100644 include/ArduinoJson/Internals/JsonArrayImpl.hpp create mode 100644 include/ArduinoJson/Internals/JsonArrayNode.hpp delete mode 100644 include/ArduinoJson/Internals/JsonNode.hpp delete mode 100644 include/ArduinoJson/Internals/JsonNodeIterator.hpp delete mode 100644 include/ArduinoJson/Internals/JsonNodeWrapper.hpp create mode 100644 include/ArduinoJson/Internals/JsonObjectNode.hpp delete mode 100644 include/ArduinoJson/Internals/JsonPairInternal.hpp create mode 100644 include/ArduinoJson/Internals/JsonSerializer.hpp create mode 100644 include/ArduinoJson/Internals/JsonValueContent.hpp create mode 100644 include/ArduinoJson/Internals/JsonValueImpl.hpp delete mode 100644 include/ArduinoJson/Internals/JsonValueInternal.hpp create mode 100644 include/ArduinoJson/Internals/JsonValueType.hpp create mode 100644 src/Internals/JsonArrayImpl.cpp rename src/Internals/{JsonNode.cpp => JsonSerializer.cpp} (100%) diff --git a/include/ArduinoJson/ForwardDeclarations.hpp b/include/ArduinoJson/ForwardDeclarations.hpp index 33526794..23651ee2 100644 --- a/include/ArduinoJson/ForwardDeclarations.hpp +++ b/include/ArduinoJson/ForwardDeclarations.hpp @@ -6,22 +6,26 @@ #pragma once +// TODO: cleanup + namespace ArduinoJson { class JsonArray; class JsonBuffer; -class JsonObject; -class JsonObjectIterator; -class JsonObjectKeyValue; +class JsonPair; class JsonValue; -template -class JsonIterator; -template -class JsonConstIterator; +class JsonObject; namespace Internals { class IndentedPrint; +class JsonArrayConstIterator; +class JsonArrayImpl; +class JsonArrayIterator; class JsonNode; +class JsonObjectImpl; +class JsonObjectIterator; class JsonParser; +class JsonValueImpl; class JsonWriter; +struct JsonArrayNode; } } diff --git a/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp b/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp index c42ad6ce..49d8d900 100644 --- a/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp +++ b/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp @@ -6,33 +6,33 @@ #pragma once -#include "JsonValueInternal.hpp" +#include "JsonArrayNode.hpp" namespace ArduinoJson { namespace Internals { class JsonArrayConstIterator { public: - explicit JsonArrayConstIterator(Internals::JsonNode *node) : _value(node) {} + explicit JsonArrayConstIterator(JsonArrayNode *node) : _node(node) {} - JsonValue operator*() const { return _value; } - JsonValue *operator->() { return &_value; } + const JsonValueImpl &operator*() const { return _node->value; } + const JsonValueImpl *operator->() { return &_node->value; } bool operator==(const JsonArrayConstIterator &other) const { - return _value.isSameAs(other._value); + return _node == other._node; } bool operator!=(const JsonArrayConstIterator &other) const { - return !_value.isSameAs(other._value); + return _node != other._node; } JsonArrayConstIterator &operator++() { - _value.moveToNext(); + _node = _node->next; return *this; } private: - JsonValueInternal _value; + JsonArrayNode *_node; }; } } diff --git a/include/ArduinoJson/Internals/JsonArrayImpl.hpp b/include/ArduinoJson/Internals/JsonArrayImpl.hpp new file mode 100644 index 00000000..a8274cc1 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonArrayImpl.hpp @@ -0,0 +1,41 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include "../JsonBuffer.hpp" +#include "JsonArrayIterator.hpp" +#include "JsonArrayConstIterator.hpp" + +namespace ArduinoJson { +namespace Internals { +class JsonArrayImpl { + public: + typedef JsonValueImpl *value_type; + typedef JsonArrayIterator iterator; + typedef JsonArrayConstIterator const_iterator; + + JsonArrayImpl(JsonBuffer *buffer) : _buffer(buffer) {} + + value_type *operator[](int index) const; + + value_type *add(); + + JsonArrayImpl *createNestedArray(); + JsonObjectImpl *createNestedObject(); + + iterator begin() { return iterator(_firstChild); } + iterator end() { return iterator(0); } + + const_iterator begin() const { return const_iterator(_firstChild); } + const_iterator end() const { return const_iterator(0); } + + private: + JsonBuffer *_buffer; + Internals::JsonArrayNode *_firstChild; +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonArrayIterator.hpp b/include/ArduinoJson/Internals/JsonArrayIterator.hpp index e79f2f36..c7e111df 100644 --- a/include/ArduinoJson/Internals/JsonArrayIterator.hpp +++ b/include/ArduinoJson/Internals/JsonArrayIterator.hpp @@ -6,33 +6,33 @@ #pragma once -#include "JsonValueInternal.hpp" +#include "JsonArrayNode.hpp" namespace ArduinoJson { namespace Internals { class JsonArrayIterator { public: - explicit JsonArrayIterator(Internals::JsonNode *node) : _value(node) {} + explicit JsonArrayIterator(Internals::JsonArrayNode *node) : _node(node) {} - JsonValue operator*() const { return _value; } - JsonValue *operator->() { return &_value; } + JsonValueImpl &operator*() const { return _node->value; } + JsonValueImpl *operator->() { return &_node->value; } bool operator==(const JsonArrayIterator &other) const { - return _value.isSameAs(other._value); + return _node == other._node; } bool operator!=(const JsonArrayIterator &other) const { - return !_value.isSameAs(other._value); + return _node != other._node; } JsonArrayIterator &operator++() { - _value.moveToNext(); + _node = _node->next; return *this; } private: - JsonValueInternal _value; + JsonArrayNode *_node; }; } } diff --git a/include/ArduinoJson/Internals/JsonArrayNode.hpp b/include/ArduinoJson/Internals/JsonArrayNode.hpp new file mode 100644 index 00000000..f58bba56 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonArrayNode.hpp @@ -0,0 +1,19 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include "../JsonValue.hpp" + +namespace ArduinoJson { +namespace Internals { + +struct JsonArrayNode { + JsonArrayNode *next; + JsonValueImpl value; +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonNode.hpp b/include/ArduinoJson/Internals/JsonNode.hpp deleted file mode 100644 index 2f6957ee..00000000 --- a/include/ArduinoJson/Internals/JsonNode.hpp +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "../ForwardDeclarations.hpp" - -namespace ArduinoJson { -namespace Internals { - -class JsonNode { - enum JsonNodeType { - JSON_UNDEFINED, - JSON_NULL, - JSON_ARRAY, - JSON_OBJECT, - JSON_KEY_VALUE, - JSON_BOOLEAN, - JSON_STRING, - JSON_LONG, - JSON_PROXY, - JSON_DOUBLE_0_DECIMALS, - JSON_DOUBLE_1_DECIMAL, - JSON_DOUBLE_2_DECIMALS - // etc. - }; - - union JsonNodeContent { - bool asBoolean; - double asDouble; - long asInteger; - const char *asString; - - struct { - const char *key; - JsonNode *value; - } asKeyValue; - - struct { - JsonNode *child; - JsonBuffer *buffer; - } asContainer; - - struct { - JsonNode *target; - } asProxy; - }; - - public: - JsonNode() : next(0), type(JSON_UNDEFINED) {} - - JsonNode *next; - - void writeTo(JsonWriter &); // TODO: <- move in JsonNodeSerializer - - void setAsArray(JsonBuffer *buffer) { - type = JSON_ARRAY; - content.asContainer.child = 0; - content.asContainer.buffer = buffer; - } - - void setAsBoolean(bool value) { - type = JSON_BOOLEAN; - content.asBoolean = value; - } - - void setAsLong(int value) { - type = JSON_LONG; - content.asInteger = value; - } - - void setAsString(char const *value) { - type = JSON_STRING; - content.asString = value; - } - - void setAsDouble(double value, int decimals) { - type = static_cast(JSON_DOUBLE_0_DECIMALS + decimals); - content.asDouble = value; - } - - void setAsObject(JsonBuffer *buffer) { - type = JSON_OBJECT; - content.asContainer.child = 0; - content.asContainer.buffer = buffer; - } - - void setAsObjectKeyValue(const char *key, JsonNode *value) { - type = JSON_KEY_VALUE; - content.asKeyValue.key = key; - content.asKeyValue.value = value; - } - - bool getAsBoolean() { - return type == JSON_BOOLEAN ? content.asBoolean : false; - } - - double getAsDouble() { - return type >= JSON_DOUBLE_0_DECIMALS ? content.asDouble : 0; - } - - long getAsInteger() { return type == JSON_LONG ? content.asInteger : 0; } - - const char *getAsString() { - return type == JSON_STRING ? content.asString : 0; - } - - JsonBuffer *getContainerBuffer() { - if (type == JSON_PROXY) return content.asProxy.target->getContainerBuffer(); - return type == JSON_ARRAY || type == JSON_OBJECT - ? content.asContainer.buffer - : 0; - } - - JsonNode *getContainerChild() { - if (type == JSON_PROXY) return content.asProxy.target->getContainerChild(); - return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.child - : 0; - } - - const char *getAsObjectKey() { - return type == JSON_KEY_VALUE ? content.asKeyValue.key : 0; - } - - JsonNode *getAsObjectValue() { - return type == JSON_KEY_VALUE ? content.asKeyValue.value : 0; - } - - JsonNode *getProxyTarget() { - return type == JSON_PROXY ? content.asProxy.target : this; - } - - bool isArray() { return type == JSON_ARRAY; } - - bool isObject() { return type == JSON_OBJECT; } - - void addChild(JsonNode *childToAdd); - - void removeChild(JsonNode *childToRemove); - - void duplicate(JsonNode *other); - - private: - JsonNodeType type; - JsonNodeContent content; - - inline void writeArrayTo( - JsonWriter &); // TODO: <- move in JsonNodeSerializer - inline void writeObjectTo( - JsonWriter &); // TODO: <- move in JsonNodeSerializer - - void setAsProxyOfSelf(); - - void setAsProxyOf(JsonNode *target) { - type = JSON_PROXY; - content.asProxy.target = target; - } -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonNodeIterator.hpp b/include/ArduinoJson/Internals/JsonNodeIterator.hpp deleted file mode 100644 index 40310268..00000000 --- a/include/ArduinoJson/Internals/JsonNodeIterator.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "JsonNode.hpp" - -namespace ArduinoJson { -namespace Internals { -// TODO: replace by JsonArrayIterator and JsonObjectIterator -class JsonNodeIterator { - public: - explicit JsonNodeIterator(JsonNode *node) : _node(node) {} - - bool operator!=(const JsonNodeIterator &other) const { - return _node != other._node; - } - - void operator++() { _node = _node->next; } - - JsonNode *operator*() const { return _node; } - - JsonNode *operator->() const { return _node; } - - private: - JsonNode *_node; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonNodeWrapper.hpp b/include/ArduinoJson/Internals/JsonNodeWrapper.hpp deleted file mode 100644 index dc1bb055..00000000 --- a/include/ArduinoJson/Internals/JsonNodeWrapper.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "JsonNode.hpp" - -namespace ArduinoJson { -namespace Internals { - -class JsonNodeWrapper { - protected: - JsonNodeWrapper() : _node(0) {} - - explicit JsonNodeWrapper(JsonNode *node) : _node(node) {} - - void duplicate(const JsonNodeWrapper &other) { - if (!_node) { - _node = other._node; - } else { - _node->duplicate(other._node); - } - } - - JsonNode *_node; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp b/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp index 0cc78f85..347d8e6e 100644 --- a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp +++ b/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp @@ -6,33 +6,34 @@ #pragma once -#include "JsonPairInternal.hpp" +#include "JsonObjectNode.hpp" namespace ArduinoJson { namespace Internals { class JsonObjectConstIterator { public: - explicit JsonObjectConstIterator(Internals::JsonNode *node) : _pair(node) {} + explicit JsonObjectConstIterator(Internals::JsonObjectNode *node) + : _node(node) {} - JsonPair operator*() const { return _pair; } - JsonPair *operator->() { return &_pair; } + JsonPair operator*() const { return _node->pair; } + JsonPair *operator->() { return &_node->pair; } bool operator==(const JsonObjectConstIterator &other) const { - return _pair.isSameAs(other._pair); + return _node == other._node; } bool operator!=(const JsonObjectConstIterator &other) const { - return !_pair.isSameAs(other._pair); + return _node != other._node; } JsonObjectConstIterator &operator++() { - _pair.moveToNext(); + _node = _node->next; return *this; } private: - JsonPairInternal _pair; + JsonObjectNode *_node; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectIterator.hpp b/include/ArduinoJson/Internals/JsonObjectIterator.hpp index 745380c9..f28946df 100644 --- a/include/ArduinoJson/Internals/JsonObjectIterator.hpp +++ b/include/ArduinoJson/Internals/JsonObjectIterator.hpp @@ -6,33 +6,31 @@ #pragma once -#include "JsonPairInternal.hpp" - namespace ArduinoJson { namespace Internals { class JsonObjectIterator { public: - explicit JsonObjectIterator(Internals::JsonNode *node) : _pair(node) {} + explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _node(node) {} - JsonPair operator*() const { return _pair; } - JsonPair *operator->() { return &_pair; } + JsonPair &operator*() const { return _node->pair; } + JsonPair *operator->() { return &_node->pair; } bool operator==(const JsonObjectIterator &other) const { - return _pair.isSameAs(other._pair); + return _node == other._node; } bool operator!=(const JsonObjectIterator &other) const { - return !_pair.isSameAs(other._pair); + return _node != other._node; } JsonObjectIterator &operator++() { - _pair.moveToNext(); + _node = _node->next; return *this; } private: - JsonPairInternal _pair; + JsonObjectNode *_node; }; } } diff --git a/include/ArduinoJson/Internals/JsonObjectNode.hpp b/include/ArduinoJson/Internals/JsonObjectNode.hpp new file mode 100644 index 00000000..1ccd29f0 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonObjectNode.hpp @@ -0,0 +1,19 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include "../JsonPair.hpp" + +namespace ArduinoJson { +namespace Internals { + +struct JsonObjectNode { + JsonObjectNode *next; + JsonPair pair; +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonPairInternal.hpp b/include/ArduinoJson/Internals/JsonPairInternal.hpp deleted file mode 100644 index eb2db8ed..00000000 --- a/include/ArduinoJson/Internals/JsonPairInternal.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "../JsonPair.hpp" - -namespace ArduinoJson { -class JsonPairInternal : public JsonPair { - public: - explicit JsonPairInternal(Internals::JsonNode* node) : JsonPair(node) {} - - void moveToNext() { _node = _node->next; } - - bool isSameAs(const JsonPairInternal& other) const { - return _node == other._node; - } -}; -} diff --git a/include/ArduinoJson/Internals/JsonParser.hpp b/include/ArduinoJson/Internals/JsonParser.hpp index a3a33508..735b3726 100644 --- a/include/ArduinoJson/Internals/JsonParser.hpp +++ b/include/ArduinoJson/Internals/JsonParser.hpp @@ -7,7 +7,7 @@ #pragma once #include "../ForwardDeclarations.hpp" -#include "JsonNode.hpp" +#include "../JsonBuffer.hpp" namespace ArduinoJson { namespace Internals { @@ -16,24 +16,23 @@ class JsonParser { public: JsonParser(JsonBuffer *buffer, char *json) : _buffer(buffer), _ptr(json) {} - JsonNode *parseAnything(); + JsonArray parseArray(); + JsonObject parseObject(); private: - JsonBuffer *_buffer; - char *_ptr; - bool isEnd() { return *_ptr == 0; } bool skip(char charToSkip); void skipSpaces(); - inline JsonNode *parseArray(); - inline JsonNode *parseBoolean(); - inline JsonNode *parseNull(); - inline JsonNode *parseNumber(); - inline JsonNode *parseObject(); - inline JsonNode *parseObjectKeyValue(); - inline JsonNode *parseString(); + void parseValueTo(JsonValue); + inline void parseBooleanTo(JsonValue &destination); + inline void parseNullTo(JsonValue &destination); + inline void parseNumberTo(JsonValue &destination); + inline const char *parseString(); + + JsonBuffer *_buffer; + char *_ptr; }; } } diff --git a/include/ArduinoJson/Internals/JsonSerializer.hpp b/include/ArduinoJson/Internals/JsonSerializer.hpp new file mode 100644 index 00000000..51b68080 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonSerializer.hpp @@ -0,0 +1,23 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include "../ForwardDeclarations.hpp" + +namespace ArduinoJson { +namespace Internals { + +class JsonSerializer { + public: + static writeTo(JsonValue& value, JsonWriter&); + + private: + inline void writeArrayTo(JsonValue& value, JsonWriter&); + inline void writeObjectTo(JsonValue& value, JsonWriter&); +}; +} +} \ No newline at end of file diff --git a/include/ArduinoJson/Internals/JsonValueContent.hpp b/include/ArduinoJson/Internals/JsonValueContent.hpp new file mode 100644 index 00000000..0334f737 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonValueContent.hpp @@ -0,0 +1,23 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include "../ForwardDeclarations.hpp" + +namespace ArduinoJson { +namespace Internals { + +union JsonValueContent { + bool asBoolean; + double asDouble; + long asInteger; + const char* asString; + JsonArrayImpl* asArray; + JsonObjectImpl* asObject; +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonValueImpl.hpp b/include/ArduinoJson/Internals/JsonValueImpl.hpp new file mode 100644 index 00000000..905c33be --- /dev/null +++ b/include/ArduinoJson/Internals/JsonValueImpl.hpp @@ -0,0 +1,79 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +#include + +#include "../ForwardDeclarations.hpp" +#include "JsonValueContent.hpp" +#include "JsonValueType.hpp" + +namespace ArduinoJson { +namespace Internals { + +class JsonValueImpl { + public: + JsonValueImpl() : _type(JSON_UNDEFINED) {} + + void set(bool value) { + _type = JSON_BOOLEAN; + _content.asBoolean = value; + } + + void set(const char *value) { + _type = JSON_STRING; + _content.asString = value; + } + + void set(double value, int decimals = 2) { + _type = static_cast(JSON_DOUBLE_0_DECIMALS + decimals); + _content.asDouble = value; + } + + void set(long value) { + _type = JSON_LONG; + _content.asInteger = value; + } + + void set(JsonArrayImpl *array) { + _type = JSON_ARRAY; + _content.asArray = array; + } + + void set(JsonObjectImpl *object) { + _type = JSON_OBJECT; + _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 { + return _type == JSON_ARRAY ? _content.asArray : NULL; + } + + operator JsonObjectImpl *() const { + return _type == JSON_OBJECT ? _content.asObject : NULL; + } + + private: + Internals::JsonValueType _type; + Internals::JsonValueContent _content; +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonValueInternal.hpp b/include/ArduinoJson/Internals/JsonValueInternal.hpp deleted file mode 100644 index af398433..00000000 --- a/include/ArduinoJson/Internals/JsonValueInternal.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "../JsonValue.hpp" - -namespace ArduinoJson { -namespace Internals { - -class JsonValueInternal : public JsonValue { - public: - explicit JsonValueInternal(Internals::JsonNode* node) : JsonValue(node) {} - - void moveToNext() { _node = _node->next; } - - bool isSameAs(const JsonValueInternal& other) const { - return _node == other._node; - } -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonValueType.hpp b/include/ArduinoJson/Internals/JsonValueType.hpp new file mode 100644 index 00000000..89137e07 --- /dev/null +++ b/include/ArduinoJson/Internals/JsonValueType.hpp @@ -0,0 +1,25 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +enum JsonValueType { + JSON_UNDEFINED, + JSON_ARRAY, + JSON_OBJECT, + JSON_BOOLEAN, + JSON_STRING, + JSON_LONG, + JSON_DOUBLE_0_DECIMALS + // JSON_DOUBLE_1_DECIMAL + // JSON_DOUBLE_2_DECIMALS + // etc. +}; +} +} diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index 48435dbd..42e9131c 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -6,9 +6,8 @@ #pragma once -#include "Internals/JsonArrayConstIterator.hpp" -#include "Internals/JsonArrayIterator.hpp" #include "JsonContainer.hpp" +#include "Internals/JsonArrayImpl.hpp" namespace ArduinoJson { class JsonArray : public JsonContainer { @@ -18,33 +17,37 @@ class JsonArray : public JsonContainer { typedef Internals::JsonArrayConstIterator const_iterator; JsonArray() {} + JsonArray(Internals::JsonArrayImpl* impl) : _impl(impl) {} - explicit JsonArray(Internals::JsonNode *node) - : JsonContainer(node) {} // TODO: hide + value_type operator[](int index) const; - JsonValue operator[](int index) const; + value_type add(); template void add(T value) { - addNewValue() = value; + add().set(value); } - void add(double value, int decimals = 2) { - addNewValue().set(value, decimals); - } + void add(double value, int decimals = 2) { add().set(value, decimals); } JsonArray createNestedArray(); JsonObject createNestedObject(); - bool success() { return _node && _node->isArray(); } - - iterator begin() { return iterator(firstChild()); } + iterator begin() { + if (!_impl) return end(); + return _impl->begin(); + } iterator end() { return iterator(0); } - const_iterator begin() const { return const_iterator(firstChild()); } + const_iterator begin() const { + if (!_impl) return end(); + return const_cast(_impl)->begin(); + } const_iterator end() const { return const_iterator(0); } -private: - JsonValue addNewValue(); + static JsonArray null() { return JsonArray(NULL); } + + private: + Internals::JsonArrayImpl* _impl; }; } diff --git a/include/ArduinoJson/JsonBuffer.hpp b/include/ArduinoJson/JsonBuffer.hpp index c4fc894e..84afe4bd 100644 --- a/include/ArduinoJson/JsonBuffer.hpp +++ b/include/ArduinoJson/JsonBuffer.hpp @@ -6,43 +6,39 @@ #pragma once +#include + #include "ForwardDeclarations.hpp" -#include "JsonArray.hpp" -#include "JsonObject.hpp" +#include "JsonValue.hpp" namespace ArduinoJson { class JsonBuffer { - friend class JsonContainer; - friend class Internals::JsonNode; - friend class Internals::JsonParser; - public: virtual ~JsonBuffer() {} - JsonArray createArray() { return JsonArray(createArrayNode()); } - - JsonObject createObject() { return JsonObject(createObjectNode()); } - + JsonArray createArray(); + JsonObject createObject(); JsonValue createValue(); - JsonArray parseArray(char *json); - JsonObject parseObject(char *json); - JsonValue parseValue(char *json); // TODO: remove + template + JsonValue createValue(T x) { + JsonValue value; + value = x; + return value; + } - protected: - virtual void *allocateNode() = 0; + JsonArray parseArray(char* json); + JsonObject parseObject(char* json); + JsonValue parseValue(char* json); - private: - Internals::JsonNode *createNode(); + template + T* create() { + void* p = alloc(sizeof(T)); + if (!p) return NULL; + return new (p) T(); + } - Internals::JsonNode *createArrayNode(); - Internals::JsonNode *createBoolNode(bool value); - 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); + virtual void* alloc(size_t size) = 0; }; } diff --git a/include/ArduinoJson/JsonContainer.hpp b/include/ArduinoJson/JsonContainer.hpp index a067210a..d745603f 100644 --- a/include/ArduinoJson/JsonContainer.hpp +++ b/include/ArduinoJson/JsonContainer.hpp @@ -7,40 +7,16 @@ #pragma once #include "Arduino/Printable.hpp" -#include "Internals/JsonNodeIterator.hpp" -#include "Internals/JsonNodeWrapper.hpp" namespace ArduinoJson { -class JsonContainer : public Printable, public Internals::JsonNodeWrapper { +class JsonContainer : public Printable { public: - JsonContainer() {} - - explicit JsonContainer(Internals::JsonNode *node) : JsonNodeWrapper(node) {} - - size_t size() const; - - bool operator==(JsonContainer const &other) const; - size_t printTo(char *buffer, size_t bufferSize) const; virtual size_t printTo(Print &print) const; size_t prettyPrintTo(char *buffer, size_t bufferSize) const; size_t prettyPrintTo(ArduinoJson::Internals::IndentedPrint &print) const; size_t prettyPrintTo(Print &print) const; - - protected: - Internals::JsonNodeIterator beginChildren() const { - return Internals::JsonNodeIterator(_node ? _node->getContainerChild() : 0); - } - - Internals::JsonNodeIterator endChildren() const { - return Internals::JsonNodeIterator(0); - } - - void addChild(Internals::JsonNode *); - void removeChild(Internals::JsonNode *); - Internals::JsonNode *createNode(); - Internals::JsonNode *firstChild() const; }; } diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index 1c56deec..69392947 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -9,6 +9,7 @@ #include "Internals/JsonObjectConstIterator.hpp" #include "Internals/JsonObjectIterator.hpp" #include "JsonContainer.hpp" +#include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { class JsonObject : public JsonContainer { @@ -17,9 +18,7 @@ class JsonObject : public JsonContainer { typedef Internals::JsonObjectIterator iterator; typedef Internals::JsonObjectConstIterator const_iterator; - JsonObject() {} - - explicit JsonObject(Internals::JsonNode *node) : JsonContainer(node) {} + JsonObject(JsonBuffer *buffer) : _buffer(buffer) {} JsonValue operator[](const char *key); void remove(const char *key); @@ -27,16 +26,17 @@ class JsonObject : public JsonContainer { JsonArray createNestedArray(const char *key); JsonObject createNestedObject(const char *key); - bool success() { return _node && _node->isObject(); } - - iterator begin() { return iterator(firstChild()); } + iterator begin() { return iterator(_firstChild); } iterator end() { return iterator(0); } - const_iterator begin() const { return const_iterator(firstChild()); } + const_iterator begin() const { return const_iterator(_firstChild); } const_iterator end() const { return const_iterator(0); } private: Internals::JsonNode *getPairAt(const char *key); Internals::JsonNode *getOrCreateValueAt(const char *key); + + JsonBuffer *_buffer; + Internals::JsonObjectNode *_firstChild; }; } diff --git a/include/ArduinoJson/JsonPair.hpp b/include/ArduinoJson/JsonPair.hpp index 0cf6a892..d8d3084c 100644 --- a/include/ArduinoJson/JsonPair.hpp +++ b/include/ArduinoJson/JsonPair.hpp @@ -6,20 +6,18 @@ #pragma once -#include "Internals/JsonValueInternal.hpp" +#include "JsonValue.hpp" namespace ArduinoJson { class JsonPair { public: - const char *key() const { return _node->getAsObjectKey(); } + JsonPair(const char *k) : _key(k) {} - JsonValue value() { - return Internals::JsonValueInternal(_node->getAsObjectValue()); - } + const char *key() const { return _key; } + JsonValue &value() { return _value; } - protected: - explicit JsonPair(Internals::JsonNode *node) : _node(node) {} - - Internals::JsonNode *_node; + private: + const char *_key; + JsonValue _value; }; } diff --git a/include/ArduinoJson/JsonValue.hpp b/include/ArduinoJson/JsonValue.hpp index a1819d70..404a95e0 100644 --- a/include/ArduinoJson/JsonValue.hpp +++ b/include/ArduinoJson/JsonValue.hpp @@ -6,40 +6,46 @@ #pragma once +#include + #include "ForwardDeclarations.hpp" -#include "Internals/JsonNodeWrapper.hpp" +#include "Internals/JsonValueImpl.hpp" namespace ArduinoJson { -class JsonValue : public Internals::JsonNodeWrapper { +class JsonValue { public: - JsonValue() {} + JsonValue() : _impl(NULL) {} + JsonValue(Internals::JsonValueImpl *impl) : _impl(impl) {} - void operator=(bool value); - void operator=(const char *value); - void operator=(double value) { set(value, 2); } - void operator=(int value); - void operator=(const JsonValue &value) { duplicate(value); } - void operator=(const Internals::JsonNodeWrapper &object) { - duplicate(object); + template + void operator=(T value) { + if (_impl) _impl->set(value); } - operator bool() const; - operator const char *() const; - operator double() const; - operator long() const; - operator int() const { return operator long(); } - operator JsonArray() const; - operator JsonObject() const; - - void set(double value, int decimals); + void set(double value, int decimals) { + if (_impl) _impl->set(value, decimals); + } template T as() { return static_cast(*this); } - protected: - JsonValue(Internals::JsonNode *node) : Internals::JsonNodeWrapper(node) {} + 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); + } + operator JsonArray() const; + + bool success() { return _impl; } + + static JsonValue null() { return JsonValue(NULL); } + + private: + Internals::JsonValueImpl *_impl; }; } diff --git a/src/Internals/JsonArrayImpl.cpp b/src/Internals/JsonArrayImpl.cpp new file mode 100644 index 00000000..3fd1b751 --- /dev/null +++ b/src/Internals/JsonArrayImpl.cpp @@ -0,0 +1,52 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + +#include "ArduinoJson/JsonArray.hpp" +#include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/JsonValue.hpp" + +using namespace ArduinoJson; +using namespace ArduinoJson::Internals; + +JsonValueImpl *JsonArray::operator[](int index) const { + for (const_iterator it = begin(); it != end(); ++it) { + if (!index) return *it; + index--; + } + + return NULL; +} + +JsonValueImpl *JsonArray::add() { + if (_buffer) return NULL; + + JsonArrayNode *node = _buffer->create(); + if (!node) return NULL; + + return &node.value; +} + +JsonArrayImpl *JsonArray::createNestedArray() { + JsonNode *node = createNode(); + + if (node) { + node->setAsArray(_node->getContainerBuffer()); + addChild(node); + } + + return JsonArray(node); +} + +JsonObject JsonArray::createNestedObject() { + JsonNode *node = createNode(); + + if (node) { + node->setAsObject(_node->getContainerBuffer()); + addChild(node); + } + + return JsonObject(node); +} diff --git a/src/Internals/JsonParser.cpp b/src/Internals/JsonParser.cpp index 90a970d5..45ba838a 100644 --- a/src/Internals/JsonParser.cpp +++ b/src/Internals/JsonParser.cpp @@ -9,9 +9,13 @@ #include // for strtol, strtod #include +#include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonBuffer.hpp" +#include "ArduinoJson/JsonValue.hpp" +#include "ArduinoJson/JsonObject.hpp" #include "ArduinoJson/Internals/QuotedString.hpp" +using namespace ArduinoJson; using namespace ArduinoJson::Internals; void JsonParser::skipSpaces() { @@ -26,16 +30,18 @@ bool JsonParser::skip(char charToSkip) { return true; } -JsonNode *JsonParser::parseAnything() { +void JsonParser::parseValueTo(JsonValue destination) { skipSpaces(); switch (*_ptr) { case '[': - return parseArray(); + destination = parseArray(); + break; case 't': case 'f': - return parseBoolean(); + parseBooleanTo(destination); + break; case '-': case '.': @@ -49,113 +55,106 @@ JsonNode *JsonParser::parseAnything() { case '7': case '8': case '9': - return parseNumber(); + parseNumberTo(destination); + break; case 'n': - return parseNull(); + parseNullTo(destination); + break; case '{': - return parseObject(); + destination = parseObject(); + break; case '\'': case '\"': - return parseString(); + destination = parseString(); + break; default: - return NULL; // invalid JSON + destination = NULL; // invalid JSON } } -JsonNode *JsonParser::parseArray() { - JsonNode *node = _buffer->createArrayNode(); - +JsonArray JsonParser::parseArray() { skip('['); - if (isEnd()) return 0; + if (isEnd()) return NULL; - if (skip(']')) return node; // empty array + JsonArray array = _buffer->createArray(); + if (skip(']')) return array; // empty array for (;;) { - JsonNode *child = parseAnything(); + JsonValue child = array.add(); - if (!child) return 0; // child parsing failed + parseValueTo(child); + if (!child.success()) return NULL; - node->addChild(child); + if (skip(']')) return array; // end of the array - if (skip(']')) return node; // end of the array - - if (!skip(',')) return 0; // comma is missing + if (!skip(',')) return NULL; // comma is missing } } -JsonNode *JsonParser::parseBoolean() { +void JsonParser::parseBooleanTo(JsonValue &destination) { bool value = *_ptr == 't'; + // TODO: bug if string ends here !!! + _ptr += value ? 4 : 5; // 4 = strlen("true") // 5 = strlen("false"); - return _buffer->createBoolNode(value); + destination = value; } -JsonNode *JsonParser::parseNumber() { +void JsonParser::parseNumberTo(JsonValue &destination) { char *endOfLong; long longValue = strtol(_ptr, &endOfLong, 10); if (*endOfLong == '.') { // stopped on a decimal separator - double value = strtod(_ptr, &_ptr); + double douleValue = strtod(_ptr, &_ptr); int decimals = _ptr - endOfLong - 1; - return _buffer->createDoubleNode(value, decimals); + destination.set(douleValue, decimals); } else { _ptr = endOfLong; - return _buffer->createLongNode(longValue); + destination = longValue; } } -JsonNode *JsonParser::parseNull() { +void JsonParser::parseNullTo(JsonValue &destination) { _ptr += 4; // strlen("null") - return _buffer->createStringNode(0); + destination = static_cast(NULL); } -JsonNode *JsonParser::parseObject() { - JsonNode *node = _buffer->createObjectNode(); - +JsonObject JsonParser::parseObject() { skip('{'); - if (isEnd()) return 0; // premature ending + if (isEnd()) return NULL; // premature ending - if (skip('}')) return node; // empty object + JsonObject object = _buffer->createObject(); + + if (skip('}')) return object; // empty object for (;;) { - JsonNode *child = parseObjectKeyValue(); + const char *key = parseString(); + if (!key) return NULL; - if (!child) return 0; // child parsing failed + skip(':') - node->addChild(child); + JsonValue value = object[key]; - if (skip('}')) return node; // end of the object + parseValueTo(value); + if (!value.success()) return NULL; + + if (skip('}')) return object; // end of the object if (!skip(',')) return 0; // comma is missing } } -JsonNode *JsonParser::parseObjectKeyValue() { - const char *key = QuotedString::extractFrom(_ptr, &_ptr); - - if (!key) return 0; // failed to extract key - - if (!skip(':')) return 0; // colon is missing - - JsonNode *value = parseAnything(); - - if (!value) return 0; // value parsing failed - - return _buffer->createObjectKeyValueNode(key, value); -} - -JsonNode *JsonParser::parseString() { - const char *s = QuotedString::extractFrom(_ptr, &_ptr); - return _buffer->createStringNode(s); +const char *JsonParser::parseString() { + return QuotedString::extractFrom(_ptr, &_ptr); } diff --git a/src/Internals/JsonNode.cpp b/src/Internals/JsonSerializer.cpp similarity index 100% rename from src/Internals/JsonNode.cpp rename to src/Internals/JsonSerializer.cpp diff --git a/src/JsonArray.cpp b/src/JsonArray.cpp index 3cb1a541..1428b4a3 100644 --- a/src/JsonArray.cpp +++ b/src/JsonArray.cpp @@ -12,38 +12,16 @@ using namespace ArduinoJson; using namespace ArduinoJson::Internals; JsonValue JsonArray::operator[](int index) const { - for (const_iterator it = begin(); it != end(); ++it) { - if (!index) return *it; - index--; - } - - return JsonValue(); -} - -JsonValue JsonArray::addNewValue() { - JsonNode *node = createNode(); - if (node) addChild(node); - return JsonValueInternal(node); + if (!_impl) return JsonValue::null(); + return JsonValue((*_impl)[index]); } JsonArray JsonArray::createNestedArray() { - JsonNode *node = createNode(); - - if (node) { - node->setAsArray(_node->getContainerBuffer()); - addChild(node); - } - - return JsonArray(node); + if (!_impl) return JsonArray::null(); + return JsonArray(_impl->createNestedArray()); } JsonObject JsonArray::createNestedObject() { - JsonNode *node = createNode(); - - if (node) { - node->setAsObject(_node->getContainerBuffer()); - addChild(node); - } - - return JsonObject(node); -} + if (!_impl) return JsonObject::null(); + return JsonObject(_impl->createNestedObject())); +} \ No newline at end of file diff --git a/src/JsonValue.cpp b/src/JsonValue.cpp index 984e4038..07e17865 100644 --- a/src/JsonValue.cpp +++ b/src/JsonValue.cpp @@ -7,39 +7,9 @@ #include "ArduinoJson/JsonValue.hpp" #include "ArduinoJson/JsonArray.hpp" -#include "ArduinoJson/JsonObject.hpp" -#include "ArduinoJson/Internals/JsonNode.hpp" using namespace ArduinoJson; -void JsonValue::operator=(bool value) { - if (_node) _node->setAsBoolean(value); +JsonValue::operator JsonArray() const { + return _impl ? JsonArray(*_impl) : JsonArray(); } - -void JsonValue::operator=(char const *value) { - if (_node) _node->setAsString(value); -} - -void JsonValue::set(double value, int decimals) { - if (_node) _node->setAsDouble(value, decimals); -} - -void JsonValue::operator=(int value) { - if (_node) _node->setAsLong(value); -} - -JsonValue::operator bool() const { - return _node ? _node->getAsBoolean() : false; -} - -JsonValue::operator char const *() const { - return _node ? _node->getAsString() : 0; -} - -JsonValue::operator double() const { return _node ? _node->getAsDouble() : 0; } - -JsonValue::operator long() const { return _node ? _node->getAsInteger() : 0; } - -JsonValue::operator JsonArray() const { return JsonArray(_node); } - -JsonValue::operator JsonObject() const { return JsonObject(_node); }