PW32CP const struct php_win32_cp *php_win32_cp_get_by_id(DWORD id) {/*{{{*/ size_t i; if (id < php_win32_cp_map[0].id) { switch (id) { case CP_ACP: id = GetACP(); break; case CP_OEMCP: id = GetOEMCP(); break; } } for (i = 0; i < sizeof(php_win32_cp_map)/sizeof(struct php_win32_cp); i++) { if (php_win32_cp_map[i].id == id) { return &php_win32_cp_map[i]; } } SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_FOUND); return NULL; }/*}}}*/
__forceinline static char *php_win32_cp_from_w_int(const wchar_t* in, size_t in_len, size_t *out_len, UINT cp, DWORD flags) {/*{{{*/ int r; int target_len, tmp_len; char* target; if (!in || in_len > INT_MAX) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } assert(in_len ? in[in_len] == '\0' : 1); tmp_len = !in_len ? -1 : (int)in_len + 1; target_len = WideCharToMultiByte(cp, flags, in, tmp_len, NULL, 0, NULL, NULL); if (target_len == 0) { SET_ERRNO_FROM_WIN32_CODE(GetLastError()); return NULL; } target = malloc(target_len); if (target == NULL) { SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); return NULL; } r = WideCharToMultiByte(cp, flags, in, tmp_len, target, target_len, NULL, NULL); if (r == 0) { free(target); SET_ERRNO_FROM_WIN32_CODE(GetLastError()); return NULL; } assert(target ? r == target_len : 1); assert(target ? strlen(target) == target_len - 1 : 1); target[target_len-1] = '\0'; if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { *out_len = target_len - 1; } return target; }/*}}}*/
__forceinline static wchar_t *php_win32_cp_to_w_int(const char* in, size_t in_len, size_t *out_len, UINT cp, DWORD flags) {/*{{{*/ wchar_t *ret; int ret_len, tmp_len; if (!in || in_len > (size_t)INT_MAX) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } assert(in_len ? (in[in_len] == L'\0') : 1); tmp_len = !in_len ? -1 : (int)in_len + 1; ret_len = MultiByteToWideChar(cp, flags, in, tmp_len, NULL, 0); if (ret_len == 0) { SET_ERRNO_FROM_WIN32_CODE(GetLastError()); return NULL; } ret = malloc(ret_len * sizeof(wchar_t)); if (!ret) { SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); return NULL; } tmp_len = MultiByteToWideChar(cp, flags, in, tmp_len, ret, ret_len); if (tmp_len == 0) { free(ret); SET_ERRNO_FROM_WIN32_CODE(GetLastError()); return NULL; } assert(ret ? tmp_len == ret_len : 1); assert(ret ? wcslen(ret) == ret_len - 1 : 1); ret[ret_len-1] = L'\0'; if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { *out_len = ret_len - 1; } return ret; }/*}}}*/
PW32CP wchar_t *php_win32_cp_env_any_to_w(const char* env) {/*{{{*/ wchar_t *envw = NULL, ew[32760]; char *cur = (char *)env, *prev; size_t bin_len = 0; if (!env) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } do { wchar_t *tmp; size_t tmp_len; tmp = php_win32_cp_any_to_w(cur); if (tmp) { tmp_len = wcslen(tmp) + 1; memmove(ew + bin_len, tmp, tmp_len * sizeof(wchar_t)); free(tmp); bin_len += tmp_len; } prev = cur; } while (NULL != (cur = strchr(prev, '\0')) && cur++ && *cur && bin_len + (cur - prev) < 32760); envw = (wchar_t *) malloc((bin_len + 3) * sizeof(wchar_t)); if (!envw) { SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); return NULL; } memmove(envw, ew, bin_len * sizeof(wchar_t)); envw[bin_len] = L'\0'; envw[bin_len + 1] = L'\0'; envw[bin_len + 2] = L'\0'; return envw; }/*}}}*/
PW32CP const struct php_win32_cp *php_win32_cp_get_by_id(DWORD id) {/*{{{*/ size_t i; for (i = 0; i < sizeof(php_win32_cp_map)/sizeof(struct php_win32_cp); i++) { if (php_win32_cp_map[i].id == id) { return &php_win32_cp_map[i]; } } SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_FOUND); return NULL; }/*}}}*/
PW32CP const struct php_win32_cp *php_win32_cp_set_by_id(DWORD id) {/*{{{*/ const struct php_win32_cp *tmp; if (!IsValidCodePage(id)) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } tmp = php_win32_cp_get_by_id(id); if (tmp) { cur_cp = tmp; } return cur_cp; }/*}}}*/
PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size_t *out_len) {/*{{{*/ wchar_t *ret = NULL; const char *idx = in, *end; assert(in && in_len ? in[in_len] == '\0' : 1); if (!in) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } else if (0 == in_len) { /* Not binary safe. */ in_len = strlen(in); if (in_len > (size_t)INT_MAX) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } } end = in + in_len; while (idx != end) { if (!__isascii(*idx) && '\0' != *idx) { break; } idx++; } if (idx == end) { size_t i = 0; int k = 0; wchar_t *ret_idx; ret = malloc((in_len+1)*sizeof(wchar_t)); if (!ret) { SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); return NULL; } ret_idx = ret; do { k = _snwprintf(ret_idx, in_len - i, L"%.*hs", (int)(in_len - i), in); if (-1 == k) { free(ret); SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } i += k + 1; if (i < in_len) { /* Advance as this seems to be a string with \0 in it. */ in += k + 1; ret_idx += k + 1; } } while (i < in_len); ret[in_len] = L'\0'; assert(ret ? wcslen(ret) == in_len : 1); if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { *out_len = in_len; } } else { if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { *out_len = 0; } } return ret; }/*}}}*/