static tb_object_ref_t tb_object_bin_reader_func_number(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); // the number type tb_size_t number_type = (tb_size_t)size; // read number tb_object_ref_t number = tb_null; switch (number_type) { case TB_NUMBER_TYPE_UINT64: number = tb_object_number_init_from_uint64(tb_stream_bread_u64_be(reader->stream)); break; case TB_NUMBER_TYPE_SINT64: number = tb_object_number_init_from_sint64(tb_stream_bread_s64_be(reader->stream)); break; case TB_NUMBER_TYPE_UINT32: number = tb_object_number_init_from_uint32(tb_stream_bread_u32_be(reader->stream)); break; case TB_NUMBER_TYPE_SINT32: number = tb_object_number_init_from_sint32(tb_stream_bread_s32_be(reader->stream)); break; case TB_NUMBER_TYPE_UINT16: number = tb_object_number_init_from_uint16(tb_stream_bread_u16_be(reader->stream)); break; case TB_NUMBER_TYPE_SINT16: number = tb_object_number_init_from_sint16(tb_stream_bread_s16_be(reader->stream)); break; case TB_NUMBER_TYPE_UINT8: number = tb_object_number_init_from_uint8(tb_stream_bread_u8(reader->stream)); break; case TB_NUMBER_TYPE_SINT8: number = tb_object_number_init_from_sint8(tb_stream_bread_s8(reader->stream)); break; #ifdef TB_CONFIG_TYPE_FLOAT case TB_NUMBER_TYPE_FLOAT: { tb_byte_t data[4] = {0}; if (!tb_stream_bread(reader->stream, data, 4)) return tb_null; number = tb_object_number_init_from_float(tb_bits_get_float_be(data)); } break; case TB_NUMBER_TYPE_DOUBLE: { tb_byte_t data[8] = {0}; if (!tb_stream_bread(reader->stream, data, 8)) return tb_null; number = tb_object_number_init_from_double(tb_bits_get_double_bbe(data)); } break; #endif default: tb_assert_and_check_return_val(0, tb_null); break; } // ok? return number; }
static tb_object_ref_t tb_object_number_copy(tb_object_ref_t object) { // check tb_object_number_t* number = (tb_object_number_t*)object; tb_assert_and_check_return_val(number, tb_null); // copy switch (number->type) { case TB_NUMBER_TYPE_UINT64: return tb_object_number_init_from_uint64(number->v.u64); case TB_NUMBER_TYPE_SINT64: return tb_object_number_init_from_sint64(number->v.s64); case TB_NUMBER_TYPE_UINT32: return tb_object_number_init_from_uint32(number->v.u32); case TB_NUMBER_TYPE_SINT32: return tb_object_number_init_from_sint32(number->v.s32); case TB_NUMBER_TYPE_UINT16: return tb_object_number_init_from_uint16(number->v.u16); case TB_NUMBER_TYPE_SINT16: return tb_object_number_init_from_sint16(number->v.s16); case TB_NUMBER_TYPE_UINT8: return tb_object_number_init_from_uint8(number->v.u8); case TB_NUMBER_TYPE_SINT8: return tb_object_number_init_from_sint8(number->v.s8); #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_NUMBER_TYPE_FLOAT: return tb_object_number_init_from_float(number->v.f); case TB_NUMBER_TYPE_DOUBLE: return tb_object_number_init_from_double(number->v.d); #endif default: break; } return tb_null; }
static tb_object_ref_t tb_object_json_reader_func_number(tb_object_json_reader_t* reader, tb_char_t type) { // check tb_assert_and_check_return_val(reader && reader->stream, tb_null); // init data tb_static_string_t data; tb_char_t buff[256]; if (!tb_static_string_init(&data, buff, 256)) return tb_null; // done tb_object_ref_t number = tb_null; do { // append character tb_static_string_chrcat(&data, type); // walk tb_bool_t bs = (type == '-')? tb_true : tb_false; tb_bool_t bf = (type == '.')? tb_true : tb_false; tb_bool_t failed = tb_false; while (!failed && tb_stream_left(reader->stream)) { // need one character tb_byte_t* p = tb_null; if (!tb_stream_need(reader->stream, &p, 1) && p) { failed = tb_true; break; } // the character tb_char_t ch = *p; // is float? if (!bf && ch == '.') bf = tb_true; else if (bf && ch == '.') { failed = tb_true; break; } // append character if (tb_isdigit10(ch) || ch == '.' || ch == 'e' || ch == 'E' || ch == '-' || ch == '+') tb_static_string_chrcat(&data, ch); else break; // skip it tb_stream_skip(reader->stream, 1); } // failed? tb_check_break(!failed); // check tb_assert_and_check_break(tb_static_string_size(&data)); // trace tb_trace_d("number: %s", tb_static_string_cstr(&data)); // init number #ifdef TB_CONFIG_TYPE_FLOAT if (bf) number = tb_object_number_init_from_float(tb_stof(tb_static_string_cstr(&data))); #else if (bf) tb_trace_noimpl(); #endif else if (bs) { tb_sint64_t value = tb_stoi64(tb_static_string_cstr(&data)); tb_size_t bytes = tb_object_need_bytes(-value); switch (bytes) { case 1: number = tb_object_number_init_from_sint8((tb_sint8_t)value); break; case 2: number = tb_object_number_init_from_sint16((tb_sint16_t)value); break; case 4: number = tb_object_number_init_from_sint32((tb_sint32_t)value); break; case 8: number = tb_object_number_init_from_sint64((tb_sint64_t)value); break; default: break; } } else { tb_uint64_t value = tb_stou64(tb_static_string_cstr(&data)); tb_size_t bytes = tb_object_need_bytes(value); switch (bytes) { case 1: number = tb_object_number_init_from_uint8((tb_uint8_t)value); break; case 2: number = tb_object_number_init_from_uint16((tb_uint16_t)value); break; case 4: number = tb_object_number_init_from_uint32((tb_uint32_t)value); break; case 8: number = tb_object_number_init_from_uint64((tb_uint64_t)value); break; default: break; } } } while (0); // exit data tb_static_string_exit(&data); // ok? return number; }