1#include "include/pw.h"
2
3bool _pw_get(PwValuePtr result, PwValuePtr container, ...)
4{
5 PwValue obj = pw_clone(container);
6 va_list ap;
7 va_start(ap);
8 for (;;) {{
9 char8_t* key = va_arg(ap, char8_t*);
10 if (key == nullptr) {
11 va_end(ap);
12 return true;
13 }
14 pw_destroy(result);
15
16 // get RandomAccess interface
17 PwInterface_RandomAccess* interface = pw_lookup_interface(obj.type_id, RandomAccess);
18 if (!interface) {
19 va_end(ap);
20 pw_set_status(PwStatus(PW_ERROR_KEY_NOT_FOUND));
21 return false;
22 }
23
24 // get value by key
25 PwValue k = PW_NULL;
26 if (!pw_create_string(key, &k)) {
27 va_end(ap);
28 return false;
29 }
30 if (!pw_call2(interface, get_item, &obj, &k, result)) {
31 va_end(ap);
32 return false;
33 }
34
35 // go to the deeper object
36 pw_clone2(result, &obj);
37 }}
38}
39
40bool _pw_set(PwValuePtr value, PwValuePtr container, ...)
41{
42 PwValue obj = pw_clone(container);
43 va_list ap;
44 va_start(ap);
45
46 // get first key
47 char8_t* key = va_arg(ap, char8_t*);
48 if (key == nullptr) {
49 va_end(ap);
50 pw_set_status(PwStatus(PW_ERROR_KEY_NOT_FOUND));
51 return false;
52 }
53 for (;;) {{
54 // get next key
55 char8_t* next_key = va_arg(ap, char8_t*);
56 if (next_key == nullptr) {
57 break;
58 }
59 // get RandomAccess interface
60 PwInterface_RandomAccess* interface = pw_lookup_interface(obj.type_id, RandomAccess);
61 if (!interface) {
62 pw_set_status(PwStatus(PW_ERROR_KEY_NOT_FOUND));
63 va_end(ap);
64 return false;
65 }
66
67 // get nested object by key
68 PwValue k = PW_NULL;
69 if (!pw_create_string(key, &k)) {
70 va_end(ap);
71 return false;
72 }
73 PwValue nested_obj = PW_NULL;
74 if (!pw_call2(interface, get_item, &obj, &k, &nested_obj)) {
75 va_end(ap);
76 return false;
77 }
78 // go to the deeper object
79 pw_move(&nested_obj, &obj);
80 key = next_key;
81 }}
82 va_end(ap);
83
84 // set value
85 PwInterface_RandomAccess* interface = pw_lookup_interface(obj.type_id, RandomAccess);
86 if (!interface) {
87 pw_set_status(PwStatus(PW_ERROR_KEY_NOT_FOUND));
88 return false;
89 }
90 PwValue k = PW_NULL;
91 if (!pw_create_string(key, &k)) {
92 return false;
93 }
94 return pw_call2(interface, set_item, &obj, &k, value);
95}