1 #include <ucode/module.h>
4 static uc_resource_type_t
*reader_type
, *hashtbl_type
;
8 writer_store_data(struct uht_writer
*wr
, uc_value_t
*val
)
13 switch (ucv_type(val
)) {
15 return uht_writer_add_string(wr
, ucv_string_get(val
));
17 return uht_writer_add_int(wr
, ucv_int64_get(val
));
19 return uht_writer_add_double(wr
, ucv_double_get(val
));
21 return uht_writer_add_bool(wr
, ucv_boolean_get(val
));
23 len
= ucv_array_length(val
);
24 data
= calloc(len
, sizeof(*data
));
25 for (i
= 0; i
< len
; i
++)
26 data
[i
] = writer_store_data(wr
, ucv_array_get(val
, i
));
27 ret
= uht_writer_add_array(wr
, data
, len
);
31 len
= ucv_object_length(val
);
32 if (ucv_is_truish(ucv_object_get(val
, hash_key
, NULL
))) {
33 ret
= uht_writer_hashtbl_alloc(wr
, len
- 1);
34 ucv_object_foreach(val
, key
, value
) {
35 if (!strcmp(key
, hash_key
))
37 uht_writer_hashtbl_add_element(wr
, ret
, key
,
38 writer_store_data(wr
, value
));
40 uht_writer_hashtbl_done(wr
, ret
);
43 data
= calloc(2 * len
, sizeof(*data
));
45 ucv_object_foreach(val
, key
, value
) {
46 data
[i
] = uht_writer_add_string(wr
, key
);
47 data
[len
+ i
] = writer_store_data(wr
, value
);
50 ret
= uht_writer_add_object(wr
, data
, data
+ len
, len
);
59 writer_save(uc_vm_t
*vm
, size_t nargs
)
61 struct uht_writer wr
= {};
62 uc_value_t
*file
= uc_fn_arg(0);
63 uc_value_t
*data
= uc_fn_arg(1);
68 if (ucv_type(file
) != UC_STRING
|| !data
)
71 f
= fopen(ucv_string_get(file
), "w");
76 val
= writer_store_data(&wr
, data
);
78 ret
= uht_writer_save(&wr
, f
, val
);
83 return ucv_boolean_new(ret
== 0);
87 __reader_get_value(uc_vm_t
*vm
, struct uht_reader
*r
, uint32_t attr
, bool dump
)
89 enum uht_type type
= uht_entry_type(attr
);
97 return ucv_string_new(uht_reader_get_string(r
, attr
));
99 return ucv_int64_new(uht_reader_get_int(r
, attr
));
101 return ucv_double_new(uht_reader_get_double(r
, attr
));
103 return ucv_boolean_new(uht_reader_get_bool(r
, attr
));
106 return ucv_resource_new(hashtbl_type
, (void *)(uintptr_t)attr
);
109 val
= ucv_object_new(vm
);
110 if (type
== UHT_HASHTBL
)
111 ucv_object_add(val
, hash_key
, ucv_boolean_new(true));
112 uht_for_each(r
, iter
, attr
)
113 ucv_object_add(val
, iter
.key
, ucv_get(__reader_get_value(vm
, r
, iter
.val
, dump
)));
116 val
= ucv_array_new(vm
);
118 uht_for_each(r
, iter
, attr
)
119 ucv_array_set(val
, i
++, ucv_get(__reader_get_value(vm
, r
, iter
.val
, dump
)));
127 reader_open(uc_vm_t
*vm
, size_t nargs
)
129 uc_value_t
*file
= uc_fn_arg(0);
130 struct uht_reader
*r
;
132 if (ucv_type(file
) != UC_STRING
)
135 r
= calloc(1, sizeof(*r
));
136 if (uht_reader_open(r
, ucv_string_get(file
))) {
141 return ucv_resource_new(reader_type
, r
);
145 reader_free(void *ptr
)
147 struct uht_reader
*r
= ptr
;
154 set_hashtbl_key(uc_vm_t
*vm
, size_t nargs
)
156 uc_value_t
*key
= uc_fn_arg(0);
158 if (ucv_type(key
) != UC_STRING
)
162 hash_key
= strdup(ucv_string_get(key
));
164 return ucv_boolean_new(true);
168 mark_hashtbl(uc_vm_t
*vm
, size_t nargs
)
170 uc_value_t
*obj
= uc_fn_arg(0);
172 if (ucv_type(obj
) != UC_OBJECT
)
175 ucv_object_add(obj
, hash_key
, ucv_boolean_new(true));
176 return ucv_boolean_new(true);
180 reader_get_htable(uc_value_t
*tbl
)
184 if (ucv_type(tbl
) != UC_RESOURCE
)
187 htbl
= ucv_resource_data(tbl
, "uht.hashtbl");
191 return (uint32_t)(uintptr_t)htbl
;
195 reader_get(uc_vm_t
*vm
, size_t nargs
)
197 struct uht_reader
*r
= uc_fn_thisval("uht.reader");
198 uc_value_t
*tbl
= uc_fn_arg(0);
199 uc_value_t
*key
= uc_fn_arg(1);
200 uc_value_t
*dump
= uc_fn_arg(2);
207 val
= reader_get_htable(tbl
);
212 if (uht_entry_type(val
) != UHT_HASHTBL
)
215 val
= uht_reader_hashtbl_lookup(r
, val
, ucv_string_get(key
));
218 return __reader_get_value(vm
, r
, val
, ucv_is_truish(dump
));
221 static const uc_function_list_t no_fns
[] = {};
223 static const uc_function_list_t reader_fns
[] = {
224 { "get", reader_get
},
227 static const uc_function_list_t hashtbl_fns
[] = {
228 { "save", writer_save
},
229 { "open", reader_open
},
230 { "mark_hashtable", mark_hashtbl
},
231 { "set_hashtable_key", set_hashtbl_key
},
234 void uc_module_init(uc_vm_t
*vm
, uc_value_t
*scope
)
236 hash_key
= strdup("##hash_table");
237 reader_type
= uc_type_declare(vm
, "uht.reader", reader_fns
, reader_free
);
238 hashtbl_type
= uc_type_declare(vm
, "uht.hashtbl", no_fns
, NULL
);
239 uc_function_list_register(scope
, hashtbl_fns
);