Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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;
    }
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
Archivo: option.c Proyecto: waruqi/tbox
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);
    }
}
Ejemplo n.º 9
0
Archivo: json.c Proyecto: luxuan/tbox
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;
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * 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;
}
Ejemplo n.º 14
0
Archivo: object.c Proyecto: luxuan/tbox
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
Archivo: json.c Proyecto: luxuan/tbox
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}