tb_size_t tb_wcslcpy(tb_wchar_t* s1, tb_wchar_t const* s2, tb_size_t n) { // check tb_assert_and_check_return_val(s1 && s2, 0); // no size or same? tb_check_return_val(n && s1 != s2, tb_wcslen(s1)); // copy #if 0 tb_wchar_t const* s = s2; --n; while (*s1 = *s2) { if (n) { --n; ++s1; } ++s2; } return s2 - s; #else tb_size_t sn = tb_wcslen(s2); tb_memcpy(s1, s2, tb_min(sn + 1, n) * sizeof(tb_wchar_t)); return tb_min(sn, n); #endif }
tb_wchar_t* tb_wcsncpy(tb_wchar_t* s1, tb_wchar_t const* s2, tb_size_t n) { // check tb_assert_and_check_return_val(s1 && s2, s1); // no size or same? tb_check_return_val(n && s1 != s2, s1); // copy #if 0 tb_wchar_t* s = s1; while (n) { if (*s = *s2) s2++; ++s; --n; } return s1; #else tb_size_t sn = tb_wcslen(s2); tb_size_t cn = tb_min(sn, n); tb_size_t fn = sn < n? n - sn : 0; tb_memcpy(s1, s2, cn * sizeof(tb_wchar_t)); if (fn) tb_memset(s1 + cn, 0, fn * sizeof(tb_wchar_t)); return s1; #endif }
tb_wchar_t* tb_wcscpy(tb_wchar_t* s1, tb_wchar_t const* s2) { tb_assert_and_check_return_val(s1 && s2, tb_null); __tb_register__ tb_wchar_t* s = s1; if (s1 == s2) return s; #if 1 tb_memcpy(s1, s2, (tb_wcslen(s2) + 1) * sizeof(tb_wchar_t)); #elif defined(__tb_small__) while ((*s++ = *s2++)) ; #else while (1) { if (!(s1[0] = s2[0])) break; if (!(s1[1] = s2[1])) break; if (!(s1[2] = s2[2])) break; if (!(s1[3] = s2[3])) break; s1 += 4; s2 += 4; } #endif return s; }
static tb_void_t tb_directory_walk_impl(tb_wchar_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(path && func); // last tb_long_t last = tb_wcslen(path) - 1; tb_assert_and_check_return(last >= 0); // add \*.* tb_wchar_t temp_w[4096] = {0}; tb_char_t temp_a[4096] = {0}; tb_swprintf(temp_w, 4095, L"%s%s*.*", path, path[last] == L'\\'? L"" : L"\\"); // init info WIN32_FIND_DATAW find = {0}; HANDLE directory = INVALID_HANDLE_VALUE; if (INVALID_HANDLE_VALUE != (directory = FindFirstFileW(temp_w, &find))) { // walk do { // check if (tb_wcscmp(find.cFileName, L".") && tb_wcscmp(find.cFileName, L"..")) { // the temp path tb_long_t n = tb_swprintf(temp_w, 4095, L"%s%s%s", path, path[last] == L'\\'? L"" : L"\\", find.cFileName); if (n >= 0 && n < 4096) temp_w[n] = L'\0'; // wtoa temp n = tb_wtoa(temp_a, temp_w, 4095); if (n >= 0 && n < 4096) temp_a[n] = '\0'; // the file info tb_file_info_t info = {0}; if (tb_file_info(temp_a, &info)) { // do callback if (prefix) func(temp_a, &info, priv); // walk to the next directory if (info.type == TB_FILE_TYPE_DIRECTORY && recursion) tb_directory_walk_impl(temp_w, recursion, prefix, func, priv); // do callback if (!prefix) func(temp_a, &info, priv); } } } while (FindNextFileW(directory, &find)); // exit directory FindClose(directory); } }
static tb_void_t tb_test_wcslen(tb_wchar_t const* s) { __tb_volatile__ tb_long_t n = 1000000; __tb_volatile__ tb_long_t r = 0; tb_hong_t t = tb_mclock(); while (n--) { r = tb_wcslen(s); } t = tb_mclock() - t; tb_wprintf(L"%lld ms, tb_test_wcslen(%s) = %ld\n", t, s, r); }
tb_long_t tb_wputs(tb_wchar_t const* string) { // check tb_check_return_val(string, 0); // wtoa tb_char_t line[8192] = {0}; tb_long_t size = tb_wtoa(line, string, 8191); if (size >= 0 && size < 8192) line[size] = '\0'; // print it tb_printl(line); // ok? return tb_wcslen(string); }
tb_long_t tb_wputs(tb_wchar_t const* string) { // check tb_check_return_val(string, 0); // wtoa tb_char_t line[8192] = {0}; tb_long_t size = tb_wtoa(line, string, 8191); tb_assert_and_check_return_val(size != -1, 0); // print it tb_printl(line); // ok? return tb_wcslen(string); }
tb_size_t tb_wcstombs(tb_char_t* s1, tb_wchar_t const* s2, tb_size_t n) { // check tb_assert_and_check_return_val(s1 && s2, 0); // init tb_long_t r = 0; tb_size_t l = tb_wcslen(s2); // atow if (l) { tb_size_t e = (sizeof(tb_wchar_t) == 4)? TB_CHARSET_TYPE_UCS4 : TB_CHARSET_TYPE_UCS2; r = tb_charset_conv_data(e | TB_CHARSET_TYPE_LE, TB_CHARSET_TYPE_UTF8, (tb_byte_t const*)s2, l * sizeof(tb_wchar_t), (tb_byte_t*)s1, n); } // strip if (r >= 0) s1[r] = '\0'; // ok? return r > 0? r : -1; }
/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ tb_wchar_t* tb_wcsirstr(tb_wchar_t const* s1, tb_wchar_t const* s2) { tb_assert_and_check_return_val(s1, tb_null); return tb_wcsnirstr(s1, tb_wcslen(s1), s2); }