diff --git a/picojson.h b/picojson.h index f75c399..2e446b8 100644 --- a/picojson.h +++ b/picojson.h @@ -183,6 +183,8 @@ class value { template void serialize(Iter os, bool prettify = false) const; std::string serialize(bool prettify = false) const; + int get_type() const; + private: template value(const T *); // intentionally defined to block implicit conversion of pointer to bool template static void _indent(Iter os, int indent); @@ -634,6 +636,10 @@ inline std::string value::_serialize(int indent) const { return s; } +inline int value::get_type() const { + return type_; +} + template class input { protected: Iter cur_, end_; @@ -1129,6 +1135,147 @@ inline bool operator==(const value &x, const value &y) { inline bool operator!=(const value &x, const value &y) { return !(x == y); } + +class easyjson +{ +public: + + //Constructors + + easyjson() : + internal_value(*new picojson::value()), + needsDelete(true) { + } + + easyjson(picojson::value & v) : + internal_value(v), + needsDelete(false) { + } + + easyjson(bool b): + internal_value(*new picojson::value(b)), + needsDelete(true) { + } + + easyjson(const char * c): + internal_value(*new picojson::value(std::string(c))), + needsDelete(true) { + } + + easyjson(const std::string & s): + internal_value(*new picojson::value(s)), + needsDelete(true) { + } + + easyjson(int value): + internal_value(*new picojson::value(double(value))), + needsDelete(true) { + } + + easyjson(double d): + internal_value(*new picojson::value(d)), + needsDelete(true) { + } + + // Copy constructor + + easyjson(const easyjson & other) : + internal_value(*new picojson::value(other.get_value())), + needsDelete(true) { + get_value() = other.get_value(); + } + + // picojson::value accessor + + const value & get_value() const + { + return internal_value; + } + + value & get_value() + { + return internal_value; + } + + + // Equality operators + + easyjson & operator=(bool b) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == boolean_type); + get_value() = picojson::value(b); + return *this; + } + + easyjson & operator=(const char * c) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == string_type); + get_value() = picojson::value(std::string(c)); + return *this; + } + + easyjson & operator=(const std::string & s) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == string_type); + get_value() = picojson::value(s); + return *this; + } + + easyjson & operator=(int i) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == number_type); + get_value() = picojson::value(double(i)); + return *this; + } + + easyjson & operator=(double d) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == number_type); + get_value() = picojson::value(d); + return *this; + } + + easyjson & operator=(const easyjson & other) { + get_value() = other.get_value(); + return *this; + } + + // Assignment operators + + easyjson operator[](const std::string & s) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == object_type); + + if (get_value().get_type() == null_type) + get_value().set(picojson::value::object()); + + return get_value().get()[std::string(s)]; + } + + easyjson operator[](const char * c) { + return operator[](std::string(c)); + } + + easyjson operator[](picojson::value::array::size_type index) { + PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == array_type); + + if (get_value().get_type() == null_type) { + get_value().set(picojson::value::array(index + 1)); + } + + if (get_value().get().size() <= index) { + get_value().get().resize(index + 1); + } + + return get_value().get().at(index); + } + + ~easyjson() + { + if (needsDelete) + { + delete &internal_value; + } + } +private: + picojson::value & internal_value; + bool needsDelete; +}; + } #if !PICOJSON_USE_RVALUE_REFERENCE diff --git a/test.cc b/test.cc index 0779c55..6e15750 100644 --- a/test.cc +++ b/test.cc @@ -50,7 +50,7 @@ int main(void) // constructors #define TEST(expr, expected) \ is(picojson::value expr .serialize(), string(expected), "picojson::value" #expr) - + TEST( (true), "true"); TEST( (false), "false"); TEST( (42.0), "42"); @@ -73,9 +73,9 @@ int main(void) a *= 2; } } - + #undef TEST - + #define TEST(in, type, cmp, serialize_test) { \ picojson::value v; \ const char* s = in; \ @@ -116,7 +116,7 @@ int main(void) TEST(array, "[]"); TEST(object, "{}"); #undef TEST - + { picojson::value v; const char *s = "[1,true,\"hello\"]"; @@ -135,7 +135,7 @@ int main(void) is(v.get(2).get(), string("hello"), "check array[2] value"); _ok(!v.contains(3), "check not contains array[3]"); } - + { picojson::value v; const char *s = "{ \"a\": true }"; @@ -173,7 +173,7 @@ int main(void) TEST("\n\bbell", "2 near: bell"); TEST("\"abc\nd\"", "1 near: "); #undef TEST - + { picojson::value v1, v2; const char *s; @@ -226,7 +226,7 @@ int main(void) _ok(picojson::value(3.0).serialize() == "3", "integral number should be serialized as a integer"); - + { const char* s = "{ \"a\": [1,2], \"d\": 2 }"; picojson::null_parse_context ctx; @@ -234,7 +234,7 @@ int main(void) picojson::_parse(ctx, s, s + strlen(s), &err); _ok(err.empty(), "null_parse_context"); } - + { picojson::value v1, v2; v1 = picojson::value(true); @@ -254,7 +254,7 @@ int main(void) _ok(v1.is(), "swap (array)"); _ok(v2.is(), "swap (object)"); } - + { picojson::value v; const char *s = "{ \"a\": 1, \"b\": [ 2, { \"b1\": \"abc\" } ], \"c\": {}, \"d\": [] }"; @@ -344,5 +344,69 @@ int main(void) is(*reststr, 'a', "should point at the next char"); } + { + picojson::easyjson v("foo"); + _ok(v.get_value().get() == "foo", "equals value"); + v = "bar"; + _ok(v.get_value().get() == "bar", "equals value"); + } + + { + picojson::easyjson v(std::string("foo")); + _ok(v.get_value().get() == "foo", "equals value"); + v = std::string("bar"); + _ok(v.get_value().get() == "bar", "equals value"); + } + + { + picojson::easyjson v(1); + _ok(v.get_value().get() == 1, "equals value"); + v = 2; + _ok(v.get_value().get() == 2, "equals value"); + } + + { + picojson::easyjson v(1.0f); + _ok(v.get_value().get() == 1.0f, "equals value"); + v = 2.0f; + _ok(v.get_value().get() == 2.0f, "equals value"); + } + + { + picojson::easyjson v(1.0); + _ok(v.get_value().get() == 1.0, "equals value"); + v = 2.0; + _ok(v.get_value().get() == 2.0, "equals value"); + } + + { + picojson::easyjson v; + v["foo"] = 12; + _ok(v["foo"].get_value().get() == 12, "equals value"); + } + + { + picojson::easyjson v; + v[12] = "foo"; + _ok(v[12].get_value().get() == "foo", "equals value"); + } + + { + picojson::easyjson v, v_equal; + v["foo"] = "bar"; + v_equal = v; + picojson::easyjson v_copy(v); + + _ok(v["foo"].get_value().get() == v_copy["foo"].get_value().get(), "copy equals original"); + _ok(v["foo"].get_value().get() == v_equal["foo"].get_value().get(), "equality assigned to original"); + + v_copy["foo"] = "baz"; + v_equal["foo"] = "picojson rocks !"; + + _ok(v["foo"].get_value().get() == "bar", "original not modified"); + _ok(v_copy["foo"].get_value().get() == "baz", "changed value in copy is OK"); + _ok(v_equal["foo"].get_value().get() == "picojson rocks !", "changed value after equality is OK"); + } + return done_testing(); }