Esempio n. 1
0
static void
test_struct (void) {

    xmlrpc_env env;
    xmlrpc_value * value1P;
    xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value;
    size_t size;
    int present;
    xmlrpc_bool bval;
    char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'};

    xmlrpc_env_init(&env);

    /* Create a struct. */
    s = xmlrpc_struct_new(&env);
    TEST_NO_FAULT(&env);
    TEST(s != NULL);
    TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 0);

    /* Create some elements to insert into our struct. */
    i1 = xmlrpc_build_value(&env, "s", "Item #1");
    TEST_NO_FAULT(&env);
    i2 = xmlrpc_build_value(&env, "s", "Item #2");
    TEST_NO_FAULT(&env);
    i3 = xmlrpc_build_value(&env, "s", "Item #3");
    TEST_NO_FAULT(&env);

    /* Insert a single item. */
    xmlrpc_struct_set_value(&env, s, "foo", i1);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 1);

    /* Insert an item whose key has the same hash value as "foo". */
    xmlrpc_struct_set_value(&env, s, "qmdebdw", i2);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 2);
    i = xmlrpc_struct_get_value(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(i == i1);
    i = xmlrpc_struct_get_value(&env, s, "qmdebdw");
    TEST_NO_FAULT(&env);
    TEST(i == i2);

    /* Replace an existing element with a different element. */
    xmlrpc_struct_set_value(&env, s, "foo", i3);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 2);
    i = xmlrpc_struct_get_value(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(i == i3);

    /* Insert an item with a NUL in the key */
    xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);

    test_struct_get_element(s, i3, i2, weirdKey, sizeof(weirdKey));

    /* Replace an existing element with the same element (tricky). */
    xmlrpc_struct_set_value(&env, s, "foo", i3);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);
    i = xmlrpc_struct_get_value(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(i == i3);

    /* Test for the presence and absence of elements. */
    present = xmlrpc_struct_has_key(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "qmdebdw");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "bogus");
    TEST_NO_FAULT(&env);
    TEST(!present);

    /* Make sure our typechecks work correctly. */
    xmlrpc_struct_size(&env, i1);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_has_key(&env, i1, "foo");
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_set_value(&env, i1, "foo", i2);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_set_value_v(&env, s, s, i2);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    /* Test cleanup code (w/memprof). */
    xmlrpc_DECREF(s);

    s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}",
                           "foo", "Hello!",
                           "bar", (xmlrpc_int32) 1,
                           "baz", (xmlrpc_bool) 0);
    TEST_NO_FAULT(&env);
    TEST(s != NULL);
    TEST(xmlrpc_value_type(s) == XMLRPC_TYPE_STRUCT);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);
    present = xmlrpc_struct_has_key(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "bar");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "baz");
    TEST_NO_FAULT(&env);
    TEST(present);
    xmlrpc_struct_read_value(&env, s, "baz", &value1P);
    TEST_NO_FAULT(&env);
    xmlrpc_read_bool(&env, value1P, &bval);
    TEST_NO_FAULT(&env);
    TEST(!bval);
    xmlrpc_DECREF(value1P);

    testStructReadout(s, 3);

    test_struct_decompose(s);

    /* Test type check. */
    xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
    TEST(key == NULL && value == NULL);
    
    /* Test bounds checks. */
    xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value);
    TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
    TEST(key == NULL && value == NULL);

    xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value);
    TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
    TEST(key == NULL && value == NULL);
    
    /* Test cleanup code (w/memprof). */
    xmlrpc_DECREF(s);

    xmlrpc_DECREF(i1);
    xmlrpc_DECREF(i2);
    xmlrpc_DECREF(i3);
    xmlrpc_env_clean(&env);
}
static void
test_struct (void) {

    xmlrpc_env env;
    xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value;
    size_t size;
    int present;
    xmlrpc_int32 ival;
    xmlrpc_bool bval;
    char *sval;
    char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'};

    xmlrpc_env_init(&env);

    /* Create a struct. */
    s = xmlrpc_struct_new(&env);
    TEST_NO_FAULT(&env);
    TEST(s != NULL);
    TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 0);

    /* Create some elements to insert into our struct. */
    i1 = xmlrpc_build_value(&env, "s", "Item #1");
    TEST_NO_FAULT(&env);
    i2 = xmlrpc_build_value(&env, "s", "Item #2");
    TEST_NO_FAULT(&env);
    i3 = xmlrpc_build_value(&env, "s", "Item #3");
    TEST_NO_FAULT(&env);

    /* Insert a single item. */
    xmlrpc_struct_set_value(&env, s, "foo", i1);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 1);

    /* Insert two more items with conflicting hash codes. (We assume that
    ** nobody has changed the hash function.) */
    xmlrpc_struct_set_value(&env, s, "bar", i2);
    TEST_NO_FAULT(&env);
    xmlrpc_struct_set_value(&env, s, "aas", i3);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);

    /* Replace an existing element with a different element. */
    xmlrpc_struct_set_value(&env, s, "aas", i1);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);

    /* Insert an item with a NUL in the key */
    xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 4);

    test_struct_get_element(s, i1, i2, weirdKey, sizeof(weirdKey));

    /* Replace an existing element with the same element (tricky). */
    xmlrpc_struct_set_value(&env, s, "aas", i1);
    TEST_NO_FAULT(&env);
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 4);
    i = xmlrpc_struct_get_value(&env, s, "aas");
    TEST_NO_FAULT(&env);
    TEST(i == i1);

    /* Test for the presence and absence of elements. */
    present = xmlrpc_struct_has_key(&env, s, "aas");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "bogus");
    TEST_NO_FAULT(&env);
    TEST(!present);

    /* Make sure our typechecks work correctly. */
    xmlrpc_struct_size(&env, i1);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_has_key(&env, i1, "foo");
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_set_value(&env, i1, "foo", i2);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    xmlrpc_struct_set_value_v(&env, s, s, i2);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    /* Test cleanup code (w/memprof). */
    xmlrpc_DECREF(s);

    /* Build a struct using our automagic struct builder. */
    s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}",
                           "foo", "Hello!",
                           "bar", (xmlrpc_int32) 1,
                           "baz", (xmlrpc_bool) 0);
    TEST_NO_FAULT(&env);
    TEST(s != NULL);
    TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
    size = xmlrpc_struct_size(&env, s);
    TEST_NO_FAULT(&env);
    TEST(size == 3);
    present = xmlrpc_struct_has_key(&env, s, "foo");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "bar");
    TEST_NO_FAULT(&env);
    TEST(present);
    present = xmlrpc_struct_has_key(&env, s, "baz");
    TEST_NO_FAULT(&env);
    TEST(present);
    i = xmlrpc_struct_get_value(&env, s, "baz");
    TEST_NO_FAULT(&env);
    xmlrpc_decompose_value(&env, i, "b", &bval);
    TEST_NO_FAULT(&env);
    TEST(!bval);

    testStructReadout(s, 3);

    /* Test our automagic struct parser. */
    xmlrpc_decompose_value(&env, s, "{s:b,s:s,s:i,*}",
                           "baz", &bval,
                           "foo", &sval,
                           "bar", &ival);
    TEST_NO_FAULT(&env);
    TEST(ival == 1);
    TEST(!bval);
    TEST(strcmp(sval, "Hello!") == 0);
    free(sval);

    /* Test automagic struct parser with value of wrong type. */
    xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
                           "baz", &bval,
                           "foo", &sval);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);

    /* Test automagic struct parser with bad key. */
    xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
                           "baz", &bval,
                           "nosuch", &sval);
    TEST_FAULT(&env, XMLRPC_INDEX_ERROR);

    /* Test type check. */
    xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
    TEST(key == NULL && value == NULL);
    
    /* Test bounds checks. */
    xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value);
    TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
    TEST(key == NULL && value == NULL);

    xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value);
    TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
    TEST(key == NULL && value == NULL);
    
    /* Test cleanup code (w/memprof). */
    xmlrpc_DECREF(s);

    xmlrpc_DECREF(i1);
    xmlrpc_DECREF(i2);
    xmlrpc_DECREF(i3);
    xmlrpc_env_clean(&env);
}