Răsfoiți Sursa

Epic refactoring in progress

Benoit Blanchon 11 ani în urmă
părinte
comite
e0980292ef
29 a modificat fișierele cu 481 adăugiri și 545 ștergeri
  1. 11 7
      include/ArduinoJson/ForwardDeclarations.hpp
  2. 8 8
      include/ArduinoJson/Internals/JsonArrayConstIterator.hpp
  3. 41 0
      include/ArduinoJson/Internals/JsonArrayImpl.hpp
  4. 8 8
      include/ArduinoJson/Internals/JsonArrayIterator.hpp
  5. 19 0
      include/ArduinoJson/Internals/JsonArrayNode.hpp
  6. 0 163
      include/ArduinoJson/Internals/JsonNode.hpp
  7. 0 32
      include/ArduinoJson/Internals/JsonNodeIterator.hpp
  8. 0 31
      include/ArduinoJson/Internals/JsonNodeWrapper.hpp
  9. 9 8
      include/ArduinoJson/Internals/JsonObjectConstIterator.hpp
  10. 7 9
      include/ArduinoJson/Internals/JsonObjectIterator.hpp
  11. 19 0
      include/ArduinoJson/Internals/JsonObjectNode.hpp
  12. 0 22
      include/ArduinoJson/Internals/JsonPairInternal.hpp
  13. 11 12
      include/ArduinoJson/Internals/JsonParser.hpp
  14. 23 0
      include/ArduinoJson/Internals/JsonSerializer.hpp
  15. 23 0
      include/ArduinoJson/Internals/JsonValueContent.hpp
  16. 79 0
      include/ArduinoJson/Internals/JsonValueImpl.hpp
  17. 0 25
      include/ArduinoJson/Internals/JsonValueInternal.hpp
  18. 25 0
      include/ArduinoJson/Internals/JsonValueType.hpp
  19. 18 15
      include/ArduinoJson/JsonArray.hpp
  20. 24 28
      include/ArduinoJson/JsonBuffer.hpp
  21. 1 25
      include/ArduinoJson/JsonContainer.hpp
  22. 7 7
      include/ArduinoJson/JsonObject.hpp
  23. 7 9
      include/ArduinoJson/JsonPair.hpp
  24. 28 22
      include/ArduinoJson/JsonValue.hpp
  25. 52 0
      src/Internals/JsonArrayImpl.cpp
  26. 52 53
      src/Internals/JsonParser.cpp
  27. 0 0
      src/Internals/JsonSerializer.cpp
  28. 7 29
      src/JsonArray.cpp
  29. 2 32
      src/JsonValue.cpp

+ 11 - 7
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 <typename T>
-class JsonIterator;
-template <typename T>
-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;
 }
 }

+ 8 - 8
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;
 };
 }
 }

+ 41 - 0
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;
+};
+}
+}

+ 8 - 8
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;
 };
 }
 }

+ 19 - 0
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;
+};
+}
+}

+ 0 - 163
include/ArduinoJson/Internals/JsonNode.hpp

@@ -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<JsonNodeType>(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;
-  }
-};
-}
-}

+ 0 - 32
include/ArduinoJson/Internals/JsonNodeIterator.hpp

@@ -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;
-};
-}
-}

+ 0 - 31
include/ArduinoJson/Internals/JsonNodeWrapper.hpp

@@ -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;
-};
-}
-}

+ 9 - 8
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;
 };
 }
 }

+ 7 - 9
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;
 };
 }
 }

+ 19 - 0
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;
+};
+}
+}

+ 0 - 22
include/ArduinoJson/Internals/JsonPairInternal.hpp

@@ -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;
-  }
-};
-}

+ 11 - 12
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;
 };
 }
 }

+ 23 - 0
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&);
+};
+}
+}

+ 23 - 0
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;
+};
+}
+}

+ 79 - 0
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 <stddef.h>
+
+#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<JsonValueType>(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;
+};
+}
+}

+ 0 - 25
include/ArduinoJson/Internals/JsonValueInternal.hpp

@@ -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;
-  }
-};
-}
-}

+ 25 - 0
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.
+};
+}
+}

+ 18 - 15
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 <typename T>
   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<const Internals::JsonArrayImpl*>(_impl)->begin();
