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_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; }