static tb_object_ref_t tb_object_xplist_reader_done(tb_stream_ref_t stream) { // init reader tb_object_xplist_reader_t reader = {0}; reader.reader = tb_xml_reader_init(); tb_assert_and_check_return_val(reader.reader, tb_null); // open reader tb_object_ref_t object = tb_null; if (tb_xml_reader_open(reader.reader, stream, tb_false)) { // done tb_bool_t leave = tb_false; tb_size_t event = TB_XML_READER_EVENT_NONE; while (!leave && !object && (event = tb_xml_reader_next(reader.reader))) { switch (event) { case TB_XML_READER_EVENT_ELEMENT_EMPTY: case TB_XML_READER_EVENT_ELEMENT_BEG: { // name tb_char_t const* name = tb_xml_reader_element(reader.reader); tb_assert_and_check_break_state(name, leave, tb_true); // <plist/> ? if (tb_stricmp(name, "plist")) { // func tb_object_xplist_reader_func_t func = tb_object_xplist_reader_func(name); tb_assert_and_check_break_state(func, leave, tb_true); // read object = func(&reader, event); } } break; default: break; } } } // exit reader tb_xml_reader_exit(reader.reader); // ok? return object; }
static tb_void_t tb_demo_spider_parser_exit(tb_thread_pool_worker_ref_t worker, tb_cpointer_t priv) { // check tb_demo_spider_parser_t* parser = (tb_demo_spider_parser_t*)priv; tb_assert_and_check_return(parser); // exit stream if (parser->stream) tb_stream_exit(parser->stream); parser->stream = tb_null; // exit reader if (parser->reader) tb_xml_reader_exit(parser->reader); parser->reader = tb_null; // exit cache if (parser->cache) tb_circle_queue_exit(parser->cache); parser->cache = tb_null; // exit iurl tb_url_exit(&parser->iurl); // exit it tb_free(parser); }