static tb_object_dictionary_t* tb_object_dictionary_init_base() { // done tb_bool_t ok = tb_false; tb_object_dictionary_t* dictionary = tb_null; do { // make dictionary dictionary = tb_malloc0_type(tb_object_dictionary_t); tb_assert_and_check_break(dictionary); // init dictionary if (!tb_object_init((tb_object_ref_t)dictionary, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_DICTIONARY)) break; // init base dictionary->base.copy = tb_object_dictionary_copy; dictionary->base.exit = tb_object_dictionary_exit; dictionary->base.clear = tb_object_dictionary_clear; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (dictionary) tb_object_exit((tb_object_ref_t)dictionary); dictionary = tb_null; } // ok? return dictionary; }
static tb_oc_date_t* tb_oc_date_init_base() { // done tb_bool_t ok = tb_false; tb_oc_date_t* date = tb_null; do { // make date date = tb_malloc0_type(tb_oc_date_t); tb_assert_and_check_break(date); // init date if (!tb_object_init((tb_object_ref_t)date, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_DATE)) break; // init base date->base.copy = tb_oc_date_copy; date->base.exit = tb_oc_date_exit; date->base.clear = tb_oc_date_clear; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (date) tb_object_exit((tb_object_ref_t)date); date = tb_null; } // ok? return date; }
static tb_oc_number_t* tb_oc_number_init_base() { // done tb_bool_t ok = tb_false; tb_oc_number_t* number = tb_null; do { // make number number = tb_malloc0_type(tb_oc_number_t); tb_assert_and_check_break(number); // init number if (!tb_object_init((tb_object_ref_t)number, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_NUMBER)) break; // init base number->base.copy = tb_oc_number_copy; number->base.exit = tb_oc_number_exit; number->base.clear = tb_oc_number_clear; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (number) tb_object_exit((tb_object_ref_t)number); number = tb_null; } // ok? return number; }
static tb_bool_t tb_oc_bplist_writer_func_array(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size) { // check tb_assert_and_check_return_val(writer && writer->stream && object, tb_false); // index tables tb_byte_t* index_tables = (tb_byte_t*)tb_object_getp(object); // size tb_size_t size = tb_oc_array_size(object); tb_assert_and_check_return_val(!size == !index_tables, tb_false); // writ flag tb_uint8_t flag = TB_OBJECT_BPLIST_TYPE_ARRAY | (size < 15 ? (tb_uint8_t)size : 0xf); if (!tb_stream_bwrit_u8(writer->stream, flag)) return tb_false; // writ size if (size >= 15) { // init osize tb_object_ref_t osize = tb_oc_bplist_writer_init_number(size); tb_assert_and_check_return_val(osize, tb_false); // writ it if (!tb_oc_bplist_writer_func_number(writer, osize, item_size)) { tb_object_exit(osize); return tb_false; } // exit osize tb_object_exit(osize); } // writ index tables if (index_tables) { if (!tb_stream_bwrit(writer->stream, index_tables, size * item_size)) return tb_false; } // ok return tb_true; }
tb_void_t tb_object_dictionary_insert(tb_object_ref_t object, tb_char_t const* key, tb_object_ref_t val) { // check tb_object_dictionary_t* dictionary = tb_object_dictionary_cast(object); tb_assert_and_check_return(dictionary && dictionary->hash && key && val); // add tb_hash_map_insert(dictionary->hash, key, val); // refn-- if (!dictionary->incr) tb_object_exit(val); }
static tb_void_t tb_element_obj_free(tb_element_ref_t element, tb_pointer_t buff) { // check tb_assert_and_check_return(element && buff); // exit tb_object_ref_t object = *((tb_object_ref_t*)buff); if (object) { tb_object_exit(object); *((tb_object_ref_t*)buff) = tb_null; } }
static tb_bool_t tb_oc_bplist_writer_func_rdata(tb_oc_bplist_writer_t* writer, tb_uint8_t bype, tb_byte_t const* data, tb_size_t size, tb_size_t item_size) { // check tb_assert_and_check_return_val(writer && writer->stream && !data == !size, tb_false); // writ flag tb_uint8_t flag = bype | (tb_uint8_t)(size < 15 ? size : 0xf); if (!tb_stream_bwrit_u8(writer->stream, flag)) return tb_false; // writ size if (size >= 15) { // init object tb_object_ref_t object = tb_oc_bplist_writer_init_number(size); tb_assert_and_check_return_val(object, tb_false); // writ it if (!tb_oc_bplist_writer_func_number(writer, object, item_size)) { tb_object_exit(object); return tb_false; } // exit object tb_object_exit(object); } // unicode? adjust size if (bype == TB_OBJECT_BPLIST_TYPE_UNICODE) size <<= 1; // writ data if (data) if (!tb_stream_bwrit(writer->stream, data, size)) return tb_false; // ok return tb_true; }
tb_void_t tb_option_exit(tb_option_ref_t option) { tb_option_impl_t* impl = (tb_option_impl_t*)option; if (impl) { // exit help tb_string_exit(&impl->help); // exit list if (impl->list) tb_object_exit(impl->list); impl->list = tb_null; // exit option tb_free(impl); } }
static tb_object_ref_t tb_object_json_reader_func_array(tb_object_json_reader_t* reader, tb_char_t type) { // check tb_assert_and_check_return_val(reader && reader->stream && type == '[', tb_null); // init array tb_object_ref_t array = tb_object_array_init(TB_OBJECT_JSON_READER_ARRAY_GROW, tb_false); tb_assert_and_check_return_val(array, tb_null); // done tb_char_t ch; tb_bool_t ok = tb_true; while (ok && tb_stream_left(reader->stream)) { // read one character ch = tb_stream_bread_s8(reader->stream); // end? if (ch == ']') break; // no space? skip ',' else if (!tb_isspace(ch) && ch != ',') { // the func tb_object_json_reader_func_t func = tb_object_json_reader_func(ch); tb_assert_and_check_break_state(func, ok, tb_false); // read item tb_object_ref_t item = func(reader, ch); tb_assert_and_check_break_state(item, ok, tb_false); // append item tb_object_array_append(array, item); } } // failed? if (!ok) { // exit it if (array) tb_object_exit(array); array = tb_null; } // ok? return array; }
static tb_void_t tb_element_obj_repl(tb_element_ref_t element, tb_pointer_t buff, tb_cpointer_t data) { // check tb_assert_and_check_return(element && buff); // save the previous object tb_object_ref_t object = *((tb_object_ref_t*)buff); // refn++ if (data) tb_object_retain((tb_object_ref_t)data); // copy it *((tb_cpointer_t*)buff) = data; // refn-- if (object) tb_object_exit(object); }
static tb_object_ref_t tb_object_bplist_reader_func_date(tb_object_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size) { // check tb_assert_and_check_return_val(reader && reader->stream, tb_null); // the date data tb_object_ref_t data = tb_object_bplist_reader_func_number(reader, TB_OBJECT_BPLIST_TYPE_REAL, size, item_size); tb_assert_and_check_return_val(data, tb_null); // init date tb_object_ref_t date = tb_object_date_init_from_time(tb_object_bplist_reader_time_apple2host((tb_time_t)tb_object_number_uint64(data))); // exit data tb_object_exit(data); // ok? return date; }
static tb_long_t tb_object_bplist_reader_func_size(tb_object_bplist_reader_t* reader, tb_size_t item_size) { // check tb_assert_and_check_return_val(reader && reader->stream, -1); // read size tb_object_ref_t object = tb_object_bplist_reader_func_object(reader, item_size); tb_assert_and_check_return_val(object, -1); tb_long_t size = -1; if (tb_object_type(object) == TB_OBJECT_TYPE_NUMBER) size = tb_object_number_uint32(object); // exit tb_object_exit(object); // size return size; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_object_dump_main(tb_int_t argc, tb_char_t** argv) { // read tb_object_ref_t root = tb_object_read_from_url(argv[1]); // writ if (root) { // seek? tb_object_ref_t object = root; if (argv[2]) object = tb_object_seek(root, argv[2], TB_OBJECT_TYPE_NONE); // dump object if (object) tb_object_dump(object); // exit object tb_object_exit(root); } return 0; }
tb_object_ref_t tb_object_dump(tb_object_ref_t object, tb_size_t format) { // check tb_assert_and_check_return_val(object, tb_null); // data tb_object_ref_t odata = tb_object_data(object, format); if (odata) { // the data and size tb_byte_t const* data = (tb_byte_t const*)tb_object_data_getp(odata); tb_size_t size = tb_object_data_size(odata); if (data && size) { // done tb_char_t const* p = (tb_char_t const*)data; tb_char_t const* e = (tb_char_t const*)data + size; tb_char_t b[4096 + 1]; if (p && p < e) { while (p < e && *p && tb_isspace(*p)) p++; while (p < e && *p) { tb_char_t* q = b; tb_char_t const* d = b + 4096; for (; p < e && q < d && *p; p++, q++) *q = *p; *q = '\0'; tb_printf("%s", b); } tb_printf("\n"); } } // exit data tb_object_exit(odata); } // the object return object; }
tb_object_ref_t tb_object_dump(tb_object_ref_t object) { // check tb_assert_and_check_return_val(object, tb_null); // data tb_object_ref_t odata = tb_object_data(object, TB_OBJECT_FORMAT_XML); if (odata) { // data & size tb_byte_t const* data = (tb_byte_t const*)tb_object_data_getp(odata); tb_size_t size = tb_object_data_size(odata); if (data && size) { tb_char_t const* p = tb_strstr((tb_char_t const*)data, "?>"); tb_char_t const* e = (tb_char_t const*)data + size; tb_char_t b[4096 + 1]; if (p && p + 2 < e) { p += 2; while (p < e && *p && tb_isspace(*p)) p++; while (p < e && *p) { tb_char_t* q = b; tb_char_t const* d = b + 4096; for (; p < e && q < d && *p; p++, q++) *q = *p; *q = '\0'; tb_printf("%s", b); } tb_printf("\n"); } } // exit data tb_object_exit(odata); } return object; }
static tb_object_ref_t tb_object_json_reader_func_dictionary(tb_object_json_reader_t* reader, tb_char_t type) { // check tb_assert_and_check_return_val(reader && reader->stream && type == '{', tb_null); // init key name tb_static_string_t kname; tb_char_t kdata[8192]; if (!tb_static_string_init(&kname, kdata, 8192)) return tb_null; // init dictionary tb_object_ref_t dictionary = tb_object_dictionary_init(0, tb_false); tb_assert_and_check_return_val(dictionary, tb_null); // walk tb_char_t ch; tb_bool_t ok = tb_true; tb_bool_t bkey = tb_false; tb_size_t bstr = 0; while (ok && tb_stream_left(reader->stream)) { // read one character ch = tb_stream_bread_s8(reader->stream); // end? if (ch == '}') break; // no space? skip ',' else if (!tb_isspace(ch) && ch != ',') { // no key? if (!bkey) { // is str? if (ch == '\"' || ch == '\'') bstr = !bstr; // is key end? else if (!bstr && ch == ':') bkey = tb_true; // append key else if (bstr) tb_static_string_chrcat(&kname, ch); } // key ok? read val else { // trace tb_trace_d("key: %s", tb_static_string_cstr(&kname)); // the func tb_object_json_reader_func_t func = tb_object_json_reader_func(ch); tb_assert_and_check_break_state(func, ok, tb_false); // read val tb_object_ref_t val = func(reader, ch); tb_assert_and_check_break_state(val, ok, tb_false); // set key => val tb_object_dictionary_insert(dictionary, tb_static_string_cstr(&kname), val); // reset key bstr = 0; bkey = tb_false; tb_static_string_clear(&kname); } } } // failed? if (!ok) { // exit it if (dictionary) tb_object_exit(dictionary); dictionary = tb_null; } // exit key name tb_static_string_exit(&kname); // ok? return dictionary; }
static tb_object_ref_t tb_object_bin_reader_func_array(tb_object_bin_reader_t* reader, tb_size_t type, tb_uint64_t size) { // check tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null); // empty? if (!size) return tb_object_array_init(TB_OBJECT_BIN_READER_ARRAY_GROW, tb_false); // init array tb_object_ref_t array = tb_object_array_init(TB_OBJECT_BIN_READER_ARRAY_GROW, tb_false); tb_assert_and_check_return_val(array, tb_null); // walk tb_size_t i = 0; tb_size_t n = (tb_size_t)size; for (i = 0; i < n; i++) { // the type & size tb_size_t type = 0; tb_uint64_t size = 0; tb_object_reader_bin_type_size(reader->stream, &type, &size); // trace tb_trace_d("item: type: %lu, size: %llu", type, size); // is index? tb_object_ref_t item = tb_null; if (!type) { // the object index tb_size_t index = (tb_size_t)size; // check tb_assert_and_check_break(index < tb_vector_size(reader->list)); // the item item = (tb_object_ref_t)tb_iterator_item(reader->list, index); // refn++ if (item) tb_object_inc(item); } else { // the reader func tb_object_bin_reader_func_t func = tb_object_bin_reader_func(type); tb_assert_and_check_break(func); // read it item = func(reader, type, size); // save it tb_vector_insert_tail(reader->list, item); } // check tb_assert_and_check_break(item); // append item tb_object_array_append(array, item); } // failed? if (i != n) { if (array) tb_object_exit(array); array = tb_null; } // ok? return array; }
static tb_object_ref_t tb_object_xplist_reader_func_dictionary(tb_object_xplist_reader_t* reader, tb_size_t event) { // check tb_assert_and_check_return_val(reader && reader->reader && event, tb_null); // empty? if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY) return tb_object_dictionary_init(TB_OBJECT_DICTIONARY_SIZE_MICRO, tb_false); // init key name tb_static_string_t kname; tb_char_t kdata[8192]; if (!tb_static_string_init(&kname, kdata, 8192)) return tb_null; // init dictionary tb_object_ref_t dictionary = tb_object_dictionary_init(0, tb_false); tb_assert_and_check_return_val(dictionary, tb_null); // done tb_long_t ok = 0; tb_bool_t key = tb_false; while (!ok && (event = tb_xml_reader_next(reader->reader))) { switch (event) { case TB_XML_READER_EVENT_ELEMENT_BEG: case TB_XML_READER_EVENT_ELEMENT_EMPTY: { // name tb_char_t const* name = tb_xml_reader_element(reader->reader); tb_assert_and_check_break_state(name, ok, -1); tb_trace_d("%s", name); // is key if (!tb_stricmp(name, "key")) key = tb_true; else if (!key) { // func tb_object_xplist_reader_func_t func = tb_object_xplist_reader_func(name); tb_assert_and_check_break_state(func, ok, -1); // read tb_object_ref_t object = func(reader, event); tb_trace_d("%s => %p", tb_static_string_cstr(&kname), object); tb_assert_and_check_break_state(object, ok, -1); // set key & value if (tb_static_string_size(&kname) && dictionary) tb_object_dictionary_insert(dictionary, tb_static_string_cstr(&kname), object); // clear key name tb_static_string_clear(&kname); } } break; case TB_XML_READER_EVENT_ELEMENT_END: { // name tb_char_t const* name = tb_xml_reader_element(reader->reader); tb_assert_and_check_break_state(name, ok, -1); // is end? if (!tb_stricmp(name, "dict")) ok = 1; else if (!tb_stricmp(name, "key")) key = tb_false; } break; case TB_XML_READER_EVENT_TEXT: { if (key) { // text tb_char_t const* text = tb_xml_reader_text(reader->reader); tb_assert_and_check_break_state(text, ok, -1); // writ key name tb_static_string_cstrcpy(&kname, text); } } break; default: break; } } // failed if (ok < 0) { // exit it if (dictionary) tb_object_exit(dictionary); dictionary = tb_null; } // exit key name tb_static_string_exit(&kname); // ok? return dictionary; }
static tb_object_ref_t tb_object_xplist_reader_func_array(tb_object_xplist_reader_t* reader, tb_size_t event) { // check tb_assert_and_check_return_val(reader && reader->reader && event, tb_null); // empty? if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY) return tb_object_array_init(TB_OBJECT_XPLIST_READER_ARRAY_GROW, tb_false); // init array tb_object_ref_t array = tb_object_array_init(TB_OBJECT_XPLIST_READER_ARRAY_GROW, tb_false); tb_assert_and_check_return_val(array, tb_null); // done tb_long_t ok = 0; while (!ok && (event = tb_xml_reader_next(reader->reader))) { switch (event) { case TB_XML_READER_EVENT_ELEMENT_BEG: case TB_XML_READER_EVENT_ELEMENT_EMPTY: { // name tb_char_t const* name = tb_xml_reader_element(reader->reader); tb_assert_and_check_break_state(name, ok, -1); tb_trace_d("item: %s", name); // func tb_object_xplist_reader_func_t func = tb_object_xplist_reader_func(name); tb_assert_and_check_break_state(func, ok, -1); // read tb_object_ref_t object = func(reader, event); // append object if (object) tb_object_array_append(array, object); } break; case TB_XML_READER_EVENT_ELEMENT_END: { // name tb_char_t const* name = tb_xml_reader_element(reader->reader); tb_assert_and_check_break_state(name, ok, -1); // is end? if (!tb_stricmp(name, "array")) ok = 1; } break; default: break; } } // failed? if (ok < 0) { // exit it if (array) tb_object_exit(array); array = tb_null; } // ok? return array; }
static tb_object_ref_t tb_object_bin_reader_func_dictionary(tb_object_bin_reader_t* reader, tb_size_t type, tb_uint64_t size) { // check tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null); // empty? if (!size) return tb_object_dictionary_init(TB_OBJECT_DICTIONARY_SIZE_MICRO, tb_false); // init dictionary tb_object_ref_t dictionary = tb_object_dictionary_init(0, tb_false); tb_assert_and_check_return_val(dictionary, tb_null); // walk tb_size_t i = 0; tb_size_t n = (tb_size_t)size; for (i = 0; i < n; i++) { // read key tb_object_ref_t key = tb_null; do { // the type & size tb_size_t type = 0; tb_uint64_t size = 0; tb_object_reader_bin_type_size(reader->stream, &type, &size); // trace tb_trace_d("key: type: %lu, size: %llu", type, size); // is index? if (!type) { // the object index tb_size_t index = (tb_size_t)size; // check tb_assert_and_check_break(index < tb_vector_size(reader->list)); // the item key = (tb_object_ref_t)tb_iterator_item(reader->list, index); } else { // check tb_assert_and_check_break(type == TB_OBJECT_TYPE_STRING); // the reader func tb_object_bin_reader_func_t func = tb_object_bin_reader_func(type); tb_assert_and_check_break(func); // read it key = func(reader, type, size); tb_assert_and_check_break(key); // save it tb_vector_insert_tail(reader->list, key); // refn-- tb_object_dec(key); } } while (0); // check tb_assert_and_check_break(key && tb_object_type(key) == TB_OBJECT_TYPE_STRING); tb_assert_and_check_break(tb_object_string_size(key) && tb_object_string_cstr(key)); // read val tb_object_ref_t val = tb_null; do { // the type & size tb_size_t type = 0; tb_uint64_t size = 0; tb_object_reader_bin_type_size(reader->stream, &type, &size); // trace tb_trace_d("val: type: %lu, size: %llu", type, size); // is index? if (!type) { // the object index tb_size_t index = (tb_size_t)size; // check tb_assert_and_check_break(index < tb_vector_size(reader->list)); // the item val = (tb_object_ref_t)tb_iterator_item(reader->list, index); // refn++ if (val) tb_object_inc(val); } else { // the reader func tb_object_bin_reader_func_t func = tb_object_bin_reader_func(type); tb_assert_and_check_break(func); // read it val = func(reader, type, size); // save it if (val) tb_vector_insert_tail(reader->list, val); } } while (0); // check tb_assert_and_check_break(val); // set key => val tb_object_dictionary_set(dictionary, tb_object_string_cstr(key), val); } // failed? if (i != n) { if (dictionary) tb_object_exit(dictionary); dictionary = tb_null; } // ok? return dictionary; }