tb_char_t const* tb_backtrace_symbols_name(tb_handle_t symbols, tb_pointer_t* frames, tb_size_t nframe, tb_size_t iframe) { // check tb_check_return_val(symbols && frames && nframe && iframe < nframe, tb_null); // the frame address tb_pointer_t frame = frames[iframe]; tb_check_return_val(frame, tb_null); // the frame dlinfo Dl_info dlinfo = {0}; if (!dladdr(frame, &dlinfo)) return tb_null; // format tb_long_t size = 0; tb_size_t maxn = 8192; if (dlinfo.dli_fname) size = tb_snprintf((tb_char_t*)symbols, maxn, "%s(", dlinfo.dli_fname); if (dlinfo.dli_sname && size >= 0) size += tb_snprintf((tb_char_t*)symbols + size, maxn - size, "%s", dlinfo.dli_sname); if (dlinfo.dli_sname && frame >= dlinfo.dli_saddr && size >= 0) size += tb_snprintf((tb_char_t*)symbols + size, maxn - size, "+%#lx", (tb_size_t)(frame - dlinfo.dli_saddr)); if (size >= 0) size += tb_snprintf((tb_char_t*)symbols + size, maxn - size, ") [%p]", frame); if (size >= 0) ((tb_char_t*)symbols)[size] = '\0'; // ok return symbols; }
static tb_bool_t tb_demo_spider_make_ourl(tb_demo_spider_t* spider, tb_char_t const* url, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(spider && url && data && maxn, tb_false); // skip protocol tb_char_t* p = (tb_char_t*)url; if (!tb_strnicmp(p, "http://", 7)) p += 7; else if (!tb_strnicmp(p, "https://", 8)) p += 8; // skip space while (*p && tb_isspace(*p)) p++; // format ourl tb_long_t n = tb_snprintf(data, maxn, "%s/%s", spider->root, p); tb_assert_and_check_return_val(n > 0 && n < maxn, tb_false); // no root? append '/' if (!tb_strchr(p, '/') && !tb_strchr(p, '\\')) data[n++] = '/'; tb_assert_and_check_return_val(n < maxn, tb_false); // '\\' => '/' if (data[n - 1] == '/') data[n - 1] = '/'; // directory? append index.html if (data[n - 1] == '/') n += tb_snprintf(data + n, maxn - n, "%s", "index.html"); tb_assert_and_check_return_val(n > 0 && n < maxn, tb_false); // end data[n] = '\0'; // replace '?' => '_' p = data; while (*p) { // replace if (*p == '?') *p = '_'; // next p++; } // trace tb_trace_d("make: %s => %s", url, data); // ok? return n > 0? tb_true : tb_false; }
tb_char_t const* tb_uuid_make_cstr(tb_char_t uuid_cstr[37], tb_char_t const* name) { // check tb_assert_and_check_return_val(uuid_cstr, tb_null); // make uuid bytes tb_byte_t uuid[16]; if (!tb_uuid_make(uuid, name)) return tb_null; // make uuid string tb_long_t size = tb_snprintf( uuid_cstr , 37 , "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X" , uuid[0], uuid[1], uuid[2], uuid[3] , uuid[4], uuid[5] , uuid[6], uuid[7] , uuid[8], uuid[9] , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); tb_assert_and_check_return_val(size == 36, tb_null); // end uuid_cstr[36] = '\0'; // ok return uuid_cstr; }
static tb_long_t gb_prefix_printf_format_shape(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the shape gb_shape_ref_t shape = (gb_shape_ref_t)object; // done tb_long_t ok = -1; switch (shape->type) { case GB_SHAPE_TYPE_ARC: ok = gb_prefix_printf_format_arc(&shape->u.arc, cstr, maxn); break; case GB_SHAPE_TYPE_PATH: ok = gb_prefix_printf_format_path(shape->u.path, cstr, maxn); break; case GB_SHAPE_TYPE_LINE: ok = gb_prefix_printf_format_line(&shape->u.line, cstr, maxn); break; case GB_SHAPE_TYPE_RECT: ok = gb_prefix_printf_format_rect(&shape->u.rect, cstr, maxn); break; case GB_SHAPE_TYPE_POINT: ok = gb_prefix_printf_format_point(&shape->u.point, cstr, maxn); break; case GB_SHAPE_TYPE_CIRCLE: ok = gb_prefix_printf_format_circle(&shape->u.circle, cstr, maxn); break; case GB_SHAPE_TYPE_ELLIPSE: ok = gb_prefix_printf_format_ellipse(&shape->u.ellipse, cstr, maxn); break; case GB_SHAPE_TYPE_POLYGON: ok = gb_prefix_printf_format_polygon(&shape->u.polygon, cstr, maxn); break; case GB_SHAPE_TYPE_TRIANGLE: ok = gb_prefix_printf_format_triangle(&shape->u.triangle, cstr, maxn); break; default: ok = tb_snprintf(cstr, maxn, "(unknown: %u)", shape->type); break; } // ok? return ok; }
static tb_bool_t tb_demo_http_session_resp_send(tb_demo_http_session_ref_t session, tb_char_t const* cstr) { // check tb_assert_and_check_return_val(session && session->sock, tb_false); // make the response header tb_long_t size = tb_snprintf( (tb_char_t*)session->data , sizeof(session->data) , "HTTP/1.1 %lu %s\r\n" "Server: %s\r\n" "Content-Type: text/html\r\n" "Content-Length: %llu\r\n" "Connection: %s\r\n" "\r\n" "%s" , session->code , tb_demo_http_session_code_cstr(session->code) , TB_VERSION_SHORT_STRING , session->file? tb_file_size(session->file) : (cstr? tb_strlen(cstr) : 0) , session->keep_alive? "keep-alive" : "close" , cstr? cstr : ""); tb_assert_and_check_return_val(size > 0, tb_false); // end session->data[size] = 0; // send the response header if (!tb_demo_http_session_data_send(session->sock, session->data, size)) return tb_false; // send the response file if exists if (session->file && !tb_demo_http_session_file_send(session->sock, session->file)) return tb_false; // ok return tb_true; }
static tb_bool_t tb_directory_walk_impl(tb_char_t const* path, tb_bool_t recursion, tb_bool_t prefix, tb_directory_walk_func_t func, tb_cpointer_t priv) { // check tb_assert_and_check_return_val(path && func, tb_false); // last tb_long_t last = tb_strlen(path) - 1; tb_assert_and_check_return_val(last >= 0, tb_false); // done tb_bool_t ok = tb_true; tb_char_t temp[4096] = {0}; DIR* directory = tb_null; if ((directory = opendir(path))) { // walk struct dirent* item = tb_null; while ((item = readdir(directory))) { // check tb_assert_and_check_continue(item->d_reclen); // the item name tb_char_t name[1024] = {0}; tb_strncpy(name, item->d_name, tb_min(item->d_reclen, sizeof(name) - 1)); if (tb_strcmp(name, ".") && tb_strcmp(name, "..")) { // the temp path tb_long_t n = tb_snprintf(temp, 4095, "%s%s%s", path, path[last] == '/'? "" : "/", name); if (n >= 0) temp[n] = '\0'; // the file info tb_file_info_t info = {0}; if (tb_file_info(temp, &info)) { // do callback if (prefix) ok = func(temp, &info, priv); tb_check_break(ok); // walk to the next directory if (info.type == TB_FILE_TYPE_DIRECTORY && recursion) ok = tb_directory_walk_impl(temp, recursion, prefix, func, priv); tb_check_break(ok); // do callback if (!prefix) ok = func(temp, &info, priv); tb_check_break(ok); } } } // exit directory closedir(directory); } // continue ? return ok; }
tb_long_t gb_mesh_edge_list_cstr(gb_mesh_edge_list_ref_t list, gb_mesh_edge_ref_t edge, tb_char_t* data, tb_size_t maxn) { // check gb_mesh_edge_list_impl_t* impl = (gb_mesh_edge_list_impl_t*)list; tb_assert_and_check_return_val(impl && impl->element.cstr && edge && maxn, -1); // make the edge info tb_char_t edge_info[4096] = {0}; tb_char_t const* pedge_info = impl->element.cstr(&impl->element, gb_mesh_edge_list_data(list, edge), edge_info, sizeof(edge_info)); if (!pedge_info) pedge_info = impl->element.cstr(&impl->element, gb_mesh_edge_list_data(list, edge->sym), edge_info, sizeof(edge_info)); if (!pedge_info) { tb_snprintf(edge_info, sizeof(edge_info) - 1, "<e%lu>", edge->id); pedge_info = edge_info; } // make it, @note only for the debug mode return tb_snprintf(data, maxn, "(%s: %{mesh_vertex} => %{mesh_vertex})", pedge_info, edge->org, edge->sym->org); }
/* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ static tb_long_t gb_prefix_printf_format_float(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(cstr && maxn && object, -1); // the value gb_float_t* value = (gb_float_t*)object; // format #ifdef TB_CONFIG_TYPE_HAVE_FLOAT tb_long_t size = tb_snprintf(cstr, maxn - 1, "%f", gb_float_to_tb(*value)); if (size >= 0) cstr[size] = '\0'; #else tb_long_t size = tb_snprintf(cstr, maxn - 1, "%ld", gb_float_to_long(*value)); if (size >= 0) cstr[size] = '\0'; #endif // ok? return size; }
/* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ static tb_long_t tb_math_printf_format_fixed(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(cstr && maxn, -1); // the fixed tb_fixed_t fixed = (tb_fixed_t)object; // format #ifdef TB_CONFIG_TYPE_FLOAT tb_long_t size = tb_snprintf(cstr, maxn - 1, "%f", tb_fixed_to_float(fixed)); if (size >= 0) cstr[size] = '\0'; #else tb_long_t size = tb_snprintf(cstr, maxn - 1, "%ld", tb_fixed_to_long(fixed)); if (size >= 0) cstr[size] = '\0'; #endif // ok? return size; }
static tb_void_t tb_demo_coroutine_client(tb_cpointer_t priv) { // check tb_socket_ref_t sock = (tb_socket_ref_t)priv; tb_assert_and_check_return(sock); // done tb_demo_http_session_t session; do { // init session if (!tb_demo_http_session_init(&session, sock)) break; // read the request header if (!tb_demo_http_session_head_recv(&session)) break; // trace tb_trace_d("path: %s", session.path); // get file or data? tb_char_t const* data = tb_null; if (session.method == TB_HTTP_METHOD_GET) { // only send data? if (g_onlydata) data = g_rootdir; else { // make full path tb_long_t size = tb_snprintf((tb_char_t*)session.data, sizeof(session.data), "%s%s%s", g_rootdir, session.path[0] != '/'? "/" : "", session.path); if (size > 0) session.data[size] = 0; // init file session.file = tb_file_init((tb_char_t*)session.data, TB_FILE_MODE_RO | TB_FILE_MODE_BINARY); // not found? if (!session.file) session.code = TB_HTTP_CODE_NOT_FOUND; } } // send the response if (!tb_demo_http_session_resp_send(&session, data)) break; // exit file if (session.file) tb_file_exit(session.file); session.file = tb_null; // trace tb_trace_d("ok!"); } while (session.keep_alive); // exit session tb_demo_http_session_exit(&session); }
tb_long_t gb_mesh_face_list_cstr(gb_mesh_face_list_ref_t list, gb_mesh_face_ref_t face, tb_char_t* data, tb_size_t maxn) { // check gb_mesh_face_list_impl_t* impl = (gb_mesh_face_list_impl_t*)list; tb_assert_and_check_return_val(impl && impl->element.cstr && face && maxn, -1); // make it tb_char_t face_info[256] = {0}; tb_cpointer_t face_data = gb_mesh_face_list_data(list, face); return face_data? tb_snprintf(data, maxn, "(%s)", impl->element.cstr(&impl->element, face_data, face_info, sizeof(face_info))) : tb_snprintf(data, maxn, "(f%lu)", face->id); }
static tb_char_t const* tb_item_func_uint16_cstr(tb_item_func_t* func, tb_cpointer_t data, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(func && cstr, ""); // format string tb_long_t n = tb_snprintf(cstr, maxn, "%u", (tb_uint16_t)(tb_size_t)data); if (n >= 0 && n < (tb_long_t)maxn) cstr[n] = '\0'; // ok? return (tb_char_t const*)cstr; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ static tb_char_t const* tb_element_obj_cstr(tb_element_ref_t element, tb_cpointer_t data, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(cstr, ""); // format string tb_long_t n = tb_snprintf(cstr, maxn, "<object: %p>", data); if (n >= 0 && n < (tb_long_t)maxn) cstr[n] = '\0'; // ok? return (tb_char_t const*)cstr; }
tb_char_t const* tb_hwaddr_cstr(tb_hwaddr_ref_t hwaddr, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(hwaddr && data && maxn >= TB_HWADDR_CSTR_MAXN, tb_null); // make it tb_long_t size = tb_snprintf(data, maxn - 1, "%02x:%02x:%02x:%02x:%02x:%02x", hwaddr->u8[0], hwaddr->u8[1], hwaddr->u8[2], hwaddr->u8[3], hwaddr->u8[4], hwaddr->u8[5]); if (size >= 0) data[size] = '\0'; // ok return data; }
tb_char_t const* tb_ipv4_cstr(tb_ipv4_ref_t ipv4, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(ipv4 && data && maxn >= TB_IPV4_CSTR_MAXN, tb_null); // make it tb_long_t size = tb_snprintf(data, maxn - 1, "%u.%u.%u.%u", ipv4->u8[0], ipv4->u8[1], ipv4->u8[2], ipv4->u8[3]); if (size >= 0) data[size] = '\0'; // ok return data; }
tb_char_t const* tb_ipv4_get(tb_ipv4_t const* ipv4, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(ipv4 && data && maxn > 15, tb_null); // format tb_size_t size = tb_snprintf(data, maxn, "%{ipv4}", ipv4); data[size] = '\0'; // ok return data; }
static tb_char_t const* gb_tessellator_event_queue_cstr(tb_element_ref_t element, tb_cpointer_t data, tb_char_t* cstr, tb_size_t maxn) { // check gb_mesh_vertex_ref_t event = (gb_mesh_vertex_ref_t)data; tb_assert_and_check_return_val(event, tb_null); // make info tb_long_t size = tb_snprintf(cstr, maxn, "%{mesh_vertex}", event); if (size >= 0) cstr[size] = '\0'; // ok? return cstr; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_utils_md5_main(tb_int_t argc, tb_char_t** argv) { tb_byte_t ob[16]; tb_size_t on = tb_md5_encode((tb_byte_t const*)argv[1], tb_strlen(argv[1]), ob, 16); if (on != 16) return 0; tb_size_t i = 0; tb_char_t md5[256] = {0}; for (i = 0; i < 16; ++i) tb_snprintf(md5 + (i << 1), 3, "%02X", ob[i]); tb_printf("%s: %lu\n", md5, on); return 0; }
static tb_char_t const* gb_tessellator_face_cstr(tb_element_t* func, tb_cpointer_t data, tb_char_t* cstr, tb_size_t maxn) { // check gb_tessellator_face_ref_t face = (gb_tessellator_face_ref_t)data; tb_assert_and_check_return_val(face, tb_null); // make info tb_long_t size = tb_snprintf(cstr, maxn, "inside: %d", face->inside); if (size >= 0) cstr[size] = '\0'; // ok? return cstr; }
static tb_void_t tb_demo_test_cstr_h(tb_size_t index) { // the count tb_size_t count = 1000000; // save func g_func_indx = index; g_func_prev = tb_item_func_str(tb_true); // the func tb_item_func_t func = g_func_prev; func.hash = tb_demo_test_hash_func; // init filter tb_bloom_filter_ref_t filter = tb_bloom_filter_init(TB_BLOOM_FILTER_PROBABILITY_0_001, 1, count, func); if (filter) { // clear random tb_random_clear(tb_random_generator()); // done tb_size_t i = 0; tb_size_t r = 0; tb_char_t s[256] = {0}; tb_hong_t t = tb_mclock(); for (i = 0; i < count; i++) { // the value tb_long_t value = tb_random(); // format it tb_snprintf(s, sizeof(s) - 1, "%ld", value); // set value to filter if (!tb_bloom_filter_set(filter, s)) { // repeat++ r++; } } t = tb_mclock() - t; // trace tb_trace_i("cstr: index: %lu, repeat: %lu, time: %lld ms", index, r, t); // exit filter tb_bloom_filter_exit(filter); } }
static tb_long_t gb_prefix_printf_format_ellipse(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the ellipse gb_ellipse_ref_t ellipse = (gb_ellipse_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(c: %{point}, rx: %{float}, ry: %{float})", &ellipse->c, &ellipse->rx, &ellipse->ry); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_line(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the line gb_line_ref_t line = (gb_line_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(%{point} => %{point})", &line->p0, &line->p1); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_arc(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the arc gb_arc_ref_t arc = (gb_arc_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(c: %{point}, rx: %{float}, ry: %{float}, ab: %{float}, an: %{float})", &arc->c, &arc->rx, &arc->ry, &arc->ab, &arc->an); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_polygon(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the polygon gb_polygon_ref_t polygon = (gb_polygon_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(polygon: %p)", polygon); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_color(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the color gb_color_ref_t color = (gb_color_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(a: %u, r: %u, g: %u, b: %u)", color->a, color->r, color->g, color->b); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
/* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ static tb_long_t tb_network_printf_format_ipv4(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the ipv4 tb_ipv4_ref_t ipv4 = (tb_ipv4_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "%u.%u.%u.%u", ipv4->u8[0], ipv4->u8[1], ipv4->u8[2], ipv4->u8[3]); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_matrix(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the matrix gb_matrix_ref_t matrix = (gb_matrix_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(sx: %{float}, sy: %{float}, kx: %{float}, ky: %{float}, tx: %{float}, ty: %{float})", &matrix->sx, &matrix->sy, &matrix->kx, &matrix->ky, &matrix->tx, &matrix->ty); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_bitmap(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the bitmap gb_bitmap_ref_t bitmap = (gb_bitmap_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(%lux%lu, %s, %u)", gb_bitmap_width(bitmap), gb_bitmap_height(bitmap), gb_pixmap(gb_bitmap_pixfmt(bitmap), 0xff)->name, gb_bitmap_has_alpha(bitmap)); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_long_t gb_prefix_printf_format_rect(tb_cpointer_t object, tb_char_t* cstr, tb_size_t maxn) { // check tb_assert_and_check_return_val(object && cstr && maxn, -1); // the rect gb_rect_ref_t rect = (gb_rect_ref_t)object; // format tb_long_t size = tb_snprintf(cstr, maxn - 1, "(x: %{float}, y: %{float}, w: %{float}, h: %{float})", &rect->x, &rect->y, &rect->w, &rect->h); if (size >= 0) cstr[size] = '\0'; // ok? return size; }
static tb_char_t const* gb_tessellator_vertex_cstr(tb_element_t* func, tb_cpointer_t data, tb_char_t* cstr, tb_size_t maxn) { // check gb_tessellator_vertex_ref_t vertex = (gb_tessellator_vertex_ref_t)data; tb_assert_and_check_return_val(vertex, tb_null); // the vertex base gb_mesh_vertex_ref_t vertex_base = ((gb_mesh_vertex_ref_t)vertex) - 1; // make info tb_long_t size = tb_snprintf(cstr, maxn, "v%lu: %{point}", vertex_base->id, &vertex->point); if (size >= 0) cstr[size] = '\0'; // ok? return cstr; }