Huge refactoring in progress...

This commit is contained in:
Benoit Blanchon
2014-10-30 10:49:02 +01:00
parent 5cf744dbac
commit c3001e9ea9
9 changed files with 119 additions and 103 deletions

View File

@ -14,16 +14,16 @@
namespace ArduinoJson { namespace ArduinoJson {
class JsonArray : public JsonPrintable { class JsonArray : public JsonPrintable {
friend class JsonBuffer;
public: public:
typedef JsonValue value_type; typedef JsonValue value_type;
typedef JsonArrayIterator iterator; typedef JsonArrayIterator iterator;
typedef JsonArrayConstIterator const_iterator; typedef JsonArrayConstIterator const_iterator;
JsonArray(JsonBuffer *buffer = NULL) : _buffer(buffer), _firstNode(NULL) {}
int size() const; int size() const;
bool success() {return _buffer != NULL;} bool success() { return _buffer != NULL; }
value_type &operator[](int index) const; value_type &operator[](int index) const;
value_type &add(); value_type &add();
@ -33,13 +33,9 @@ class JsonArray : public JsonPrintable {
add().set(value); add().set(value);
} }
void add(JsonArray &nestedArray) { void add(double value, int decimals) { add().set(value, decimals); }
add().set(nestedArray); void add(JsonArray &nestedArray) { add().set(nestedArray); }
} void add(JsonObject &nestedObject) { add().set(nestedObject); }
void add(JsonObject&nestedObject){
add().set(nestedObject);
}
JsonArray &createNestedArray(); JsonArray &createNestedArray();
JsonObject &createNestedObject(); JsonObject &createNestedObject();
@ -55,8 +51,12 @@ class JsonArray : public JsonPrintable {
virtual void writeTo(Internals::JsonWriter &writer) const; virtual void writeTo(Internals::JsonWriter &writer) const;
private: private:
JsonArray(const JsonArray&); // copy is forbidden, use a reference instead // constructor is private: instance must be created via a JsonBuffer
JsonArray& operator=(const JsonArray&); // copy is forbidden, use a reference instead JsonArray(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
JsonArray(const JsonArray &); // copy is forbidden, use a reference instead
JsonArray &operator=(
const JsonArray &); // copy is forbidden, use a reference instead
inline void addNode(Internals::JsonArrayNode *node); inline void addNode(Internals::JsonArrayNode *node);

View File

@ -14,14 +14,14 @@
namespace ArduinoJson { namespace ArduinoJson {
class JsonObject : public JsonPrintable { class JsonObject : public JsonPrintable {
friend class JsonBuffer;
public: public:
typedef const char *key_type; typedef const char *key_type;
typedef JsonPair value_type; typedef JsonPair value_type;
typedef JsonObjectIterator iterator; typedef JsonObjectIterator iterator;
typedef JsonObjectConstIterator const_iterator; typedef JsonObjectConstIterator const_iterator;
JsonObject(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
int size() const; int size() const;
JsonValue &operator[](key_type key); JsonValue &operator[](key_type key);
@ -29,16 +29,11 @@ class JsonObject : public JsonPrintable {
template <typename T> template <typename T>
void add(key_type key, T value) { void add(key_type key, T value) {
(*this)[key] = value; add(key).set(value);
} }
void add(key_type key, JsonArray &nestedArray) { void add(key_type key, JsonArray &array) { add(key).set(array); }
(*this)[key] = nestedArray; void add(key_type key, JsonObject &object) { add(key).set(object); }
}
void add(key_type key, JsonObject &nestedObject) {
(*this)[key] = nestedObject;
}
JsonArray &createNestedArray(key_type key); JsonArray &createNestedArray(key_type key);
JsonObject &createNestedObject(key_type key); JsonObject &createNestedObject(key_type key);
@ -54,9 +49,14 @@ class JsonObject : public JsonPrintable {
virtual void writeTo(Internals::JsonWriter &writer) const; virtual void writeTo(Internals::JsonWriter &writer) const;
private: private:
JsonObject(const JsonObject&); // copy is forbidden, use a reference instead // constructor is private, instance must be created via JsonBuffer
JsonObject& operator=(const JsonObject&); // copy is forbidden, use a reference instead JsonObject(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
JsonObject(const JsonObject &); // copy is forbidden, use a reference instead
JsonObject &operator=(
const JsonObject &); // copy is forbidden, use a reference instead
JsonValue &add(key_type key) { return (*this)[key]; }
void addNode(Internals::JsonObjectNode *nodeToAdd); void addNode(Internals::JsonObjectNode *nodeToAdd);
void removeNode(Internals::JsonObjectNode *nodeToRemove); void removeNode(Internals::JsonObjectNode *nodeToRemove);

View File

@ -32,25 +32,30 @@ class JsonValue {
return *this; return *this;
} }
JsonValue &operator=(JsonArray& array) { JsonValue &operator=(JsonArray &array) {
set(array); set(array);
return *this; return *this;
} }
JsonValue &operator=(JsonObject& object) { JsonValue &operator=(JsonObject &object) {
set(object); set(object);
return *this; return *this;
} }
JsonArray &asArray(); operator bool() const;
JsonObject &asObject(); operator const char *() const;
bool asBool() const; operator double() const;
const char *asString() const; operator long() const;
double asDouble() const; operator JsonArray &() const;
long asLong() const; operator JsonObject &() const;
JsonArray &asArray() { return static_cast<JsonArray &>(*this); };
JsonObject &asObject() { return static_cast<JsonObject &>(*this); };
template <typename T> template <typename T>
T as(){} T as() {
return static_cast<T>(*this);
}
static JsonValue &invalid() { return _invalid; } static JsonValue &invalid() { return _invalid; }
@ -63,8 +68,3 @@ class JsonValue {
Internals::JsonValueContent _content; Internals::JsonValueContent _content;
static JsonValue _invalid; static JsonValue _invalid;
}; };
template <>
int JsonValue::as<int>() { return asLong(); }
}

View File

@ -12,27 +12,27 @@
using namespace ArduinoJson; using namespace ArduinoJson;
using namespace ArduinoJson::Internals; using namespace ArduinoJson::Internals;
JsonArray &JsonValue::asArray() { JsonValue::operator JsonArray &() const {
return _type == JSON_ARRAY ? *_content.asArray : JsonArray::invalid(); return _type == JSON_ARRAY ? *_content.asArray : JsonArray::invalid();
} }
JsonObject &JsonValue::asObject() { JsonValue::operator JsonObject &() const {
return _type == JSON_OBJECT ? *_content.asObject : JsonObject::invalid(); return _type == JSON_OBJECT ? *_content.asObject : JsonObject::invalid();
} }
bool JsonValue::asBool() const { JsonValue::operator bool() const {
return _type == JSON_BOOLEAN ? _content.asBoolean : false; return _type == JSON_BOOLEAN ? _content.asBoolean : false;
} }
const char *JsonValue::asString() const { JsonValue::operator const char *() const {
return _type == JSON_STRING ? _content.asString : NULL; return _type == JSON_STRING ? _content.asString : NULL;
} }
double JsonValue::asDouble() const { JsonValue::operator double() const {
return _type >= JSON_DOUBLE_0_DECIMALS ? _content.asDouble : 0; return _type >= JSON_DOUBLE_0_DECIMALS ? _content.asDouble : 0;
} }
long JsonValue::asLong() const { JsonValue::operator long() const {
return _type == JSON_LONG ? _content.asInteger : 0; return _type == JSON_LONG ? _content.asInteger : 0;
} }

View File

@ -15,30 +15,43 @@ using namespace ArduinoJson;
class JsonArray_Container_Tests : public ::testing::Test { class JsonArray_Container_Tests : public ::testing::Test {
protected: protected:
JsonArray_Container_Tests() JsonArray_Container_Tests() : array(json.createArray()) {}
: array(json.createArray()) {
template <typename T>
void firstMustEqual(T expected) {
itemMustEqual(0, expected);
} }
template <typename T> template <typename T>
void firstElementMustBe(T expected) { void secondMustEqual(T expected) {
elementAtIndexMustBe(0, expected); itemMustEqual(1, expected);
} }
template <typename T> template <typename T>
void secondElementMustBe(T expected) { void firstMustReference(const T& expected) {
elementAtIndexMustBe(1, expected); itemMustReference(0, expected);
}
template <typename T>
void secondMustReference(const T& expected) {
itemMustReference(1, expected);
} }
void sizeMustBe(int expected) { EXPECT_EQ(expected, array.size()); } void sizeMustBe(int expected) { EXPECT_EQ(expected, array.size()); }
StaticJsonBuffer<256> json; StaticJsonBuffer<256> json;
JsonArray &array; JsonArray& array;
private: private:
template <typename T> template <typename T>
void elementAtIndexMustBe(int index, T expected) { void itemMustEqual(int index, T expected) {
EXPECT_EQ(expected, array[index].as<T>()); EXPECT_EQ(expected, array[index].as<T>());
} }
template <typename T>
void itemMustReference(int index, const T& expected) {
EXPECT_EQ(&expected, &array[index].as<T&>());
}
}; };
TEST_F(JsonArray_Container_Tests, SuccessIsTrue) { TEST_F(JsonArray_Container_Tests, SuccessIsTrue) {
@ -59,24 +72,24 @@ TEST_F(JsonArray_Container_Tests, CanStoreIntegers) {
array.add(123); array.add(123);
array.add(456); array.add(456);
firstElementMustBe(123); firstMustEqual(123);
secondElementMustBe(456); secondMustEqual(456);
} }
TEST_F(JsonArray_Container_Tests, CanStoreDoubles) { TEST_F(JsonArray_Container_Tests, CanStoreDoubles) {
array.add(123.45); array.add(123.45);
array.add(456.78); array.add(456.78);
firstElementMustBe(123.45); firstMustEqual(123.45);
secondElementMustBe(456.78); secondMustEqual(456.78);
} }
TEST_F(JsonArray_Container_Tests, CanStoreBooleans) { TEST_F(JsonArray_Container_Tests, CanStoreBooleans) {
array.add(true); array.add(true);
array.add(false); array.add(false);
firstElementMustBe(true); firstMustEqual(true);
secondElementMustBe(false); secondMustEqual(false);
} }
TEST_F(JsonArray_Container_Tests, CanStoreStrings) { TEST_F(JsonArray_Container_Tests, CanStoreStrings) {
@ -86,44 +99,44 @@ TEST_F(JsonArray_Container_Tests, CanStoreStrings) {
array.add(firstString); array.add(firstString);
array.add(secondString); array.add(secondString);
firstElementMustBe(firstString); firstMustEqual(firstString);
secondElementMustBe(secondString); secondMustEqual(secondString);
} }
TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) { TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) {
JsonArray &innerarray1 = json.createArray(); JsonArray& innerarray1 = json.createArray();
JsonArray &innerarray2 = json.createArray(); JsonArray& innerarray2 = json.createArray();
array.add(innerarray1); array.add(innerarray1);
array.add(innerarray2); array.add(innerarray2);
firstElementMustBe(innerarray1); firstMustReference(innerarray1);
secondElementMustBe(innerarray2); secondMustReference(innerarray2);
} }
TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) { TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) {
JsonObject innerObject1 = json.createObject(); JsonObject& innerObject1 = json.createObject();
JsonObject innerObject2 = json.createObject(); JsonObject& innerObject2 = json.createObject();
array.add(innerObject1); array.add(innerObject1);
array.add(innerObject2); array.add(innerObject2);
firstElementMustBe(innerObject1); firstMustReference(innerObject1);
secondElementMustBe(innerObject2); secondMustReference(innerObject2);
} }
TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) { TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) {
JsonArray innerarray1 = array.createNestedArray(); JsonArray& innerarray1 = array.createNestedArray();
JsonArray innerarray2 = array.createNestedArray(); JsonArray& innerarray2 = array.createNestedArray();
firstElementMustBe(innerarray1); firstMustReference(innerarray1);
secondElementMustBe(innerarray2); secondMustReference(innerarray2);
} }
TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) { TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) {
JsonObject innerObject1 = array.createNestedObject(); JsonObject& innerObject1 = array.createNestedObject();
JsonObject innerObject2 = array.createNestedObject(); JsonObject& innerObject2 = array.createNestedObject();
firstElementMustBe(innerObject1); firstMustReference(innerObject1);
secondElementMustBe(innerObject2); secondMustReference(innerObject2);
} }

View File

@ -13,13 +13,14 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonArray_PrettyPrintTo_Tests : public testing::Test { class JsonArray_PrettyPrintTo_Tests : public testing::Test {
public:
JsonArray_PrettyPrintTo_Tests() : array(json.createArray()) {}
protected: protected:
JsonArray array; JsonArray& array;
StaticJsonBuffer<30> json; StaticJsonBuffer<30> json;
virtual void SetUp() { array = json.createArray(); } void outputMustBe(const char* expected) {
void outputMustBe(const char *expected) {
size_t n = array.prettyPrintTo(buffer, sizeof(buffer)); size_t n = array.prettyPrintTo(buffer, sizeof(buffer));
EXPECT_STREQ(expected, buffer); EXPECT_STREQ(expected, buffer);
EXPECT_EQ(strlen(expected), n); EXPECT_EQ(strlen(expected), n);
@ -63,11 +64,11 @@ TEST_F(JsonArray_PrettyPrintTo_Tests, EmptyNestedArrays) {
} }
TEST_F(JsonArray_PrettyPrintTo_Tests, NestedArrays) { TEST_F(JsonArray_PrettyPrintTo_Tests, NestedArrays) {
JsonArray nested1 = array.createNestedArray(); JsonArray& nested1 = array.createNestedArray();
nested1.add(1); nested1.add(1);
nested1.add(2); nested1.add(2);
JsonObject nested2 = array.createNestedObject(); JsonObject& nested2 = array.createNestedObject();
nested2["key"] = 3; nested2["key"] = 3;
outputMustBe( outputMustBe(

View File

@ -12,11 +12,12 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonArray_PrintTo_Tests : public testing::Test { class JsonArray_PrintTo_Tests : public testing::Test {
protected: public:
JsonArray array; JsonArray_PrintTo_Tests() : array(json.createArray()) {}
StaticJsonBuffer<3> json;
virtual void SetUp() { array = json.createArray(); } protected:
JsonArray &array;
StaticJsonBuffer<3> json;
void outputMustBe(const char *expected) { void outputMustBe(const char *expected) {
size_t n = array.printTo(buffer, sizeof(buffer)); size_t n = array.printTo(buffer, sizeof(buffer));

View File

@ -14,11 +14,12 @@
using namespace ArduinoJson; using namespace ArduinoJson;
class JsonObject_Container_Tests : public ::testing::Test { class JsonObject_Container_Tests : public ::testing::Test {
protected: public:
virtual void SetUp() { object = json.createObject(); } JsonObject_Container_Tests() : object(json.createObject()) {}
protected:
StaticJsonBuffer<42> json; StaticJsonBuffer<42> json;
JsonObject object; JsonObject& object;
}; };
TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) { TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) {
@ -95,23 +96,23 @@ TEST_F(JsonObject_Container_Tests, CanStoreStrings) {
} }
TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) { TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) {
JsonArray innerarray1 = json.createArray(); JsonArray& innerarray1 = json.createArray();
JsonArray innerarray2 = json.createArray(); JsonArray& innerarray2 = json.createArray();
object["hello"] = innerarray1; object["hello"] = innerarray1;
object["world"] = innerarray2; object["world"] = innerarray2;
EXPECT_EQ(innerarray1, object["hello"].as<JsonArray>()); EXPECT_EQ(&innerarray1, &object["hello"].asArray());
EXPECT_EQ(innerarray2, object["world"].as<JsonArray>()); EXPECT_EQ(&innerarray2, &object["world"].asArray());
} }
TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) { TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) {
JsonObject innerObject1 = json.createObject(); JsonObject& innerObject1 = json.createObject();
JsonObject innerObject2 = json.createObject(); JsonObject& innerObject2 = json.createObject();
object["hello"] = innerObject1; object["hello"] = innerObject1;
object["world"] = innerObject2; object["world"] = innerObject2;
EXPECT_EQ(innerObject1, object["hello"].as<JsonObject>()); EXPECT_EQ(&innerObject1, &object["hello"].asObject());
EXPECT_EQ(innerObject2, object["world"].as<JsonObject>()); EXPECT_EQ(&innerObject2, &object["world"].asObject());
} }

View File

@ -13,7 +13,7 @@ using namespace ArduinoJson;
TEST(JsonObject_Iterator_Test, SimpleTest) { TEST(JsonObject_Iterator_Test, SimpleTest) {
StaticJsonBuffer<42> jsonBuffer; StaticJsonBuffer<42> jsonBuffer;
JsonObject object = jsonBuffer.createObject(); JsonObject &object = jsonBuffer.createObject();
object["ab"] = 12; object["ab"] = 12;
object["cd"] = 34; object["cd"] = 34;
@ -21,12 +21,12 @@ TEST(JsonObject_Iterator_Test, SimpleTest) {
JsonObject::iterator end = object.end(); JsonObject::iterator end = object.end();
EXPECT_NE(end, it); EXPECT_NE(end, it);
EXPECT_STREQ("ab", it->key()); EXPECT_STREQ("ab", it->key);
EXPECT_EQ(12, it->value().as<int>()); EXPECT_EQ(12, it->value.as<int>());
++it; ++it;
EXPECT_NE(end, it); EXPECT_NE(end, it);
EXPECT_STREQ("cd", it->key()); EXPECT_STREQ("cd", it->key);
EXPECT_EQ(34, it->value().as<int>()); EXPECT_EQ(34, it->value.as<int>());
++it; ++it;
EXPECT_EQ(object.end(), it); EXPECT_EQ(object.end(), it);
} }