24# include <emmintrin.h>
38__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)
43 if (!in || in_len > (
size_t)
INT_MAX) {
47 assert(in_len ? (in[in_len] == L
'\0') : 1);
49 tmp_len = !in_len ? -1 : (int)in_len + 1;
51 ret_len = MultiByteToWideChar(
cp,
flags, in, tmp_len,
NULL, 0);
57 ret = malloc(ret_len *
sizeof(
wchar_t));
63 tmp_len = MultiByteToWideChar(
cp,
flags, in, tmp_len,
ret, ret_len);
73 ret[ret_len-1] = L
'\0';
76 *out_len = ret_len - 1;
84 return php_win32_cp_to_w_int(in, in_len, out_len,
CP_UTF8, MB_ERR_INVALID_CHARS);
91 ret = php_win32_cp_to_w_int(in, in_len, out_len,
cur_cp->id,
cur_cp->from_w_fl);
98 return php_win32_cp_to_w_int(in, in_len, out_len,
cp,
flags);
101#define ASCII_FAIL_RETURN() \
102 if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { \
108 wchar_t *
ret, *ret_idx;
109 const char *idx = in, *
end;
113 size_t save_in_len = in_len;
116 assert(in && in_len ? in[in_len] ==
'\0' : 1);
121 }
else if (0 == in_len) {
142 uint8x16_t ver_err = {0};
143 while (
end - idx > 15) {
144 const uint8x16_t block = vld1q_u8((
const void*)idx);
145 ver_err = vorrq_u8(ver_err, block);
148 ver_err = vshrq_n_u8(ver_err, 7);
149 if (vmaxvq_u8(ver_err)) {
153 __m128i vec_err = _mm_setzero_si128();
154 while (
end - idx > 15) {
155 const __m128i block = _mm_load_si128((__m128i *)idx);
156 vec_err = _mm_or_si128(vec_err, block);
159 if (_mm_movemask_epi8(vec_err)) {
174 ret = malloc((in_len+1)*
sizeof(
wchar_t));
188 *ret_idx++ = (wchar_t)*idx++;
192 if (
end - idx > 15) {
194 while (
end - idx > 15) {
199 uint8x16x2_t vec = {{
200 vld1q_u8((
const void*)idx),
204 vst2q_u8((
void*)ret_idx, vec);
209 const __m128i mask = _mm_set1_epi32(0);
210 while (
end - idx > 15) {
211 const __m128i block = _mm_load_si128((__m128i *)idx);
213 const __m128i lo = _mm_unpacklo_epi8(block, mask);
214 _mm_storeu_si128((__m128i *)ret_idx, lo);
217 const __m128i hi = _mm_unpackhi_epi8(block, mask);
218 _mm_storeu_si128((__m128i *)ret_idx, hi);
229 *ret_idx++ = (wchar_t)*idx++;
234 assert(
ret && !save_in_len ? wcslen(
ret) == in_len : 1);
242#undef ASCII_FAIL_RETURN
244__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)
247 int target_len, tmp_len;
254 assert(in_len ? in[in_len] ==
'\0' : 1);
256 tmp_len = !in_len ? -1 : (int)in_len + 1;
259 if (target_len == 0) {
264 target = malloc(target_len);
265 if (target ==
NULL) {
270 r = WideCharToMultiByte(
cp,
flags, in, tmp_len, target, target_len,
NULL,
NULL);
277 assert(target ? r == target_len : 1);
278 assert(target && !in_len ?
strlen(target) == target_len - 1 : 1);
280 target[target_len-1] =
'\0';
283 *out_len = target_len - 1;
291 return php_win32_cp_from_w_int(in, in_len, out_len,
CP_UTF8, WC_ERR_INVALID_CHARS);
298 ret = php_win32_cp_from_w_int(in, in_len, out_len,
cur_cp->id,
cur_cp->from_w_fl);
305 return php_win32_cp_from_w_int(in, in_len, out_len,
cp,
flags);
309__forceinline
static char *php_win32_cp_get_enc(
void)
316 }
else if (
SG(default_charset) &&
SG(default_charset)[0] ) {
317 enc =
SG(default_charset);
342 if (
id < php_win32_cp_map[0].
id) {
353 for (i = 0; i <
sizeof(php_win32_cp_map)/
sizeof(
struct php_win32_cp); i++) {
354 if (php_win32_cp_map[i].
id ==
id) {
355 return &php_win32_cp_map[i];
366 size_t enc_len = 0, i;
374 for (i = 0; i <
sizeof(php_win32_cp_map)/
sizeof(
struct php_win32_cp); i++) {
390 while (
NULL != idx) {
410 if (!IsValidCodePage(
id)) {
425 return 65001 ==
cur_cp->id;
430 wchar_t *envw =
NULL, ew[32760];
431 char *cur = (
char *)env, *
prev;
444 size_t tmp_len = wcslen(tmp) + 1;
445 memmove(ew + bin_len, tmp, tmp_len *
sizeof(
wchar_t));
453 }
while (
NULL != (cur =
strchr(
prev,
'\0')) && cur++ && *cur && bin_len + (cur -
prev) < 32760);
455 envw = (
wchar_t *) malloc((bin_len + 3) *
sizeof(
wchar_t));
460 memmove(envw, ew, bin_len *
sizeof(
wchar_t));
461 envw[bin_len] = L
'\0';
462 envw[bin_len + 1] = L
'\0';
463 envw[bin_len + 2] = L
'\0';
468static BOOL php_win32_cp_cli_io_setup(
void)
472 if (
PG(input_encoding) &&
PG(input_encoding)[0]) {
481 if (
PG(output_encoding) &&
PG(output_encoding)[0]) {
500 enc = php_win32_cp_get_enc();
520 php_win32_cp_cli_io_setup();
529 enc = php_win32_cp_get_enc();
564 if (php_win32_cp_cli_io_setup()) {
576 cli_io_restored = cli_io_restored && SetConsoleCP(
orig_in_cp->id);
580 cli_io_restored = cli_io_restored && SetConsoleOutputCP(
orig_out_cp->id);
583 if (cli_io_restored &&
id) {
661 size_t ret_len, tmpw_len;
681 if (string_in_codepage !=
NULL) {
700 if (string_out_codepage !=
NULL) {
sapi_windows_cp_get(string $kind="")
sapi_windows_cp_conv(int|string $in_codepage, int|string $out_codepage, string $subject)
prev(array|object &$array)
sapi_windows_cp_is_utf8()
sapi_windows_cp_set(int $codepage)
strpbrk(string $string, string $characters)
assert(mixed $assertion, Throwable|string|null $description=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
PW32CP const struct php_win32_cp * php_win32_cp_cli_do_restore(DWORD id)
PW32CP BOOL php_win32_cp_use_unicode(void)
PW32CP const struct php_win32_cp * php_win32_cp_shutdown(void)
PW32CP const struct php_win32_cp * php_win32_cp_do_update(const char *enc)
PW32CP wchar_t * php_win32_cp_conv_ascii_to_w(const char *in, size_t in_len, size_t *out_len)
ZEND_TLS const struct php_win32_cp * cur_out_cp
PW32CP wchar_t * php_win32_cp_conv_cur_to_w(const char *in, size_t in_len, size_t *out_len)
PW32CP const struct php_win32_cp * php_win32_cp_get_current(void)
#define ASCII_FAIL_RETURN()
PW32CP const struct php_win32_cp * php_win32_cp_set_by_id(DWORD id)
ZEND_TLS const struct php_win32_cp * orig_in_cp
PW32CP char * php_win32_cp_conv_w_to_cur(const wchar_t *in, size_t in_len, size_t *out_len)
PW32CP const struct php_win32_cp * php_win32_cp_do_setup(const char *enc)
PW32CP wchar_t * php_win32_cp_conv_to_w(DWORD cp, DWORD flags, const char *in, size_t in_len, size_t *out_len)
PW32CP const struct php_win32_cp * php_win32_cp_get_orig(void)
PW32CP wchar_t * php_win32_cp_conv_utf8_to_w(const char *in, size_t in_len, size_t *out_len)
ZEND_TLS const struct php_win32_cp * cur_in_cp
PW32CP const struct php_win32_cp * php_win32_cp_get_by_enc(const char *enc)
ZEND_TLS const struct php_win32_cp * cur_cp
ZEND_TLS const struct php_win32_cp * orig_cp
PW32CP const struct php_win32_cp * php_win32_cp_cli_do_setup(DWORD id)
ZEND_TLS const struct php_win32_cp * orig_out_cp
PW32CP const struct php_win32_cp * php_win32_cp_get_by_id(DWORD id)
PW32CP wchar_t * php_win32_cp_env_any_to_w(const char *env)
PW32CP char * php_win32_cp_conv_w_to_utf8(const wchar_t *in, size_t in_len, size_t *out_len)
PW32CP char * php_win32_cp_conv_from_w(DWORD cp, DWORD flags, const wchar_t *in, size_t in_len, size_t *out_len)
#define php_win32_cp_setup()
#define php_win32_cp_any_to_w(in)
#define PHP_WIN32_CP_IGNORE_LEN_P
PHP_WINUTIL_API BOOL php_win32_console_is_cli_sapi(void)
PHPAPI bool php_get_module_initialized(void)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
const mbfl_encoding * internal_encoding
unsigned const char * end
#define SET_ERRNO_FROM_WIN32_CODE(err)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
#define ZEND_PARSE_PARAMETERS_END()
#define zend_parse_parameters_none()
#define Z_PARAM_STR(dest)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_STR_OR_LONG(dest_str, dest_long)
#define RETVAL_STRINGL(s, l)
struct _zend_string zend_string
ZEND_API const char * zend_multibyte_get_encoding_name(const zend_encoding *encoding)
ZEND_API const zend_encoding * zend_multibyte_get_internal_encoding(void)
struct _zend_encoding zend_encoding
ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2)
#define ZEND_SLIDE_TO_ALIGNED16(ptr)
#define ZEND_LONG_UINT_OVFL(zlong)
#define ZEND_SIZE_T_INT_OVFL(size)
#define zend_string_equals_literal_ci(str, c)