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>