diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 62ea18c4470d..f6a01053df20 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -32,6 +32,7 @@ if test "$PHP_INTL" != "no"; then common/common_error.cpp \ dateformat/dateformat_class.cpp \ converter/converter.cpp \ + converter/converter_class.cpp \ dateformat/dateformat.cpp \ dateformat/dateformat_attr.cpp \ dateformat/dateformat_attrcpp.cpp \ diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index 984ba94907ab..3cde431ce66e 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -29,6 +29,7 @@ if (PHP_INTL != "no") { ", "intl"); ADD_SOURCES(configure_module_dirname + "/converter", "\ converter.cpp \ + converter_class.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/formatter", "\ formatter_attr.cpp \ diff --git a/ext/intl/converter/converter.cpp b/ext/intl/converter/converter.cpp index 1369b88742f4..565f18573d71 100644 --- a/ext/intl/converter/converter.cpp +++ b/ext/intl/converter/converter.cpp @@ -20,7 +20,7 @@ #include #include -#include "../intl_icu_compat.h" +#include "converter_class.h" extern "C" { #include "converter.h" @@ -28,23 +28,6 @@ extern "C" { #include "../intl_error.h" #include "../intl_common.h" } -#include "converter_arginfo.h" - -typedef struct _php_converter_object { - UConverter *src, *dest; - zend_fcall_info_cache to_cache, from_cache; - intl_error error; - zend_object obj; -} php_converter_object; - - -static inline php_converter_object *php_converter_fetch_object(zend_object *obj) { - return (php_converter_object *)((char*)(obj) - offsetof(php_converter_object, obj)); -} -#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv)) - -static zend_class_entry *php_converter_ce; -static zend_object_handlers php_converter_object_handlers; #define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv))) #define THROW_UFAILURE(obj, error) php_converter_throw_failure(obj, error, \ @@ -332,7 +315,7 @@ static void php_converter_from_u_callback(const void *context, /* }}} */ /* {{{ php_converter_set_callbacks */ -static inline bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) { +bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) { bool ret = true; UErrorCode error = U_ZERO_ERROR; @@ -504,21 +487,6 @@ PHP_METHOD(UConverter, getDestinationType) { } /* }}} */ -static void php_converter_resolve_callback( - zend_fcall_info_cache *fcc, - zend_object *this_ptr, - const char *callback_name, - size_t callback_name_len -) { - zend_function *fn = reinterpret_cast(zend_hash_str_find_ptr_lc(&this_ptr->ce->function_table, callback_name, callback_name_len)); - ZEND_ASSERT(fn != nullptr); - - fcc->function_handler = fn; - fcc->object = this_ptr; - fcc->called_scope = this_ptr->ce; - fcc->closure = nullptr; -} - /* {{{ */ PHP_METHOD(UConverter, __construct) { php_converter_object *objval = CONV_GET(ZEND_THIS); @@ -900,87 +868,3 @@ PHP_METHOD(UConverter, getStandards) { } } /* }}} */ - -/* {{{ Converter create/clone/destroy */ -static void php_converter_free_object(zend_object *obj) { - php_converter_object *objval = php_converter_fetch_object(obj); - - if (objval->src) { - ucnv_close(objval->src); - } - - if (objval->dest) { - ucnv_close(objval->dest); - } - - intl_error_reset(&objval->error); - zend_object_std_dtor(obj); -} - -static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) { - php_converter_object *objval; - - objval = reinterpret_cast(zend_object_alloc(sizeof(php_converter_object), ce)); - - zend_object_std_init(&objval->obj, ce); - object_properties_init(&objval->obj, ce); - intl_error_init(&(objval->error)); - php_converter_resolve_callback(&objval->to_cache, &objval->obj, ZEND_STRL("toUCallback")); - php_converter_resolve_callback(&objval->from_cache, &objval->obj, ZEND_STRL("fromUCallback")); - - *pobjval = objval; - - return &objval->obj; -} - -static zend_object *php_converter_create_object(zend_class_entry *ce) { - php_converter_object *objval = nullptr; - zend_object *retval = php_converter_object_ctor(ce, &objval); - - object_properties_init(&(objval->obj), ce); - - return retval; -} - -static zend_object *php_converter_clone_object(zend_object *object) { - const php_converter_object *oldobj = php_converter_fetch_object(object); - php_converter_object *objval; - zend_object *retval = php_converter_object_ctor(object->ce, &objval); - UErrorCode error = U_ZERO_ERROR; - - objval->src = intl_icu_compat_ucnv_clone(oldobj->src, &error); - if (U_SUCCESS(error)) { - error = U_ZERO_ERROR; - objval->dest = intl_icu_compat_ucnv_clone(oldobj->dest, &error); - } - - if (U_FAILURE(error)) { - zend_throw_error(NULL, "Failed to clone UConverter"); - return retval; - } - - /* Update contexts for converter error handlers */ - php_converter_set_callbacks(objval, objval->src ); - php_converter_set_callbacks(objval, objval->dest); - - zend_objects_clone_members(&(objval->obj), &(oldobj->obj)); - - /* Newly cloned object deliberately does not inherit error state from original object */ - - return retval; -} -/* }}} */ - -/* {{{ php_converter_minit */ -U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) { - php_converter_ce = register_class_UConverter(); - php_converter_ce->create_object = php_converter_create_object; - php_converter_ce->default_object_handlers = &php_converter_object_handlers; - memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_converter_object_handlers.offset = offsetof(php_converter_object, obj); - php_converter_object_handlers.clone_obj = php_converter_clone_object; - php_converter_object_handlers.free_obj = php_converter_free_object; - - return SUCCESS; -} -/* }}} */ diff --git a/ext/intl/converter/converter_class.cpp b/ext/intl/converter/converter_class.cpp new file mode 100644 index 000000000000..d2efd1d27631 --- /dev/null +++ b/ext/intl/converter/converter_class.cpp @@ -0,0 +1,121 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + +#include "converter_class.h" +#include "converter.h" +#include "../intl_icu_compat.h" +#include "zend_exceptions.h" +#include "converter_arginfo.h" + +zend_class_entry *php_converter_ce; +static zend_object_handlers php_converter_object_handlers; + +static void php_converter_resolve_callback( + zend_fcall_info_cache *fcc, + zend_object *this_ptr, + const char *callback_name, + size_t callback_name_len +) { + zend_function *fn = reinterpret_cast(zend_hash_str_find_ptr_lc(&this_ptr->ce->function_table, callback_name, callback_name_len)); + ZEND_ASSERT(fn != nullptr); + + fcc->function_handler = fn; + fcc->object = this_ptr; + fcc->called_scope = this_ptr->ce; + fcc->closure = nullptr; +} + +/* {{{ Converter create/clone/destroy */ +static void php_converter_free_object(zend_object *obj) { + php_converter_object *objval = php_converter_fetch_object(obj); + + if (objval->src) { + ucnv_close(objval->src); + } + + if (objval->dest) { + ucnv_close(objval->dest); + } + + intl_error_reset(&objval->error); + zend_object_std_dtor(obj); +} + +static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) { + php_converter_object *objval; + + objval = reinterpret_cast(zend_object_alloc(sizeof(php_converter_object), ce)); + + zend_object_std_init(&objval->obj, ce); + object_properties_init(&objval->obj, ce); + intl_error_init(&(objval->error)); + php_converter_resolve_callback(&objval->to_cache, &objval->obj, ZEND_STRL("toUCallback")); + php_converter_resolve_callback(&objval->from_cache, &objval->obj, ZEND_STRL("fromUCallback")); + + *pobjval = objval; + + return &objval->obj; +} + +static zend_object *php_converter_create_object(zend_class_entry *ce) { + php_converter_object *objval = nullptr; + zend_object *retval = php_converter_object_ctor(ce, &objval); + + object_properties_init(&(objval->obj), ce); + + return retval; +} + +static zend_object *php_converter_clone_object(zend_object *object) { + const php_converter_object *oldobj = php_converter_fetch_object(object); + php_converter_object *objval; + zend_object *retval = php_converter_object_ctor(object->ce, &objval); + UErrorCode error = U_ZERO_ERROR; + + objval->src = intl_icu_compat_ucnv_clone(oldobj->src, &error); + if (U_SUCCESS(error)) { + error = U_ZERO_ERROR; + objval->dest = intl_icu_compat_ucnv_clone(oldobj->dest, &error); + } + + if (U_FAILURE(error)) { + zend_throw_error(NULL, "Failed to clone UConverter"); + return retval; + } + + /* Update contexts for converter error handlers */ + php_converter_set_callbacks(objval, objval->src ); + php_converter_set_callbacks(objval, objval->dest); + + zend_objects_clone_members(&(objval->obj), &(oldobj->obj)); + + /* Newly cloned object deliberately does not inherit error state from original object */ + + return retval; +} +/* }}} */ + +/* {{{ php_converter_minit */ +U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) { + php_converter_ce = register_class_UConverter(); + php_converter_ce->create_object = php_converter_create_object; + php_converter_ce->default_object_handlers = &php_converter_object_handlers; + memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_converter_object_handlers.offset = offsetof(php_converter_object, obj); + php_converter_object_handlers.clone_obj = php_converter_clone_object; + php_converter_object_handlers.free_obj = php_converter_free_object; + + return SUCCESS; +} +/* }}} */ diff --git a/ext/intl/converter/converter_class.h b/ext/intl/converter/converter_class.h new file mode 100644 index 000000000000..9b16e3b417d2 --- /dev/null +++ b/ext/intl/converter/converter_class.h @@ -0,0 +1,45 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + +#ifndef PHP_INTL_CONVERTER_CLASS_H +#define PHP_INTL_CONVERTER_CLASS_H + +#include "php.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif +#include "../intl_error.h" +#ifdef __cplusplus +} +#endif + +typedef struct _php_converter_object { + UConverter *src, *dest; + zend_fcall_info_cache to_cache, from_cache; + intl_error error; + zend_object obj; +} php_converter_object; + +static inline php_converter_object *php_converter_fetch_object(zend_object *obj) { + return ZEND_CONTAINER_OF(obj, php_converter_object, obj); +} +#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv)) + +extern zend_class_entry *php_converter_ce; + +bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv); + +#endif /* PHP_INTL_CONVERTER_CLASS_H */