root/ext/intl/transliterator/transliterator_class.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. transliterator_object_construct
  2. transliterator_object_init
  3. transliterator_object_destroy
  4. Transliterator_objects_dtor
  5. Transliterator_objects_free
  6. Transliterator_object_create
  7. Transliterator_clone_obj
  8. Transliterator_get_property_ptr_ptr
  9. Transliterator_read_property
  10. Transliterator_write_property
  11. transliterator_register_Transliterator_class

   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( Z_OBJCE_P( object ) 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, int type,
 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, type, 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  */

/* [<][>][^][v][top][bottom][index][help] */