34#ifdef ZEND_INTRIN_AVX2_NATIVE
37# include <immintrin.h>
38# define mb_utf16be_to_wchar mb_utf16be_to_wchar_avx2
39# define mb_utf16le_to_wchar mb_utf16le_to_wchar_avx2
40# define mb_wchar_to_utf16be mb_wchar_to_utf16be_avx2
41# define mb_wchar_to_utf16le mb_wchar_to_utf16le_avx2
43static size_t mb_utf16be_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
45static size_t mb_utf16le_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
48#elif defined(ZEND_INTRIN_AVX2_RESOLVER)
52# include <immintrin.h>
55static size_t mb_utf16be_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
57static size_t mb_utf16le_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
60# ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
78 return zend_cpu_supports_avx2() ? mb_utf16be_to_wchar_avx2 : mb_utf16be_to_wchar_default;
85 return zend_cpu_supports_avx2() ? mb_wchar_to_utf16be_avx2 : mb_wchar_to_utf16be_default;
92 return zend_cpu_supports_avx2() ? mb_utf16le_to_wchar_avx2 : mb_utf16le_to_wchar_default;
99 return zend_cpu_supports_avx2() ? mb_wchar_to_utf16le_avx2 : mb_wchar_to_utf16le_default;
108#ifdef HAVE_FUNC_ATTRIBUTE_TARGET
109static size_t mb_utf16be_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
__attribute__((target(
"avx2")));
111static size_t mb_utf16le_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
__attribute__((target(
"avx2")));
114static size_t mb_utf16be_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
116static size_t mb_utf16le_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
127 return utf16be_to_wchar_ptr(in, in_len,
buf, bufsize,
NULL);
137 return utf16le_to_wchar_ptr(in, in_len,
buf, bufsize,
NULL);
145void init_convert_utf16(
void)
147 if (zend_cpu_supports_avx2()) {
148 utf16be_to_wchar_ptr = mb_utf16be_to_wchar_avx2;
149 wchar_to_utf16be_ptr = mb_wchar_to_utf16be_avx2;
150 utf16le_to_wchar_ptr = mb_utf16le_to_wchar_avx2;
151 wchar_to_utf16le_ptr = mb_wchar_to_utf16le_avx2;
153 utf16be_to_wchar_ptr = mb_utf16be_to_wchar_default;
154 wchar_to_utf16be_ptr = mb_wchar_to_utf16be_default;
155 utf16le_to_wchar_ptr = mb_utf16le_to_wchar_default;
156 wchar_to_utf16le_ptr = mb_wchar_to_utf16le_default;
164# define mb_utf16be_to_wchar mb_utf16be_to_wchar_default
165# define mb_utf16le_to_wchar mb_utf16le_to_wchar_default
166# define mb_wchar_to_utf16be mb_wchar_to_utf16be_default
167# define mb_wchar_to_utf16le mb_wchar_to_utf16le_default
169static size_t mb_utf16be_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
171static size_t mb_utf16le_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
177static size_t mb_utf16_to_wchar(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state);
178static zend_string* mb_cut_utf16(
unsigned char *str,
size_t from,
size_t len,
unsigned char *
end);
179static zend_string* mb_cut_utf16be(
unsigned char *str,
size_t from,
size_t len,
unsigned char *
end);
180static zend_string* mb_cut_utf16le(
unsigned char *str,
size_t from,
size_t len,
unsigned char *
end);
182static const char *mbfl_encoding_utf16_aliases[] = {
"utf16",
NULL};
188 mbfl_encoding_utf16_aliases,
235 mbfl_filt_conv_utf16_wchar_flush,
255 mbfl_filt_conv_utf16_wchar_flush,
275 mbfl_filt_conv_utf16_wchar_flush,
289#define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
295 if (filter->
status == 0) {
296 filter->
cache = c & 0xFF;
299 int n = (filter->
cache << 8) | (c & 0xFF);
306 if (
n >= 0xD800 &&
n <= 0xDBFF) {
307 filter->
cache =
n & 0x3FF;
310 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
313 }
else if (
n != 0xFEFF) {
328 filter->
cache = c & 0xFF;
333 n = (filter->
cache << 8) | (c & 0xFF);
334 if (
n >= 0xD800 &&
n <= 0xDBFF) {
335 filter->
cache =
n & 0x3FF;
337 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
348 filter->
cache = (filter->
cache << 8) | (c & 0xFF);
353 n = ((filter->
cache & 0xFF) << 8) | (c & 0xFF);
354 if (
n >= 0xD800 &&
n <= 0xDBFF) {
356 filter->
cache =
n & 0x3FF;
359 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
361 n = ((filter->
cache & 0x3FF00) << 2) + (
n & 0x3FF) + 0x10000;
381 n = ((c >> 10) - 0x40) | 0xd800;
384 n = (c & 0x3ff) | 0xdc00;
400 filter->
cache = c & 0xff;
405 if ((c & 0xfc) == 0xd8) {
407 filter->
cache += ((c & 0x3) << 8);
409 }
else if ((c & 0xfc) == 0xdc) {
420 filter->
cache = (filter->
cache << 10) + (c & 0xff);
425 n = (filter->
cache & 0xFF) | ((c & 0xFF) << 8);
426 if (
n >= 0xD800 &&
n <= 0xDBFF) {
429 filter->
cache =
n & 0x3FF;
432 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
433 n = filter->
cache + ((c & 0x3) << 8) + 0x10000;
457 n = ((c >> 10) - 0x40) | 0xd800;
460 n = (c & 0x3ff) | 0xdc00;
488static size_t mb_utf16_to_wchar(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
494 }
else if (*in_len >= 2) {
495 unsigned char *
p = *in;
496 unsigned char c1 = *
p++;
497 unsigned char c2 = *
p++;
498 uint16_t
n = (c1 << 8) | c2;
517static size_t mb_utf16be_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
520 unsigned char *
p = *in, *e =
p + (*in_len & ~1);
523 uint32_t *
out =
buf, *limit =
buf + bufsize - 1;
525 while (
p < e &&
out < limit) {
526 unsigned char c1 = *
p++;
527 unsigned char c2 = *
p++;
528 uint16_t
n = (c1 << 8) | c2;
530 if (
n >= 0xD800 &&
n <= 0xDBFF) {
533 unsigned char c3 = *
p++;
534 unsigned char c4 = *
p++;
535 uint16_t n2 = (c3 << 8) | c4;
537 if (n2 >= 0xD800 && n2 <= 0xDBFF) {
541 }
else if (n2 >= 0xDC00 && n2 <= 0xDFFF) {
542 *
out++ = (((
n & 0x3FF) << 10) | (n2 & 0x3FF)) + 0x10000;
551 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
559 if (
p == e && (*in_len & 0x1) &&
out < limit) {
565 *in_len -= (
p - *in);
572 unsigned char *
out, *limit;
580 out = mb_convert_buf_add2(
out, (w >> 8) & 0xFF, w & 0xFF);
582 uint16_t n1 = ((w >> 10) - 0x40) | 0xD800;
583 uint16_t n2 = (w & 0x3FF) | 0xDC00;
585 out = mb_convert_buf_add4(
out, (n1 >> 8) & 0xFF, n1 & 0xFF, (n2 >> 8) & 0xFF, n2 & 0xFF);
595static size_t mb_utf16le_to_wchar_default(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
598 unsigned char *
p = *in, *e =
p + (*in_len & ~1);
601 uint32_t *
out =
buf, *limit =
buf + bufsize - 1;
603 while (
p < e &&
out < limit) {
604 unsigned char c1 = *
p++;
605 unsigned char c2 = *
p++;
606 uint16_t
n = (c2 << 8) | c1;
608 if (
n >= 0xD800 &&
n <= 0xDBFF) {
611 unsigned char c3 = *
p++;
612 unsigned char c4 = *
p++;
613 uint16_t n2 = (c4 << 8) | c3;
615 if (n2 >= 0xD800 && n2 <= 0xDBFF) {
619 }
else if (n2 >= 0xDC00 && n2 <= 0xDFFF) {
620 *
out++ = (((
n & 0x3FF) << 10) | (n2 & 0x3FF)) + 0x10000;
629 }
else if (
n >= 0xDC00 &&
n <= 0xDFFF) {
637 if (
p == e && (*in_len & 0x1) &&
out < limit) {
643 *in_len -= (
p - *in);
650 unsigned char *
out, *limit;
658 out = mb_convert_buf_add2(
out, w & 0xFF, (w >> 8) & 0xFF);
660 uint16_t n1 = ((w >> 10) - 0x40) | 0xD800;
661 uint16_t n2 = (w & 0x3FF) | 0xDC00;
663 out = mb_convert_buf_add4(
out, n1 & 0xFF, (n1 >> 8) & 0xFF, n2 & 0xFF, (n2 >> 8) & 0xFF);
673#if defined(ZEND_INTRIN_AVX2_NATIVE) || defined(ZEND_INTRIN_AVX2_RESOLVER)
675#ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
676size_t mb_utf16be_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
678static size_t mb_utf16be_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
681 size_t len = *in_len;
683 if (
len >= 32 && bufsize >= 16) {
684 unsigned char *
p = *in;
688 const __m256i _f8 = _mm256_set1_epi16(0xF8);
689 const __m256i _d8 = _mm256_set1_epi16(0xD8);
692 const __m256i swap_bytes = _mm256_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
695 __m256i operand = _mm256_loadu_si256((__m256i*)
p);
697 uint32_t surrogate_bitvec = _mm256_movemask_epi8(_mm256_cmpeq_epi16(_mm256_and_si256(operand, _f8), _d8));
698 if (surrogate_bitvec == 0) {
702 operand = _mm256_shuffle_epi8(operand, swap_bytes);
703 _mm256_storeu_si256((__m256i*)
out, _mm256_cvtepu16_epi32(_mm256_castsi256_si128(operand)));
704 _mm256_storeu_si256((__m256i*)(
out + 8), _mm256_cvtepu16_epi32(_mm256_extracti128_si256(operand, 1)));
707 p +=
sizeof(__m256i);
708 len -=
sizeof(__m256i);
709 }
else if ((surrogate_bitvec & 1) == 0) {
711 uint8_t n_chars = zend_ulong_ntz(surrogate_bitvec) >> 1;
712 operand = _mm256_shuffle_epi8(operand, swap_bytes);
718 _mm256_storeu_si256((__m256i*)
out, _mm256_cvtepu16_epi32(_mm256_castsi256_si128(operand)));
720 _mm256_storeu_si256((__m256i*)(
out + 8), _mm256_cvtepu16_epi32(_mm256_extracti128_si256(operand, 1)));
729 surrogate_bitvec = ~surrogate_bitvec;
730 unsigned int n_chars = surrogate_bitvec ? zend_ulong_ntz(surrogate_bitvec) >> 1 : 16;
732 unsigned char c1 = *
p++;
733 unsigned char c2 = *
p++;
735 if (c1 & 0x4 ||
len < 4) {
745 uint16_t
n = (c1 << 8) | c2;
746 unsigned char c3 = *
p++;
747 unsigned char c4 = *
p++;
749 if ((c3 & 0xFC) == 0xDC) {
751 uint16_t n2 = (c3 << 8) | c4;
752 *
out++ = (((
n & 0x3FF) << 10) | (n2 & 0x3FF)) + 0x10000;
755#ifdef PHP_HAVE_BUILTIN_USUB_OVERFLOW
759 if (__builtin_usub_overflow(n_chars, 2, &n_chars)) {
767 if (n_chars == UINT_MAX) {
782 }
while (
len >= 32 && bufsize >= 16);
784 if (
len && bufsize >= 4) {
793 return mb_utf16be_to_wchar_default(in, in_len,
buf, bufsize,
NULL);
799#ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
806 unsigned char *
out, *limit;
811 const __m256i bmp_mask = _mm256_set1_epi32(0xFFFF);
813 const __m256i pack_8x16 = _mm256_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 12, 13, 8, 9, 4, 5, 0, 1, 12, 13, 8, 9, 4, 5, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1);
816 __m256i operand = _mm256_loadu_si256((__m256i*)in);
818 uint32_t bmp_bitvec = _mm256_movemask_epi8(_mm256_cmpeq_epi32(_mm256_and_si256(operand, bmp_mask), operand));
819 if (bmp_bitvec == 0xFFFFFFFF) {
823 operand = _mm256_shuffle_epi8(operand, pack_8x16);
824 __m256i operand2 = _mm256_permute2x128_si256(operand, operand, 1);
825 operand = _mm256_alignr_epi8(operand2, operand, 8);
826 _mm_storeu_si128((__m128i*)
out, _mm256_castsi256_si128(operand));
830 }
else if (bmp_bitvec & 1) {
832 unsigned int n_bytes = zend_ulong_ntz(~bmp_bitvec);
833 operand = _mm256_shuffle_epi8(operand, pack_8x16);
834 __m256i operand2 = _mm256_permute2x128_si256(operand, operand, 1);
835 operand = _mm256_alignr_epi8(operand2, operand, 8);
838 _mm_storeu_si128((__m128i*)
out, _mm256_castsi256_si128(operand));
845 unsigned int n_words = bmp_bitvec ? zend_ulong_ntz(bmp_bitvec) >> 2 : 8;
852 uint16_t n1 = ((w >> 10) - 0x40) | 0xD800;
853 uint16_t n2 = (w & 0x3FF) | 0xDC00;
855 out = mb_convert_buf_add4(
out, (n1 >> 8) & 0xFF, n1 & 0xFF, (n2 >> 8) & 0xFF, n2 & 0xFF);
868 mb_wchar_to_utf16be_default(in,
len,
buf,
end);
872#ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
873size_t mb_utf16le_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
875static size_t mb_utf16le_to_wchar_avx2(
unsigned char **in,
size_t *in_len, uint32_t *
buf,
size_t bufsize,
unsigned int *
state)
881 size_t len = *in_len;
883 if (
len >= 32 && bufsize >= 16) {
884 unsigned char *
p = *in;
887 const __m256i _f8 = _mm256_set1_epi16(0xF800);
888 const __m256i _d8 = _mm256_set1_epi16(0xD800);
891 __m256i operand = _mm256_loadu_si256((__m256i*)
p);
893 uint32_t surrogate_bitvec = _mm256_movemask_epi8(_mm256_cmpeq_epi16(_mm256_and_si256(operand, _f8), _d8));
894 if (surrogate_bitvec == 0) {
896 _mm256_storeu_si256((__m256i*)
out, _mm256_cvtepu16_epi32(_mm256_castsi256_si128(operand)));
897 _mm256_storeu_si256((__m256i*)(
out + 8), _mm256_cvtepu16_epi32(_mm256_extracti128_si256(operand, 1)));
900 p +=
sizeof(__m256i);
901 len -=
sizeof(__m256i);
902 }
else if ((surrogate_bitvec & 1) == 0) {
904 uint8_t n_chars = zend_ulong_ntz(surrogate_bitvec) >> 1;
905 _mm256_storeu_si256((__m256i*)
out, _mm256_cvtepu16_epi32(_mm256_castsi256_si128(operand)));
907 _mm256_storeu_si256((__m256i*)(
out + 8), _mm256_cvtepu16_epi32(_mm256_extracti128_si256(operand, 1)));
915 surrogate_bitvec = ~surrogate_bitvec;
916 unsigned int n_chars = surrogate_bitvec ? zend_ulong_ntz(surrogate_bitvec) >> 1 : 16;
918 unsigned char c1 = *
p++;
919 unsigned char c2 = *
p++;
921 if (c2 & 0x4 ||
len < 4) {
931 uint16_t
n = (c2 << 8) | c1;
932 unsigned char c3 = *
p++;
933 unsigned char c4 = *
p++;
935 if ((c4 & 0xFC) == 0xDC) {
937 uint16_t n2 = (c4 << 8) | c3;
938 *
out++ = (((
n & 0x3FF) << 10) | (n2 & 0x3FF)) + 0x10000;
941#ifdef PHP_HAVE_BUILTIN_USUB_OVERFLOW
942 if (__builtin_usub_overflow(n_chars, 2, &n_chars)) {
947 if (n_chars == UINT_MAX) {
962 }
while (
len >= 32 && bufsize >= 16);
964 if (
len && bufsize >= 4) {
972 return mb_utf16le_to_wchar_default(in, in_len,
buf, bufsize,
NULL);
978#ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
985 unsigned char *
out, *limit;
990 const __m256i bmp_mask = _mm256_set1_epi32(0xFFFF);
992 const __m256i pack_8x16 = _mm256_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 13, 12, 9, 8, 5, 4, 1, 0, 13, 12, 9, 8, 5, 4, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1);
995 __m256i operand = _mm256_loadu_si256((__m256i*)in);
997 uint32_t bmp_bitvec = _mm256_movemask_epi8(_mm256_cmpeq_epi32(_mm256_and_si256(operand, bmp_mask), operand));
998 if (bmp_bitvec == 0xFFFFFFFF) {
1002 operand = _mm256_shuffle_epi8(operand, pack_8x16);
1003 __m256i operand2 = _mm256_permute2x128_si256(operand, operand, 1);
1004 operand = _mm256_alignr_epi8(operand2, operand, 8);
1005 _mm_storeu_si128((__m128i*)
out, _mm256_castsi256_si128(operand));
1009 }
else if (bmp_bitvec & 1) {
1011 unsigned int n_bytes = zend_ulong_ntz(~bmp_bitvec);
1012 operand = _mm256_shuffle_epi8(operand, pack_8x16);
1013 __m256i operand2 = _mm256_permute2x128_si256(operand, operand, 1);
1014 operand = _mm256_alignr_epi8(operand2, operand, 8);
1015 _mm_storeu_si128((__m128i*)
out, _mm256_castsi256_si128(operand));
1016 out += n_bytes >> 1;
1017 len -= n_bytes >> 2;
1021 unsigned int n_words = bmp_bitvec ? zend_ulong_ntz(bmp_bitvec) >> 2 : 8;
1028 uint16_t n1 = ((w >> 10) - 0x40) | 0xD800;
1029 uint16_t n2 = (w & 0x3FF) | 0xDC00;
1031 out = mb_convert_buf_add4(
out, n1 & 0xFF, (n1 >> 8) & 0xFF, n2 & 0xFF, (n2 >> 8) & 0xFF);
1044 mb_wchar_to_utf16le_default(in,
len,
buf,
end);
1063 uint32_t start_cp = (*
start << 8) + *(
start + 1);
1064 if (start_cp >= 0xDC00 && start_cp <= 0xDFFF) {
1065 uint32_t preceding_cp = (*(
start - 2) << 8) + *(
start - 1);
1066 if (preceding_cp >= 0xD800 && preceding_cp <= 0xDBFF) {
1076 uint32_t ending_cp = (*(_end - 2) << 8) + *(_end - 1);
1077 if (ending_cp >= 0xD800 && ending_cp <= 0xDBFF) {
1080 return zend_string_init_fast((
char*)
start, _end -
start);
1096 uint32_t start_cp = (*(
start + 1) << 8) + *
start;
1097 if (start_cp >= 0xDC00 && start_cp <= 0xDFFF) {
1098 uint32_t preceding_cp = (*(
start - 1) << 8) + *(
start - 2);
1099 if (preceding_cp >= 0xD800 && preceding_cp <= 0xDBFF) {
1109 uint32_t ending_cp = (*(_end - 1) << 8) + *(_end - 2);
1110 if (ending_cp >= 0xD800 && ending_cp <= 0xDBFF) {
1113 return zend_string_init_fast((
char*)
start, _end -
start);
1118 if (
len < 2 || (
end - str) < 2) {
1121 uint32_t
cp = (*str << 8) + *(str + 1);
1129 if (
cp == 0xFEFF &&
from < 2) {
zend_ffi_ctype_name_buf buf
int mbfl_filt_conv_utf16_wchar(int c, mbfl_convert_filter *filter)
#define mb_utf16be_to_wchar
int mbfl_filt_conv_wchar_utf16le(int c, mbfl_convert_filter *filter)
const mbfl_encoding mbfl_encoding_utf16be
int mbfl_filt_conv_utf16be_wchar(int c, mbfl_convert_filter *filter)
const struct mbfl_convert_vtbl vtbl_utf16le_wchar
int mbfl_filt_conv_wchar_utf16be(int c, mbfl_convert_filter *filter)
const mbfl_encoding mbfl_encoding_utf16le
const struct mbfl_convert_vtbl vtbl_utf16be_wchar
int mbfl_filt_conv_utf16le_wchar(int c, mbfl_convert_filter *filter)
#define mb_wchar_to_utf16le
const mbfl_encoding mbfl_encoding_utf16
#define mb_utf16le_to_wchar
const struct mbfl_convert_vtbl vtbl_wchar_utf16be
const struct mbfl_convert_vtbl vtbl_wchar_utf16le
const struct mbfl_convert_vtbl vtbl_utf16_wchar
const struct mbfl_convert_vtbl vtbl_wchar_utf16
#define mb_wchar_to_utf16be
#define MBFL_WCSPLANE_UCS2MAX
#define MBFL_WCSPLANE_SUPMAX
#define MBFL_WCSPLANE_UTF32MAX
#define MBFL_WCSPLANE_SUPMIN
int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter)
int mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter)
void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter)
struct _mbfl_convert_filter mbfl_convert_filter
@ mbfl_no_encoding_utf16be
@ mbfl_no_encoding_utf16le
size_t(* mb_to_wchar_fn)(unsigned char **in, size_t *in_len, uint32_t *out, size_t out_len, unsigned int *state)
#define MB_CONVERT_BUF_STORE(buf, _out, _limit)
#define MB_CONVERT_BUF_ENSURE(buf, out, limit, needed)
#define MB_CONVERT_ERROR(buf, out, limit, bad_cp, conv_fn)
void(* mb_from_wchar_fn)(uint32_t *in, size_t in_len, mb_convert_buf *out, bool end)
#define MB_CONVERT_BUF_LOAD(buf, _out, _limit)
unsigned const char * end
output_function_t output_function
int(* filter_function)(int c, mbfl_convert_filter *filter)
flush_function_t flush_function
enum mbfl_no_encoding from
#define ZEND_NO_SANITIZE_ADDRESS
struct _zend_string zend_string
#define ZEND_INTRIN_AVX2_FUNC_DECL(func)
#define ZEND_ATTRIBUTE_UNUSED
ZEND_API zend_string * zend_empty_string