diff --git a/include/ArduinoJson/ForwardDeclarations.hpp b/include/ArduinoJson/ForwardDeclarations.hpp index 42cc6495..fc9a188e 100644 --- a/include/ArduinoJson/ForwardDeclarations.hpp +++ b/include/ArduinoJson/ForwardDeclarations.hpp @@ -10,23 +10,20 @@ namespace ArduinoJson { class JsonArray; +class JsonArrayConstIterator; +class JsonArrayIterator; class JsonBuffer; -class JsonPair; -class JsonValue; class JsonObject; +class JsonObjectConstIterator; +class JsonObjectIterator; +struct JsonPair; +class JsonValue; namespace Internals { class IndentedPrint; -class JsonArrayConstIterator; -class JsonArrayImpl; -class JsonArrayIterator; class JsonArrayNode; -class JsonObjectConstIterator; -class JsonObjectImpl; -class JsonObjectIterator; class JsonObjectNode; class JsonParser; -class JsonValueImpl; class JsonWriter; } } diff --git a/include/ArduinoJson/Internals/JsonArrayImpl.hpp b/include/ArduinoJson/Internals/JsonArrayImpl.hpp deleted file mode 100644 index cb60a82e..00000000 --- a/include/ArduinoJson/Internals/JsonArrayImpl.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "../ForwardDeclarations.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; - - static JsonArrayImpl *createFrom(JsonBuffer *buffer); - - int size() const; - - value_type operator[](int index) const; - value_type add(); - - JsonArrayImpl *createNestedArray(); - JsonObjectImpl *createNestedObject(); - - void writeTo(JsonWriter &writer) const; - - iterator begin() { return iterator(_firstNode); } - iterator end() { return iterator(0); } - - const_iterator begin() const { return const_iterator(_firstNode); } - const_iterator end() const { return const_iterator(0); } - - private: - JsonArrayImpl(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} - - inline void addNode(JsonArrayNode *node); - - JsonBuffer *_buffer; - Internals::JsonArrayNode *_firstNode; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonArrayNode.hpp b/include/ArduinoJson/Internals/JsonArrayNode.hpp index 0c7a9c7e..842bb443 100644 --- a/include/ArduinoJson/Internals/JsonArrayNode.hpp +++ b/include/ArduinoJson/Internals/JsonArrayNode.hpp @@ -6,7 +6,7 @@ #pragma once -#include "JsonValueImpl.hpp" +#include "../JsonValue.hpp" #include "../JsonBuffer.hpp" namespace ArduinoJson { @@ -20,7 +20,7 @@ class JsonArrayNode { } JsonArrayNode* next; - JsonValueImpl value; + JsonValue value; private: JsonArrayNode() : next(0) {} diff --git a/include/ArduinoJson/Internals/JsonObjectImpl.hpp b/include/ArduinoJson/Internals/JsonObjectImpl.hpp deleted file mode 100644 index f3299560..00000000 --- a/include/ArduinoJson/Internals/JsonObjectImpl.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -#include "JsonObjectConstIterator.hpp" -#include "JsonObjectIterator.hpp" -#include "JsonObjectNode.hpp" - -namespace ArduinoJson { -namespace Internals { -class JsonObjectImpl { - public: - typedef const char *key_type; - typedef JsonPair value_type; - typedef JsonObjectIterator iterator; - typedef JsonObjectConstIterator const_iterator; - - static JsonObjectImpl *createFrom(JsonBuffer *buffer); - - 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(_firstNode); } - iterator end() { return iterator(0); } - - const_iterator begin() const { return const_iterator(_firstNode); } - const_iterator end() const { return const_iterator(0); } - - void writeTo(JsonWriter &writer) const; - - private: - JsonObjectImpl(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} - - void addNode(JsonObjectNode *nodeToAdd); - void removeNode(JsonObjectNode *nodeToRemove); - - JsonObjectNode *getNodeAt(key_type key); - JsonObjectNode *getOrCreateNodeAt(key_type key); - - JsonBuffer *_buffer; - JsonObjectNode *_firstNode; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonObjectIterator.hpp b/include/ArduinoJson/Internals/JsonObjectIterator.hpp deleted file mode 100644 index ebfd87fd..00000000 --- a/include/ArduinoJson/Internals/JsonObjectIterator.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#pragma once - -namespace ArduinoJson { -namespace Internals { - -class JsonObjectIterator { - public: - explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _pair(node) {} - - JsonPair &operator*() { return _pair; } - JsonPair *operator->() { return &_pair; } - - bool operator==(const JsonObjectIterator &other) const { - return _pair._node == other._pair._node; - } - - bool operator!=(const JsonObjectIterator &other) const { - return _pair._node != other._pair._node; - } - - JsonObjectIterator &operator++() { - if (_pair._node) _pair._node = _pair._node->next; - return *this; - } - - private: - JsonPair _pair; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonObjectNode.hpp b/include/ArduinoJson/Internals/JsonObjectNode.hpp index c7c9b2c1..e3be8178 100644 --- a/include/ArduinoJson/Internals/JsonObjectNode.hpp +++ b/include/ArduinoJson/Internals/JsonObjectNode.hpp @@ -6,7 +6,7 @@ #pragma once -#include "JsonValueImpl.hpp" +#include "../JsonPair.hpp" #include "../JsonBuffer.hpp" namespace ArduinoJson { @@ -19,12 +19,11 @@ class JsonObjectNode { return ptr ? new (ptr) JsonObjectNode(key) : NULL; } - const char* const key; - JsonValueImpl value; + JsonPair pair; JsonObjectNode* next; private: - JsonObjectNode(const char* k) : key(k), next(NULL) {} + JsonObjectNode(const char* k) : pair(k), next(NULL) {} }; } } diff --git a/include/ArduinoJson/Internals/JsonParser.hpp b/include/ArduinoJson/Internals/JsonParser.hpp index 342bb1ad..0741cbb8 100644 --- a/include/ArduinoJson/Internals/JsonParser.hpp +++ b/include/ArduinoJson/Internals/JsonParser.hpp @@ -16,9 +16,8 @@ class JsonParser { public: JsonParser(JsonBuffer *buffer, char *json) : _buffer(buffer), _ptr(json) {} - JsonArray parseArray(); - JsonObject parseObject(); - JsonValue parseValue(); + JsonArray &parseArray(); + JsonObject &parseObject(); private: bool isEnd() { return *_ptr == 0; } @@ -26,7 +25,7 @@ class JsonParser { bool skip(char charToSkip); void skipSpaces(); - void parseValueTo(JsonValue); + void parseAnythingTo(JsonValue &destination); inline void parseBooleanTo(JsonValue &destination); inline void parseNullTo(JsonValue &destination); inline void parseNumberTo(JsonValue &destination); diff --git a/include/ArduinoJson/Internals/JsonValueContent.hpp b/include/ArduinoJson/Internals/JsonValueContent.hpp index 0334f737..bf94b44a 100644 --- a/include/ArduinoJson/Internals/JsonValueContent.hpp +++ b/include/ArduinoJson/Internals/JsonValueContent.hpp @@ -16,8 +16,8 @@ union JsonValueContent { double asDouble; long asInteger; const char* asString; - JsonArrayImpl* asArray; - JsonObjectImpl* asObject; + JsonArray* asArray; + JsonObject* asObject; }; } } diff --git a/include/ArduinoJson/Internals/JsonValueImpl.hpp b/include/ArduinoJson/Internals/JsonValueImpl.hpp deleted file mode 100644 index 15f2a5c8..00000000 --- a/include/ArduinoJson/Internals/JsonValueImpl.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// 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) {} - - static JsonValueImpl *createFrom(JsonBuffer *buffer); - - 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; - } - - JsonArrayImpl *asArray() { - return _type == JSON_ARRAY ? _content.asArray : NULL; - } - - 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: - Internals::JsonValueType _type; - Internals::JsonValueContent _content; -}; -} -} diff --git a/include/ArduinoJson/Internals/JsonValueType.hpp b/include/ArduinoJson/Internals/JsonValueType.hpp index 89137e07..5d9574cd 100644 --- a/include/ArduinoJson/Internals/JsonValueType.hpp +++ b/include/ArduinoJson/Internals/JsonValueType.hpp @@ -11,6 +11,7 @@ namespace Internals { enum JsonValueType { JSON_UNDEFINED, + JSON_INVALID, JSON_ARRAY, JSON_OBJECT, JSON_BOOLEAN, diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index 7294bb4f..0b211a64 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -6,58 +6,48 @@ #pragma once +#include "ForwardDeclarations.hpp" +#include "JsonArrayIterator.hpp" +#include "JsonArrayConstIterator.hpp" #include "JsonPrintable.hpp" -#include "Internals/JsonArrayImpl.hpp" namespace ArduinoJson { class JsonArray : public JsonPrintable { - friend class JsonValue; - public: typedef JsonValue value_type; - typedef Internals::JsonArrayIterator iterator; - typedef Internals::JsonArrayConstIterator const_iterator; + typedef JsonArrayIterator iterator; + typedef JsonArrayConstIterator const_iterator; - JsonArray() : _impl(NULL) {} - JsonArray(Internals::JsonArrayImpl* impl) : _impl(impl) {} + JsonArray(JsonBuffer *buffer = NULL) : _buffer(buffer), _firstNode(NULL) {} - bool success() const { return _impl; } + int size() const; - int size() const { return _impl ? _impl->size() : 0; } - - value_type operator[](int index) const; - value_type add(); + value_type &operator[](int index) const; + value_type &add(); template void add(T value) { add().set(value); } - void add(double value, int decimals = 2) { add().set(value, decimals); } + JsonArray &createNestedArray(); + JsonObject &createNestedObject(); - JsonArray createNestedArray(); - JsonObject createNestedObject(); - - iterator begin() { - if (!_impl) return end(); - return _impl->begin(); - } + iterator begin() { return iterator(_firstNode); } iterator end() { return iterator(0); } - const_iterator begin() const { - if (!_impl) return end(); - return const_cast(_impl)->begin(); - } + const_iterator begin() const { return const_iterator(_firstNode); } const_iterator end() const { return const_iterator(0); } - bool operator==(const JsonArray& other) const { return _impl == other._impl; } + static JsonArray &invalid() { return _invalid; } - protected: - virtual void writeTo(Internals::JsonWriter& writer) const { - if (_impl) _impl->writeTo(writer); - } + virtual void writeTo(Internals::JsonWriter &writer) const; private: - Internals::JsonArrayImpl* _impl; + inline void addNode(Internals::JsonArrayNode *node); + + JsonBuffer *_buffer; + Internals::JsonArrayNode *_firstNode; + static JsonArray _invalid; }; } diff --git a/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp b/include/ArduinoJson/JsonArrayConstIterator.hpp similarity index 58% rename from include/ArduinoJson/Internals/JsonArrayConstIterator.hpp rename to include/ArduinoJson/JsonArrayConstIterator.hpp index 423e4864..4703987c 100644 --- a/include/ArduinoJson/Internals/JsonArrayConstIterator.hpp +++ b/include/ArduinoJson/JsonArrayConstIterator.hpp @@ -6,18 +6,17 @@ #pragma once -#include "JsonArrayNode.hpp" +#include "Internals/JsonArrayNode.hpp" namespace ArduinoJson { -namespace Internals { -// TODO: copy from JsonArrayIterator class JsonArrayConstIterator { public: - explicit JsonArrayConstIterator(JsonArrayNode *node) : _node(node) {} + explicit JsonArrayConstIterator(Internals::JsonArrayNode *node) + : _node(node) {} - const JsonValueImpl &operator*() const { return _node->value; } - const JsonValueImpl *operator->() { return &_node->value; } + const JsonValue &operator*() const { return _node->value; } + const JsonValue *operator->() { return &_node->value; } bool operator==(const JsonArrayConstIterator &other) const { return _node == other._node; @@ -28,12 +27,11 @@ class JsonArrayConstIterator { } JsonArrayConstIterator &operator++() { - _node = _node->next; + if (_node) _node = _node->next; return *this; } private: - JsonArrayNode *_node; + Internals::JsonArrayNode *_node; }; -} -} +} \ No newline at end of file diff --git a/include/ArduinoJson/Internals/JsonArrayIterator.hpp b/include/ArduinoJson/JsonArrayIterator.hpp similarity index 58% rename from include/ArduinoJson/Internals/JsonArrayIterator.hpp rename to include/ArduinoJson/JsonArrayIterator.hpp index 3163cd17..d043b76e 100644 --- a/include/ArduinoJson/Internals/JsonArrayIterator.hpp +++ b/include/ArduinoJson/JsonArrayIterator.hpp @@ -6,19 +6,16 @@ #pragma once -#include "JsonArrayNode.hpp" +#include "Internals/JsonArrayNode.hpp" namespace ArduinoJson { -namespace Internals { class JsonArrayIterator { public: - explicit JsonArrayIterator(Internals::JsonArrayNode *node) : _node(node) { - updateValue(); - } + explicit JsonArrayIterator(Internals::JsonArrayNode *node) : _node(node) {} - JsonValue operator*() const { return _value; } - JsonValue *operator->() { return &_value; } + JsonValue &operator*() const { return _node->value; } + JsonValue *operator->() { return &_node->value; } bool operator==(const JsonArrayIterator &other) const { return _node == other._node; @@ -29,18 +26,11 @@ class JsonArrayIterator { } JsonArrayIterator &operator++() { - if (_node) { - _node = _node->next; - updateValue(); - } + if (_node) _node = _node->next; return *this; } private: - void updateValue() { _value = JsonValue(_node ? &_node->value : NULL); } - - JsonArrayNode *_node; - JsonValue _value; + Internals::JsonArrayNode *_node; }; } -} diff --git a/include/ArduinoJson/JsonBuffer.hpp b/include/ArduinoJson/JsonBuffer.hpp index a2cc4d9e..ca323c37 100644 --- a/include/ArduinoJson/JsonBuffer.hpp +++ b/include/ArduinoJson/JsonBuffer.hpp @@ -17,21 +17,12 @@ class JsonBuffer { public: virtual ~JsonBuffer() {} - JsonArray createArray(); - JsonObject createObject(); - JsonValue createValue(); + JsonArray &createArray(); + JsonObject &createObject(); - template - JsonValue createValue(T x) { - JsonValue value; - value = x; - return value; - } + JsonArray &parseArray(char *json); + JsonObject &parseObject(char *json); - JsonArray parseArray(char* json); - JsonObject parseObject(char* json); - JsonValue parseValue(char* json); - - virtual void* alloc(size_t size) = 0; + virtual void *alloc(size_t size) = 0; }; } diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index 3daf36a4..a43e1c7e 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -6,56 +6,53 @@ #pragma once +#include "JsonObjectConstIterator.hpp" +#include "JsonObjectIterator.hpp" #include "JsonPrintable.hpp" -#include "Internals/JsonObjectImpl.hpp" +#include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { class JsonObject : public JsonPrintable { - friend class JsonValue; - public: - typedef const char* key_type; + typedef const char *key_type; typedef JsonPair value_type; - typedef Internals::JsonObjectIterator iterator; - typedef Internals::JsonObjectConstIterator const_iterator; + typedef JsonObjectIterator iterator; + typedef JsonObjectConstIterator const_iterator; - JsonObject() : _impl(NULL) {} - JsonObject(Internals::JsonObjectImpl* impl) : _impl(impl) {} + JsonObject(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} - bool success() const { return _impl; } + int size() const; - int size() const { return _impl ? _impl->size() : 0; } + JsonValue &operator[](key_type key); + void remove(key_type key); - JsonValue operator[](key_type key); - void remove(key_type key) { - if (_impl) _impl->remove(key); + template + void add(key_type key, T value) { + (*this)[key] = value; } - JsonArray createNestedArray(key_type key); - JsonObject createNestedObject(key_type key); + JsonArray &createNestedArray(key_type key); + JsonObject &createNestedObject(key_type key); - iterator begin() { - if (!_impl) return end(); - return _impl->begin(); - } + iterator begin() { return iterator(_firstNode); } iterator end() { return iterator(0); } - const_iterator begin() const { - if (!_impl) return end(); - return const_cast(_impl)->begin(); - } + const_iterator begin() const { return const_iterator(_firstNode); } const_iterator end() const { return const_iterator(0); } - bool operator==(const JsonObject& other) const { - return _impl == other._impl; - } + static JsonObject &invalid() { return _invalid; } - protected: - virtual void writeTo(Internals::JsonWriter& writer) const { - if (_impl) _impl->writeTo(writer); - } + virtual void writeTo(Internals::JsonWriter &writer) const; private: - Internals::JsonObjectImpl* _impl; + void addNode(Internals::JsonObjectNode *nodeToAdd); + void removeNode(Internals::JsonObjectNode *nodeToRemove); + + Internals::JsonObjectNode *getNodeAt(key_type key); + Internals::JsonObjectNode *getOrCreateNodeAt(key_type key); + + JsonBuffer *_buffer; + Internals::JsonObjectNode *_firstNode; + static JsonObject _invalid; }; } diff --git a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp b/include/ArduinoJson/JsonObjectConstIterator.hpp similarity index 58% rename from include/ArduinoJson/Internals/JsonObjectConstIterator.hpp rename to include/ArduinoJson/JsonObjectConstIterator.hpp index baa6f291..72c045b4 100644 --- a/include/ArduinoJson/Internals/JsonObjectConstIterator.hpp +++ b/include/ArduinoJson/JsonObjectConstIterator.hpp @@ -6,35 +6,33 @@ #pragma once -#include "../JsonPair.hpp" -#include "JsonObjectNode.hpp" +#include "ForwardDeclarations.hpp" +#include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { -namespace Internals { class JsonObjectConstIterator { public: explicit JsonObjectConstIterator(Internals::JsonObjectNode *node) - : _pair(node) {} + : _node(node) {} - const JsonPair operator*() const { return _pair; } - const JsonPair *operator->() { return &_pair; } + const JsonPair &operator*() { return _node->pair; } + const JsonPair *operator->() { return &_node->pair; } bool operator==(const JsonObjectConstIterator &other) const { - return _pair._node == other._pair._node; + return _node == other._node; } bool operator!=(const JsonObjectConstIterator &other) const { - return _pair._node != other._pair._node; + return _node != other._node; } JsonObjectConstIterator &operator++() { - _pair._node = _pair._node->next; + if (_node) _node = _node->next; return *this; } private: - JsonPair _pair; + Internals::JsonObjectNode *_node; }; } -} diff --git a/include/ArduinoJson/JsonObjectIterator.hpp b/include/ArduinoJson/JsonObjectIterator.hpp index 388233f5..e2536fd9 100644 --- a/include/ArduinoJson/JsonObjectIterator.hpp +++ b/include/ArduinoJson/JsonObjectIterator.hpp @@ -1,33 +1,37 @@ +// Copyright Benoit Blanchon 2014 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson + #pragma once -#include "ArduinoJson/JsonObjectKeyValue.hpp" +#include "ForwardDeclarations.hpp" +#include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { -class JsonObject; class JsonObjectIterator { - friend class JsonObject; - public: - explicit JsonObjectIterator(Internals::JsonNode* node) : _node(node) {} + explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _node(node) {} - const char* key() const { return operator*().key(); } + JsonPair &operator*() { return _node->pair; } + JsonPair *operator->() { return &_node->pair; } - JsonValue value() const { return operator*().value(); } - - void operator++() { _node = _node->next; } - - JsonObjectKeyValue operator*() const { return JsonObjectKeyValue(_node); } - - bool operator==(const JsonObjectIterator& other) const { + bool operator==(const JsonObjectIterator &other) const { return _node == other._node; } - bool operator!=(const JsonObjectIterator& other) const { + bool operator!=(const JsonObjectIterator &other) const { return _node != other._node; } + JsonObjectIterator &operator++() { + if (_node) _node = _node->next; + return *this; + } + private: - Internals::JsonNode* _node; + Internals::JsonObjectNode *_node; }; -} \ No newline at end of file +} diff --git a/include/ArduinoJson/JsonPair.hpp b/include/ArduinoJson/JsonPair.hpp index 40b4097e..774fb84a 100644 --- a/include/ArduinoJson/JsonPair.hpp +++ b/include/ArduinoJson/JsonPair.hpp @@ -10,17 +10,10 @@ #include "Internals/JsonObjectNode.hpp" namespace ArduinoJson { -class JsonPair { - friend class Internals::JsonObjectIterator; - friend class Internals::JsonObjectConstIterator; +struct JsonPair { + JsonPair(const char* k) : key(k) {} - public: - JsonPair(Internals::JsonObjectNode *node) : _node(node) {} - - const char *key() const { return _node->key; } - JsonValue value() { return JsonValue(&_node->value); } - - private: - Internals::JsonObjectNode *_node; + const char* const key; + JsonValue value; }; } diff --git a/include/ArduinoJson/JsonValue.hpp b/include/ArduinoJson/JsonValue.hpp index 7144a576..672df832 100644 --- a/include/ArduinoJson/JsonValue.hpp +++ b/include/ArduinoJson/JsonValue.hpp @@ -9,62 +9,45 @@ #include #include "ForwardDeclarations.hpp" -#include "Internals/JsonValueImpl.hpp" +#include "Internals/JsonValueContent.hpp" +#include "Internals/JsonValueType.hpp" namespace ArduinoJson { class JsonValue { public: - JsonValue() : _impl(NULL) {} - JsonValue(Internals::JsonValueImpl *impl) : _impl(impl) {} + JsonValue() : _type(Internals::JSON_UNDEFINED) {} - void set(const char *value) { - if (_impl) _impl->set(value); - } - 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); + void set(bool value); + void set(const char *value); + void set(double value, int decimals = 2); + void set(int value) { set(static_cast(value)); } + void set(long value); + void set(JsonArray &array); + void set(JsonObject &object); - 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; } + JsonArray &asArray(); + JsonObject &asObject(); + bool asBool() const; + const char *asString() const; + double asDouble() const; + long asLong() const; template - JsonValue operator=(T value) { + JsonValue &operator=(T value) { set(value); return *this; } - template - T as() { - return static_cast(*this); - } + static JsonValue &invalid() { return _invalid; } - protected: - virtual void writeTo(Internals::JsonWriter &writer) const { - if (_impl) _impl->writeTo(writer); - } + bool success() { return _type != Internals::JSON_INVALID; } + + void writeTo(Internals::JsonWriter &writer) const; private: - Internals::JsonValueImpl *_impl; + Internals::JsonValueType _type; + Internals::JsonValueContent _content; + static JsonValue _invalid; }; } diff --git a/src/Internals/JsonArrayImpl.cpp b/src/Internals/JsonArrayImpl.cpp deleted file mode 100644 index d640364e..00000000 --- a/src/Internals/JsonArrayImpl.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#include "ArduinoJson/Internals/JsonArrayImpl.hpp" - -#include "ArduinoJson/JsonBuffer.hpp" -#include "ArduinoJson/Internals/JsonObjectImpl.hpp" -#include "ArduinoJson/Internals/JsonWriter.hpp" - -using namespace ArduinoJson; -using namespace ArduinoJson::Internals; - -JsonArrayImpl *JsonArrayImpl::createFrom(JsonBuffer *buffer) { - void *ptr = buffer->alloc(sizeof(JsonArrayImpl)); - return ptr ? new (ptr) JsonArrayImpl(buffer) : NULL; -} - -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 = _firstNode; - while (node && index--) node = node->next; - return node ? &node->value : NULL; -} - -JsonValueImpl *JsonArrayImpl::add() { - JsonArrayNode *node = JsonArrayNode::createFrom(_buffer); - if (!node) return NULL; - - addNode(node); - - return &node->value; -} - -void JsonArrayImpl::addNode(JsonArrayNode *newNode) { - if (_firstNode) { - JsonArrayNode *lastNode = _firstNode; - while (lastNode->next) lastNode = lastNode->next; - lastNode->next = newNode; - } else { - _firstNode = newNode; - } -} - -JsonArrayImpl *JsonArrayImpl::createNestedArray() { - JsonValueImpl *value = add(); - if (!value) return NULL; - - JsonArrayImpl *array = JsonArrayImpl::createFrom(_buffer); - value->set(array); - - return array; -} - -JsonObjectImpl *JsonArrayImpl::createNestedObject() { - JsonValueImpl *value = add(); - if (!value) return NULL; - - JsonObjectImpl *array = JsonObjectImpl::createFrom(_buffer); - value->set(array); - - return array; -} - -void JsonArrayImpl::writeTo(JsonWriter &writer) const { - JsonArrayNode *child = _firstNode; - - if (child) { - writer.beginArray(); - - for (;;) { - child->value.writeTo(writer); - - child = child->next; - if (!child) break; - - writer.writeComma(); - } - - writer.endArray(); - } else { - writer.writeEmptyArray(); - } -} diff --git a/src/Internals/JsonObjectImpl.cpp b/src/Internals/JsonObjectImpl.cpp deleted file mode 100644 index adabea68..00000000 --- a/src/Internals/JsonObjectImpl.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// https://github.com/bblanchon/ArduinoJson - -#include "ArduinoJson/JsonObject.hpp" - -#include // for strcmp - -#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; - -JsonObjectImpl *JsonObjectImpl::createFrom(JsonBuffer *buffer) { - void *ptr = buffer->alloc(sizeof(JsonObjectImpl)); - return ptr ? new (ptr) JsonObjectImpl(buffer) : NULL; -} - -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) { - JsonObjectNode *node = getOrCreateNodeAt(key); - if (!node) return NULL; - - JsonArrayImpl *array = JsonArrayImpl::createFrom(_buffer); - node->value.set(array); - - return array; -} - -JsonObjectImpl *JsonObjectImpl::createNestedObject(const char *key) { - JsonObjectNode *node = getOrCreateNodeAt(key); - if (!node) return NULL; - - JsonObjectImpl *object = JsonObjectImpl::createFrom(_buffer); - node->value.set(object); - - return object; -} - -JsonObjectNode *JsonObjectImpl::getNodeAt(const char *key) { - for (JsonObjectNode *node = _firstNode; node; node = node->next) { - if (!strcmp(node->key, key)) return node; - } - return NULL; -} - -JsonObjectNode *JsonObjectImpl::getOrCreateNodeAt(const char *key) { - JsonObjectNode *existingNode = getNodeAt(key); - if (existingNode) return existingNode; - - JsonObjectNode *newNode = JsonObjectNode::createFrom(_buffer, key); - - if (newNode) addNode(newNode); - - return newNode; -} - -void JsonObjectImpl::addNode(JsonObjectNode *nodeToAdd) { - if (!_firstNode) { - _firstNode = nodeToAdd; - } else { - JsonObjectNode *lastNode = _firstNode; - while (lastNode->next) lastNode = lastNode->next; - lastNode->next = nodeToAdd; - } -} - -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; - } -} - -void JsonObjectImpl::writeTo(JsonWriter &writer) const { - JsonObjectNode *node = _firstNode; - - if (node) { - writer.beginObject(); - - for (;;) { - writer.writeString(node->key); - writer.writeColon(); - node->value.writeTo(writer); - - node = node->next; - if (!node) break; - - writer.writeComma(); - } - - writer.endObject(); - } else { - writer.writeEmptyObject(); - } -} diff --git a/src/Internals/JsonParser.cpp b/src/Internals/JsonParser.cpp index 764b13d3..70c5f98d 100644 --- a/src/Internals/JsonParser.cpp +++ b/src/Internals/JsonParser.cpp @@ -30,7 +30,7 @@ bool JsonParser::skip(char charToSkip) { return true; } -void JsonParser::parseValueTo(JsonValue destination) { +void JsonParser::parseAnythingTo(JsonValue &destination) { skipSpaces(); switch (*_ptr) { @@ -73,23 +73,23 @@ void JsonParser::parseValueTo(JsonValue destination) { } } -JsonArray JsonParser::parseArray() { +JsonArray &JsonParser::parseArray() { skip('['); - if (isEnd()) return NULL; + if (isEnd()) return JsonArray::invalid(); - JsonArray array = _buffer->createArray(); + JsonArray &array = _buffer->createArray(); if (skip(']')) return array; // empty array for (;;) { - JsonValue child = array.add(); + JsonValue &child = array.add(); - parseValueTo(child); - if (!child.success()) return NULL; + parseAnythingTo(child); + if (!child.success()) return JsonArray::invalid(); // child parsing failed if (skip(']')) return array; // end of the array - if (!skip(',')) return NULL; // comma is missing + if (!skip(',')) return JsonArray::invalid(); // comma is missing } } @@ -126,38 +126,34 @@ void JsonParser::parseNullTo(JsonValue &destination) { destination = static_cast(NULL); } -JsonObject JsonParser::parseObject() { +JsonObject &JsonParser::parseObject() { skip('{'); - if (isEnd()) return NULL; // premature ending + if (isEnd()) return JsonObject::invalid(); // premature ending - JsonObject object = _buffer->createObject(); + JsonObject &object = _buffer->createObject(); if (skip('}')) return object; // empty object for (;;) { const char *key = parseString(); - if (!key) return NULL; + if (!key) break; // key parsing failed - if (!skip(':')) return NULL; + if (!skip(':')) break; // colon is missing - JsonValue value = object[key]; + JsonValue &value = object[key]; - parseValueTo(value); - if (!value.success()) return NULL; + parseAnythingTo(value); + if (!value.success()) break; // value parsing failed if (skip('}')) return object; // end of the object - if (!skip(',')) return 0; // comma is missing + if (!skip(',')) break; // comma is missing } + + return JsonObject::invalid(); } 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 deleted file mode 100644 index a500b80c..00000000 --- a/src/Internals/JsonValueImpl.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright Benoit Blanchon 2014 -// MIT License -// -// Arduino JSON library -// 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; -using namespace ArduinoJson::Internals; - -JsonValueImpl* JsonValueImpl::createFrom(JsonBuffer* buffer) { - void* ptr = buffer->alloc(sizeof(JsonValueImpl)); - return ptr ? new (ptr) JsonValueImpl() : NULL; -} - -void JsonValueImpl::writeTo(JsonWriter& writer) const { - switch (_type) { - case JSON_ARRAY: - _content.asArray->writeTo(writer); - break; - - case JSON_OBJECT: - _content.asObject->writeTo(writer); - break; - - case JSON_STRING: - writer.writeString(_content.asString); - break; - - case JSON_LONG: - writer.writeInteger(_content.asInteger); - break; - - case JSON_BOOLEAN: - writer.writeBoolean(_content.asBoolean); - break; - - default: // >= 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 cca79d1f..72972e30 100644 --- a/src/JsonArray.cpp +++ b/src/JsonArray.cpp @@ -5,22 +5,76 @@ // https://github.com/bblanchon/ArduinoJson #include "ArduinoJson/JsonArray.hpp" + +#include "ArduinoJson/JsonBuffer.hpp" #include "ArduinoJson/JsonObject.hpp" -#include "ArduinoJson/JsonValue.hpp" +#include "ArduinoJson/Internals/JsonWriter.hpp" using namespace ArduinoJson; using namespace ArduinoJson::Internals; -JsonValue JsonArray::add() { return JsonValue(_impl ? _impl->add() : NULL); } - -JsonValue JsonArray::operator[](int index) const { - return JsonValue(_impl ? (*_impl)[index] : NULL); +int JsonArray::size() const { + int nodeCount = 0; + for (JsonArrayNode *node = _firstNode; node; node = node->next) nodeCount++; + return nodeCount; } -JsonArray JsonArray::createNestedArray() { - return JsonArray(_impl ? _impl->createNestedArray() : NULL); +JsonValue &JsonArray::operator[](int index) const { + JsonArrayNode *node = _firstNode; + while (node && index--) node = node->next; + return node ? node->value : JsonValue::invalid(); } -JsonObject JsonArray::createNestedObject() { - return JsonObject(_impl ? _impl->createNestedObject() : NULL); -} \ No newline at end of file +JsonValue &JsonArray::add() { + JsonArrayNode *node = JsonArrayNode::createFrom(_buffer); + if (!node) return JsonValue::invalid(); + + addNode(node); + + return node->value; +} + +void JsonArray::addNode(JsonArrayNode *newNode) { + if (_firstNode) { + JsonArrayNode *lastNode = _firstNode; + while (lastNode->next) lastNode = lastNode->next; + lastNode->next = newNode; + } else { + _firstNode = newNode; + } +} + +JsonArray &JsonArray::createNestedArray() { + if (!_buffer) return JsonArray::invalid(); + JsonArray &array = _buffer->createArray(); + add(array); + return array; +} + +JsonObject &JsonArray::createNestedObject() { + if (!_buffer) return JsonObject::invalid(); + JsonObject &object = _buffer->createObject(); + add(object); + return object; +} + +void JsonArray::writeTo(JsonWriter &writer) const { + JsonArrayNode *child = _firstNode; + + if (child) { + writer.beginArray(); + + for (;;) { + child->value.writeTo(writer); + + child = child->next; + if (!child) break; + + writer.writeComma(); + } + + writer.endArray(); + } else { + writer.writeEmptyArray(); + } +} diff --git a/src/JsonBuffer.cpp b/src/JsonBuffer.cpp index 29a83492..fa59ce20 100644 --- a/src/JsonBuffer.cpp +++ b/src/JsonBuffer.cpp @@ -7,39 +7,31 @@ #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; using namespace ArduinoJson::Internals; -JsonArray JsonBuffer::createArray() { - return JsonArray(JsonArrayImpl::createFrom(this)); +JsonArray &JsonBuffer::createArray() { + void *ptr = alloc(sizeof(JsonArray)); + if (ptr) return *new (ptr) JsonArray(this); + return JsonArray::invalid(); } -JsonObject JsonBuffer::createObject() { - return JsonObject(JsonObjectImpl::createFrom(this)); +JsonObject &JsonBuffer::createObject() { + void *ptr = alloc(sizeof(JsonObject)); + if (ptr) return *new (ptr) JsonObject(this); + return JsonObject::invalid(); } -JsonValue JsonBuffer::createValue() { - return JsonValue(JsonValueImpl::createFrom(this)); -} - -JsonArray JsonBuffer::parseArray(char* json) { +JsonArray &JsonBuffer::parseArray(char *json) { JsonParser parser(this, json); - return JsonArray(parser.parseArray()); + return parser.parseArray(); } -JsonObject JsonBuffer::parseObject(char* json) { +JsonObject &JsonBuffer::parseObject(char *json) { JsonParser parser(this, json); - return JsonObject(parser.parseObject()); + return 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/JsonObject.cpp b/src/JsonObject.cpp index 96a700ad..277920fe 100644 --- a/src/JsonObject.cpp +++ b/src/JsonObject.cpp @@ -4,20 +4,102 @@ // Arduino JSON library // https://github.com/bblanchon/ArduinoJson -#include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonObject.hpp" + +#include // for strcmp + +#include "ArduinoJson/JsonBuffer.hpp" +#include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonValue.hpp" +#include "ArduinoJson/Internals/JsonWriter.hpp" +#include "ArduinoJson/Internals/StringBuilder.hpp" using namespace ArduinoJson; +using namespace ArduinoJson::Internals; -JsonValue JsonObject::operator[](char const *key) { - return JsonValue(_impl ? (*_impl)[key] : NULL); +int JsonObject::size() const { + int nodeCount = 0; + for (JsonObjectNode *node = _firstNode; node; node = node->next) nodeCount++; + return nodeCount; } -JsonArray JsonObject::createNestedArray(key_type key) { - return JsonArray(_impl ? _impl->createNestedArray(key) : NULL); +JsonValue &JsonObject::operator[](const char *key) { + JsonObjectNode *node = getOrCreateNodeAt(key); + return node ? node->pair.value : JsonValue::invalid(); } -JsonObject JsonObject::createNestedObject(key_type key) { - return JsonObject(_impl ? _impl->createNestedObject(key) : NULL); +void JsonObject::remove(char const *key) { removeNode(getNodeAt(key)); } + +JsonArray &JsonObject::createNestedArray(char const *key) { + if (!_buffer) return JsonArray::invalid(); + JsonArray &array = _buffer->createArray(); + add(key, array); + return array; +} + +JsonObject &JsonObject::createNestedObject(const char *key) { + if (!_buffer) return JsonObject::invalid(); + JsonObject &object = _buffer->createObject(); + add(key, object); + return object; +} + +JsonObjectNode *JsonObject::getNodeAt(const char *key) { + for (JsonObjectNode *node = _firstNode; node; node = node->next) { + if (!strcmp(node->pair.key, key)) return node; + } + return NULL; +} + +JsonObjectNode *JsonObject::getOrCreateNodeAt(const char *key) { + JsonObjectNode *existingNode = getNodeAt(key); + if (existingNode) return existingNode; + + JsonObjectNode *newNode = JsonObjectNode::createFrom(_buffer, key); + + if (newNode) addNode(newNode); + + return newNode; +} + +void JsonObject::addNode(JsonObjectNode *nodeToAdd) { + if (!_firstNode) { + _firstNode = nodeToAdd; + } else { + JsonObjectNode *lastNode = _firstNode; + while (lastNode->next) lastNode = lastNode->next; + lastNode->next = nodeToAdd; + } +} + +void JsonObject::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; + } +} + +void JsonObject::writeTo(JsonWriter &writer) const { + JsonObjectNode *node = _firstNode; + + if (node) { + writer.beginObject(); + + for (;;) { + writer.writeString(node->pair.key); + writer.writeColon(); + node->pair.value.writeTo(writer); + + node = node->next; + if (!node) break; + + writer.writeComma(); + } + + writer.endObject(); + } else { + writer.writeEmptyObject(); + } } diff --git a/src/JsonValue.cpp b/src/JsonValue.cpp index fd3e26ff..4d64b221 100644 --- a/src/JsonValue.cpp +++ b/src/JsonValue.cpp @@ -4,24 +4,98 @@ // Arduino JSON library // https://github.com/bblanchon/ArduinoJson +#include "ArduinoJson/JsonValue.hpp" #include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonObject.hpp" -#include "ArduinoJson/JsonValue.hpp" +#include "ArduinoJson/Internals/JsonWriter.hpp" using namespace ArduinoJson; +using namespace ArduinoJson::Internals; -JsonValue::operator JsonArray() { - return JsonArray(_impl ? _impl->asArray() : NULL); +JsonArray &JsonValue::asArray() { + return _type == JSON_ARRAY ? *_content.asArray : JsonArray::invalid(); } -JsonValue::operator JsonObject() { - return JsonObject(_impl ? _impl->asObject() : NULL); +JsonObject &JsonValue::asObject() { + return _type == JSON_OBJECT ? *_content.asObject : JsonObject::invalid(); } -void JsonValue::set(JsonArray array) { - if (_impl) _impl->set(array._impl); +bool JsonValue::asBool() const { + return _type == JSON_BOOLEAN ? _content.asBoolean : false; } -void JsonValue::set(JsonObject object) { - if (_impl) _impl->set(object._impl); +const char *JsonValue::asString() const { + return _type == JSON_STRING ? _content.asString : NULL; +} + +double JsonValue::asDouble() const { + return _type >= JSON_DOUBLE_0_DECIMALS ? _content.asDouble : 0; +} + +long JsonValue::asLong() const { + return _type == JSON_LONG ? _content.asInteger : 0; +} + +void JsonValue::set(bool value) { + if (_type == JSON_INVALID) return; + _type = Internals::JSON_BOOLEAN; + _content.asBoolean = value; +} + +void JsonValue::set(const char *value) { + if (_type == JSON_INVALID) return; + _type = JSON_STRING; + _content.asString = value; +} + +void JsonValue::set(double value, int decimals) { + if (_type == JSON_INVALID) return; + _type = static_cast(JSON_DOUBLE_0_DECIMALS + decimals); + _content.asDouble = value; +} + +void JsonValue::set(long value) { + if (_type == JSON_INVALID) return; + _type = JSON_LONG; + _content.asInteger = value; +} + +void JsonValue::set(JsonArray &array) { + if (_type == JSON_INVALID) return; + _type = JSON_ARRAY; + _content.asArray = &array; +} + +void JsonValue::set(JsonObject &object) { + if (_type == JSON_INVALID) return; + _type = JSON_OBJECT; + _content.asObject = &object; +} + +void JsonValue::writeTo(JsonWriter &writer) const { + switch (_type) { + case JSON_ARRAY: + _content.asArray->writeTo(writer); + break; + + case JSON_OBJECT: + _content.asObject->writeTo(writer); + break; + + case JSON_STRING: + writer.writeString(_content.asString); + break; + + case JSON_LONG: + writer.writeInteger(_content.asInteger); + break; + + case JSON_BOOLEAN: + writer.writeBoolean(_content.asBoolean); + break; + + default: // >= JSON_DOUBLE_0_DECIMALS + writer.writeDouble(_content.asDouble, _type - JSON_DOUBLE_0_DECIMALS); + break; + } } \ No newline at end of file