Annotation of embedaddon/php/ext/intl/resourcebundle/resourcebundle_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: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
! 14: +----------------------------------------------------------------------+
! 15: */
! 16:
! 17: #include <stdlib.h>
! 18: #include <unicode/ures.h>
! 19: #include <unicode/uenum.h>
! 20:
! 21: #include <zend.h>
! 22: #include <Zend/zend_exceptions.h>
! 23: #include <Zend/zend_interfaces.h>
! 24: #include <php.h>
! 25:
! 26: #include "php_intl.h"
! 27: #include "intl_data.h"
! 28:
! 29: #include "resourcebundle/resourcebundle.h"
! 30: #include "resourcebundle/resourcebundle_iterator.h"
! 31: #include "resourcebundle/resourcebundle_class.h"
! 32:
! 33: zend_class_entry *ResourceBundle_ce_ptr = NULL;
! 34:
! 35: static zend_object_handlers ResourceBundle_object_handlers;
! 36:
! 37: /* {{{ ResourceBundle_object_dtor */
! 38: static void ResourceBundle_object_destroy( void *object, zend_object_handle handle TSRMLS_DC )
! 39: {
! 40: ResourceBundle_object *rb = (ResourceBundle_object *) object;
! 41:
! 42: // only free local errors
! 43: intl_error_reset( INTL_DATA_ERROR_P(rb) TSRMLS_CC );
! 44:
! 45: if (rb->me) {
! 46: ures_close( rb->me );
! 47: }
! 48: if (rb->child) {
! 49: ures_close( rb->child );
! 50: }
! 51:
! 52: zend_object_std_dtor( object TSRMLS_CC );
! 53: efree(object);
! 54: }
! 55: /* }}} */
! 56:
! 57: /* {{{ ResourceBundle_object_create */
! 58: static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRMLS_DC )
! 59: {
! 60: zend_object_value retval;
! 61: ResourceBundle_object *rb;
! 62:
! 63: rb = ecalloc( 1, sizeof(ResourceBundle_object) );
! 64:
! 65: zend_object_std_init( (zend_object *) rb, ce TSRMLS_CC );
! 66:
! 67: intl_error_init( INTL_DATA_ERROR_P(rb) TSRMLS_CC );
! 68: rb->me = NULL;
! 69: rb->child = NULL;
! 70:
! 71: retval.handlers = &ResourceBundle_object_handlers;
! 72: retval.handle = zend_objects_store_put( rb, ResourceBundle_object_destroy, NULL, NULL TSRMLS_CC );
! 73:
! 74: return retval;
! 75: }
! 76: /* }}} */
! 77:
! 78: /* {{{ ResourceBundle_ctor */
! 79: static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
! 80: {
! 81: char * bundlename;
! 82: int bundlename_len = 0;
! 83: char * locale;
! 84: int locale_len = 0;
! 85: zend_bool fallback = 1;
! 86:
! 87: char * pbuf;
! 88:
! 89: zval *object = return_value;
! 90: ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC);
! 91:
! 92: intl_error_reset( NULL TSRMLS_CC );
! 93:
! 94: if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss|b",
! 95: &locale, &locale_len, &bundlename, &bundlename_len, &fallback ) == FAILURE )
! 96: {
! 97: intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 98: "resourcebundle_ctor: unable to parse input parameters", 0 TSRMLS_CC );
! 99: zval_dtor( return_value );
! 100: RETURN_NULL();
! 101: }
! 102:
! 103: INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
! 104:
! 105: if (fallback) {
! 106: rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
! 107: } else {
! 108: rb->me = ures_openDirect(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
! 109: }
! 110:
! 111: INTL_CTOR_CHECK_STATUS(rb, "resourcebundle_ctor: Cannot load libICU resource bundle");
! 112:
! 113: if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
! 114: intl_errors_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
! 115: spprintf( &pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource '%s' without fallback from %s to %s",
! 116: bundlename, locale, ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(rb)) );
! 117: intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
! 118: efree(pbuf);
! 119: zval_dtor( return_value );
! 120: RETURN_NULL();
! 121: }
! 122: }
! 123: /* }}} */
! 124:
! 125: /* {{{ arginfo_resourcebundle__construct */
! 126: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle___construct, 0, 0, 2 )
! 127: ZEND_ARG_INFO( 0, locale )
! 128: ZEND_ARG_INFO( 0, bundlename )
! 129: ZEND_ARG_INFO( 0, fallback )
! 130: ZEND_END_ARG_INFO()
! 131: /* }}} */
! 132:
! 133: /* {{{ proto void ResourceBundle::__construct( string $locale [, string $bundlename [, bool $fallback = true ]] )
! 134: * ResourceBundle object constructor
! 135: */
! 136: PHP_METHOD( ResourceBundle, __construct )
! 137: {
! 138: return_value = getThis();
! 139: resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
! 140: }
! 141: /* }}} */
! 142:
! 143: /* {{{ proto ResourceBundle ResourceBundle::create( string $locale [, string $bundlename [, bool $fallback = true ]] )
! 144: proto ResourceBundle resourcebundle_create( string $locale [, string $bundlename [, bool $fallback = true ]] )
! 145: */
! 146: PHP_FUNCTION( resourcebundle_create )
! 147: {
! 148: object_init_ex( return_value, ResourceBundle_ce_ptr );
! 149: resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
! 150: }
! 151: /* }}} */
! 152:
! 153: /* {{{ resourcebundle_array_fetch */
! 154: static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC)
! 155: {
! 156: int32_t meindex;
! 157: char * mekey;
! 158: long mekeylen;
! 159: zend_bool is_numeric = 0;
! 160: char *pbuf;
! 161: ResourceBundle_object *rb;
! 162:
! 163: intl_error_reset( NULL TSRMLS_CC );
! 164: RESOURCEBUNDLE_METHOD_FETCH_OBJECT;
! 165:
! 166: if(Z_TYPE_P(offset) == IS_LONG) {
! 167: is_numeric = 1;
! 168: meindex = Z_LVAL_P(offset);
! 169: rb->child = ures_getByIndex( rb->me, meindex, rb->child, &INTL_DATA_ERROR_CODE(rb) );
! 170: } else if(Z_TYPE_P(offset) == IS_STRING) {
! 171: mekey = Z_STRVAL_P(offset);
! 172: mekeylen = Z_STRLEN_P(offset);
! 173: rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) );
! 174: } else {
! 175: intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,
! 176: "resourcebundle_get: index should be integer or string", 0 TSRMLS_CC);
! 177: RETURN_NULL();
! 178: }
! 179:
! 180: intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
! 181: if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) {
! 182: if (is_numeric) {
! 183: spprintf( &pbuf, 0, "Cannot load resource element %d", meindex );
! 184: } else {
! 185: spprintf( &pbuf, 0, "Cannot load resource element '%s'", mekey );
! 186: }
! 187: intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
! 188: efree(pbuf);
! 189: RETURN_NULL();
! 190: }
! 191:
! 192: if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
! 193: UErrorCode icuerror;
! 194: const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror );
! 195: if (is_numeric) {
! 196: spprintf( &pbuf, 0, "Cannot load element %d without fallback from to %s", meindex, locale );
! 197: } else {
! 198: spprintf( &pbuf, 0, "Cannot load element '%s' without fallback from to %s", mekey, locale );
! 199: }
! 200: intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
! 201: efree(pbuf);
! 202: RETURN_NULL();
! 203: }
! 204:
! 205: resourcebundle_extract_value( return_value, rb TSRMLS_CC );
! 206: }
! 207: /* }}} */
! 208:
! 209: /* {{{ resourcebundle_array_get */
! 210: zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC)
! 211: {
! 212: zval *retval;
! 213:
! 214: if(offset == NULL) {
! 215: php_error( E_ERROR, "Cannot apply [] to ResourceBundle object" );
! 216: }
! 217: MAKE_STD_ZVAL(retval);
! 218:
! 219: resourcebundle_array_fetch(object, offset, retval, 1 TSRMLS_CC);
! 220: Z_DELREF_P(retval);
! 221: return retval;
! 222: }
! 223: /* }}} */
! 224:
! 225: /* {{{ arginfo_resourcebundle_get */
! 226: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get, 0, 0, 1 )
! 227: ZEND_ARG_INFO( 0, index )
! 228: ZEND_ARG_INFO( 0, fallback )
! 229: ZEND_END_ARG_INFO()
! 230: /* }}} */
! 231:
! 232: /* {{{ proto mixed ResourceBundle::get( integer|string $resindex [, bool $fallback = true ] )
! 233: * proto mixed resourcebundle_get( ResourceBundle $rb, integer|string $resindex [, bool $fallback = true ] )
! 234: * Get resource identified by numerical index or key name.
! 235: */
! 236: PHP_FUNCTION( resourcebundle_get )
! 237: {
! 238: zend_bool fallback = 1;
! 239: zval * offset;
! 240: zval * object;
! 241:
! 242: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz|b", &object, ResourceBundle_ce_ptr, &offset, &fallback ) == FAILURE) {
! 243: intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 244: "resourcebundle_get: unable to parse input params", 0 TSRMLS_CC);
! 245: RETURN_FALSE;
! 246: }
! 247:
! 248: resourcebundle_array_fetch(object, offset, return_value, fallback TSRMLS_CC);
! 249: }
! 250: /* }}} */
! 251:
! 252: /* {{{ resourcebundle_array_count */
! 253: int resourcebundle_array_count(zval *object, long *count TSRMLS_DC)
! 254: {
! 255: ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC);
! 256:
! 257: *count = ures_getSize( rb->me );
! 258:
! 259: return SUCCESS;
! 260: }
! 261: /* }}} */
! 262:
! 263: /* {{{ arginfo_resourcebundle_count */
! 264: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_count, 0, 0, 0 )
! 265: ZEND_END_ARG_INFO()
! 266: /* }}} */
! 267:
! 268: /* {{{ proto int ResourceBundle::count()
! 269: * proto int resourcebundle_count( ResourceBundle $bundle )
! 270: * Get resources count
! 271: */
! 272: PHP_FUNCTION( resourcebundle_count )
! 273: {
! 274: int32_t len;
! 275: RESOURCEBUNDLE_METHOD_INIT_VARS;
! 276:
! 277: if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) {
! 278: intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 279: "resourcebundle_count: unable to parse input params", 0 TSRMLS_CC);
! 280: RETURN_FALSE;
! 281: }
! 282:
! 283: RESOURCEBUNDLE_METHOD_FETCH_OBJECT;
! 284:
! 285: len = ures_getSize( rb->me );
! 286: RETURN_LONG( len );
! 287: }
! 288:
! 289: /* {{{ arginfo_resourcebundle_getlocales */
! 290: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_getlocales, 0, 0, 1 )
! 291: ZEND_ARG_INFO( 0, bundlename )
! 292: ZEND_END_ARG_INFO()
! 293: /* }}} */
! 294:
! 295: /* {{{ proto array ResourceBundle::getLocales( string $bundlename )
! 296: * proto array resourcebundle_locales( string $bundlename )
! 297: * Get available locales from ResourceBundle name
! 298: */
! 299: PHP_FUNCTION( resourcebundle_locales )
! 300: {
! 301: char * bundlename;
! 302: int bundlename_len = 0;
! 303: const char * entry;
! 304: int entry_len;
! 305: UEnumeration *icuenum;
! 306: UErrorCode icuerror = U_ZERO_ERROR;
! 307:
! 308: intl_errors_reset( NULL TSRMLS_CC );
! 309:
! 310: if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &bundlename, &bundlename_len ) == FAILURE )
! 311: {
! 312: intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 313: "resourcebundle_locales: unable to parse input params", 0 TSRMLS_CC);
! 314: RETURN_FALSE;
! 315: }
! 316:
! 317: if(bundlename_len == 0) {
! 318: // fetch default locales list
! 319: bundlename = NULL;
! 320: }
! 321:
! 322: icuenum = ures_openAvailableLocales( bundlename, &icuerror );
! 323: INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");
! 324:
! 325: uenum_reset( icuenum, &icuerror );
! 326: INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");
! 327:
! 328: array_init( return_value );
! 329: while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) {
! 330: add_next_index_stringl( return_value, (char *) entry, entry_len, 1 );
! 331: }
! 332: uenum_close( icuenum );
! 333: }
! 334: /* }}} */
! 335:
! 336: /* {{{ arginfo_resourcebundle_get_error_code */
! 337: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_code, 0, 0, 0 )
! 338: ZEND_END_ARG_INFO()
! 339: /* }}} */
! 340:
! 341: /* {{{ proto string ResourceBundle::getErrorCode( )
! 342: * proto string resourcebundle_get_error_code( ResourceBundle $bundle )
! 343: * Get text description for ResourceBundle's last error code.
! 344: */
! 345: PHP_FUNCTION( resourcebundle_get_error_code )
! 346: {
! 347: RESOURCEBUNDLE_METHOD_INIT_VARS;
! 348:
! 349: if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
! 350: &object, ResourceBundle_ce_ptr ) == FAILURE )
! 351: {
! 352: intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 353: "resourcebundle_get_error_code: unable to parse input params", 0 TSRMLS_CC );
! 354: RETURN_FALSE;
! 355: }
! 356:
! 357: rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
! 358:
! 359: RETURN_LONG(INTL_DATA_ERROR_CODE(rb));
! 360: }
! 361: /* }}} */
! 362:
! 363: /* {{{ arginfo_resourcebundle_get_error_message */
! 364: ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_message, 0, 0, 0 )
! 365: ZEND_END_ARG_INFO()
! 366: /* }}} */
! 367:
! 368: /* {{{ proto string ResourceBundle::getErrorMessage( )
! 369: * proto string resourcebundle_get_error_message( ResourceBundle $bundle )
! 370: * Get text description for ResourceBundle's last error.
! 371: */
! 372: PHP_FUNCTION( resourcebundle_get_error_message )
! 373: {
! 374: char* message = NULL;
! 375: RESOURCEBUNDLE_METHOD_INIT_VARS;
! 376:
! 377: if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
! 378: &object, ResourceBundle_ce_ptr ) == FAILURE )
! 379: {
! 380: intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
! 381: "resourcebundle_get_error_message: unable to parse input params", 0 TSRMLS_CC );
! 382: RETURN_FALSE;
! 383: }
! 384:
! 385: rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
! 386: message = (char *)intl_error_get_message(INTL_DATA_ERROR_P(rb) TSRMLS_CC);
! 387: RETURN_STRING(message, 0);
! 388: }
! 389: /* }}} */
! 390:
! 391: /* {{{ ResourceBundle_class_functions
! 392: * Every 'ResourceBundle' class method has an entry in this table
! 393: */
! 394: static function_entry ResourceBundle_class_functions[] = {
! 395: PHP_ME( ResourceBundle, __construct, arginfo_resourcebundle___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR )
! 396: ZEND_NAMED_ME( create, ZEND_FN( resourcebundle_create ), arginfo_resourcebundle___construct, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC )
! 397: ZEND_NAMED_ME( get, ZEND_FN(resourcebundle_get), arginfo_resourcebundle_get, ZEND_ACC_PUBLIC )
! 398: ZEND_NAMED_ME( count, ZEND_FN(resourcebundle_count), arginfo_resourcebundle_count, ZEND_ACC_PUBLIC )
! 399: ZEND_NAMED_ME( getLocales, ZEND_FN(resourcebundle_locales), arginfo_resourcebundle_getlocales, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
! 400: ZEND_NAMED_ME( getErrorCode, ZEND_FN(resourcebundle_get_error_code), arginfo_resourcebundle_get_error_code, ZEND_ACC_PUBLIC )
! 401: ZEND_NAMED_ME( getErrorMessage, ZEND_FN(resourcebundle_get_error_message), arginfo_resourcebundle_get_error_message, ZEND_ACC_PUBLIC )
! 402: PHP_FE_END
! 403: };
! 404: /* }}} */
! 405:
! 406: /* {{{ resourcebundle_register_class
! 407: * Initialize 'ResourceBundle' class
! 408: */
! 409: void resourcebundle_register_class( TSRMLS_D )
! 410: {
! 411: zend_class_entry ce;
! 412:
! 413: INIT_CLASS_ENTRY( ce, "ResourceBundle", ResourceBundle_class_functions );
! 414:
! 415: ce.create_object = ResourceBundle_object_create;
! 416: ce.get_iterator = resourcebundle_get_iterator;
! 417:
! 418: ResourceBundle_ce_ptr = zend_register_internal_class( &ce TSRMLS_CC );
! 419:
! 420: if( !ResourceBundle_ce_ptr )
! 421: {
! 422: zend_error(E_ERROR, "Failed to register ResourceBundle class");
! 423: return;
! 424: }
! 425:
! 426: ResourceBundle_object_handlers = std_object_handlers;
! 427: ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */
! 428: ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get;
! 429: ResourceBundle_object_handlers.count_elements = resourcebundle_array_count;
! 430: }
! 431: /* }}} */
! 432:
! 433: /*
! 434: * Local variables:
! 435: * tab-width: 4
! 436: * c-basic-offset: 4
! 437: * End:
! 438: * vim600: noet sw=4 ts=4 fdm=marker
! 439: * vim<600: noet sw=4 ts=4
! 440: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>