2 * Copyright (c) 2010-2016 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This is a test of libheimbase functionality. If you make any changes
38 * to libheimbase or to this test you should run it under valgrind with
39 * the following options:
41 * -v --track-fds=yes --num-callers=30 --leak-check=full
43 * and make sure that there are no leaks that don't have
44 * __heim_string_constant() or heim_db_register() in their stack trace.
52 #include <sys/types.h>
68 memory_free(heim_object_t obj
)
77 ptr
= heim_alloc(10, "memory", memory_free
);
87 ptr
= heim_alloc(10, "memory", NULL
);
96 HEIMDAL_MUTEX m
= HEIMDAL_MUTEX_INITIALIZER
;
98 HEIMDAL_MUTEX_lock(&m
);
99 HEIMDAL_MUTEX_unlock(&m
);
100 HEIMDAL_MUTEX_destroy(&m
);
102 HEIMDAL_MUTEX_init(&m
);
103 HEIMDAL_MUTEX_lock(&m
);
104 HEIMDAL_MUTEX_unlock(&m
);
105 HEIMDAL_MUTEX_destroy(&m
);
113 HEIMDAL_RWLOCK l
= HEIMDAL_RWLOCK_INITIALIZER
;
115 HEIMDAL_RWLOCK_rdlock(&l
);
116 HEIMDAL_RWLOCK_unlock(&l
);
117 HEIMDAL_RWLOCK_wrlock(&l
);
118 HEIMDAL_RWLOCK_unlock(&l
);
119 if (HEIMDAL_RWLOCK_trywrlock(&l
) != 0)
120 err(1, "HEIMDAL_RWLOCK_trywrlock() failed with lock not held");
121 HEIMDAL_RWLOCK_unlock(&l
);
122 if (HEIMDAL_RWLOCK_tryrdlock(&l
))
123 err(1, "HEIMDAL_RWLOCK_tryrdlock() failed with lock not held");
124 HEIMDAL_RWLOCK_unlock(&l
);
125 HEIMDAL_RWLOCK_destroy(&l
);
127 HEIMDAL_RWLOCK_init(&l
);
128 HEIMDAL_RWLOCK_rdlock(&l
);
129 HEIMDAL_RWLOCK_unlock(&l
);
130 HEIMDAL_RWLOCK_wrlock(&l
);
131 HEIMDAL_RWLOCK_unlock(&l
);
132 if (HEIMDAL_RWLOCK_trywrlock(&l
))
133 err(1, "HEIMDAL_RWLOCK_trywrlock() failed with lock not held");
134 HEIMDAL_RWLOCK_unlock(&l
);
135 if (HEIMDAL_RWLOCK_tryrdlock(&l
))
136 err(1, "HEIMDAL_RWLOCK_tryrdlock() failed with lock not held");
137 HEIMDAL_RWLOCK_unlock(&l
);
138 HEIMDAL_RWLOCK_destroy(&l
);
147 heim_number_t a1
= heim_number_create(1);
148 heim_string_t a2
= heim_string_create("hejsan");
149 heim_number_t a3
= heim_number_create(3);
150 heim_string_t a4
= heim_string_create("foosan");
152 dict
= heim_dict_create(10);
154 heim_dict_set_value(dict
, a1
, a2
);
155 heim_dict_set_value(dict
, a3
, a4
);
157 heim_dict_delete_key(dict
, a3
);
158 heim_dict_delete_key(dict
, a1
);
171 test_auto_release(void)
173 heim_auto_release_t ar1
, ar2
;
177 ar1
= heim_auto_release_create();
179 s1
= heim_string_create("hejsan");
180 heim_auto_release(s1
);
182 n1
= heim_number_create(1);
183 heim_auto_release(n1
);
185 ar2
= heim_auto_release_create();
187 n1
= heim_number_create(1);
188 heim_auto_release(n1
);
199 heim_string_t s1
, s2
;
200 const char *string
= "hejsan";
202 s1
= heim_string_create(string
);
203 s2
= heim_string_create(string
);
205 if (heim_cmp(s1
, s2
) != 0) {
206 printf("the same string is not the same\n");
222 e
= heim_error_create(10, "foo: %s", "bar");
223 heim_assert(heim_error_get_code(e
) == 10, "error_code != 10");
225 s
= heim_error_copy_string(e
);
226 heim_assert(strcmp(heim_string_get_utf8(s
), "foo: bar") == 0, "msg wrong");
238 "{ \"k1\" : \"s1\", \"k2\" : \"s2\" }",
239 "{ \"k1\" : [\"s1\", \"s2\", \"s3\"], \"k2\" : \"s3\" }",
240 "{ \"k1\" : {\"k2\":\"s1\",\"k3\":\"s2\",\"k4\":\"s3\"}, \"k5\" : \"s4\" }",
241 "[ \"v1\", \"v2\", [\"v3\",\"v4\",[\"v 5\",\" v 7 \"]], -123456789, "
242 "null, true, false, 123456789, \"\"]",
248 heim_string_t k1
= heim_string_create("k1");
250 o
= heim_json_create("\"string\"", 10, 0, NULL
);
251 heim_assert(o
!= NULL
, "string");
252 heim_assert(heim_get_tid(o
) == heim_string_get_type_id(), "string-tid");
253 heim_assert(strcmp("string", heim_string_get_utf8(o
)) == 0, "wrong string");
256 o
= heim_json_create(" \"foo\\\"bar\" ]", 10, 0, NULL
);
257 heim_assert(o
!= NULL
, "string");
258 heim_assert(heim_get_tid(o
) == heim_string_get_type_id(), "string-tid");
259 heim_assert(strcmp("foo\"bar", heim_string_get_utf8(o
)) == 0, "wrong string");
262 o
= heim_json_create(" { \"key\" : \"value\" }", 10, 0, NULL
);
263 heim_assert(o
!= NULL
, "dict");
264 heim_assert(heim_get_tid(o
) == heim_dict_get_type_id(), "dict-tid");
267 o
= heim_json_create("{ { \"k1\" : \"s1\", \"k2\" : \"s2\" } : \"s3\", "
268 "{ \"k3\" : \"s4\" } : -1 }", 10, 0, NULL
);
269 heim_assert(o
!= NULL
, "dict");
270 heim_assert(heim_get_tid(o
) == heim_dict_get_type_id(), "dict-tid");
273 o
= heim_json_create("{ { \"k1\" : \"s1\", \"k2\" : \"s2\" } : \"s3\", "
274 "{ \"k3\" : \"s4\" } : -1 }", 10,
275 HEIM_JSON_F_STRICT_DICT
, NULL
);
276 heim_assert(o
== NULL
, "dict");
278 o
= heim_json_create(" { \"k1\" : \"s1\", \"k2\" : \"s2\" }", 10, 0, NULL
);
279 heim_assert(o
!= NULL
, "dict");
280 heim_assert(heim_get_tid(o
) == heim_dict_get_type_id(), "dict-tid");
281 o2
= heim_dict_copy_value(o
, k1
);
282 heim_assert(heim_get_tid(o2
) == heim_string_get_type_id(), "string-tid");
286 o
= heim_json_create(" { \"k1\" : { \"k2\" : \"s2\" } }", 10, 0, NULL
);
287 heim_assert(o
!= NULL
, "dict");
288 heim_assert(heim_get_tid(o
) == heim_dict_get_type_id(), "dict-tid");
289 o2
= heim_dict_copy_value(o
, k1
);
290 heim_assert(heim_get_tid(o2
) == heim_dict_get_type_id(), "dict-tid");
294 o
= heim_json_create("{ \"k1\" : 1 }", 10, 0, NULL
);
295 heim_assert(o
!= NULL
, "array");
296 heim_assert(heim_get_tid(o
) == heim_dict_get_type_id(), "dict-tid");
297 o2
= heim_dict_copy_value(o
, k1
);
298 heim_assert(heim_get_tid(o2
) == heim_number_get_type_id(), "number-tid");
302 o
= heim_json_create("-10", 10, 0, NULL
);
303 heim_assert(o
!= NULL
, "number");
304 heim_assert(heim_get_tid(o
) == heim_number_get_type_id(), "number-tid");
307 o
= heim_json_create("99", 10, 0, NULL
);
308 heim_assert(o
!= NULL
, "number");
309 heim_assert(heim_get_tid(o
) == heim_number_get_type_id(), "number-tid");
312 o
= heim_json_create(" [ 1 ]", 10, 0, NULL
);
313 heim_assert(o
!= NULL
, "array");
314 heim_assert(heim_get_tid(o
) == heim_array_get_type_id(), "array-tid");
317 o
= heim_json_create(" [ -1 ]", 10, 0, NULL
);
318 heim_assert(o
!= NULL
, "array");
319 heim_assert(heim_get_tid(o
) == heim_array_get_type_id(), "array-tid");
322 for (i
= 0; i
< (sizeof (j
) / sizeof (j
[0])); i
++) {
323 o
= heim_json_create(j
[i
], 10, 0, NULL
);
325 fprintf(stderr
, "Failed to parse this JSON: %s\n", j
[i
]);
329 /* Simple fuzz test */
330 for (k
= strlen(j
[i
]) - 1; k
> 0; k
--) {
331 o
= heim_json_create_with_bytes(j
[i
], k
, 10, 0, NULL
);
333 fprintf(stderr
, "Invalid JSON parsed: %.*s\n", (int)k
, j
[i
]);
337 /* Again, but this time make it so valgrind can find invalid accesses */
338 for (k
= strlen(j
[i
]) - 1; k
> 0; k
--) {
339 s
= strndup(j
[i
], k
);
342 o
= heim_json_create(s
, 10, 0, NULL
);
345 fprintf(stderr
, "Invalid JSON parsed: %s\n", j
[i
]);
349 /* Again, but with no NUL termination */
350 for (k
= strlen(j
[i
]) - 1; k
> 0; k
--) {
355 o
= heim_json_create_with_bytes(s
, k
, 10, 0, NULL
);
358 fprintf(stderr
, "Invalid JSON parsed: %s\n", j
[i
]);
372 heim_dict_t dict
= heim_dict_create(11);
373 heim_string_t p1
= heim_string_create("abc");
374 heim_string_t p2a
= heim_string_create("def");
375 heim_string_t p2b
= heim_string_create("DEF");
376 heim_number_t p3
= heim_number_create(0);
377 heim_string_t p4a
= heim_string_create("ghi");
378 heim_string_t p4b
= heim_string_create("GHI");
379 heim_array_t a
= heim_array_create();
380 heim_number_t l1
= heim_number_create(42);
381 heim_number_t l2
= heim_number_create(813);
382 heim_number_t l3
= heim_number_create(1234);
383 heim_string_t k1
= heim_string_create("k1");
384 heim_string_t k2
= heim_string_create("k2");
385 heim_string_t k3
= heim_string_create("k3");
386 heim_string_t k2_1
= heim_string_create("k2-1");
387 heim_string_t k2_2
= heim_string_create("k2-2");
388 heim_string_t k2_3
= heim_string_create("k2-3");
389 heim_string_t k2_4
= heim_string_create("k2-4");
390 heim_string_t k2_5
= heim_string_create("k2-5");
391 heim_string_t k2_5_1
= heim_string_create("k2-5-1");
393 heim_object_t neg_num
;
396 if (!dict
|| !p1
|| !p2a
|| !p2b
|| !p4a
|| !p4b
)
399 ret
= heim_path_create(dict
, 11, a
, NULL
, p1
, p2a
, NULL
);
403 ret
= heim_path_create(dict
, 11, l3
, NULL
, p1
, p2b
, NULL
);
406 o
= heim_path_get(dict
, NULL
, p1
, p2b
, NULL
);
409 ret
= heim_path_create(dict
, 11, NULL
, NULL
, p1
, p2a
, p3
, NULL
);
412 ret
= heim_path_create(dict
, 11, l1
, NULL
, p1
, p2a
, p3
, p4a
, NULL
);
415 ret
= heim_path_create(dict
, 11, l2
, NULL
, p1
, p2a
, p3
, p4b
, NULL
);
419 o
= heim_path_get(dict
, NULL
, p1
, p2a
, p3
, p4a
, NULL
);
422 o
= heim_path_get(dict
, NULL
, p1
, p2a
, p3
, p4b
, NULL
);
428 /* Test that JSON parsing works right by using heim_path_get() */
429 dict
= heim_json_create("{\"k1\":1,"
430 "\"k2\":{\"k2-1\":21,"
434 "\"k2-5\":[1,2,3,{\"k2-5-1\":-1},-2]},"
435 "\"k3\":[true,false,0,42]}", 10, 0, NULL
);
436 heim_assert(dict
!= NULL
, "dict");
437 o
= heim_path_get(dict
, NULL
, k1
, NULL
);
438 if (heim_cmp(o
, heim_number_create(1))) return 1;
439 o
= heim_path_get(dict
, NULL
, k2
, NULL
);
440 if (heim_get_tid(o
) != heim_dict_get_type_id()) return 1;
441 o
= heim_path_get(dict
, NULL
, k2
, k2_1
, NULL
);
442 if (heim_cmp(o
, heim_number_create(21))) return 1;
443 o
= heim_path_get(dict
, NULL
, k2
, k2_2
, NULL
);
444 if (heim_cmp(o
, heim_null_create())) return 1;
445 o
= heim_path_get(dict
, NULL
, k2
, k2_3
, NULL
);
446 if (heim_cmp(o
, heim_bool_create(1))) return 1;
447 o
= heim_path_get(dict
, NULL
, k2
, k2_4
, NULL
);
448 if (heim_cmp(o
, heim_bool_create(0))) return 1;
449 o
= heim_path_get(dict
, NULL
, k2
, k2_5
, NULL
);
450 if (heim_get_tid(o
) != heim_array_get_type_id()) return 1;
451 o
= heim_path_get(dict
, NULL
, k2
, k2_5
, heim_number_create(0), NULL
);
452 if (heim_cmp(o
, heim_number_create(1))) return 1;
453 o
= heim_path_get(dict
, NULL
, k2
, k2_5
, heim_number_create(1), NULL
);
454 if (heim_cmp(o
, heim_number_create(2))) return 1;
455 o
= heim_path_get(dict
, NULL
, k2
, k2_5
, heim_number_create(3), k2_5_1
, NULL
);
456 if (heim_cmp(o
, neg_num
= heim_number_create(-1))) return 1;
457 heim_release(neg_num
);
458 o
= heim_path_get(dict
, NULL
, k2
, k2_5
, heim_number_create(4), NULL
);
459 if (heim_cmp(o
, neg_num
= heim_number_create(-2))) return 1;
460 heim_release(neg_num
);
461 o
= heim_path_get(dict
, NULL
, k3
, heim_number_create(3), NULL
);
462 if (heim_cmp(o
, heim_number_create(42))) return 1;
478 heim_release(k2_5_1
);
483 typedef struct dict_db
{
489 dict_db_open(void *plug
, const char *dbtype
, const char *dbname
,
490 heim_dict_t options
, void **db
, heim_error_t
*error
)
493 heim_dict_t contents
= NULL
;
497 if (dbtype
&& *dbtype
&& strcmp(dbtype
, "dictdb"))
499 if (dbname
&& *dbname
&& strcmp(dbname
, "MEMORY") != 0)
501 dictdb
= heim_alloc(sizeof (*dictdb
), "dict_db", NULL
);
505 if (contents
!= NULL
)
506 dictdb
->dict
= contents
;
508 dictdb
->dict
= heim_dict_create(29);
509 if (dictdb
->dict
== NULL
) {
510 heim_release(dictdb
);
520 dict_db_close(void *db
, heim_error_t
*error
)
522 dict_db_t dictdb
= db
;
526 heim_release(dictdb
->dict
);
527 heim_release(dictdb
);
532 dict_db_lock(void *db
, int read_only
, heim_error_t
*error
)
534 dict_db_t dictdb
= db
;
545 dict_db_unlock(void *db
, heim_error_t
*error
)
547 dict_db_t dictdb
= db
;
556 dict_db_copy_value(void *db
, heim_string_t table
, heim_data_t key
,
559 dict_db_t dictdb
= db
;
564 return heim_retain(heim_path_get(dictdb
->dict
, error
, table
, key
, NULL
));
568 dict_db_set_value(void *db
, heim_string_t table
,
569 heim_data_t key
, heim_data_t value
, heim_error_t
*error
)
571 dict_db_t dictdb
= db
;
579 return heim_path_create(dictdb
->dict
, 29, value
, error
, table
, key
, NULL
);
583 dict_db_del_key(void *db
, heim_string_t table
, heim_data_t key
,
586 dict_db_t dictdb
= db
;
594 heim_path_delete(dictdb
->dict
, error
, table
, key
, NULL
);
598 struct dict_db_iter_ctx
{
599 heim_db_iterator_f_t iter_f
;
603 static void dict_db_iter_f(heim_object_t key
, heim_object_t value
, void *arg
)
605 struct dict_db_iter_ctx
*ctx
= arg
;
607 ctx
->iter_f((heim_object_t
)key
, (heim_object_t
)value
, ctx
->iter_ctx
);
611 dict_db_iter(void *db
, heim_string_t table
, void *iter_data
,
612 heim_db_iterator_f_t iter_f
, heim_error_t
*error
)
614 dict_db_t dictdb
= db
;
615 struct dict_db_iter_ctx ctx
;
616 heim_dict_t table_dict
;
624 table_dict
= heim_dict_copy_value(dictdb
->dict
, table
);
625 if (table_dict
== NULL
)
628 ctx
.iter_ctx
= iter_data
;
631 heim_dict_iterate_f(table_dict
, &ctx
, dict_db_iter_f
);
632 heim_release(table_dict
);
636 test_db_iter(heim_data_t k
, heim_data_t v
, void *arg
)
639 const void *kptr
, *vptr
;
642 heim_assert(heim_get_tid(k
) == heim_data_get_type_id(), "...");
644 kptr
= heim_data_get_ptr(k
);
645 klen
= heim_data_get_length(k
);
646 vptr
= heim_data_get_ptr(v
);
647 vlen
= heim_data_get_length(v
);
649 if (klen
== strlen("msg") && !strncmp(kptr
, "msg", strlen("msg")) &&
650 vlen
== strlen("abc") && !strncmp(vptr
, "abc", strlen("abc")))
652 else if (klen
== strlen("msg2") &&
653 !strncmp(kptr
, "msg2", strlen("msg2")) &&
654 vlen
== strlen("FooBar") && !strncmp(vptr
, "FooBar", strlen("FooBar")))
660 static struct heim_db_type dbt
= {
661 1, dict_db_open
, NULL
, dict_db_close
,
662 dict_db_lock
, dict_db_unlock
, NULL
, NULL
, NULL
, NULL
,
663 dict_db_copy_value
, dict_db_set_value
,
664 dict_db_del_key
, dict_db_iter
668 test_db(const char *dbtype
, const char *dbname
)
670 heim_data_t k1
, k2
, v
, v1
, v2
, v3
;
674 if (dbtype
== NULL
) {
675 ret
= heim_db_register("dictdb", NULL
, &dbt
);
676 heim_assert(!ret
, "...");
677 db
= heim_db_create("dictdb", "foo", NULL
, NULL
);
678 heim_assert(!db
, "...");
679 db
= heim_db_create("foobar", "MEMORY", NULL
, NULL
);
680 heim_assert(!db
, "...");
681 db
= heim_db_create("dictdb", "MEMORY", NULL
, NULL
);
682 heim_assert(db
, "...");
686 options
= heim_dict_create(11);
687 if (options
== NULL
) return ENOMEM
;
688 if (heim_dict_set_value(options
, HSTR("journal-filename"),
689 HSTR("json-journal")))
691 if (heim_dict_set_value(options
, HSTR("create"), heim_null_create()))
693 if (heim_dict_set_value(options
, HSTR("truncate"), heim_null_create()))
695 db
= heim_db_create(dbtype
, dbname
, options
, NULL
);
696 heim_assert(db
, "...");
697 heim_release(options
);
700 k1
= heim_data_create("msg", strlen("msg"));
701 k2
= heim_data_create("msg2", strlen("msg2"));
702 v1
= heim_data_create("Hello world!", strlen("Hello world!"));
703 v2
= heim_data_create("FooBar", strlen("FooBar"));
704 v3
= heim_data_create("abc", strlen("abc"));
706 ret
= heim_db_set_value(db
, NULL
, k1
, v1
, NULL
);
707 heim_assert(!ret
, "...");
709 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
710 heim_assert(v
&& !heim_cmp(v
, v1
), "...");
713 ret
= heim_db_set_value(db
, NULL
, k2
, v2
, NULL
);
714 heim_assert(!ret
, "...");
716 v
= heim_db_copy_value(db
, NULL
, k2
, NULL
);
717 heim_assert(v
&& !heim_cmp(v
, v2
), "...");
720 ret
= heim_db_set_value(db
, NULL
, k1
, v3
, NULL
);
721 heim_assert(!ret
, "...");
723 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
724 heim_assert(v
&& !heim_cmp(v
, v3
), "...");
728 heim_db_iterate_f(db
, NULL
, &ret
, test_db_iter
, NULL
);
729 heim_assert(!ret
, "...");
731 ret
= heim_db_begin(db
, 0, NULL
);
732 heim_assert(!ret
, "...");
734 ret
= heim_db_commit(db
, NULL
);
735 heim_assert(!ret
, "...");
737 ret
= heim_db_begin(db
, 0, NULL
);
738 heim_assert(!ret
, "...");
740 ret
= heim_db_rollback(db
, NULL
);
741 heim_assert(!ret
, "...");
743 ret
= heim_db_begin(db
, 0, NULL
);
744 heim_assert(!ret
, "...");
746 ret
= heim_db_set_value(db
, NULL
, k1
, v1
, NULL
);
747 heim_assert(!ret
, "...");
749 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
750 heim_assert(v
&& !heim_cmp(v
, v1
), "...");
753 ret
= heim_db_rollback(db
, NULL
);
754 heim_assert(!ret
, "...");
756 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
757 heim_assert(v
&& !heim_cmp(v
, v3
), "...");
760 ret
= heim_db_begin(db
, 0, NULL
);
761 heim_assert(!ret
, "...");
763 ret
= heim_db_set_value(db
, NULL
, k1
, v1
, NULL
);
764 heim_assert(!ret
, "...");
766 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
767 heim_assert(v
&& !heim_cmp(v
, v1
), "...");
770 ret
= heim_db_commit(db
, NULL
);
771 heim_assert(!ret
, "...");
773 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
774 heim_assert(v
&& !heim_cmp(v
, v1
), "...");
777 ret
= heim_db_begin(db
, 0, NULL
);
778 heim_assert(!ret
, "...");
780 ret
= heim_db_delete_key(db
, NULL
, k1
, NULL
);
781 heim_assert(!ret
, "...");
783 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
784 heim_assert(v
== NULL
, "...");
787 ret
= heim_db_rollback(db
, NULL
);
788 heim_assert(!ret
, "...");
790 v
= heim_db_copy_value(db
, NULL
, k1
, NULL
);
791 heim_assert(v
&& !heim_cmp(v
, v1
), "...");
794 if (dbtype
!= NULL
) {
795 heim_data_t k3
= heim_data_create("value-is-a-dict", strlen("value-is-a-dict"));
796 heim_dict_t vdict
= heim_dict_create(11);
799 heim_assert(k3
&& vdict
, "...");
800 ret
= heim_dict_set_value(vdict
, HSTR("vdict-k1"), heim_number_create(11));
801 heim_assert(!ret
, "...");
802 ret
= heim_dict_set_value(vdict
, HSTR("vdict-k2"), heim_null_create());
803 heim_assert(!ret
, "...");
804 ret
= heim_dict_set_value(vdict
, HSTR("vdict-k3"), HSTR("a value"));
805 heim_assert(!ret
, "...");
806 ret
= heim_db_set_value(db
, NULL
, k3
, (heim_data_t
)vdict
, NULL
);
807 heim_assert(!ret
, "...");
811 db2
= heim_db_create(dbtype
, dbname
, NULL
, NULL
);
812 heim_assert(db2
, "...");
814 vdict
= (heim_dict_t
)heim_db_copy_value(db2
, NULL
, k3
, NULL
);
817 heim_assert(vdict
, "...");
818 heim_assert(heim_get_tid(vdict
) == heim_dict_get_type_id(), "...");
820 v
= heim_dict_copy_value(vdict
, HSTR("vdict-k1"));
821 heim_assert(v
&& !heim_cmp(v
, heim_number_create(11)), "...");
824 v
= heim_dict_copy_value(vdict
, HSTR("vdict-k2"));
825 heim_assert(v
&& !heim_cmp(v
, heim_null_create()), "...");
828 v
= heim_dict_copy_value(vdict
, HSTR("vdict-k3"));
829 heim_assert(v
&& !heim_cmp(v
, HSTR("a value")), "...");
845 struct test_array_iter_ctx
{
849 static void test_array_iter(heim_object_t elt
, void *arg
, int *stop
)
851 struct test_array_iter_ctx
*iter_ctx
= arg
;
853 strcat(iter_ctx
->buf
, heim_string_get_utf8((heim_string_t
)elt
));
859 struct test_array_iter_ctx iter_ctx
;
860 heim_string_t s1
= heim_string_create("abc");
861 heim_string_t s2
= heim_string_create("def");
862 heim_string_t s3
= heim_string_create("ghi");
863 heim_string_t s4
= heim_string_create("jkl");
864 heim_string_t s5
= heim_string_create("mno");
865 heim_string_t s6
= heim_string_create("pqr");
866 heim_array_t a
= heim_array_create();
868 if (!s1
|| !s2
|| !s3
|| !s4
|| !s5
|| !s6
|| !a
)
871 heim_array_append_value(a
, s4
);
872 heim_array_append_value(a
, s5
);
873 heim_array_insert_value(a
, 0, s3
);
874 heim_array_insert_value(a
, 0, s2
);
875 heim_array_append_value(a
, s6
);
876 heim_array_insert_value(a
, 0, s1
);
878 iter_ctx
.buf
[0] = '\0';
879 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
880 if (strcmp(iter_ctx
.buf
, "abcdefghijklmnopqr") != 0)
883 iter_ctx
.buf
[0] = '\0';
884 heim_array_delete_value(a
, 2);
885 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
886 if (strcmp(iter_ctx
.buf
, "abcdefjklmnopqr") != 0)
889 iter_ctx
.buf
[0] = '\0';
890 heim_array_delete_value(a
, 2);
891 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
892 if (strcmp(iter_ctx
.buf
, "abcdefmnopqr") != 0)
895 iter_ctx
.buf
[0] = '\0';
896 heim_array_delete_value(a
, 0);
897 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
898 if (strcmp(iter_ctx
.buf
, "defmnopqr") != 0)
901 iter_ctx
.buf
[0] = '\0';
902 heim_array_delete_value(a
, 2);
903 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
904 if (strcmp(iter_ctx
.buf
, "defmno") != 0)
907 heim_array_insert_value(a
, 0, s1
);
908 iter_ctx
.buf
[0] = '\0';
909 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
910 if (strcmp(iter_ctx
.buf
, "abcdefmno") != 0)
913 heim_array_insert_value(a
, 0, s2
);
914 iter_ctx
.buf
[0] = '\0';
915 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
916 if (strcmp(iter_ctx
.buf
, "defabcdefmno") != 0)
919 heim_array_append_value(a
, s3
);
920 iter_ctx
.buf
[0] = '\0';
921 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
922 if (strcmp(iter_ctx
.buf
, "defabcdefmnoghi") != 0)
925 heim_array_append_value(a
, s6
);
926 iter_ctx
.buf
[0] = '\0';
927 heim_array_iterate_f(a
, &iter_ctx
, test_array_iter
);
928 if (strcmp(iter_ctx
.buf
, "defabcdefmnoghipqr") != 0)
943 main(int argc
, char **argv
)
947 res
|= test_memory();
949 res
|= test_rwlock();
951 res
|= test_auto_release();
952 res
|= test_string();
956 res
|= test_db(NULL
, NULL
);
957 res
|= test_db("json", argc
> 1 ? argv
[1] : "test_db.json");