+  }
   const_iterator end() const { return const_iterator(0); }
 
-private:
-  JsonValue addNewValue();
+  static JsonArray null() { return JsonArray(NULL); }
+
+ private:
+  Internals::JsonArrayImpl* _impl;
 };
 }

+ 24 - 28
include/ArduinoJson/JsonBuffer.hpp

@@ -6,43 +6,39 @@
 
 #pragma once
 
+#include <new>
+
 #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
-
- protected:
-  virtual void *allocateNode() = 0;
-
- private:
-  Internals::JsonNode *createNode();
-
-  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);
+  template <typename T>
+  JsonValue createValue(T x) {
+    JsonValue value;
+    value = x;
+    return value;
+  }
+
+  JsonArray parseArray(char* json);
+  JsonObject parseObject(char* json);
+  JsonValue parseValue(char* json);
+
+  template <typename T>
+  T* create() {
+    void* p = alloc(sizeof(T));
+    if (!p) return NULL;
+    return new (p) T();
+  }
+
+  virtual void* alloc(size_t size) = 0;
 };
 }

+ 1 - 25
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;
 };
 }

+ 7 - 7
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;
 };
 }

+ 7 - 9
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;
 };
 }

+ 28 - 22
include/ArduinoJson/JsonValue.hpp

@@ -6,40 +6,46 @@
 
 #pragma once
 
+#include <stddef.h>
+
 #include "ForwardDeclarations.hpp"
-#include "Internals/JsonNodeWrapper.hpp"
+#include "Internals/JsonValueImpl.hpp"
 
 namespace ArduinoJson {
 
-class JsonValue : public Internals::JsonNodeWrapper {
+class JsonValue {
  public:
-  JsonValue() {}
-
-  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);
-  }
+  JsonValue() : _impl(NULL) {}
+  JsonValue(Internals::JsonValueImpl *impl) : _impl(impl) {}
 
-  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;
+  template <typename T>
+  void operator=(T value) {
+    if (_impl) _impl->set(value);
+  }
 
-  void set(double value, int decimals);
+  void set(double value, int decimals) {
+    if (_impl) _impl->set(value, decimals);
+  }
 
   template <typename T>
   T as() {
     return static_cast<T>(*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<char *>(NULL);
+  }
+  operator JsonArray() const;
+
+  bool success() { return _impl; }
+
+  static JsonValue null() { return JsonValue(NULL); }
+
+ private:
+  Internals::JsonValueImpl *_impl;
 };
 }

+ 52 - 0
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<JsonArrayNode>();
+  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);
+}

+ 52 - 53
src/Internals/JsonParser.cpp

@@ -9,9 +9,13 @@
 #include <stdlib.h>  // for strtol, strtod
 #include <ctype.h>
 
+#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();
-
-    if (!child) return 0;  // child parsing failed
+    JsonValue child = array.add();
 
-    node->addChild(child);
+    parseValueTo(child);
+    if (!child.success()) return NULL;
 
-    if (skip(']')) return node;  // end of the array
+    if (skip(']')) return array;  // 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<const char *>(NULL);
 }
 
-JsonNode *JsonParser::parseObject() {
-  JsonNode *node = _buffer->createObjectNode();
-
+JsonObject JsonParser::parseObject() {
   skip('{');
 
-  if (isEnd()) return 0;  // premature ending
+  if (isEnd()) return NULL;  // premature ending
+
+  JsonObject object = _buffer->createObject();
 
-  if (skip('}')) return node;  // empty object
+  if (skip('}')) return object;  // empty object
 
   for (;;) {
-    JsonNode *child = parseObjectKeyValue();
+    const char *key = parseString();
+    if (!key) return NULL;
+
+    skip(':')
 
-    if (!child) return 0;  // child parsing failed
+        JsonValue value = object[key];
 
-    node->addChild(child);
+    parseValueTo(value);
+    if (!value.success()) return NULL;
 
-    if (skip('}')) return node;  // end of the object
+    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);
 }

+ 0 - 0
src/Internals/JsonNode.cpp → src/Internals/JsonSerializer.cpp


+ 7 - 29
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()));
+}

+ 2 - 32
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); }