static tb_object_ref_t tb_oc_number_copy(tb_object_ref_t object) { // check tb_oc_number_t* number = (tb_oc_number_t*)object; tb_assert_and_check_return_val(number, tb_null); // copy switch (number->type) { case TB_OC_NUMBER_TYPE_UINT64: return tb_oc_number_init_from_uint64(number->v.u64); case TB_OC_NUMBER_TYPE_SINT64: return tb_oc_number_init_from_sint64(number->v.s64); case TB_OC_NUMBER_TYPE_UINT32: return tb_oc_number_init_from_uint32(number->v.u32); case TB_OC_NUMBER_TYPE_SINT32: return tb_oc_number_init_from_sint32(number->v.s32); case TB_OC_NUMBER_TYPE_UINT16: return tb_oc_number_init_from_uint16(number->v.u16); case TB_OC_NUMBER_TYPE_SINT16: return tb_oc_number_init_from_sint16(number->v.s16); case TB_OC_NUMBER_TYPE_UINT8: return tb_oc_number_init_from_uint8(number->v.u8); case TB_OC_NUMBER_TYPE_SINT8: return tb_oc_number_init_from_sint8(number->v.s8); #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OC_NUMBER_TYPE_FLOAT: return tb_oc_number_init_from_float(number->v.f); case TB_OC_NUMBER_TYPE_DOUBLE: return tb_oc_number_init_from_double(number->v.d); #endif default: break; } return tb_null; }
static tb_object_ref_t tb_oc_xplist_reader_func_number(tb_oc_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_oc_number_init_from_uint32(0); // done tb_bool_t leave = tb_false; tb_object_ref_t number = tb_null; while (!leave && (event = tb_xml_reader_next(reader->reader))) { switch (event) { 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, leave, tb_true); // is end? if (!tb_stricmp(name, "integer") || !tb_stricmp(name, "real")) leave = tb_true; } break; case TB_XML_READER_EVENT_TEXT: { // text tb_char_t const* text = tb_xml_reader_text(reader->reader); tb_assert_and_check_break_state(text, leave, tb_true); tb_trace_d("number: %s", text); // has sign? is float? tb_size_t s = 0; tb_size_t f = 0; tb_char_t const* p = text; for (; *p; p++) { if (!s && *p == '-') s = 1; if (!f && *p == '.') f = 1; if (s && f) break; } // number #ifdef TB_CONFIG_TYPE_HAVE_FLOAT if (f) number = tb_oc_number_init_from_double(tb_atof(text)); #else if (f) tb_trace_noimpl(); #endif else number = s? tb_oc_number_init_from_sint64(tb_stoi64(text)) : tb_oc_number_init_from_uint64(tb_stou64(text)); tb_assert_and_check_break_state(number, leave, tb_true); } break; default: break; } } // ok? return number; }