/* ////////////////////////////////////////////////////////////////////////////////////// * implementions */ gb_pixmap_ref_t gb_pixmap(tb_size_t pixfmt, tb_byte_t alpha) { // big endian? tb_size_t bendian = GB_PIXFMT_BE(pixfmt); // the pixfmt pixfmt = GB_PIXFMT(pixfmt); tb_assert_abort(pixfmt); // opaque? if (alpha > GB_ALPHA_MAXN) { // check tb_assert_abort(pixfmt && (pixfmt - 1) < tb_arrayn(g_pixmaps_lo)); // ok return bendian? g_pixmaps_bo[pixfmt - 1] : g_pixmaps_lo[pixfmt - 1]; } // alpha? else if (alpha >= GB_ALPHA_MINN) { // check tb_assert_abort(pixfmt && (pixfmt - 1) < tb_arrayn(g_pixmaps_la)); // ok return bendian? g_pixmaps_ba[pixfmt - 1] : g_pixmaps_la[pixfmt - 1]; } // transparent return tb_null; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t main(tb_int_t argc, tb_char_t** argv) { // init tbox #if 0 if (!tb_init(tb_null, tb_default_allocator((tb_byte_t*)malloc(300 * 1024 * 1024), 300 * 1024 * 1024))) return -1; #elif 0 if (!tb_init(tb_null, tb_static_allocator((tb_byte_t*)malloc(300 * 1024 * 1024), 300 * 1024 * 1024))) return -1; #elif (defined(__tb_valgrind__) && defined(TB_CONFIG_VALGRIND_HAVE_VALGRIND_STACK_REGISTER)) \ || defined(__tb_sanitize_address__) || defined(__tb_sanitize_thread__) if (!tb_init(tb_null, tb_native_allocator())) return -1; #else if (!tb_init(tb_null, tb_null)) return -1; #endif // find the main func from the first argument tb_int_t ok = 0; tb_char_t const* name = tb_null; if (argc > 1 && argv[1]) { tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) { // find it? if (g_demo[i].name && !tb_stricmp(g_demo[i].name, argv[1])) { // save name name = g_demo[i].name; // done main ok = g_demo[i].main(argc - 1, argv + 1); break; } } } // no this demo? help it if (!name) { tb_trace_i("======================================================================"); tb_trace_i("Usages: xmake r demo [testname] arguments ..."); tb_trace_i(""); tb_trace_i(".e.g"); tb_trace_i(" xmake r demo stream http://www.xxxxx.com /tmp/a"); tb_trace_i(""); // walk name tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) tb_trace_i("testname: %s", g_demo[i].name); } // exit tbox tb_exit(); // ok? return ok; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t main(tb_int_t argc, tb_char_t** argv) { // init tbox #if 1 if (!tb_init(tb_null, tb_static_allocator((tb_byte_t*)malloc(1024 * 1024), 1024 * 1024))) return 0; #else if (!tb_init(tb_null, tb_native_allocator())) return 0; #endif // find the main func from the first argument tb_int_t ok = 0; tb_char_t const* name = tb_null; if (argc > 1 && argv[1]) { tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) { // find it? if (g_demo[i].name && !tb_stricmp(g_demo[i].name, argv[1])) { // save name name = g_demo[i].name; // done main ok = g_demo[i].main(argc - 1, argv + 1); break; } } } // no this demo? help it if (!name) { tb_trace_i("======================================================================"); tb_trace_i("Usages: xmake r demo [testname] arguments ..."); tb_trace_i(""); tb_trace_i(".e.g"); tb_trace_i(" xmake r demo stream http://www.xxxxx.com /tmp/a"); tb_trace_i(""); // walk name tb_size_t i = 0; tb_size_t n = tb_arrayn(g_demo); for (i = 0; i < n; i++) tb_trace_i("testname: %s", g_demo[i].name); } // exit tbox tb_exit(); // ok? return ok; }
tb_zip_ref_t tb_zip_init(tb_size_t algo, tb_size_t action) { // table static tb_zip_ref_t (*s_init[])(tb_size_t action) = { tb_null , tb_zip_rlc_init , tb_null , tb_null , tb_null #ifdef TB_CONFIG_PACKAGE_HAVE_ZLIB , tb_zip_zlibraw_init , tb_zip_zlib_init , tb_zip_gzip_init #else , tb_null , tb_null , tb_null #endif , tb_null }; tb_assert_and_check_return_val(algo < tb_arrayn(s_init) && s_init[algo], tb_null); // init return s_init[algo](action); }
tb_void_t tb_zip_exit(tb_zip_ref_t zip) { // check tb_assert_and_check_return(zip); // table static tb_void_t (*s_exit[])(tb_zip_ref_t zip) = { tb_null , tb_zip_rlc_exit , tb_null , tb_null , tb_null #ifdef TB_CONFIG_PACKAGE_HAVE_ZLIB , tb_zip_zlibraw_exit , tb_zip_zlib_exit , tb_zip_gzip_exit #else , tb_null , tb_null , tb_null #endif , tb_null }; tb_assert_and_check_return(zip->algo < tb_arrayn(s_exit) && s_exit[zip->algo]); // exit s_exit[zip->algo](zip); }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_aico_ref_t tb_aico_init(tb_aicp_ref_t aicp) { // check tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)aicp; tb_assert_and_check_return_val(aicp_impl && aicp_impl->pool, tb_null); // enter tb_spinlock_enter(&aicp_impl->lock); // make aico tb_aico_impl_t* aico = (tb_aico_impl_t*)tb_fixed_pool_malloc0(aicp_impl->pool); // init aico if (aico) { aico->aicp = aicp; aico->type = TB_AICO_TYPE_NONE; aico->handle = tb_null; aico->state = TB_STATE_CLOSED; // init timeout tb_size_t i = 0; tb_size_t n = tb_arrayn(aico->timeout); for (i = 0; i < n; i++) aico->timeout[i] = -1; } // leave tb_spinlock_leave(&aicp_impl->lock); // ok? return (tb_aico_ref_t)aico; }
static __tb_inline__ tb_void_t g2_gl_draw_apply_wrap(g2_gl_draw_t* draw) { // wrap static g2_GLuint_t wrap[] = { G2_GL_CLAMP_TO_BORDER , G2_GL_CLAMP_TO_BORDER , G2_GL_CLAMP_TO_EDGE , G2_GL_REPEAT , G2_GL_MIRRORED_REPEAT }; tb_assert(draw->shader->wrap < tb_arrayn(wrap)); // wrap switch (draw->shader->type) { case G2_GL_SHADER_TYPE_BITMAP: g2_glTexParameteri(G2_GL_TEXTURE_2D, G2_GL_TEXTURE_WRAP_S, wrap[draw->shader->wrap]); g2_glTexParameteri(G2_GL_TEXTURE_2D, G2_GL_TEXTURE_WRAP_T, wrap[draw->shader->wrap]); break; case G2_GL_SHADER_TYPE_LINEAR: case G2_GL_SHADER_TYPE_RADIAL: g2_glTexParameteri(G2_GL_TEXTURE_2D, G2_GL_TEXTURE_WRAP_S, wrap[draw->shader->wrap]); g2_glTexParameteri(G2_GL_TEXTURE_2D, G2_GL_TEXTURE_WRAP_T, G2_GL_CLAMP_TO_EDGE); break; default: break; } }
tb_void_t tb_small_pool_dump(tb_small_pool_ref_t pool) { // check tb_small_pool_impl_t* impl = (tb_small_pool_impl_t*)pool; tb_assert_and_check_return(impl && impl->large_pool); // trace tb_trace_i(""); // dump fixed pool tb_size_t i = 0; tb_size_t n = tb_arrayn(impl->fixed_pool); for (i = 0; i < n; i++) { // exists? if (impl->fixed_pool[i]) { // check it tb_fixed_pool_walk(impl->fixed_pool[i], tb_small_pool_item_check, (tb_cpointer_t)impl->fixed_pool[i]); // dump it tb_fixed_pool_dump(impl->fixed_pool[i]); } } }
tb_double_t tb_sbtod(tb_char_t const* s, tb_int_t base) { // check tb_assert_and_check_return_val(s, 0); // the convect functions static tb_double_t (*s_conv[])(tb_char_t const*) = { tb_null , tb_null , tb_s2tod , tb_null , tb_null , tb_null , tb_null , tb_null , tb_s8tod , tb_null , tb_s10tod , tb_null , tb_null , tb_null , tb_null , tb_null , tb_s16tod }; tb_assert_and_check_return_val(base < tb_arrayn(s_conv) && s_conv[base], 0); // convect it return s_conv[base](s); }
/* ////////////////////////////////////////////////////////////////////////////////////// * spak */ static __tb_inline__ tb_size_t tb_aiop_aioe_code(tb_aice_ref_t aice) { // the aioe code static tb_size_t s_code[] = { TB_AIOE_CODE_NONE , TB_AIOE_CODE_ACPT //< acpt , TB_AIOE_CODE_CONN //< conn , TB_AIOE_CODE_RECV //< recv , TB_AIOE_CODE_SEND //< send , TB_AIOE_CODE_RECV //< urecv , TB_AIOE_CODE_SEND //< usend , TB_AIOE_CODE_RECV //< recvv , TB_AIOE_CODE_SEND //< sendv , TB_AIOE_CODE_RECV //< urecvv , TB_AIOE_CODE_SEND //< usendv , TB_AIOE_CODE_SEND //< sendf , TB_AIOE_CODE_NONE , TB_AIOE_CODE_NONE , TB_AIOE_CODE_NONE , TB_AIOE_CODE_NONE , TB_AIOE_CODE_NONE , TB_AIOE_CODE_NONE }; tb_assert_and_check_return_val(aice->code && aice->code < tb_arrayn(s_code), TB_AIOE_CODE_NONE); // the aioe code return s_code[aice->code]; }
tb_object_ref_t tb_oc_reader_done(tb_stream_ref_t stream) { // check tb_assert_and_check_return_val(stream, tb_null); // probe it tb_size_t i = 0; tb_size_t n = tb_arrayn(g_reader); tb_size_t m = 0; tb_size_t f = 0; for (i = 0; i < n && m < 100; i++) { // the reader tb_oc_reader_t* reader = g_reader[i]; if (reader && reader->probe) { // the probe score tb_size_t score = reader->probe(stream); if (score > m) { m = score; f = i; } } } // ok? read it return (m && g_reader[f] && g_reader[f]->read)? g_reader[f]->read(stream) : tb_null; }
/* /////////////////////////////////////////////////////////////////////// * implementation */ g2_image_decoder_t* g2_image_decoder_init(tb_size_t pixfmt, tb_gstream_t* gst) { // init the image decoder list static g2_image_decoder_t* (*init[])(tb_size_t , tb_gstream_t* ) = { tb_null #ifdef TB_CONFIG_JPG , g2_jpg_decoder_init #endif #ifdef TB_CONFIG_PNG , g2_png_decoder_init #endif , g2_bmp_decoder_init , g2_gif_decoder_init }; // try initing it tb_size_t i = 1; tb_size_t n = tb_arrayn(init); g2_image_decoder_t* decoder = tb_null; for (i = 0; i < n; i++) { if (init[i] && (decoder = init[i](pixfmt, gst))) return decoder; } return tb_null; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_char_t const* tb_http_method_cstr(tb_size_t method) { // check tb_assert_and_check_return_val(method < tb_arrayn(g_http_methods), tb_null); // ok return g_http_methods[method]; }
gb_color_t const gb_color_from_index(tb_size_t index) { // check tb_assert_and_check_return_val(index < tb_arrayn(g_named_colors), GB_COLOR_DEFAULT); // ok return g_named_colors[index].color; }
tb_void_t tb_aico_timeout_set(tb_aico_ref_t aico, tb_size_t type, tb_long_t timeout) { // check tb_aico_impl_t* impl = (tb_aico_impl_t*)aico; tb_assert_and_check_return(impl && type < tb_arrayn(impl->timeout)); // set the impl timeout tb_atomic_set((tb_atomic_t*)(impl->timeout + type), timeout); }
tb_long_t tb_aico_timeout(tb_aico_ref_t aico, tb_size_t type) { // check tb_aico_impl_t* impl = (tb_aico_impl_t*)aico; tb_assert_and_check_return_val(impl && type < tb_arrayn(impl->timeout), -1); // the impl timeout return tb_atomic_get((tb_atomic_t*)(impl->timeout + type)); }
tb_cpointer_t tb_thread_pool_worker_getp(tb_thread_pool_worker_ref_t worker, tb_size_t index) { // check tb_thread_pool_worker_t* worker_impl = (tb_thread_pool_worker_t*)worker; tb_assert_and_check_return_val(worker_impl && index < tb_arrayn(worker_impl->priv), tb_null); // get the private data return worker_impl->priv[index].priv; }
tb_oc_reader_t* tb_oc_reader_get(tb_size_t format) { // check format &= 0x00ff; tb_assert_and_check_return_val((format < tb_arrayn(g_reader)), tb_null); // ok return g_reader[format]; }
static tb_void_t tb_aiop_spak_wait_timeout(tb_bool_t killed, tb_cpointer_t priv) { // the aico tb_aiop_aico_t* aico = (tb_aiop_aico_t*)priv; tb_assert_and_check_return(aico && aico->waiting); // the impl tb_aiop_ptor_impl_t* impl = aico->impl; tb_assert_and_check_return(impl && impl->aiop); // for sock if (aico->base.type == TB_AICO_TYPE_SOCK) { // check tb_assert_and_check_return(aico->aioo); // delo aioo tb_aiop_delo(impl->aiop, aico->aioo); aico->aioo = tb_null; } // have been waited ok for the spak loop? need not spak it repeatly tb_bool_t ok = tb_false; if (!aico->wait_ok) { // the priority tb_size_t priority = tb_aice_impl_priority(&aico->aice); tb_assert_and_check_return(priority < tb_arrayn(impl->spak) && impl->spak[priority]); // trace tb_trace_d("wait: timeout: code: %lu, priority: %lu, time: %lld", aico->aice.code, priority, tb_cache_time_mclock()); // enter tb_spinlock_enter(&impl->lock); // spak aice if (!tb_queue_full(impl->spak[priority])) { // save state aico->aice.state = killed? TB_STATE_KILLED : TB_STATE_TIMEOUT; // put it tb_queue_put(impl->spak[priority], &aico->aice); // ok ok = tb_true; aico->wait_ok = 1; } else tb_assert(0); // leave tb_spinlock_leave(&impl->lock); } // work it if (ok) tb_aiop_spak_work(impl); }
/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ tb_dns_looker_ref_t tb_dns_looker_init(tb_char_t const* name) { // check tb_assert_and_check_return_val(name, tb_null); // must be not address tb_assert(!tb_ipaddr_ip_cstr_set(tb_null, name, TB_IPADDR_FAMILY_NONE)); // done tb_bool_t ok = tb_false; tb_dns_looker_t* looker = tb_null; do { // make looker looker = tb_malloc0_type(tb_dns_looker_t); tb_assert_and_check_return_val(looker, tb_null); // dump server // tb_dns_server_dump(); // get the dns server list looker->maxn = tb_dns_server_get(looker->list); tb_check_break(looker->maxn && looker->maxn <= tb_arrayn(looker->list)); // init name if (!tb_static_string_init(&looker->name, (tb_char_t*)looker->data, TB_DNS_NAME_MAXN)) break; tb_static_string_cstrcpy(&looker->name, name); // init rpkt if (!tb_static_buffer_init(&looker->rpkt, looker->data + TB_DNS_NAME_MAXN, TB_DNS_RPKT_MAXN)) break; // init family looker->family = TB_IPADDR_FAMILY_IPV4; // init sock looker->sock = tb_socket_init(TB_SOCKET_TYPE_UDP, looker->family); tb_assert_and_check_break(looker->sock); // init itor looker->itor = 1; // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (looker) tb_dns_looker_exit((tb_dns_looker_ref_t)looker); looker = tb_null; } // ok? return (tb_dns_looker_ref_t)looker; }
static tb_wchar_t* tb_printf_object(tb_wchar_t* pb, tb_wchar_t* pe, tb_printf_entry_t e, tb_cpointer_t object) { // the object name tb_char_t data[1024] = {0}; tb_wtoa(data, e.object, tb_arrayn(data)); // find the object func tb_printf_object_func_t func = tb_printf_object_find(data); if (func) { // printf it tb_long_t size = func(object, data, tb_arrayn(data) - 1); if (size >= 0) { // end data[size] = '\0'; // atow size = tb_atow(pb, data, pe - pb); if (size >= 0) pb += size; } else { // invalid if (pb < pe) *pb++ = L'i'; if (pb < pe) *pb++ = L'n'; if (pb < pe) *pb++ = L'v'; if (pb < pe) *pb++ = L'a'; if (pb < pe) *pb++ = L'l'; if (pb < pe) *pb++ = L'i'; if (pb < pe) *pb++ = L'd'; } } else { // null if (pb < pe) *pb++ = L'n'; if (pb < pe) *pb++ = L'u'; if (pb < pe) *pb++ = L'l'; if (pb < pe) *pb++ = L'l'; } return pb; }
tb_void_t tb_thread_pool_worker_setp(tb_thread_pool_worker_ref_t worker, tb_size_t index, tb_thread_pool_priv_exit_func_t exit, tb_cpointer_t priv) { // check tb_thread_pool_worker_t* worker_impl = (tb_thread_pool_worker_t*)worker; tb_assert_and_check_return(worker_impl && index < tb_arrayn(worker_impl->priv)); // set the private data worker_impl->priv[index].exit = exit; worker_impl->priv[index].priv = priv; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_libc_mbstowcs_main(tb_int_t argc, tb_char_t** argv) { // convert it tb_wchar_t data[256]; tb_size_t size = tb_mbstowcs(data, "中文", tb_arrayn(data)); tb_assert_and_check_return_val(size != -1, 0); // trace tb_wprintf(L"中文: %s\n", data); return 0; }
static tb_charset_ref_t tb_charset_find_by_name(tb_char_t const* name) { // init iterator tb_iterator_t iterator = tb_iterator_init_mem(g_charsets, tb_arrayn(g_charsets), sizeof(tb_charset_t)); // find it by the binary search tb_size_t itor = tb_binary_find_all_if(&iterator, tb_charset_comp_by_name, name); // ok? if (itor != tb_iterator_tail(&iterator)) return (tb_charset_ref_t)tb_iterator_item(&iterator, itor); else return tb_null; }
static tb_charset_ref_t tb_charset_find_by_type(tb_size_t type) { // init iterator tb_iterator_t iterator = tb_iterator_init_mem(g_charsets, tb_arrayn(g_charsets), sizeof(tb_charset_t)); // find it by the binary search tb_size_t itor = tb_binary_find_all_if(&iterator, tb_charset_comp_by_type, (tb_cpointer_t)TB_CHARSET_TYPE(type)); // ok? if (itor != tb_iterator_tail(&iterator)) return (tb_charset_ref_t)tb_iterator_item(&iterator, itor); else return tb_null; }
/* ////////////////////////////////////////////////////////////////////////////////////// * malloc implementation */ static __tb_inline__ tb_size_t tb_static_large_allocator_pred_index(tb_static_large_allocator_ref_t allocator, tb_size_t space) { #ifndef TB_CONFIG_MICRO_ENABLE // the size tb_size_t size = sizeof(tb_static_large_data_head_t) + space; tb_assert(!(size & (allocator->page_size - 1))); // the page count size /= allocator->page_size; // the pred index #if 0 tb_size_t indx = tb_ilog2i(tb_align_pow2(size)); #else // faster tb_size_t indx = size > 1? (tb_ilog2i((tb_uint32_t)(size - 1)) + 1) : 0; #endif if (indx >= tb_arrayn(allocator->data_pred)) indx = tb_arrayn(allocator->data_pred) - 1; return indx; #else return 0; #endif }
static tb_bool_t tb_environment_set_impl(tb_char_t const* name, tb_char_t const* value) { // check tb_assert_and_check_return_val(name, tb_false); // done tb_bool_t ok = tb_false; tb_size_t size = 0; tb_wchar_t* value_w = tb_null; tb_size_t value_n = 0; do { // make name tb_wchar_t name_w[512] = {0}; tb_size_t name_n = tb_atow(name_w, name, tb_arrayn(name_w)); tb_assert_and_check_break(name_n); // exists value? if (value) { // make value value_n = tb_strlen(value); value_w = (tb_wchar_t*)tb_malloc0(sizeof(tb_wchar_t) * (value_n + 1)); tb_assert_and_check_break(value_w); // init value if (!tb_atow(value_w, value, value_n + 1)) break; // set it if (!tb_kernel32()->SetEnvironmentVariableW(name_w, value_w)) break; } // remove this variable else { // remove it if (!tb_kernel32()->SetEnvironmentVariableW(name_w, tb_null)) break; } // ok ok = tb_true; } while (0); // exit data if (value_w) tb_free(value_w); value_w = tb_null; // ok? return ok; }
tb_void_t tb_small_pool_clear(tb_small_pool_ref_t pool) { // check tb_small_pool_impl_t* impl = (tb_small_pool_impl_t*)pool; tb_assert_and_check_return(impl && impl->large_pool); // clear fixed pool tb_size_t i = 0; tb_size_t n = tb_arrayn(impl->fixed_pool); for (i = 0; i < n; i++) { // clear it if (impl->fixed_pool[i]) tb_fixed_pool_clear(impl->fixed_pool[i]); } }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t tb_oc_reader_set(tb_size_t format, tb_oc_reader_t* reader) { // check format &= 0x00ff; tb_assert_and_check_return_val(reader && (format < tb_arrayn(g_reader)), tb_false); // exit the older reader if exists tb_oc_reader_remove(format); // set g_reader[format] = reader; // ok return tb_true; }
tb_void_t tb_oc_reader_remove(tb_size_t format) { // check format &= 0x00ff; tb_assert_and_check_return((format < tb_arrayn(g_reader))); // exit it if (g_reader[format]) { // exit hooker if (g_reader[format]->hooker) tb_hash_map_exit(g_reader[format]->hooker); g_reader[format]->hooker = tb_null; // clear it g_reader[format] = tb_null; } }