Bläddra i källkod

Huge refactoring in progress...

Benoit Blanchon 11 år sedan
förälder
incheckning
ba2b142c8a

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

+ 0 - 48
include/ArduinoJson/Internals/JsonArrayImpl.hpp

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

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

+ 0 - 53
include/ArduinoJson/Internals/JsonObjectImpl.hpp

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

+ 0 - 36
include/ArduinoJson/Internals/JsonObjectIterator.hpp

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

+ 3 - 4
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) {}
 };
 }
 }

+ 3 - 4
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);

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

+ 0 - 83
include/ArduinoJson/Internals/JsonValueImpl.hpp

@@ -1,83 +0,0 @@
-// 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) {}
-
-  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<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;
-  }
-
-  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;
-};
-}
-}

+ 1 - 0
include/ArduinoJson/Internals/JsonValueType.hpp

@@ -11,6 +11,7 @@ namespace Internals {
 
 enum JsonValueType {
   JSON_UNDEFINED,
+  JSON_INVALID,
   JSON_ARRAY,
   JSON_OBJECT,
   JSON_BOOLEAN,

+ 20 - 30
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;
-
-  JsonArray() : _impl(NULL) {}
-  JsonArray(Internals::JsonArrayImpl* impl) : _impl(impl) {}
+  typedef JsonArrayIterator iterator;
+  typedef JsonArrayConstIterator const_iterator;
 
-  bool success() const { return _impl; }
+  JsonArray(JsonBuffer *buffer = NULL) : _buffer(buffer), _firstNode(NULL) {}
 
-  int size() const { return _impl ? _impl->size() : 0; }
+  int size() const;
 
-  value_type operator[](int index) const;
-  value_type add();
+  value_type &operator[](int index) const;
+  value_type &add();
 
   template <typename T>
   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<const Internals::JsonArrayImpl*>(_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;
 };
 }

+ 8 - 10
include/ArduinoJson/Internals/JsonArrayConstIterator.hpp → 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;
 };
-}
-}
+}

+ 6 - 16
include/ArduinoJson/Internals/JsonArrayIterator.hpp → 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;
 };
 }
-}

+ 7 - 16
include/ArduinoJson/JsonBuffer.hpp

@@ -17,21 +17,12 @@ class JsonBuffer {
  public:
   virtual ~JsonBuffer() {}
 
-  JsonArray createArray();
-  JsonObject createObject();
-  JsonValue createValue();
-
-  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);
-
-  virtual void* alloc(size_t size) = 0;
+  JsonArray &createArray();
+  JsonObject &createObject();
+
+  JsonArray &parseArray(char *json);
+  JsonObject &parseObject(char *json);
+
+  virtual void *alloc(size_t size) = 0;
 };
 }

+ 28 - 31
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 <typename T>
+  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<const Internals::JsonObjectImpl*>(_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;
 };
 }

+ 9 - 11
include/ArduinoJson/Internals/JsonObjectConstIterator.hpp → 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;
 };
 }
-}

+ 20 - 16
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) {}
-
-  const char* key() const { return operator*().key(); }
-
-  JsonValue value() const { return operator*().value(); }
+  explicit JsonObjectIterator(Internals::JsonObjectNode *node) : _node(node) {}
 
-  void operator++() { _node = _node->next; }
+  JsonPair &operator*() { return _node->pair; }
+  JsonPair *operator->() { return &_node->pair; }
 
-  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;
 };
-}
+}

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

+ 26 - 43
include/ArduinoJson/JsonValue.hpp

@@ -9,62 +9,45 @@
 #include <stddef.h>
 
 #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) {}
-
-  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<long>(value));
-  }
-  void set(long value) {
-    if (_impl) _impl->set(value);
-  }
-  void set(JsonObject object);
-  void set(JsonArray array);
-
-  operator bool() const { return _impl ? _impl->asBool() : false; }
-  operator int() const { return _impl ? _impl->asLong() : 0; }
-  operator long() const { return _impl ? _impl->asLong() : 0; }
-  operator double() const { return _impl ? _impl->asDouble() : 0.0; }
-  operator const char *() const {
-    return _impl ? _impl->asString() : static_cast<char *>(NULL);
-  }
-  operator JsonArray();
-  operator JsonObject();
-
-  bool success() { return _impl; }
+  JsonValue() : _type(Internals::JSON_UNDEFINED) {}
+
+  void set(bool value);
+  void set(const char *value);
+  void set(double value, int decimals = 2);
+  void set(int value) { set(static_cast<long>(value)); }
+  void set(long value);
+  void set(JsonArray &array);
+  void set(JsonObject &object);
+
+  JsonArray &asArray();
+  JsonObject &asObject();
+  bool asBool() const;
+  const char *asString() const;
+  double asDouble() const;
+  long asLong() const;
 
   template <typename T>
