Annotation of embedaddon/php/ext/intl/transliterator/transliterator_class.c, revision 1.1.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>