Annotation of embedaddon/php/ext/intl/transliterator/transliterator_class.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | This source file is subject to version 3.01 of the PHP license, |
! 6: | that is bundled with this package in the file LICENSE, and is |
! 7: | available through the world-wide-web at the following url: |
! 8: | http://www.php.net/license/3_01.txt |
! 9: | If you did not receive a copy of the PHP license and are unable to |
! 10: | obtain it through the world-wide-web, please send a note to |
! 11: | license@php.net so we can mail you a copy immediately. |
! 12: +----------------------------------------------------------------------+
! 13: | Authors: Gustavo Lopes <cataphract@php.net> |
! 14: +----------------------------------------------------------------------+
! 15: */
! 16:
! 17: #include "transliterator_class.h"
! 18: #include "php_intl.h"
! 19: #include "transliterator_methods.h"
! 20: #include "intl_error.h"
! 21: #include "intl_convert.h"
! 22: #include "intl_data.h"
! 23:
! 24: #include <unicode/utrans.h>
! 25:
! 26: zend_class_entry *Transliterator_ce_ptr = NULL;
! 27:
! 28: zend_object_handlers Transliterator_handlers;
! 29:
! 30: /* {{{ int transliterator_object_construct( zval *object, UTransliterator *utrans, UErrorCode *status TSRMLS_DC )
! 31: * Initialize internals of Transliterator_object.
! 32: */
! 33: int transliterator_object_construct( zval *object,
! 34: UTransliterator *utrans,
! 35: UErrorCode *status TSRMLS_DC )
! 36: {
! 37: const UChar *ustr_id;
! 38: int32_t ustr_id_len;
! 39: char *str_id;
! 40: int str_id_len;
! 41: Transliterator_object *to;
! 42:
! 43: TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
! 44:
! 45: assert( to->utrans == NULL );
! 46: /* this assignment must happen before any return with failure because the
! 47: * caller relies on it always being made (so it can just destroy the object
! 48: * to close the transliterator) */
! 49: to->utrans = utrans;
! 50:
! 51: ustr_id = utrans_getUnicodeID( utrans, &ustr_id_len );
! 52: intl_convert_utf16_to_utf8( &str_id, &str_id_len, ustr_id, (int ) ustr_id_len, status );
! 53: if( U_FAILURE( *status ) )
! 54: {
! 55: return FAILURE;
! 56: }
! 57:
! 58: zend_update_property_stringl( Transliterator_ce_ptr, object,
! 59: "id", sizeof( "id" ) - 1, str_id, str_id_len TSRMLS_CC );
! 60: efree( str_id );
! 61: return SUCCESS;
! 62: }
! 63: /* }}} */
! 64:
! 65: /*
! 66: * Auxiliary functions needed by objects of 'Transliterator' class
! 67: */
! 68:
! 69: /* {{{ void transliterator_object_init( Transliterator_object* to )
! 70: * Initialize internals of Transliterator_object.
! 71: */
! 72: static void transliterator_object_init( Transliterator_object* to TSRMLS_DC )
! 73: {
! 74: if( !to )
! 75: return;
! 76:
! 77: intl_error_init( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
! 78: }
! 79: /* }}} */
! 80:
! 81: /* {{{ void transliterator_object_destroy( Transliterator_object* to )
! 82: * Clean up mem allocted by internals of Transliterator_object
! 83: */
! 84: static void transliterator_object_destroy( Transliterator_object* to TSRMLS_DC )
! 85: {
! 86: if( !to )
! 87: return;
! 88:
! 89: if( to->utrans )
! 90: {
! 91: utrans_close( to->utrans );
! 92: to->utrans = NULL;
! 93: }
! 94:
! 95: intl_error_reset( TRANSLITERATOR_ERROR_P( to ) TSRMLS_CC );
! 96: }
! 97: /* }}} */
! 98:
! 99: /* {{{ Transliterator_objects_dtor */
! 100: static void Transliterator_objects_dtor(
! 101: void *object,
! 102: zend_object_handle handle TSRMLS_DC )
! 103: {
! 104: zend_objects_destroy_object( object, handle TSRMLS_CC );
! 105: }
! 106: /* }}} */
! 107:
! 108: /* {{{ Transliterator_objects_free */
! 109: static void Transliterator_objects_free( zend_object *object TSRMLS_DC )
! 110: {
! 111: Transliterator_object* to = (Transliterator_object*) object;
! 112:
! 113: zend_object_std_dtor( &to->zo TSRMLS_CC );
! 114:
! 115: transliterator_object_destroy( to TSRMLS_CC );
! 116:
! 117: efree( to );
! 118: }
! 119: /* }}} */
! 120:
! 121: /* {{{ Transliterator_object_create */
! 122: static zend_object_value Transliterator_object_create(
! 123: zend_class_entry *ce TSRMLS_DC )
! 124: {
! 125: zend_object_value retval;
! 126: Transliterator_object* intern;
! 127:
! 128: intern = ecalloc( 1, sizeof( Transliterator_object ) );
! 129:
! 130: zend_object_std_init( &intern->zo, ce TSRMLS_CC );
! 131: #if PHP_VERSION_ID < 50399
! 132: zend_hash_copy( intern->zo.properties, &(ce->default_properties ),
! 133: (copy_ctor_func_t) zval_add_ref, NULL, sizeof( zval* ) );
! 134: #else
! 135: object_properties_init( (zend_object*) intern, ce );
! 136: #endif
! 137: transliterator_object_init( intern TSRMLS_CC );
! 138:
! 139: retval.handle = zend_objects_store_put(
! 140: intern,
! 141: Transliterator_objects_dtor,
! 142: (zend_objects_free_object_storage_t) Transliterator_objects_free,
! 143: NULL TSRMLS_CC );
! 144:
! 145: retval.handlers = &Transliterator_handlers;
! 146:
! 147: return retval;
! 148: }
! 149: /* }}} */
! 150:
! 151: /*
! 152: * Object handlers for Transliterator class (and subclasses)
! 153: */
! 154:
! 155: /* {{{ clone handler for Transliterator */
! 156: static zend_object_value Transliterator_clone_obj( zval *object TSRMLS_DC )
! 157: {
! 158: Transliterator_object *to_orig,
! 159: *to_new;
! 160: zend_object_value ret_val;
! 161: intl_error_reset( NULL TSRMLS_CC );
! 162:
! 163: to_orig = zend_object_store_get_object( object TSRMLS_CC );
! 164: intl_error_reset( INTL_DATA_ERROR_P( to_orig ) TSRMLS_CC );
! 165: ret_val = Transliterator_ce_ptr->create_object( Transliterator_ce_ptr TSRMLS_CC );
! 166: to_new = zend_object_store_get_object_by_handle( ret_val.handle TSRMLS_CC );
! 167:
! 168: zend_objects_clone_members( &to_new->zo, ret_val,
! 169: &to_orig->zo, Z_OBJ_HANDLE_P( object ) TSRMLS_CC );
! 170:
! 171: if( to_orig->utrans != NULL )
! 172: {
! 173: UTransliterator *utrans = NULL;
! 174: zval tempz; /* dummy zval to pass to transliterator_object_construct */
! 175:
! 176: /* guaranteed to return NULL if it fails */
! 177: utrans = utrans_clone( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) );
! 178:
! 179: if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
! 180: goto err;
! 181:
! 182: Z_OBJVAL( tempz ) = ret_val;
! 183: transliterator_object_construct( &tempz, utrans,
! 184: TRANSLITERATOR_ERROR_CODE_P( to_orig ) TSRMLS_CC );
! 185:
! 186: if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) )
! 187: {
! 188: char *err_msg;
! 189: err:
! 190:
! 191: if( utrans != NULL )
! 192: transliterator_object_destroy( to_new TSRMLS_CC );
! 193:
! 194: /* set the error anyway, in case in the future we decide not to
! 195: * throw an error. It also helps build the error message */
! 196: intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to_orig ) TSRMLS_CC );
! 197: intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to_orig ),
! 198: "Could not clone transliterator", 0 TSRMLS_CC );
! 199:
! 200: err_msg = intl_error_get_message( TRANSLITERATOR_ERROR_P( to_orig ) TSRMLS_CC );
! 201: php_error_docref( NULL TSRMLS_CC, E_ERROR, "%s", err_msg );
! 202: efree( err_msg ); /* if it's changed into a warning */
! 203: /* do not destroy tempz; we need to return something */
! 204: }
! 205: }
! 206: else
! 207: {
! 208: /* We shouldn't have unconstructed objects in the first place */
! 209: php_error_docref( NULL TSRMLS_CC, E_WARNING,
! 210: "Cloning unconstructed transliterator." );
! 211: }
! 212:
! 213: return ret_val;
! 214: }
! 215: /* }}} */
! 216:
! 217: #if PHP_VERSION_ID >= 50399
! 218: # define TRANSLITERATOR_PROPERTY_HANDLER_PROLOG \
! 219: zval tmp_member; \
! 220: if( Z_TYPE_P( member ) != IS_STRING ) \
! 221: { \
! 222: tmp_member = *member; \
! 223: zval_copy_ctor( &tmp_member ); \
! 224: convert_to_string( &tmp_member ); \
! 225: member = &tmp_member; \
! 226: key = NULL; \
! 227: }
! 228: #else
! 229: # define TRANSLITERATOR_PROPERTY_HANDLER_PROLOG \
! 230: zval tmp_member; \
! 231: if( Z_TYPE_P( member ) != IS_STRING ) \
! 232: { \
! 233: tmp_member = *member; \
! 234: zval_copy_ctor( &tmp_member ); \
! 235: convert_to_string( &tmp_member ); \
! 236: member = &tmp_member; \
! 237: }
! 238: #endif
! 239:
! 240: #define TRANSLITERATOR_PROPERTY_HANDLER_EPILOG \
! 241: if( member == &tmp_member ) \
! 242: { \
! 243: zval_dtor( &tmp_member ); \
! 244: }
! 245:
! 246: /* {{{ get_property_ptr_ptr handler */
! 247: #if PHP_VERSION_ID < 50399
! 248: static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member TSRMLS_DC )
! 249: #else
! 250: static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member,
! 251: const struct _zend_literal *key TSRMLS_DC )
! 252: #endif
! 253: {
! 254: zval **retval;
! 255:
! 256: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
! 257:
! 258: if(zend_binary_strcmp( "id", sizeof( "id" ) - 1,
! 259: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 )
! 260: {
! 261: retval = NULL; /* fallback to read_property */
! 262: }
! 263: else
! 264: {
! 265: #if PHP_VERSION_ID < 50399
! 266: retval = std_object_handlers.get_property_ptr_ptr( object, member TSRMLS_CC );
! 267: #else
! 268: retval = std_object_handlers.get_property_ptr_ptr( object, member, key TSRMLS_CC );
! 269: #endif
! 270: }
! 271:
! 272: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
! 273:
! 274: return retval;
! 275: }
! 276: /* }}} */
! 277:
! 278: /* {{{ read_property handler */
! 279: #if PHP_VERSION_ID < 50399
! 280: static zval *Transliterator_read_property( zval *object, zval *member, int type TSRMLS_DC ) /* {{{ */
! 281: #else
! 282: static zval *Transliterator_read_property( zval *object, zval *member, int type,
! 283: const struct _zend_literal *key TSRMLS_DC ) /* {{{ */
! 284: #endif
! 285: {
! 286: zval *retval;
! 287:
! 288: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
! 289:
! 290: if( ( type != BP_VAR_R && type != BP_VAR_IS ) &&
! 291: ( zend_binary_strcmp( "id", sizeof( "id" ) - 1,
! 292: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 ) )
! 293: {
! 294: php_error_docref0( NULL TSRMLS_CC, E_WARNING, "The property \"id\" is read-only" );
! 295: retval = &EG( uninitialized_zval );
! 296: }
! 297: else
! 298: {
! 299: #if PHP_VERSION_ID < 50399
! 300: retval = std_object_handlers.read_property( object, member, type TSRMLS_CC );
! 301: #else
! 302: retval = std_object_handlers.read_property( object, member, type, key TSRMLS_CC );
! 303: #endif
! 304: }
! 305:
! 306: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
! 307:
! 308: return retval;
! 309: }
! 310:
! 311: /* }}} */
! 312:
! 313: /* {{{ write_property handler */
! 314: #if PHP_VERSION_ID < 50399
! 315: static void Transliterator_write_property( zval *object, zval *member, zval *value TSRMLS_DC )
! 316: #else
! 317: static void Transliterator_write_property( zval *object, zval *member, zval *value,
! 318: const struct _zend_literal *key TSRMLS_DC )
! 319: #endif
! 320: {
! 321: TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
! 322:
! 323: if( ( EG( scope ) != Transliterator_ce_ptr ) &&
! 324: ( zend_binary_strcmp( "id", sizeof( "id" ) - 1,
! 325: Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 ) )
! 326: {
! 327: php_error_docref0( NULL TSRMLS_CC, E_WARNING, "The property \"id\" is read-only" );
! 328: }
! 329: else
! 330: {
! 331: #if PHP_VERSION_ID < 50399
! 332: std_object_handlers.write_property( object, member, value TSRMLS_CC );
! 333: #else
! 334: std_object_handlers.write_property( object, member, value, key TSRMLS_CC );
! 335: #endif
! 336: }
! 337:
! 338: TRANSLITERATOR_PROPERTY_HANDLER_EPILOG;
! 339: }
! 340: /* }}} */
! 341:
! 342: /*
! 343: * 'Transliterator' class registration structures & functions
! 344: */
! 345:
! 346: /* {{{ Transliterator methods arguments info */
! 347:
! 348: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_void, 0, 0, 0 )
! 349: ZEND_END_ARG_INFO()
! 350:
! 351: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create, 0, 0, 1 )
! 352: ZEND_ARG_INFO( 0, id )
! 353: ZEND_ARG_INFO( 0, direction )
! 354: ZEND_END_ARG_INFO()
! 355:
! 356: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create_from_rules, 0, 0, 1 )
! 357: ZEND_ARG_INFO( 0, rules )
! 358: ZEND_ARG_INFO( 0, direction )
! 359: ZEND_END_ARG_INFO()
! 360:
! 361: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_create_inverse, 0, 0, 1 )
! 362: ZEND_ARG_OBJ_INFO( 0, orig_trans, Transliterator, 0 )
! 363: ZEND_END_ARG_INFO()
! 364:
! 365: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_me_transliterate, 0, 0, 1 )
! 366: ZEND_ARG_INFO( 0, subject )
! 367: ZEND_ARG_INFO( 0, start )
! 368: ZEND_ARG_INFO( 0, end )
! 369: ZEND_END_ARG_INFO()
! 370:
! 371: ZEND_BEGIN_ARG_INFO_EX( ainfo_trans_error, 0, 0, 1 )
! 372: ZEND_ARG_OBJ_INFO( 0, trans, Transliterator, 0 )
! 373: ZEND_END_ARG_INFO()
! 374:
! 375: /* }}} */
! 376:
! 377: /* {{{ Transliterator_class_functions
! 378: * Every 'Transliterator' class method has an entry in this table
! 379: */
! 380: zend_function_entry Transliterator_class_functions[] = {
! 381: PHP_ME( Transliterator, __construct, ainfo_trans_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR | ZEND_ACC_FINAL )
! 382: PHP_ME_MAPPING( create, transliterator_create, ainfo_trans_create, ZEND_ACC_STATIC |ZEND_ACC_PUBLIC )
! 383: PHP_ME_MAPPING( createFromRules,transliterator_create_from_rules, ainfo_trans_create_from_rules, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC )
! 384: PHP_ME_MAPPING( createInverse, transliterator_create_inverse, ainfo_trans_void, ZEND_ACC_PUBLIC )
! 385: PHP_ME_MAPPING( listIDs, transliterator_list_ids, ainfo_trans_void, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC )
! 386: PHP_ME_MAPPING( transliterate, transliterator_transliterate, ainfo_trans_me_transliterate, ZEND_ACC_PUBLIC )
! 387: PHP_ME_MAPPING( getErrorCode, transliterator_get_error_code, ainfo_trans_void, ZEND_ACC_PUBLIC )
! 388: PHP_ME_MAPPING( getErrorMessage,transliterator_get_error_message, ainfo_trans_void, ZEND_ACC_PUBLIC )
! 389: PHP_FE_END
! 390: };
! 391: /* }}} */
! 392:
! 393: /* {{{ transliterator_register_Transliterator_class
! 394: * Initialize 'Transliterator' class
! 395: */
! 396: void transliterator_register_Transliterator_class( TSRMLS_D )
! 397: {
! 398: zend_class_entry ce;
! 399:
! 400: /* Create and register 'Transliterator' class. */
! 401: INIT_CLASS_ENTRY( ce, "Transliterator", Transliterator_class_functions );
! 402: ce.create_object = Transliterator_object_create;
! 403: Transliterator_ce_ptr = zend_register_internal_class( &ce TSRMLS_CC );
! 404: memcpy( &Transliterator_handlers, zend_get_std_object_handlers(),
! 405: sizeof Transliterator_handlers );
! 406: Transliterator_handlers.clone_obj = Transliterator_clone_obj;
! 407: Transliterator_handlers.get_property_ptr_ptr = Transliterator_get_property_ptr_ptr;
! 408: Transliterator_handlers.read_property = Transliterator_read_property;
! 409: Transliterator_handlers.write_property = Transliterator_write_property;
! 410:
! 411: /* Declare 'Transliterator' class properties */
! 412: if( !Transliterator_ce_ptr )
! 413: {
! 414: zend_error( E_ERROR,
! 415: "Transliterator: attempt to create properties "
! 416: "on a non-registered class." );
! 417: return;
! 418: }
! 419: zend_declare_property_null( Transliterator_ce_ptr,
! 420: "id", sizeof( "id" ) - 1, ZEND_ACC_PUBLIC TSRMLS_CC );
! 421:
! 422: /* constants are declared in transliterator_register_constants, called from MINIT */
! 423:
! 424: }
! 425: /* }}} */
! 426:
! 427: /*
! 428: * Local variables:
! 429: * tab-width: 4
! 430: * c-basic-offset: 4
! 431: * End:
! 432: * vim600: noet sw=4 ts=4 fdm=marker
! 433: * vim<600: noet sw=4 ts=4
! 434: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>