-  JsonValue operator=(T value) {
+  JsonValue &operator=(T value) {
     set(value);
     return *this;
   }
 
-  template <typename T>
-  T as() {
-    return static_cast<T>(*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;
 };
 }

+ 0 - 91
src/Internals/JsonArrayImpl.cpp

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

+ 0 - 116
src/Internals/JsonObjectImpl.cpp

@@ -1,116 +0,0 @@
-// Copyright Benoit Blanchon 2014
-// MIT License
-//
-// Arduino JSON library
-// https://github.com/bblanchon/ArduinoJson
-
-#include "ArduinoJson/JsonObject.hpp"
-
-#include <string.h>  // 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();
-  }
-}

+ 19 - 23
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<const char *>(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;
-}

+ 0 - 46
src/Internals/JsonValueImpl.cpp

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

+ 63 - 9
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); }
+int JsonArray::size() const {
+  int nodeCount = 0;
+  for (JsonArrayNode *node = _firstNode; node; node = node->next) nodeCount++;
+  return nodeCount;
+}
+
+JsonValue &JsonArray::operator[](int index) const {
+  JsonArrayNode *node = _firstNode;
+  while (node && index--) node = node->next;
+  return node ? node->value : JsonValue::invalid();
+}
+
+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;
+  }
+}
 
-JsonValue JsonArray::operator[](int index) const {
-  return JsonValue(_impl ? (*_impl)[index] : NULL);
+JsonArray &JsonArray::createNestedArray() {
+  if (!_buffer) return JsonArray::invalid();
+  JsonArray &array = _buffer->createArray();
+  add(array);
+  return array;
 }
 
-JsonArray JsonArray::createNestedArray() {
-  return JsonArray(_impl ? _impl->createNestedArray() : NULL);
+JsonObject &JsonArray::createNestedObject() {
+  if (!_buffer) return JsonObject::invalid();
+  JsonObject &object = _buffer->createObject();
+  add(object);
+  return object;
 }
 
-JsonObject JsonArray::createNestedObject() {
-  return JsonObject(_impl ? _impl->createNestedObject() : NULL);
-}
+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();
+  }
+}

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

+ 89 - 7
src/JsonObject.cpp

@@ -4,20 +4,102 @@
 // Arduino JSON library
 // https://github.com/bblanchon/ArduinoJson
 
-#include "ArduinoJson/JsonArray.hpp"
 #include "ArduinoJson/JsonObject.hpp"
+
+#include <string.h>  // 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();
+}
+
+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(key_type key) {
-  return JsonObject(_impl ? _impl->createNestedObject(key) : NULL);
+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();
+  }
 }

+ 83 - 9
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;
+
+JsonArray &JsonValue::asArray() {
+  return _type == JSON_ARRAY ? *_content.asArray : JsonArray::invalid();
+}
 
-JsonValue::operator JsonArray() {
-  return JsonArray(_impl ? _impl->asArray() : NULL);
+JsonObject &JsonValue::asObject() {
+  return _type == JSON_OBJECT ? *_content.asObject : JsonObject::invalid();
 }
 
-JsonValue::operator JsonObject() {
-  return JsonObject(_impl ? _impl->asObject() : NULL);
+bool JsonValue::asBool() const {
+  return _type == JSON_BOOLEAN ? _content.asBoolean : false;
 }
 
-void JsonValue::set(JsonArray array) {
-  if (_impl) _impl->set(array._impl);
+const char *JsonValue::asString() const {
+  return _type == JSON_STRING ? _content.asString : NULL;
 }
 
-void JsonValue::set(JsonObject object) {
-  if (_impl) _impl->set(object._impl);
+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<JsonValueType>(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;
+  }
 }