Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ext/intl/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions ext/intl/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
120 changes: 2 additions & 118 deletions ext/intl/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,14 @@
#include <unicode/ucnv.h>
#include <unicode/ustring.h>

#include "../intl_icu_compat.h"
#include "converter_class.h"

extern "C" {
#include "converter.h"
#include "php_intl.h"
#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, \
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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_function *>(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);
Expand Down Expand Up @@ -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<php_converter_object *>(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;
}
/* }}} */
121 changes: 121 additions & 0 deletions ext/intl/converter/converter_class.cpp
Original file line number Diff line number Diff line change
@@ -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 <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Authors: Sara Golemon <pollita@php.net> |
+----------------------------------------------------------------------+
*/

#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_function *>(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<php_converter_object *>(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;
}
/* }}} */
45 changes: 45 additions & 0 deletions ext/intl/converter/converter_class.h
Original file line number Diff line number Diff line change
@@ -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 <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Authors: Sara Golemon <pollita@php.net> |
+----------------------------------------------------------------------+
*/

#ifndef PHP_INTL_CONVERTER_CLASS_H
#define PHP_INTL_CONVERTER_CLASS_H

#include "php.h"
#include <unicode/ucnv.h>

#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 */
Loading