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: Sara Golemon <pollita@php.net> | 14 +----------------------------------------------------------------------+ 15 */ 16 17#include "converter.h" 18#include "zend_exceptions.h" 19 20#include <unicode/utypes.h> 21#include <unicode/ucnv.h> 22#include <unicode/ustring.h> 23 24#include "../intl_error.h" 25 26typedef struct _php_converter_object { 27 zend_object obj; 28#ifdef ZTS 29 void ***tsrm_ls; 30#endif 31 UConverter *src, *dest; 32 zend_fcall_info to_cb, from_cb; 33 zend_fcall_info_cache to_cache, from_cache; 34 intl_error error; 35} php_converter_object; 36 37static zend_class_entry *php_converter_ce; 38static zend_object_handlers php_converter_object_handlers; 39 40#define CONV_GET(pzv) ((php_converter_object*)zend_objects_get_address((pzv) TSRMLS_CC)) 41#define THROW_UFAILURE(obj, fname, error) php_converter_throw_failure(obj, error TSRMLS_CC, \ 42 fname "() returned error %ld: %s", (long)error, u_errorName(error)) 43 44/* {{{ php_converter_throw_failure */ 45static inline void php_converter_throw_failure(php_converter_object *objval, UErrorCode error TSRMLS_DC, const char *format, ...) { 46 intl_error *err = objval ? &(objval->error) : NULL; 47 char message[1024]; 48 va_list vargs; 49 50 va_start(vargs, format); 51 vsnprintf(message, sizeof(message), format, vargs); 52 va_end(vargs); 53 54 intl_errors_set(err, error, message, 1 TSRMLS_CC); 55} 56/* }}} */ 57 58/* {{{ php_converter_default_callback */ 59static void php_converter_default_callback(zval *return_value, zval *zobj, long reason, zval *error TSRMLS_DC) { 60 /* Basic functionality so children can call parent::toUCallback() */ 61 switch (reason) { 62 case UCNV_UNASSIGNED: 63 case UCNV_ILLEGAL: 64 case UCNV_IRREGULAR: 65 { 66 php_converter_object *objval = (php_converter_object*)CONV_GET(zobj); 67 char chars[127]; 68 int8_t chars_len = sizeof(chars); 69 UErrorCode error = U_ZERO_ERROR; 70 71 /* Yes, this is fairly wasteful at first glance, 72 * but considering that the alternative is to store 73 * what's sent into setSubstChars() and the fact 74 * that this is an extremely unlikely codepath 75 * I'd rather take the CPU hit here, than waste time 76 * storing a value I'm unlikely to use. 77 */ 78 ucnv_getSubstChars(objval->src, chars, &chars_len, &error); 79 if (U_FAILURE(error)) { 80 THROW_UFAILURE(objval, "ucnv_getSubstChars", error); 81 chars[0] = 0x1A; 82 chars[1] = 0; 83 chars_len = 1; 84 } 85 RETVAL_STRINGL(chars, chars_len, 1); 86 } 87 } 88 zval_dtor(error); 89 ZVAL_LONG(error, U_ZERO_ERROR); 90} 91/* }}} */ 92 93/* {{{ proto void UConverter::toUCallback(long $reason, 94 string $source, string $codeUnits, 95 long &$error) */ 96ZEND_BEGIN_ARG_INFO_EX(php_converter_toUCallback_arginfo, 0, ZEND_RETURN_VALUE, 4) 97 ZEND_ARG_INFO(0, reason) 98 ZEND_ARG_INFO(0, source) 99 ZEND_ARG_INFO(0, codeUnits) 100 ZEND_ARG_INFO(1, error) 101ZEND_END_ARG_INFO(); 102static PHP_METHOD(UConverter, toUCallback) { 103 long reason; 104 zval *source, *codeUnits, *error; 105 106 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzzz", 107 &reason, &source, &codeUnits, &error) == FAILURE) { 108 return; 109 } 110 111 php_converter_default_callback(return_value, getThis(), reason, error TSRMLS_CC); 112} 113/* }}} */ 114 115/* {{{ proto void UConverter::fromUCallback(long $reason, 116 Array $source, long $codePoint, 117 long &$error) */ 118ZEND_BEGIN_ARG_INFO_EX(php_converter_fromUCallback_arginfo, 0, ZEND_RETURN_VALUE, 4) 119 ZEND_ARG_INFO(0, reason) 120 ZEND_ARG_INFO(0, source) 121 ZEND_ARG_INFO(0, codePoint) 122 ZEND_ARG_INFO(1, error) 123ZEND_END_ARG_INFO(); 124static PHP_METHOD(UConverter, fromUCallback) { 125 long reason; 126 zval *source, *codePoint, *error; 127 128 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzzz", 129 &reason, &source, &codePoint, &error) == FAILURE) { 130 return; 131 } 132 133 php_converter_default_callback(return_value, getThis(), reason, error TSRMLS_CC); 134} 135/* }}} */ 136 137/* {{{ php_converter_check_limits */ 138static inline zend_bool php_converter_check_limits(php_converter_object *objval, long available, long needed TSRMLS_DC) { 139 if (available < needed) { 140 php_converter_throw_failure(objval, U_BUFFER_OVERFLOW_ERROR TSRMLS_CC, "Buffer overrun %ld bytes needed, %ld available", needed, available); 141 return 0; 142 } 143 return 1; 144} 145/* }}} */ 146 147#define TARGET_CHECK(cnvargs, needed) php_converter_check_limits(objval, cnvargs->targetLimit - cnvargs->target, needed TSRMLS_CC) 148 149/* {{{ php_converter_append_toUnicode_target */ 150static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicodeArgs *args, php_converter_object *objval TSRMLS_DC) { 151 switch (Z_TYPE_P(val)) { 152 case IS_NULL: 153 /* Code unit is being skipped */ 154 return; 155 case IS_LONG: 156 { 157 long lval = Z_LVAL_P(val); 158 if ((lval < 0) || (lval > 0x10FFFF)) { 159 php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC, "Invalid codepoint U+%04lx", lval); 160 return; 161 } 162 if (lval > 0xFFFF) { 163 /* Supplemental planes U+010000 - U+10FFFF */ 164 if (TARGET_CHECK(args, 2)) { 165 /* TODO: Find the ICU call which does this properly */ 166 *(args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800); 167 *(args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00); 168 } 169 return; 170 } 171 /* Non-suggogate BMP codepoint */ 172 if (TARGET_CHECK(args, 1)) { 173 *(args->target++) = (UChar)lval; 174 } 175 return; 176 } 177 case IS_STRING: 178 { 179 const char *strval = Z_STRVAL_P(val); 180 int i = 0, strlen = Z_STRLEN_P(val); 181 182 while((i != strlen) && TARGET_CHECK(args, 1)) { 183 UChar c; 184 U8_NEXT(strval, i, strlen, c); 185 *(args->target++) = c; 186 } 187 return; 188 } 189 case IS_ARRAY: 190 { 191 HashTable *ht = Z_ARRVAL_P(val); 192 HashPosition pos; 193 zval **tmpzval; 194 195 for(zend_hash_internal_pointer_reset_ex(ht, &pos); 196 zend_hash_get_current_data_ex(ht, (void**)&tmpzval, &pos) == SUCCESS; 197 zend_hash_move_forward_ex(ht, &pos)) { 198 php_converter_append_toUnicode_target(*tmpzval, args, objval TSRMLS_CC); 199 } 200 return; 201 } 202 default: 203 php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC, 204 "toUCallback() specified illegal type for substitution character"); 205 } 206} 207/* }}} */ 208 209/* {{{ php_converter_to_u_callback */ 210static void php_converter_to_u_callback(const void *context, 211 UConverterToUnicodeArgs *args, 212 const char *codeUnits, int32_t length, 213 UConverterCallbackReason reason, 214 UErrorCode *pErrorCode) { 215 php_converter_object *objval = (php_converter_object*)context; 216 zval *zreason, *zsource, *zcodeunits, *zerror, *retval = NULL; 217 zval **zargs[4]; 218#ifdef ZTS 219 TSRMLS_D = objval->tsrm_ls; 220#endif 221 222 MAKE_STD_ZVAL(zreason); 223 ZVAL_LONG(zreason, reason); 224 zargs[0] = &zreason; 225 226 MAKE_STD_ZVAL(zsource); 227 ZVAL_STRINGL(zsource, args->source, args->sourceLimit - args->source, 1); 228 zargs[1] = &zsource; 229 230 MAKE_STD_ZVAL(zcodeunits); 231 ZVAL_STRINGL(zcodeunits, codeUnits, length, 1); 232 zargs[2] = &zcodeunits; 233 234 MAKE_STD_ZVAL(zerror); 235 ZVAL_LONG(zerror, *pErrorCode); 236 zargs[3] = &zerror; 237 238 objval->to_cb.param_count = 4; 239 objval->to_cb.params = zargs; 240 objval->to_cb.retval_ptr_ptr = &retval; 241 objval->to_cb.no_separation = 0; 242 if (zend_call_function(&(objval->to_cb), &(objval->to_cache) TSRMLS_CC) == FAILURE) { 243 /* Unlikely */ 244 php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Unexpected failure calling toUCallback()"); 245 } else if (retval) { 246 php_converter_append_toUnicode_target(retval, args, objval TSRMLS_CC); 247 zval_ptr_dtor(&retval); 248 } 249 250 if (Z_TYPE_P(zerror) == IS_LONG) { 251 *pErrorCode = Z_LVAL_P(zerror); 252 } 253 254 zval_ptr_dtor(&zreason); 255 zval_ptr_dtor(&zsource); 256 zval_ptr_dtor(&zcodeunits); 257 zval_ptr_dtor(&zerror); 258} 259/* }}} */ 260 261/* {{{ php_converter_append_fromUnicode_target */ 262static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUnicodeArgs *args, php_converter_object *objval TSRMLS_DC) { 263 switch (Z_TYPE_P(val)) { 264 case IS_NULL: 265 /* Ignore */ 266 return; 267 case IS_LONG: 268 if (TARGET_CHECK(args, 1)) { 269 *(args->target++) = Z_LVAL_P(val); 270 } 271 return; 272 case IS_STRING: 273 { 274 int vallen = Z_STRLEN_P(val); 275 if (TARGET_CHECK(args, vallen)) { 276 memcpy(args->target, Z_STRVAL_P(val), vallen); 277 args->target += vallen; 278 } 279 return; 280 } 281 case IS_ARRAY: 282 { 283 HashTable *ht = Z_ARRVAL_P(val); 284 HashPosition pos; 285 zval **tmpzval; 286 for(zend_hash_internal_pointer_reset_ex(ht, &pos); 287 zend_hash_get_current_data_ex(ht, (void**)&tmpzval, &pos) == SUCCESS; 288 zend_hash_move_forward_ex(ht, &pos)) { 289 php_converter_append_fromUnicode_target(*tmpzval, args, objval TSRMLS_CC); 290 } 291 return; 292 } 293 default: 294 php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC, "fromUCallback() specified illegal type for substitution character"); 295 } 296} 297/* }}} */ 298 299/* {{{ php_converter_from_u_callback */ 300static void php_converter_from_u_callback(const void *context, 301 UConverterFromUnicodeArgs *args, 302 const UChar *codeUnits, int32_t length, UChar32 codePoint, 303 UConverterCallbackReason reason, 304 UErrorCode *pErrorCode) { 305 php_converter_object *objval = (php_converter_object*)context; 306 zval *zreason, *zsource, *zcodepoint, *zerror, *retval = NULL; 307 zval **zargs[4]; 308 int i; 309#ifdef ZTS 310 TSRMLS_D = objval->tsrm_ls; 311#endif 312 313 MAKE_STD_ZVAL(zreason); 314 ZVAL_LONG(zreason, reason); 315 zargs[0] = &zreason; 316 317 MAKE_STD_ZVAL(zsource); 318 array_init(zsource); 319 i = 0; 320 while (i < length) { 321 UChar32 c; 322 U16_NEXT(codeUnits, i, length, c); 323 add_next_index_long(zsource, c); 324 } 325 zargs[1] = &zsource; 326 327 MAKE_STD_ZVAL(zcodepoint); 328 ZVAL_LONG(zcodepoint, codePoint); 329 zargs[2] = &zcodepoint; 330 331 MAKE_STD_ZVAL(zerror); 332 ZVAL_LONG(zerror, *pErrorCode); 333 zargs[3] = &zerror; 334 335 objval->from_cb.param_count = 4; 336 objval->from_cb.params = zargs; 337 objval->from_cb.retval_ptr_ptr = &retval; 338 objval->from_cb.no_separation = 0; 339 if (zend_call_function(&(objval->from_cb), &(objval->from_cache) TSRMLS_CC) == FAILURE) { 340 /* Unlikely */ 341 php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Unexpected failure calling fromUCallback()"); 342 } else if (retval) { 343 php_converter_append_fromUnicode_target(retval, args, objval TSRMLS_CC); 344 zval_ptr_dtor(&retval); 345 } 346 347 if (Z_TYPE_P(zerror) == IS_LONG) { 348 *pErrorCode = Z_LVAL_P(zerror); 349 } 350 351 zval_ptr_dtor(&zreason); 352 zval_ptr_dtor(&zsource); 353 zval_ptr_dtor(&zcodepoint); 354 zval_ptr_dtor(&zerror); 355} 356/* }}} */ 357 358/* {{{ php_converter_set_callbacks */ 359static inline zend_bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv TSRMLS_DC) { 360 zend_bool ret = 1; 361 UErrorCode error = U_ZERO_ERROR; 362 363 if (objval->obj.ce == php_converter_ce) { 364 /* Short-circuit having to go through method calls and data marshalling 365 * when we're using default behavior 366 */ 367 return 1; 368 } 369 370 ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (const void*)objval, 371 NULL, NULL, &error); 372 if (U_FAILURE(error)) { 373 THROW_UFAILURE(objval, "ucnv_setToUCallBack", error); 374 ret = 0; 375 } 376 377 error = U_ZERO_ERROR; 378 ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (const void*)objval, 379 NULL, NULL, &error); 380 if (U_FAILURE(error)) { 381 THROW_UFAILURE(objval, "ucnv_setFromUCallBack", error); 382 ret = 0; 383 } 384 return ret; 385} 386/* }}} */ 387 388/* {{{ php_converter_set_encoding */ 389static zend_bool php_converter_set_encoding(php_converter_object *objval, 390 UConverter **pcnv, 391 const char *enc, int enc_len 392 TSRMLS_DC) { 393 UErrorCode error = U_ZERO_ERROR; 394 UConverter *cnv = ucnv_open(enc, &error); 395 396 if (error == U_AMBIGUOUS_ALIAS_WARNING) { 397 UErrorCode getname_error = U_ZERO_ERROR; 398 const char *actual_encoding = ucnv_getName(cnv, &getname_error); 399 if (U_FAILURE(getname_error)) { 400 /* Should never happen */ 401 actual_encoding = "(unknown)"; 402 } 403 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ambiguous encoding specified, using %s", actual_encoding); 404 } else if (U_FAILURE(error)) { 405 if (objval) { 406 THROW_UFAILURE(objval, "ucnv_open", error); 407 } else { 408 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error setting encoding: %d - %s", (int)error, u_errorName(error)); 409 } 410 return 0; 411 } 412 413 if (objval && !php_converter_set_callbacks(objval, cnv TSRMLS_CC)) { 414 return 0; 415 } 416 417 if (*pcnv) { 418 ucnv_close(*pcnv); 419 } 420 *pcnv = cnv; 421 return 1; 422} 423/* }}} */ 424 425/* {{{ php_converter_do_set_encoding */ 426ZEND_BEGIN_ARG_INFO_EX(php_converter_set_encoding_arginfo, 0, ZEND_RETURN_VALUE, 1) 427 ZEND_ARG_INFO(0, encoding) 428ZEND_END_ARG_INFO(); 429static void php_converter_do_set_encoding(UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { 430 php_converter_object *objval = CONV_GET(getThis()); 431 char *enc; 432 int enc_len; 433 434 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &enc, &enc_len) == FAILURE) { 435 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bad arguments, " 436 "expected one string argument", 0 TSRMLS_CC); 437 RETURN_FALSE; 438 } 439 intl_errors_reset(&objval->error TSRMLS_CC); 440 441 RETURN_BOOL(php_converter_set_encoding(objval, &(objval->src), enc, enc_len TSRMLS_CC)); 442} 443/* }}} */ 444 445/* {{{ proto bool UConverter::setSourceEncoding(string encoding) */ 446static PHP_METHOD(UConverter, setSourceEncoding) { 447 php_converter_object *objval = CONV_GET(getThis()); 448 php_converter_do_set_encoding(objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); 449} 450/* }}} */ 451 452/* {{{ proto bool UConverter::setDestinationEncoding(string encoding) */ 453static PHP_METHOD(UConverter, setDestinationEncoding) { 454 php_converter_object *objval = CONV_GET(getThis()); 455 php_converter_do_set_encoding(objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); 456} 457/* }}} */ 458 459/* {{{ php_converter_do_get_encoding */ 460ZEND_BEGIN_ARG_INFO_EX(php_converter_get_encoding_arginfo, 0, ZEND_RETURN_VALUE, 0) 461ZEND_END_ARG_INFO(); 462static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { 463 const char *name; 464 465 if (zend_parse_parameters_none() == FAILURE) { 466 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC); 467 RETURN_FALSE; 468 } 469 470 intl_errors_reset(&objval->error TSRMLS_CC); 471 472 if (!cnv) { 473 RETURN_NULL(); 474 } 475 476 name = ucnv_getName(cnv, &objval->error.code); 477 if (U_FAILURE(objval->error.code)) { 478 THROW_UFAILURE(objval, "ucnv_getName()", objval->error.code); 479 RETURN_FALSE; 480 } 481 482 RETURN_STRING(name, 1); 483} 484/* }}} */ 485 486/* {{{ proto string UConverter::getSourceEncoding() */ 487static PHP_METHOD(UConverter, getSourceEncoding) { 488 php_converter_object *objval = CONV_GET(getThis()); 489 php_converter_do_get_encoding(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); 490} 491/* }}} */ 492 493/* {{{ proto string UConverter::getDestinationEncoding() */ 494static PHP_METHOD(UConverter, getDestinationEncoding) { 495 php_converter_object *objval = CONV_GET(getThis()); 496 php_converter_do_get_encoding(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); 497} 498/* }}} */ 499 500/* {{{ php_converter_do_get_type */ 501ZEND_BEGIN_ARG_INFO_EX(php_converter_get_type_arginfo, 0, ZEND_RETURN_VALUE, 0) 502ZEND_END_ARG_INFO(); 503static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { 504 UConverterType t; 505 506 if (zend_parse_parameters_none() == FAILURE) { 507 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC); 508 RETURN_FALSE; 509 } 510 intl_errors_reset(&objval->error TSRMLS_CC); 511 512 if (!cnv) { 513 RETURN_NULL(); 514 } 515 516 t = ucnv_getType(cnv); 517 if (U_FAILURE(objval->error.code)) { 518 THROW_UFAILURE(objval, "ucnv_getType", objval->error.code); 519 RETURN_FALSE; 520 } 521 522 RETURN_LONG(t); 523} 524/* }}} */ 525 526/* {{{ proto long UConverter::getSourceType() */ 527static PHP_METHOD(UConverter, getSourceType) { 528 php_converter_object *objval = CONV_GET(getThis()); 529 php_converter_do_get_type(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); 530} 531/* }}} */ 532 533/* {{{ proto long UConverter::getDestinationType() */ 534static PHP_METHOD(UConverter, getDestinationType) { 535 php_converter_object *objval = CONV_GET(getThis()); 536 php_converter_do_get_type(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); 537} 538/* }}} */ 539 540/* {{{ php_converter_resolve_callback */ 541static void php_converter_resolve_callback(zval *zobj, 542 php_converter_object *objval, 543 const char *callback_name, 544 zend_fcall_info *finfo, 545 zend_fcall_info_cache *fcache TSRMLS_DC) { 546 char *errstr = NULL; 547 zval caller; 548 549 array_init(&caller); 550 Z_ADDREF_P(zobj); 551 add_index_zval(&caller, 0, zobj); 552 add_index_string(&caller, 1, callback_name, 1); 553 if (zend_fcall_info_init(&caller, 0, finfo, fcache, NULL, &errstr TSRMLS_CC) == FAILURE) { 554 php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Error setting converter callback: %s", errstr); 555 } 556 zval_dtor(&caller); 557 if (errstr) { 558 efree(errstr); 559 } 560} 561/* }}} */ 562 563/* {{{ proto void UConverter::__construct([string dest = 'utf-8',[string src = 'utf-8']]) */ 564ZEND_BEGIN_ARG_INFO_EX(php_converter_arginfo, 0, ZEND_RETURN_VALUE, 0) 565 ZEND_ARG_INFO(0, destination_encoding) 566 ZEND_ARG_INFO(0, source_encoding) 567ZEND_END_ARG_INFO(); 568 569static PHP_METHOD(UConverter, __construct) { 570 php_converter_object *objval = CONV_GET(getThis()); 571 char *src = "utf-8"; 572 int src_len = sizeof("utf-8") - 1; 573 char *dest = src; 574 int dest_len = src_len; 575 576 intl_error_reset(NULL TSRMLS_CC); 577 578 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!", 579 &dest, &dest_len, &src, &src_len) == FAILURE) { 580 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 581 "UConverter::__construct(): bad arguments", 0 TSRMLS_CC); 582 return; 583 } 584 585 php_converter_set_encoding(objval, &(objval->src), src, src_len TSRMLS_CC); 586 php_converter_set_encoding(objval, &(objval->dest), dest, dest_len TSRMLS_CC); 587 php_converter_resolve_callback(getThis(), objval, "toUCallback", &(objval->to_cb), &(objval->to_cache) TSRMLS_CC); 588 php_converter_resolve_callback(getThis(), objval, "fromUCallback", &(objval->from_cb), &(objval->from_cache) TSRMLS_CC); 589} 590/* }}} */ 591 592/* {{{ proto bool UConverter::setSubstChars(string $chars) */ 593ZEND_BEGIN_ARG_INFO_EX(php_converter_setSubstChars_arginfo, 0, ZEND_RETURN_VALUE, 1) 594 ZEND_ARG_INFO(0, chars) 595ZEND_END_ARG_INFO(); 596 597static PHP_METHOD(UConverter, setSubstChars) { 598 php_converter_object *objval = CONV_GET(getThis()); 599 char *chars; 600 int chars_len, ret = 1; 601 602 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &chars, &chars_len) == FAILURE) { 603 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 604 "UConverter::setSubstChars(): bad arguments", 0 TSRMLS_CC); 605 RETURN_FALSE; 606 } 607 intl_errors_reset(&objval->error TSRMLS_CC); 608 609 if (objval->src) { 610 UErrorCode error = U_ZERO_ERROR; 611 ucnv_setSubstChars(objval->src, chars, chars_len, &error); 612 if (U_FAILURE(error)) { 613 THROW_UFAILURE(objval, "ucnv_setSubstChars", error); 614 ret = 0; 615 } 616 } else { 617 php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Source Converter has not been initialized yet"); 618 ret = 0; 619 } 620 621 if (objval->dest) { 622 UErrorCode error = U_ZERO_ERROR; 623 ucnv_setSubstChars(objval->dest, chars, chars_len, &error); 624 if (U_FAILURE(error)) { 625 THROW_UFAILURE(objval, "ucnv_setSubstChars", error); 626 ret = 0; 627 } 628 } else { 629 php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Destination Converter has not been initialized yet"); 630 ret = 0; 631 } 632 633 RETURN_BOOL(ret); 634} 635/* }}} */ 636 637/* {{{ proto string UConverter::getSubstChars() */ 638ZEND_BEGIN_ARG_INFO_EX(php_converter_getSubstChars_arginfo, 0, ZEND_RETURN_VALUE, 0) 639ZEND_END_ARG_INFO(); 640 641static PHP_METHOD(UConverter, getSubstChars) { 642 php_converter_object *objval = CONV_GET(getThis()); 643 char chars[127]; 644 int8_t chars_len = sizeof(chars); 645 UErrorCode error = U_ZERO_ERROR; 646 647 if (zend_parse_parameters_none() == FAILURE) { 648 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 649 "UConverter::getSubstChars(): expected no arguments", 0 TSRMLS_CC); 650 RETURN_FALSE; 651 } 652 intl_errors_reset(&objval->error TSRMLS_CC); 653 654 if (!objval->src) { 655 RETURN_NULL(); 656 } 657 658 /* src and dest get the same subst chars set, 659 * so it doesn't really matter which one we read from 660 */ 661 ucnv_getSubstChars(objval->src, chars, &chars_len, &error); 662 if (U_FAILURE(error)) { 663 THROW_UFAILURE(objval, "ucnv_getSubstChars", error); 664 RETURN_FALSE; 665 } 666 667 RETURN_STRINGL(chars, chars_len, 1); 668} 669/* }}} */ 670 671/* {{{ php_converter_do_convert */ 672static zend_bool php_converter_do_convert(UConverter *dest_cnv, char **pdest, int32_t *pdest_len, 673 UConverter *src_cnv, const char *src, int32_t src_len, 674 php_converter_object *objval 675 TSRMLS_DC) { 676 UErrorCode error = U_ZERO_ERROR; 677 int32_t dest_len, 678 temp_len; 679 char *dest; 680 UChar *temp; 681 682 if (!src_cnv || !dest_cnv) { 683 php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, 684 "Internal converters not initialized"); 685 return 0; 686 } 687 688 /* Get necessary buffer size first */ 689 temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error); 690 if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { 691 THROW_UFAILURE(objval, "ucnv_toUChars", error); 692 return 0; 693 } 694 temp = safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar)); 695 696 /* Convert to intermediate UChar* array */ 697 error = U_ZERO_ERROR; 698 temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &error); 699 if (U_FAILURE(error)) { 700 THROW_UFAILURE(objval, "ucnv_toUChars", error); 701 efree(temp); 702 return 0; 703 } 704 temp[temp_len] = 0; 705 706 /* Get necessary output buffer size */ 707 dest_len = 1 + ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); 708 if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { 709 THROW_UFAILURE(objval, "ucnv_fromUChars", error); 710 efree(temp); 711 return 0; 712 } 713 dest = safe_emalloc(sizeof(char), dest_len, sizeof(char)); 714 715 /* Convert to final encoding */ 716 error = U_ZERO_ERROR; 717 dest_len = ucnv_fromUChars(dest_cnv, dest, dest_len, temp, temp_len, &error); 718 efree(temp); 719 if (U_FAILURE(error)) { 720 THROW_UFAILURE(objval, "ucnv_fromUChars", error); 721 efree(dest); 722 return 0; 723 } 724 725 *pdest = dest; 726 if (pdest_len) { 727 *pdest_len = dest_len; 728 } 729 730 return 1; 731} 732/* }}} */ 733 734/* {{{ proto string UConverter::reasonText(long reason) */ 735#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1, 1); 736ZEND_BEGIN_ARG_INFO_EX(php_converter_reasontext_arginfo, 0, ZEND_RETURN_VALUE, 0) 737 ZEND_ARG_INFO(0, reason) 738ZEND_END_ARG_INFO(); 739static PHP_METHOD(UConverter, reasonText) { 740 long reason; 741 742 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &reason) == FAILURE) { 743 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 744 "UConverter::reasonText(): bad arguments", 0 TSRMLS_CC); 745 RETURN_FALSE; 746 } 747 intl_error_reset(NULL TSRMLS_CC); 748 749 switch (reason) { 750 UCNV_REASON_CASE(UNASSIGNED) 751 UCNV_REASON_CASE(ILLEGAL) 752 UCNV_REASON_CASE(IRREGULAR) 753 UCNV_REASON_CASE(RESET) 754 UCNV_REASON_CASE(CLOSE) 755 UCNV_REASON_CASE(CLONE) 756 default: 757 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown UConverterCallbackReason: %ld", reason); 758 RETURN_FALSE; 759 } 760} 761/* }}} */ 762 763/* {{{ proto string UConverter::convert(string str[, bool reverse]) */ 764ZEND_BEGIN_ARG_INFO_EX(php_converter_convert_arginfo, 0, ZEND_RETURN_VALUE, 1) 765 ZEND_ARG_INFO(0, str) 766 ZEND_ARG_INFO(0, reverse) 767ZEND_END_ARG_INFO(); 768 769static PHP_METHOD(UConverter, convert) { 770 php_converter_object *objval = CONV_GET(getThis()); 771 char *str, *dest; 772 int str_len, dest_len; 773 zend_bool reverse = 0; 774 775 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", 776 &str, &str_len, &reverse) == FAILURE) { 777 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 778 "UConverter::convert(): bad arguments", 0 TSRMLS_CC); 779 RETURN_FALSE; 780 } 781 intl_errors_reset(&objval->error TSRMLS_CC); 782 783 if (php_converter_do_convert(reverse ? objval->src : objval->dest, 784 &dest, &dest_len, 785 reverse ? objval->dest : objval->src, 786 str, str_len, 787 objval TSRMLS_CC)) { 788 RETURN_STRINGL(dest, dest_len, 0); 789 } else { 790 RETURN_FALSE; 791 } 792} 793/* }}} */ 794 795/* {{{ proto string UConverter::transcode(string $str, string $toEncoding, string $fromEncoding[, Array $options = array()]) */ 796ZEND_BEGIN_ARG_INFO_EX(php_converter_transcode_arginfo, 0, ZEND_RETURN_VALUE, 3) 797 ZEND_ARG_INFO(0, str) 798 ZEND_ARG_INFO(0, toEncoding) 799 ZEND_ARG_INFO(0, fromEncoding) 800 ZEND_ARG_ARRAY_INFO(0, options, 1) 801ZEND_END_ARG_INFO(); 802 803static PHP_METHOD(UConverter, transcode) { 804 char *str, *src, *dest; 805 int str_len, src_len, dest_len; 806 zval *options = NULL; 807 UConverter *src_cnv = NULL, *dest_cnv = NULL; 808 809 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|a!", 810 &str, &str_len, &dest, &dest_len, &src, &src_len, &options) == FAILURE) { 811 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 812 "UConverter::transcode(): bad arguments", 0 TSRMLS_CC); 813 RETURN_FALSE; 814 } 815 intl_error_reset(NULL TSRMLS_CC); 816 817 if (php_converter_set_encoding(NULL, &src_cnv, src, src_len TSRMLS_CC) && 818 php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len TSRMLS_CC)) { 819 char *out = NULL; 820 int out_len = 0; 821 UErrorCode error = U_ZERO_ERROR; 822 823 if (options && zend_hash_num_elements(Z_ARRVAL_P(options))) { 824 zval **tmpzval; 825 826 if (U_SUCCESS(error) && 827 zend_hash_find(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst"), (void**)&tmpzval) == SUCCESS && 828 Z_TYPE_PP(tmpzval) == IS_STRING) { 829 error = U_ZERO_ERROR; 830 ucnv_setSubstChars(src_cnv, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) & 0x7F, &error); 831 } 832 if (U_SUCCESS(error) && 833 zend_hash_find(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst"), (void**)&tmpzval) == SUCCESS && 834 Z_TYPE_PP(tmpzval) == IS_STRING) { 835 error = U_ZERO_ERROR; 836 ucnv_setSubstChars(dest_cnv, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) & 0x7F, &error); 837 } 838 } 839 840 if (U_SUCCESS(error) && 841 php_converter_do_convert(dest_cnv, &out, &out_len, src_cnv, str, str_len, NULL TSRMLS_CC)) { 842 RETVAL_STRINGL(out, out_len, 0); 843 } 844 845 if (U_FAILURE(error)) { 846 THROW_UFAILURE(NULL, "transcode", error); 847 RETVAL_FALSE; 848 } 849 } else { 850 RETVAL_FALSE; 851 } 852 853 if (src_cnv) { 854 ucnv_close(src_cnv); 855 } 856 if (dest_cnv) { 857 ucnv_close(dest_cnv); 858 } 859} 860/* }}} */ 861 862/* {{{ proto int UConverter::getErrorCode() */ 863ZEND_BEGIN_ARG_INFO_EX(php_converter_geterrorcode_arginfo, 0, ZEND_RETURN_VALUE, 0) 864ZEND_END_ARG_INFO(); 865static PHP_METHOD(UConverter, getErrorCode) { 866 php_converter_object *objval = CONV_GET(getThis()); 867 868 if (zend_parse_parameters_none() == FAILURE) { 869 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 870 "UConverter::getErrorCode(): expected no arguments", 0 TSRMLS_CC); 871 RETURN_FALSE; 872 } 873 874 RETURN_LONG(intl_error_get_code(&(objval->error) TSRMLS_CC)); 875} 876/* }}} */ 877 878/* {{{ proto string UConverter::getErrorMessage() */ 879ZEND_BEGIN_ARG_INFO_EX(php_converter_geterrormsg_arginfo, 0, ZEND_RETURN_VALUE, 0) 880ZEND_END_ARG_INFO(); 881static PHP_METHOD(UConverter, getErrorMessage) { 882 php_converter_object *objval = CONV_GET(getThis()); 883 char *message = intl_error_get_message(&(objval->error) TSRMLS_CC); 884 885 if (zend_parse_parameters_none() == FAILURE) { 886 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 887 "UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC); 888 RETURN_FALSE; 889 } 890 891 if (message) { 892 RETURN_STRING(message, 1); 893 } else { 894 RETURN_NULL(); 895 } 896} 897/* }}} */ 898 899/* {{{ proto array UConverter::getAvailable() */ 900ZEND_BEGIN_ARG_INFO_EX(php_converter_getavailable_arginfo, 0, ZEND_RETURN_VALUE, 0) 901ZEND_END_ARG_INFO(); 902static PHP_METHOD(UConverter, getAvailable) { 903 int32_t i, 904 count = ucnv_countAvailable(); 905 906 if (zend_parse_parameters_none() == FAILURE) { 907 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 908 "UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC); 909 RETURN_FALSE; 910 } 911 intl_error_reset(NULL TSRMLS_CC); 912 913 array_init(return_value); 914 for(i = 0; i < count; i++) { 915 const char *name = ucnv_getAvailableName(i); 916 add_next_index_string(return_value, name, 1); 917 } 918} 919/* }}} */ 920 921/* {{{ proto array UConverter::getAliases(string name) */ 922ZEND_BEGIN_ARG_INFO_EX(php_converter_getaliases_arginfo, 0, ZEND_RETURN_VALUE, 0) 923 ZEND_ARG_INFO(0, name) 924ZEND_END_ARG_INFO(); 925static PHP_METHOD(UConverter, getAliases) { 926 char *name; 927 int name_len; 928 UErrorCode error = U_ZERO_ERROR; 929 uint16_t i, count; 930 931 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { 932 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 933 "UConverter::getAliases(): bad arguments", 0 TSRMLS_CC); 934 RETURN_FALSE; 935 } 936 intl_error_reset(NULL TSRMLS_CC); 937 938 count = ucnv_countAliases(name, &error); 939 if (U_FAILURE(error)) { 940 THROW_UFAILURE(NULL, "ucnv_countAliases", error); 941 RETURN_FALSE; 942 } 943 944 array_init(return_value); 945 for(i = 0; i < count; i++) { 946 const char *alias; 947 948 error = U_ZERO_ERROR; 949 alias = ucnv_getAlias(name, i, &error); 950 if (U_FAILURE(error)) { 951 THROW_UFAILURE(NULL, "ucnv_getAlias", error); 952 zval_dtor(return_value); 953 RETURN_NULL(); 954 } 955 add_next_index_string(return_value, alias, 1); 956 } 957} 958/* }}} */ 959 960/* {{{ proto array UConverter::getStandards() */ 961ZEND_BEGIN_ARG_INFO_EX(php_converter_getstandards_arginfo, 0, ZEND_RETURN_VALUE, 0) 962ZEND_END_ARG_INFO(); 963static PHP_METHOD(UConverter, getStandards) { 964 uint16_t i, count; 965 966 if (zend_parse_parameters_none() == FAILURE) { 967 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, 968 "UConverter::getStandards(): expected no arguments", 0 TSRMLS_CC); 969 RETURN_FALSE; 970 } 971 intl_error_reset(NULL TSRMLS_CC); 972 973 array_init(return_value); 974 count = ucnv_countStandards(); 975 for(i = 0; i < count; i++) { 976 UErrorCode error = U_ZERO_ERROR; 977 const char *name = ucnv_getStandard(i, &error); 978 if (U_FAILURE(error)) { 979 THROW_UFAILURE(NULL, "ucnv_getStandard", error); 980 zval_dtor(return_value); 981 RETURN_NULL(); 982 } 983 add_next_index_string(return_value, name, 1); 984 } 985} 986/* }}} */ 987 988static zend_function_entry php_converter_methods[] = { 989 PHP_ME(UConverter, __construct, php_converter_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 990 991 /* Encoding selection */ 992 PHP_ME(UConverter, setSourceEncoding, php_converter_set_encoding_arginfo, ZEND_ACC_PUBLIC) 993 PHP_ME(UConverter, setDestinationEncoding, php_converter_set_encoding_arginfo, ZEND_ACC_PUBLIC) 994 PHP_ME(UConverter, getSourceEncoding, php_converter_get_encoding_arginfo, ZEND_ACC_PUBLIC) 995 PHP_ME(UConverter, getDestinationEncoding, php_converter_get_encoding_arginfo, ZEND_ACC_PUBLIC) 996 997 /* Introspection for algorithmic converters */ 998 PHP_ME(UConverter, getSourceType, php_converter_get_type_arginfo, ZEND_ACC_PUBLIC) 999 PHP_ME(UConverter, getDestinationType, php_converter_get_type_arginfo, ZEND_ACC_PUBLIC) 1000 1001 /* Basic codeunit error handling */ 1002 PHP_ME(UConverter, getSubstChars, php_converter_getSubstChars_arginfo, ZEND_ACC_PUBLIC) 1003 PHP_ME(UConverter, setSubstChars, php_converter_setSubstChars_arginfo, ZEND_ACC_PUBLIC) 1004 1005 /* Default callback handlers */ 1006 PHP_ME(UConverter, toUCallback, php_converter_toUCallback_arginfo, ZEND_ACC_PUBLIC) 1007 PHP_ME(UConverter, fromUCallback, php_converter_fromUCallback_arginfo, ZEND_ACC_PUBLIC) 1008 1009 /* Core conversion workhorses */ 1010 PHP_ME(UConverter, convert, php_converter_convert_arginfo, ZEND_ACC_PUBLIC) 1011 PHP_ME(UConverter, transcode, php_converter_transcode_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 1012 1013 /* Error inspection */ 1014 PHP_ME(UConverter, getErrorCode, php_converter_geterrorcode_arginfo, ZEND_ACC_PUBLIC) 1015 PHP_ME(UConverter, getErrorMessage, php_converter_geterrormsg_arginfo, ZEND_ACC_PUBLIC) 1016 1017 /* Ennumeration and lookup */ 1018 PHP_ME(UConverter, reasonText, php_converter_reasontext_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 1019 PHP_ME(UConverter, getAvailable, php_converter_getavailable_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 1020 PHP_ME(UConverter, getAliases, php_converter_getaliases_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 1021 PHP_ME(UConverter, getStandards, php_converter_getstandards_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 1022 { NULL, NULL, NULL } 1023}; 1024 1025/* {{{ Converter create/clone/destroy */ 1026static void php_converter_free_object(php_converter_object *objval TSRMLS_DC) { 1027 if (objval->src) { 1028 ucnv_close(objval->src); 1029 } 1030 1031 if (objval->dest) { 1032 ucnv_close(objval->dest); 1033 } 1034 1035 intl_error_reset(&(objval->error) TSRMLS_CC); 1036 zend_object_std_dtor(&(objval->obj) TSRMLS_CC); 1037 1038 efree(objval); 1039} 1040 1041static zend_object_value php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval TSRMLS_DC) { 1042 php_converter_object *objval; 1043 zend_object_value retval; 1044 1045 objval = ecalloc(1, sizeof(php_converter_object)); 1046 objval->obj.ce = ce; 1047 1048#ifdef ZTS 1049 objval->tsrm_ls = TSRMLS_C; 1050#endif 1051 intl_error_init(&(objval->error) TSRMLS_CC); 1052 1053 retval.handle = zend_objects_store_put(objval, NULL, (zend_objects_free_object_storage_t)php_converter_free_object, NULL TSRMLS_CC); 1054 retval.handlers = &php_converter_object_handlers; 1055 *pobjval = objval; 1056 1057 return retval; 1058} 1059 1060static zend_object_value php_converter_create_object(zend_class_entry *ce TSRMLS_DC) { 1061 php_converter_object *objval = NULL; 1062 zend_object_value retval = php_converter_object_ctor(ce, &objval TSRMLS_CC); 1063 1064 object_properties_init(&(objval->obj), ce); 1065 1066 return retval; 1067} 1068 1069static zend_object_value php_converter_clone_object(zval *object TSRMLS_DC) { 1070 php_converter_object *objval, *oldobj = (php_converter_object*)zend_objects_get_address(object TSRMLS_CC); 1071 zend_object_value retval = php_converter_object_ctor(Z_OBJCE_P(object), &objval TSRMLS_CC); 1072 UErrorCode error = U_ZERO_ERROR; 1073 1074 intl_errors_reset(&oldobj->error TSRMLS_CC); 1075 1076 objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error); 1077 if (U_SUCCESS(error)) { 1078 error = U_ZERO_ERROR; 1079 objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error); 1080 } 1081 if (U_FAILURE(error)) { 1082 char *err_msg; 1083 THROW_UFAILURE(oldobj, "ucnv_safeClone", error); 1084 1085 err_msg = intl_error_get_message(&oldobj->error TSRMLS_CC); 1086 zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC); 1087 efree(err_msg); 1088 1089 return retval; 1090 } 1091 1092 /* Update contexts for converter error handlers */ 1093 php_converter_set_callbacks(objval, objval->src TSRMLS_CC); 1094 php_converter_set_callbacks(objval, objval->dest TSRMLS_CC); 1095 1096 zend_objects_clone_members(&(objval->obj), retval, &(oldobj->obj), Z_OBJ_HANDLE_P(object) TSRMLS_CC); 1097 1098 /* Newly cloned object deliberately does not inherit error state from original object */ 1099 1100 return retval; 1101} 1102/* }}} */ 1103 1104#define CONV_REASON_CONST(v) zend_declare_class_constant_long(php_converter_ce, "REASON_" #v, sizeof("REASON_" #v) - 1, UCNV_ ## v TSRMLS_CC) 1105#define CONV_TYPE_CONST(v) zend_declare_class_constant_long(php_converter_ce, #v , sizeof(#v) - 1, UCNV_ ## v TSRMLS_CC) 1106 1107/* {{{ php_converter_minit */ 1108int php_converter_minit(INIT_FUNC_ARGS) { 1109 zend_class_entry ce; 1110 1111 INIT_CLASS_ENTRY(ce, "UConverter", php_converter_methods); 1112 php_converter_ce = zend_register_internal_class(&ce TSRMLS_CC); 1113 php_converter_ce->create_object = php_converter_create_object; 1114 memcpy(&php_converter_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 1115 php_converter_object_handlers.clone_obj = php_converter_clone_object; 1116 1117 /* enum UConverterCallbackReason */ 1118 CONV_REASON_CONST(UNASSIGNED); 1119 CONV_REASON_CONST(ILLEGAL); 1120 CONV_REASON_CONST(IRREGULAR); 1121 CONV_REASON_CONST(RESET); 1122 CONV_REASON_CONST(CLOSE); 1123 CONV_REASON_CONST(CLONE); 1124 1125 /* enum UConverterType */ 1126 CONV_TYPE_CONST(UNSUPPORTED_CONVERTER); 1127 CONV_TYPE_CONST(SBCS); 1128 CONV_TYPE_CONST(DBCS); 1129 CONV_TYPE_CONST(MBCS); 1130 CONV_TYPE_CONST(LATIN_1); 1131 CONV_TYPE_CONST(UTF8); 1132 CONV_TYPE_CONST(UTF16_BigEndian); 1133 CONV_TYPE_CONST(UTF16_LittleEndian); 1134 CONV_TYPE_CONST(UTF32_BigEndian); 1135 CONV_TYPE_CONST(UTF32_LittleEndian); 1136 CONV_TYPE_CONST(EBCDIC_STATEFUL); 1137 CONV_TYPE_CONST(ISO_2022); 1138 CONV_TYPE_CONST(LMBCS_1); 1139 CONV_TYPE_CONST(LMBCS_2); 1140 CONV_TYPE_CONST(LMBCS_3); 1141 CONV_TYPE_CONST(LMBCS_4); 1142 CONV_TYPE_CONST(LMBCS_5); 1143 CONV_TYPE_CONST(LMBCS_6); 1144 CONV_TYPE_CONST(LMBCS_8); 1145 CONV_TYPE_CONST(LMBCS_11); 1146 CONV_TYPE_CONST(LMBCS_16); 1147 CONV_TYPE_CONST(LMBCS_17); 1148 CONV_TYPE_CONST(LMBCS_18); 1149 CONV_TYPE_CONST(LMBCS_19); 1150 CONV_TYPE_CONST(LMBCS_LAST); 1151 CONV_TYPE_CONST(HZ); 1152 CONV_TYPE_CONST(SCSU); 1153 CONV_TYPE_CONST(ISCII); 1154 CONV_TYPE_CONST(US_ASCII); 1155 CONV_TYPE_CONST(UTF7); 1156 CONV_TYPE_CONST(BOCU1); 1157 CONV_TYPE_CONST(UTF16); 1158 CONV_TYPE_CONST(UTF32); 1159 CONV_TYPE_CONST(CESU8); 1160 CONV_TYPE_CONST(IMAP_MAILBOX); 1161 1162 return SUCCESS; 1163} 1164/* }}} */ 1165 1166/* 1167 * Local variables: 1168 * tab-width: 4 1169 * c-basic-offset: 4 1170 * End: 1171 * vim600: noet sw=4 ts=4 fdm=marker 1172 * vim<600: noet sw=4 ts=4 1173 */ 1174