18#include <unicode/utypes.h>
19#include <unicode/utf8.h>
20#include <unicode/utf16.h>
21#include <unicode/ucnv.h>
22#include <unicode/ustring.h>
40#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv))
45#define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv)))
46#define THROW_UFAILURE(obj, fname, error) php_converter_throw_failure(obj, error, \
47 fname "() returned error " ZEND_LONG_FMT ": %s", (zend_long)error, u_errorName(error))
55 va_start(vargs, format);
56 vsnprintf(message,
sizeof(message), format, vargs);
73 int8_t chars_len =
sizeof(chars);
76 php_converter_throw_failure(objval,
U_INVALID_STATE_ERROR,
"Source Converter has not been initialized yet");
92 ucnv_getSubstChars(objval->
src, chars, &chars_len, &uerror);
93 if (U_FAILURE(uerror)) {
142 if (available < needed) {
150#define TARGET_CHECK(cnvargs, needed) php_converter_check_limits(objval, cnvargs->targetLimit - cnvargs->target, needed)
161 if ((lval < 0) || (lval > 0x10FFFF)) {
169 *(
args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800);
170 *(
args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00);
176 *(
args->target++) = (UChar)lval;
188 *(
args->target++) = c;
198 php_converter_append_toUnicode_target(tmpzval,
args, objval);
204 "toUCallback() specified illegal type for substitution character");
210static void php_converter_to_u_callback(
const void *
context,
211 UConverterToUnicodeArgs *
args,
212 const char *codeUnits, int32_t length,
213 UConverterCallbackReason reason,
214 UErrorCode *pErrorCode) {
240 php_converter_append_toUnicode_target(&
retval,
args, objval);
245 *pErrorCode =
Z_LVAL(zargs[3]);
281 php_converter_append_fromUnicode_target(tmpzval,
args, objval);
286 php_converter_throw_failure(objval,
U_ILLEGAL_ARGUMENT_ERROR,
"fromUCallback() specified illegal type for substitution character");
292static void php_converter_from_u_callback(
const void *
context,
293 UConverterFromUnicodeArgs *
args,
294 const UChar *codeUnits, int32_t length, UChar32 codePoint,
295 UConverterCallbackReason reason,
296 UErrorCode *pErrorCode) {
307 U16_NEXT(codeUnits, i, length, c);
321 php_converter_append_fromUnicode_target(&
retval,
args, objval);
326 *pErrorCode =
Z_LVAL(zargs[3]);
343 if (objval->
obj.
ce == php_converter_ce) {
350 ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (
const void*)objval,
352 if (U_FAILURE(
error)) {
358 ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (
const void*)objval,
360 if (U_FAILURE(
error)) {
371 const char *enc,
size_t enc_len) {
377 const char *actual_encoding = ucnv_getName(cnv, &getname_error);
378 if (U_FAILURE(getname_error)) {
380 actual_encoding =
"(unknown)";
383 }
else if (U_FAILURE(
error)) {
395 if (objval && !php_converter_set_callbacks(objval, cnv)) {
419 RETURN_BOOL(php_converter_set_encoding(objval, pcnv, enc, enc_len));
484 t = ucnv_getType(cnv);
509static void php_converter_resolve_callback(
zval *
zobj,
511 const char *callback_name,
519 add_index_zval(&caller, 0,
zobj);
536 size_t src_len =
sizeof(
"utf-8") - 1;
538 size_t dest_len = src_len;
548 php_converter_set_encoding(objval, &(objval->
src), src, src_len );
549 php_converter_set_encoding(objval, &(objval->
dest), dest, dest_len);
570 ucnv_setSubstChars(objval->
src, chars, chars_len, &
error);
571 if (U_FAILURE(
error)) {
576 php_converter_throw_failure(objval,
U_INVALID_STATE_ERROR,
"Source Converter has not been initialized yet");
582 ucnv_setSubstChars(objval->
dest, chars, chars_len, &
error);
583 if (U_FAILURE(
error)) {
588 php_converter_throw_failure(objval,
U_INVALID_STATE_ERROR,
"Destination Converter has not been initialized yet");
600 int8_t chars_len =
sizeof(chars);
613 ucnv_getSubstChars(objval->
src, chars, &chars_len, &
error);
614 if (U_FAILURE(
error)) {
625 UConverter *src_cnv,
const char *src, int32_t src_len,
629 int32_t temp_len, ret_len;
633 if (!src_cnv || !dest_cnv) {
635 "Internal converters not initialized");
640 temp_len = 1 + ucnv_toUChars(src_cnv,
NULL, 0, src, src_len, &
error);
645 temp =
safe_emalloc(
sizeof(UChar), temp_len,
sizeof(UChar));
649 temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &
error);
650 if (U_FAILURE(
error)) {
658 ret_len = ucnv_fromUChars(dest_cnv,
NULL, 0, temp, temp_len, &
error);
665 ret = zend_string_alloc(ret_len, 0);
671 if (U_FAILURE(
error)) {
673 zend_string_efree(
ret);
682#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1);
711 bool reverse =
false;
720 ret = php_converter_do_convert(reverse ? objval->
src : objval->
dest,
721 reverse ? objval->
dest : objval->
src,
734 char *str, *src, *dest;
735 size_t str_len, src_len, dest_len;
748 if (php_converter_set_encoding(
NULL, &src_cnv, src, src_len) &&
749 php_converter_set_encoding(
NULL, &dest_cnv, dest, dest_len)) {
756 if (U_SUCCESS(
error) &&
757 (tmpzval = zend_hash_str_find_deref(
Z_ARRVAL_P(
options),
"from_subst",
sizeof(
"from_subst") - 1)) !=
NULL &&
762 if (U_SUCCESS(
error) &&
763 (tmpzval = zend_hash_str_find_deref(
Z_ARRVAL_P(
options),
"to_subst",
sizeof(
"to_subst") - 1)) !=
NULL &&
770 if (U_SUCCESS(
error) &&
771 (
ret = php_converter_do_convert(dest_cnv, src_cnv, str, str_len,
NULL)) !=
NULL) {
775 if (U_FAILURE(
error)) {
787 ucnv_close(dest_cnv);
820 count = ucnv_countAvailable();
827 for(i = 0; i <
count; i++) {
828 const char *
name = ucnv_getAvailableName(i);
847 if (U_FAILURE(
error)) {
853 for(i = 0; i <
count; i++) {
858 if (U_FAILURE(
error)) {
876 count = ucnv_countStandards();
877 for(i = 0; i <
count; i++) {
879 const char *
name = ucnv_getStandard(i, &
error);
880 if (U_FAILURE(
error)) {
891static void php_converter_free_object(
zend_object *obj) {
895 ucnv_close(objval->
src);
899 ucnv_close(objval->
dest);
934#if U_ICU_VERSION_MAJOR_NUM > 70
939 if (U_SUCCESS(
error)) {
941#if U_ICU_VERSION_MAJOR_NUM > 70
948 if (U_FAILURE(
error)) {
954 php_converter_set_callbacks(objval, objval->
src );
955 php_converter_set_callbacks(objval, objval->
dest);
967 php_converter_ce = register_class_UConverter();
968 php_converter_ce->create_object = php_converter_create_object;
969 php_converter_ce->default_object_handlers = &php_converter_object_handlers;
972 php_converter_object_handlers.clone_obj = php_converter_clone_object;
973 php_converter_object_handlers.free_obj = php_converter_free_object;
count(Countable|array $value, int $mode=COUNT_NORMAL)
const U_BUFFER_OVERFLOW_ERROR
const U_AMBIGUOUS_ALIAS_WARNING
const U_INTERNAL_PROGRAM_ERROR
const U_INVALID_STATE_ERROR
const U_ILLEGAL_ARGUMENT_ERROR
struct _php_converter_object php_converter_object
#define UCNV_REASON_CASE(v)
#define THROW_UFAILURE(obj, fname, error)
#define TARGET_CHECK(cnvargs, needed)
int php_converter_minit(INIT_FUNC_ARGS)
void intl_error_init(intl_error *err)
void intl_errors_set(intl_error *err, UErrorCode code, const char *msg, int copyMsg)
void intl_error_set(intl_error *err, UErrorCode code, const char *msg, int copyMsg)
void intl_error_reset(intl_error *err)
void intl_errors_reset(intl_error *err)
UErrorCode intl_error_get_code(intl_error *err)
zend_string * intl_error_get_message(intl_error *err)
struct _intl_error intl_error
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHP_JSON_API size_t int options
zend_fcall_info_cache to_cache
zend_fcall_info_cache from_cache
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
#define INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error)
ZEND_API void add_index_string(zval *arg, zend_ulong index, const char *str)
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
struct _zend_fcall_info_cache zend_fcall_info_cache
#define Z_PARAM_ARRAY_OR_NULL(dest)
#define RETURN_STRINGL(s, l)
#define ZEND_PARSE_PARAMETERS_END()
#define ZEND_PARSE_PARAMETERS_NONE()
#define RETVAL_NEW_STR(s)
#define Z_PARAM_STRING(dest, dest_len)
#define Z_PARAM_STR(dest)
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
#define Z_PARAM_LONG(dest)
#define RETURN_NEW_STR(s)
struct _zend_fcall_info zend_fcall_info
#define Z_PARAM_BOOL(dest)
#define Z_PARAM_ARRAY(dest)
#define Z_PARAM_ZVAL(dest)
#define ZVAL_STRINGL(z, s, l)
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define RETVAL_STRINGL(s, l)
#define ZVAL_EMPTY_STRING(z)
#define safe_emalloc(nmemb, size, offset)
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
struct _zend_string zend_string
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object)
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define XtOffsetOf(s_type, field)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
#define ZVAL_MAKE_REF(zv)
struct _zend_object_handlers zend_object_handlers
ZEND_API void zval_ptr_dtor(zval *zval_ptr)