cleaner assignment behavior
authorSean Middleditch <sean@middleditch.us>
Tue, 12 Jan 2010 09:26:47 +0000 (01:26 -0800)
committerSean Middleditch <sean@middleditch.us>
Tue, 12 Jan 2010 09:26:47 +0000 (01:26 -0800)
janssonxx.h
test.cc

index 873c4a9..6e81241 100644 (file)
@@ -47,10 +47,26 @@ public:
                return Value().take_ownership(json_loads(string, error));
        }
 
+       // construct Value from input
+       static Value from(const char* value) { return Value().take_ownership(json_string(value)); }
+       static Value from(const std::string& value) { return from(value.c_str()); }
+       static Value from(bool value) { return Value().take_ownership(value ? json_true() : json_false()); }
+       static Value from(int value) { return Value().take_ownership(json_integer(value)); }
+       static Value from(double value) { return Value().take_ownership(json_real(value)); }
+
+       // create a new empty object
+       static Value object() { return Value().take_ownership(json_object()); }
+
+       // create a new empty array
+       static Value array() { return Value().take_ownership(json_array()); }
+
+       // create a new null value
+       static Value null() { return Value().take_ownership(json_null()); }
+
        // get the underlying json_t
        json_t* as_json_t() const { return _value; }
 
-       // check Value value type
+       // check value type
        bool is_undefined() const { return _value == 0; }
        bool is_object() const { return json_is_object(_value); }
        bool is_array() const { return json_is_array(_value); }
@@ -73,7 +89,7 @@ public:
                        return 0;
        }
 
-       // get value at array index
+       // get value at array index (const version)
        const Value at(unsigned int index) const {
                if (is_array())
                        return Value(json_array_get(_value, index));
@@ -88,6 +104,21 @@ public:
        const Value operator[](signed long index) const { return at(index); }
        const Value operator[](unsigned long index) const { return at(index); }
 
+       // get value at array index (non-const version)
+       Value at(unsigned int index) {
+               if (is_array())
+                       return Value(json_array_get(_value, index));
+               else
+                       return Value();
+       }
+
+       Value operator[](signed int index) { return at(index); }
+       Value operator[](unsigned int index) { return at(index); }
+       Value operator[](signed short index) { return at(index); }
+       Value operator[](unsigned short index) { return at(index); }
+       Value operator[](signed long index) { return at(index); }
+       Value operator[](unsigned long index) { return at(index); }
+
        // get object property
        const Value get(const char* key) const {
                if (is_object())
@@ -116,34 +147,35 @@ public:
        double as_number() const { return json_number_value(_value); }
        bool as_boolean() const { return is_true(); }
 
-       // assign new string value
-       Value& operator=(const char* value) {
-               json_decref(_value);
-               _value = json_string(value);
-               return *this;
-       }
+       // set an object property (converts value to object is not one already)
+       Value& set(const char* key, const Value& value) {
+               if (!is_object()) {
+                       json_decref(_value);
+                       _value = json_object();
+               }
 
-       // assign new integer value
-       Value& operator=(int value) {
-               json_decref(_value);
-               _value = json_integer(value);
-               return *this;
-       }
+               json_object_set(_value, key, value.as_json_t());
 
-       // assign new real/double/number value
-       Value& operator=(double value) {
-               json_decref(_value);
-               _value = json_real(value);
                return *this;
        }
 
-       // assign new boolean value
-       Value& operator=(bool value) {
-               json_decref(_value);
-               _value = value ? json_true() : json_false();
+       // set an array index (converts value to object is not one already)
+       Value& set(unsigned int index, const Value& value) {
+               if (!is_array()) {
+                       json_decref(_value);
+                       _value = json_array();
+               }
+
+               if (index == size())
+                       json_array_append(_value, value.as_json_t());
+               else
+                       json_array_set(_value, index, value.as_json_t());
+
                return *this;
        }
 
+       Value& set(int index, const Value& value) { return set(static_cast<unsigned int>(index), value); }
+
 private:
        // internal value pointer
        json_t* _value;
diff --git a/test.cc b/test.cc
index 7b44bb0..165589f 100644 (file)
--- a/test.cc
+++ b/test.cc
@@ -50,17 +50,22 @@ int main() {
        i.next();
        ASSERT_FALSE(i.valid(), "iterator has more values than expected");
 
-       e3 = 12.34;
+       e3 = jansson::Value::from(12.34);
        ASSERT_TRUE(e3.is_number(), "e3 is not a number after assignment");
        ASSERT_EQ(e3.as_real(), 12.34, "e3 has incorrect value after assignment");
 
-       e3 = true;
+       e3 = jansson::Value::from(true);
        ASSERT_TRUE(e3.is_boolean(), "e3 is not a boolean after assignment");
        ASSERT_EQ(e3.as_boolean(), true, "e3 has incorrect value after assignment");
 
-       e3 = "foobar";
+       e3 = jansson::Value::from("foobar");
        ASSERT_TRUE(e3.is_string(), "e3 is not a string after assignment");
        ASSERT_EQ(e3.as_string(), "foobar", "e3 has incorrect value after assignment");
 
+       e3.set(0, jansson::Value::from("foobar"));
+       ASSERT_TRUE(e3.is_array(), "e3 is not an array after index assignment");
+       ASSERT_EQ(e3.size(), 1, "e3 has incorrect number of elements after assignment");
+       ASSERT_EQ(e3[0].as_string(), "foobar", "e3[0] has incorrect value after assignment");
+
        return 0;
 }