Ejemplo n.º 1
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.º 2
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;
}