Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding easy way to write json #103

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions picojson.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ class value {
template <typename Iter> void serialize(Iter os, bool prettify = false) const;
std::string serialize(bool prettify = false) const;

int get_type() const;

private:
template <typename T> value(const T *); // intentionally defined to block implicit conversion of pointer to bool
template <typename Iter> static void _indent(Iter os, int indent);
Expand Down Expand Up @@ -634,6 +636,10 @@ inline std::string value::_serialize(int indent) const {
return s;
}

inline int value::get_type() const {
return type_;
}

template <typename Iter> class input {
protected:
Iter cur_, end_;
Expand Down Expand Up @@ -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>(picojson::value::object());

return get_value().get<picojson::value::object>()[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>(picojson::value::array(index + 1));
}

if (get_value().get<picojson::value::array>().size() <= index) {
get_value().get<picojson::value::array>().resize(index + 1);
}

return get_value().get<picojson::value::array>().at(index);
}

~easyjson()
{
if (needsDelete)
{
delete &internal_value;
}
}
private:
picojson::value & internal_value;
bool needsDelete;
};

}

#if !PICOJSON_USE_RVALUE_REFERENCE
Expand Down
82 changes: 73 additions & 9 deletions test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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; \
Expand Down Expand Up @@ -116,7 +116,7 @@ int main(void)
TEST(array, "[]");
TEST(object, "{}");
#undef TEST

{
picojson::value v;
const char *s = "[1,true,\"hello\"]";
Expand All @@ -135,7 +135,7 @@ int main(void)
is(v.get(2).get<string>(), string("hello"), "check array[2] value");
_ok(!v.contains(3), "check not contains array[3]");
}

{
picojson::value v;
const char *s = "{ \"a\": true }";
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -226,15 +226,15 @@ 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;
string err;
picojson::_parse(ctx, s, s + strlen(s), &err);
_ok(err.empty(), "null_parse_context");
}

{
picojson::value v1, v2;
v1 = picojson::value(true);
Expand All @@ -254,7 +254,7 @@ int main(void)
_ok(v1.is<picojson::array>(), "swap (array)");
_ok(v2.is<picojson::object>(), "swap (object)");
}

{
picojson::value v;
const char *s = "{ \"a\": 1, \"b\": [ 2, { \"b1\": \"abc\" } ], \"c\": {}, \"d\": [] }";
Expand Down Expand Up @@ -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<std::string>() == "foo", "equals value");
v = "bar";
_ok(v.get_value().get<std::string>() == "bar", "equals value");
}

{
picojson::easyjson v(std::string("foo"));
_ok(v.get_value().get<std::string>() == "foo", "equals value");
v = std::string("bar");
_ok(v.get_value().get<std::string>() == "bar", "equals value");
}

{
picojson::easyjson v(1);
_ok(v.get_value().get<double>() == 1, "equals value");
v = 2;
_ok(v.get_value().get<double>() == 2, "equals value");
}

{
picojson::easyjson v(1.0f);
_ok(v.get_value().get<double>() == 1.0f, "equals value");
v = 2.0f;
_ok(v.get_value().get<double>() == 2.0f, "equals value");
}

{
picojson::easyjson v(1.0);
_ok(v.get_value().get<double>() == 1.0, "equals value");
v = 2.0;
_ok(v.get_value().get<double>() == 2.0, "equals value");
}

{
picojson::easyjson v;
v["foo"] = 12;
_ok(v["foo"].get_value().get<double>() == 12, "equals value");
}

{
picojson::easyjson v;
v[12] = "foo";
_ok(v[12].get_value().get<std::string>() == "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<std::string>() == v_copy["foo"].get_value().get<std::string>(), "copy equals original");
_ok(v["foo"].get_value().get<std::string>() == v_equal["foo"].get_value().get<std::string>(), "equality assigned to original");

v_copy["foo"] = "baz";
v_equal["foo"] = "picojson rocks !";

_ok(v["foo"].get_value().get<std::string>() == "bar", "original not modified");
_ok(v_copy["foo"].get_value().get<std::string>() == "baz", "changed value in copy is OK");
_ok(v_equal["foo"].get_value().get<std::string>() == "picojson rocks !", "changed value after equality is OK");
}

return done_testing();
}