In ICU, resource bundles are cached for efficiency, but the cache is per-process, and i seem to recall that the cache is not currently flushed. Additionally the key is the ICU locale id, so its impossible without source changes to make this work for user-created resources without collision in shared hosting mode.
that said, it would be perfectly fine for allowing access to locale data. a few additions i'd make 1. allow an indexer as an equivalent to the getByKey() method e.g. $rb["key"] === $rb->getByIndex("key") 2. cast handlers in addition to getXXX methods clayton "Andrei Zmievski" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Hmm, let me review this. I should also check with a couple of i18n folks > at Yahoo who I remember mentioning something about resource bundles and > PHP. > > -Andrei > > On Dec 13, 2006, at 8:30 AM, Michael Wallner wrote: > >> Hi, >> >> I prepared a patch to add ResourceBundle support to ext/unicode. >> Everybody fine with adding it? >> >> Regards, >> -- Michael >> Index: ext/unicode/config.m4 >> =================================================================== >> RCS file: /repository/php-src/ext/unicode/config.m4,v >> retrieving revision 1.10 >> diff -u -p -d -r1.10 config.m4 >> --- ext/unicode/config.m4 13 Jun 2006 23:46:04 -0000 1.10 >> +++ ext/unicode/config.m4 13 Dec 2006 16:28:15 -0000 >> @@ -4,4 +4,4 @@ dnl >> >> PHP_SUBST(UNICODE_SHARED_LIBADD) >> AC_DEFINE(HAVE_UNICODE, 1, [ ]) >> -PHP_NEW_EXTENSION(unicode, unicode.c locale.c unicode_iterators.c >> collator.c property.c constants.c transform.c, $ext_shared) >> +PHP_NEW_EXTENSION(unicode, unicode.c locale.c unicode_iterators.c >> collator.c property.c constants.c transform.c resourcebundle.c, >> $ext_shared) >> Index: ext/unicode/constants.c >> =================================================================== >> RCS file: /repository/php-src/ext/unicode/constants.c,v >> retrieving revision 1.1 >> diff -u -p -d -r1.1 constants.c >> --- ext/unicode/constants.c 5 May 2006 20:56:21 -0000 1.1 >> +++ ext/unicode/constants.c 13 Dec 2006 16:28:15 -0000 >> @@ -16,6 +16,7 @@ >> */ >> >> #include "php_unicode.h" >> +#include <unicode/ures.h> >> >> PHPAPI zend_class_entry *u_const_ce; >> >> @@ -578,6 +579,28 @@ static void php_register_misc_constants( >> } >> /* }}} */ >> >> +/* {{{ ResourceBundle constants */ >> +static void php_register_resourcebundle_constants(TSRMLS_D) >> +{ >> + REGISTER_U_CONST(URES_NONE); >> + REGISTER_U_CONST(URES_STRING); >> + REGISTER_U_CONST(URES_BINARY); >> + REGISTER_U_CONST(URES_TABLE); >> + REGISTER_U_CONST(URES_ALIAS); >> + REGISTER_U_CONST(URES_INT); >> + REGISTER_U_CONST(URES_ARRAY); >> + REGISTER_U_CONST(URES_INT_VECTOR); >> +} >> +/* }}} */ >> + >> +/* {{{ LocaleData constants */ >> +static void php_register_localedata_constants(TSRMLS_D) >> +{ >> + REGISTER_U_CONST(ULOC_ACTUAL_LOCALE); >> + REGISTER_U_CONST(ULOC_VALID_LOCALE); >> +} >> +/* }}} */ >> + >> void php_register_unicode_constants(TSRMLS_D) >> { >> zend_class_entry ce; >> @@ -601,6 +624,8 @@ void php_register_unicode_constants(TSRM >> php_register_numeric_type_constants(TSRMLS_C); >> php_register_hangul_syllable_constants(TSRMLS_C); >> php_register_misc_constants(TSRMLS_C); >> + php_register_resourcebundle_constants(TSRMLS_C); >> + php_register_localedata_constants(TSRMLS_C); >> } >> >> /* >> Index: ext/unicode/php_unicode.h >> =================================================================== >> RCS file: /repository/php-src/ext/unicode/php_unicode.h,v >> retrieving revision 1.14 >> diff -u -p -d -r1.14 php_unicode.h >> --- ext/unicode/php_unicode.h 5 May 2006 20:56:21 -0000 1.14 >> +++ ext/unicode/php_unicode.h 13 Dec 2006 16:28:15 -0000 >> @@ -72,6 +72,7 @@ PHP_FUNCTION(collator_get_default); >> PHP_FUNCTION(collator_set_default); >> PHP_METHOD(collator, __construct); >> >> +void php_init_resourcebundle(TSRMLS_D); >> void php_init_collation(TSRMLS_D); >> void php_register_unicode_constants(TSRMLS_D); >> >> Index: ext/unicode/resourcebundle.c >> =================================================================== >> RCS file: ext/unicode/resourcebundle.c >> diff -N ext/unicode/resourcebundle.c >> --- /dev/null 1 Jan 1970 00:00:00 -0000 >> +++ ext/unicode/resourcebundle.c 13 Dec 2006 16:28:15 -0000 >> @@ -0,0 +1,751 @@ >> +/* >> + >> +---------------------------------------------------------------------- >> + >> + | PHP Version 6 | >> + >> +---------------------------------------------------------------------- >> + >> + | This source file is subject to version 3.01 of the PHP license, | >> + | that is bundled with this package in the file LICENSE, and is | >> + | available through the world-wide-web at the following url: | >> + | http://www.php.net/license/3_01.txt | >> + | If you did not receive a copy of the PHP license and are unable to >> | >> + | obtain it through the world-wide-web, please send a note to | >> + | [EMAIL PROTECTED] so we can mail you a copy immediately. | >> + >> +---------------------------------------------------------------------- >> + >> + | Authors: Michael Wallner <[EMAIL PROTECTED]> >> | >> + >> +---------------------------------------------------------------------- >> + >> +*/ >> + >> +/* $Id: collator.c,v 1.11 2006/10/06 17:14:14 andrei Exp $ */ >> + >> +#include "php.h" >> +#include <unicode/ures.h> >> + >> +typedef struct _php_resourcebundle { >> + zend_object zo; >> + UResourceBundle *ures; >> +} php_resourcebundle; >> + >> +zend_class_entry *unicode_resourcebundle_ce; >> +static zend_object_handlers unicode_resourcebundle_oh; >> + >> +static PHP_METHOD(ResourceBundle, __construct); >> +static PHP_METHOD(ResourceBundle, factory); >> +static PHP_METHOD(ResourceBundle, open); >> +static PHP_METHOD(ResourceBundle, getVersion); >> +static PHP_METHOD(ResourceBundle, getType); >> +static PHP_METHOD(ResourceBundle, getLocale); >> +static PHP_METHOD(ResourceBundle, getKey); >> +static PHP_METHOD(ResourceBundle, getString); >> +static PHP_METHOD(ResourceBundle, getStringByIndex); >> +static PHP_METHOD(ResourceBundle, getStringByKey); >> +static PHP_METHOD(ResourceBundle, getBinary); >> +static PHP_METHOD(ResourceBundle, getInt); >> +static PHP_METHOD(ResourceBundle, getArray); >> +static PHP_METHOD(ResourceBundle, getByIndex); >> +static PHP_METHOD(ResourceBundle, getByKey); >> +static PHP_METHOD(ResourceBundle, get); >> +static PHP_METHOD(ResourceBundle, count); >> + >> +static zend_function_entry unicode_resourcebundle_fe[] = { >> + PHP_ME(ResourceBundle, factory, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) >> + PHP_ME(ResourceBundle, __construct, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, open, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getVersion, NULL, ZEND_ACC_PUBLIC) >> + PHP_MALIAS(ResourceBundle, getSize, count, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getType, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getLocale, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getKey, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getString, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getStringByIndex, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getStringByKey, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getBinary, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getInt, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getArray, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getByIndex, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, getByKey, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, get, NULL, ZEND_ACC_PUBLIC) >> + PHP_ME(ResourceBundle, count, NULL, ZEND_ACC_PUBLIC) >> + {NULL}, >> +}; >> + >> +#define IF_RB_INIT(rb) if (!(rb)->ures) { php_error_docref(NULL >> TSRMLS_CC, E_WARNING, "Use of uninitialized ResourceBundle"); } else >> +#define IF_RB_TYPE(rb, t) if (ures_getType((rb)->ures) != (t)) { >> php_error_docref(NULL TSRMLS_CC, E_WARNING, "ResourceBundle is not of >> type "#t); } else >> +#define IF_RB_SUCCESS(s) if (U_FAILURE(s)) { php_error_docref(NULL >> TSRMLS_CC, E_WARNING, "%s", u_errorName(s)); } else >> + >> +/* {{{ zend object ctor/dtor */ >> +static void unicode_resourcebundle_free_object(zend_object *zo >> TSRMLS_DC) >> +{ >> + php_resourcebundle *rb = (php_resourcebundle *) zo; >> + + zend_object_std_dtor(zo TSRMLS_CC); >> + if (rb->ures) { >> + ures_close(rb->ures); >> + } >> + efree(rb); >> +} >> + >> +static zend_object_value >> unicode_resourcebundle_create_object_ex(zend_class_entry *ce, >> php_resourcebundle **ptr, UResourceBundle *ures TSRMLS_DC) >> +{ >> + zend_object_value ov; >> + php_resourcebundle *rb = ecalloc(1, sizeof(*rb)); >> + + if (ptr) { >> + *ptr = rb; >> + } >> + if (ures) { >> + rb->ures = ures; >> + } >> + + zend_object_std_init((zend_object *) rb, ce TSRMLS_CC); >> + zend_hash_copy(rb->zo.properties, &ce->default_properties, >> (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); >> + + ov.handle = zend_objects_store_put(rb, (zend_objects_store_dtor_t) >> zend_objects_destroy_object, (zend_objects_free_object_storage_t) >> unicode_resourcebundle_free_object, NULL TSRMLS_CC); >> + ov.handlers = &unicode_resourcebundle_oh; >> + + return ov; >> +} >> + >> +static zend_object_value >> unicode_resourcebundle_create_object(zend_class_entry *ce TSRMLS_DC) >> +{ >> + return unicode_resourcebundle_create_object_ex(ce, NULL, NULL >> TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ iterators */ >> +typedef struct _php_resourcebundle_iter { >> + zval *zv; >> + php_resourcebundle *rb; >> + struct { >> + int ref; >> + zval *obj; >> + struct { >> + const char *str; >> + int len; >> + ulong num; >> + } key; >> + } next; >> +} php_resourcebundle_iter; >> + >> +static inline void >> unicode_resourcebundle_if_dtor_ex(php_resourcebundle_iter *data >> TSRMLS_DC) >> +{ >> + if (data->next.obj) { >> + zval_ptr_dtor(&data->next.obj); >> + data->next.obj = NULL; >> + } >> + if (data->next.key.str) { >> + efree(data->next.key.str); >> + data->next.key.str = NULL; >> + } >> + data->next.key.num = 0; >> +} >> + >> +static void unicode_resourcebundle_if_dtor(zend_object_iterator *iter >> TSRMLS_DC) >> +{ >> + php_resourcebundle_iter *data = iter->data; >> + + unicode_resourcebundle_if_dtor_ex(data TSRMLS_CC); >> + zval_ptr_dtor(&data->zv); >> + efree(data); >> + efree(iter); >> +} >> + >> +static int unicode_resourcebundle_if_valid(zend_object_iterator *iter >> TSRMLS_DC) >> +{ >> + return ((php_resourcebundle_iter *) iter->data)->next.obj ? SUCCESS : >> FAILURE; >> +} >> + >> +static void >> unicode_resourecbundle_if_get_current_data(zend_object_iterator *iter, >> zval ***zv TSRMLS_DC) >> +{ >> + php_resourcebundle_iter *data = iter->data; >> + + /* FIXXME: what if by_ref==1 ?*/ >> + if (data->next.obj) { >> + *zv = &data->next.obj; >> + } else { >> + *zv = NULL; >> + } >> +} >> + >> +static int >> unicode_resourcebundle_if_get_current_key(zend_object_iterator *iter, >> zstr *str_key, uint *str_len, ulong *int_key TSRMLS_DC) >> +{ >> + php_resourcebundle_iter *data = iter->data; >> + + if (data->next.key.str) { >> + /* dup! */ >> + str_key->s = estrndup(data->next.key.str, data->next.key.len); >> + *str_len = data->next.key.len + 1; >> + return HASH_KEY_IS_STRING; >> + } else { >> + *int_key = data->next.key.num - 1; >> + return HASH_KEY_IS_LONG; >> + } >> +} >> + >> +static inline void >> unicode_resourcebundle_if_move_forward_ex(php_resourcebundle_iter *data >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + const char *key_str; >> + UResourceBundle *ures; >> + + unicode_resourcebundle_if_dtor_ex(data TSRMLS_CC); >> + + ures = ures_getNextResource(data->rb->ures, NULL, &status); >> + if (U_SUCCESS(status)) { >> + ++data->next.key.num; >> + + MAKE_STD_ZVAL(data->next.obj); >> + Z_TYPE_P(data->next.obj) = IS_OBJECT; >> + Z_OBJVAL_P(data->next.obj) = >> unicode_resourcebundle_create_object_ex(data->rb->zo.ce, NULL, ures >> TSRMLS_CC); >> + + if ((key_str = ures_getKey(ures))) { >> + data->next.key.str = estrndup(key_str, data->next.key.len = >> strlen(key_str)); >> + } else { >> + data->next.key.str = NULL; >> + } >> + } >> +} >> + >> +static void unicode_resourcebundle_if_move_forward(zend_object_iterator >> *iter TSRMLS_DC) >> +{ >> + php_resourcebundle_iter *data = iter->data; >> + + unicode_resourcebundle_if_move_forward_ex(data TSRMLS_CC); >> +} >> + >> +static void unicode_resourcebundle_if_rewind(zend_object_iterator *iter >> TSRMLS_DC) >> +{ >> + php_resourcebundle_iter *data = iter->data; >> + + ures_resetIterator(data->rb->ures); >> + + unicode_resourcebundle_if_move_forward_ex(data TSRMLS_CC); >> +} >> + >> +static zend_object_iterator_funcs unicode_resourcebundle_if = { >> + unicode_resourcebundle_if_dtor, /* release all resources associated >> with this iterator instance */ >> + unicode_resourcebundle_if_valid, /* check for end of iteration >> (FAILURE or SUCCESS if data is valid) */ >> + unicode_resourecbundle_if_get_current_data, /* fetch the item data for >> the current element */ >> + unicode_resourcebundle_if_get_current_key, /* fetch the key for the >> current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) >> (optional, may be NULL) */ >> + unicode_resourcebundle_if_move_forward, /* step forwards to next >> element */ >> + unicode_resourcebundle_if_rewind, /* rewind to start of data >> (optional, may be NULL) */ >> + NULL, /* invalidate current value/key (optional, may be NULL) */ >> +}; >> + >> +static zend_object_iterator >> *unicode_resourcebundle_get_iterator(zend_class_entry *ce, zval *object, >> int by_ref TSRMLS_DC) >> +{ >> + zend_object_iterator *iter = ecalloc(1, sizeof(*iter)); >> + php_resourcebundle_iter *data = ecalloc(1, sizeof(*data)); >> + + ZVAL_ADDREF(object); >> + data->zv = object; >> + data->rb = zend_object_store_get_object(object TSRMLS_CC); >> + data->next.ref = by_ref; >> + + iter->data = data; >> + iter->funcs = &unicode_resourcebundle_if; >> + + return iter; >> +} >> +/* }}} */ >> + >> +/* {{{ extractors */ >> +#define _EXTRACT_ALL 0 >> +static inline void _extract(UResourceBundle *next, zval *zv, uint types >> TSRMLS_DC); >> + >> +static inline void _extract_intvector(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + int32_t len, i; >> + const int32_t *vec = ures_getIntVector(ures, &len, &status); >> + + IF_RB_SUCCESS(status) { >> + array_init(zv); >> + for (i = 0; i < len; ++i) { >> + add_next_index_long(zv, vec[i]); >> + } >> + } >> +} >> + >> +static inline void _extract_array(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + + array_init(zv); >> + ures_resetIterator(ures); >> + + while (ures_hasNext(ures)) { >> + UResourceBundle *next = ures_getNextResource(ures, NULL, &status); >> + + IF_RB_SUCCESS(status) { >> + zval *entry; >> + + MAKE_STD_ZVAL(entry); >> + ZVAL_NULL(entry); >> + _extract(next, entry, _EXTRACT_ALL TSRMLS_CC); >> + add_next_index_zval(zv, entry); >> + } >> + } >> +} >> + >> +static inline void _extract_table(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + + array_init(zv); >> + ures_resetIterator(ures); >> + + while (ures_hasNext(ures)) { >> + UResourceBundle *next = ures_getNextResource(ures, NULL, &status); >> + + IF_RB_SUCCESS(status) { >> + zval *entry; >> + + MAKE_STD_ZVAL(entry); >> + ZVAL_NULL(entry); >> + _extract(next, entry, _EXTRACT_ALL TSRMLS_CC); >> + add_assoc_zval(zv, ures_getKey(next), entry); >> + } >> + } >> +} >> + >> +static inline void _extract_string(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + int32_t str_len; >> + const UChar *str_buf = ures_getString(ures, &str_len, &status); >> + + if (U_SUCCESS(status)) { >> + ZVAL_UNICODEL(zv, str_buf, str_len, ZSTR_DUPLICATE); >> + } >> +} >> + >> +static inline void _extract_binary(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + int32_t bin_len; >> + const uint8_t *bin_buf = ures_getBinary(ures, &bin_len, &status); >> + + IF_RB_SUCCESS(status) { >> + ZVAL_STRINGL(zv, bin_buf, bin_len, ZSTR_DUPLICATE); >> + } >> +} >> + >> +static inline void _extract_int(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + int32_t intval = ures_getInt(ures, &status); >> + + IF_RB_SUCCESS(status) { >> + ZVAL_LONG(zv, intval); >> + } >> +} >> + >> +static inline void _extract_alias(UResourceBundle *ures, zval *zv >> TSRMLS_DC) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + UResourceBundle *alias = ures_getByIndex(ures, 0, NULL, &status); >> + + IF_RB_SUCCESS(status) { >> + _extract(alias, zv, _EXTRACT_ALL TSRMLS_CC); >> + } >> +} >> + >> +static inline void _extract(UResourceBundle *ures, zval *zv, uint types >> TSRMLS_DC) >> +{ >> + UResType type = ures_getType(ures); >> + + if (types && !(types & type)) { >> + php_error_docref(NULL TSRMLS_CC, E_WARNING, "ResourceBundle is of type >> %d", type); >> + } else { >> + switch (type) { >> + case URES_NONE: >> + break; >> + case URES_STRING: >> + _extract_string(ures, zv TSRMLS_CC); >> + break; >> + case URES_BINARY: >> + _extract_binary(ures, zv TSRMLS_CC); >> + break; >> + case URES_INT: >> + _extract_int(ures, zv TSRMLS_CC); >> + break; >> + case URES_INT_VECTOR: >> + _extract_intvector(ures, zv TSRMLS_CC); >> + break; >> + case URES_ARRAY: >> + _extract_array(ures, zv TSRMLS_CC); >> + break; >> + case URES_TABLE: >> + _extract_table(ures, zv TSRMLS_CC); >> + break; >> + case URES_ALIAS: >> + _extract_alias(ures, zv TSRMLS_CC); >> + break; >> + default: >> + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unkown ResourceBundle >> type %d", type); >> + break; >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ unicode_resourcebundle_factory */ >> +static int unicode_resourcebundle_factory(INTERNAL_FUNCTION_PARAMETERS) >> +{ >> + zval *package = NULL, *locale = NULL; >> + UErrorCode status = U_ZERO_ERROR; >> + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, >> "|z/!z/!", &package, &locale)) { >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + if (rb->ures) { >> + ures_close(rb->ures); >> + } >> + /* UTODO: use fs encoding */ >> + if (package) { >> + switch (Z_TYPE_P(package)) { >> + case IS_NULL: >> + case IS_STRING: >> + case IS_UNICODE: >> + break; >> + default: >> + convert_to_string(package); >> + break; >> + } >> + } >> + if (locale) { >> + switch (Z_TYPE_P(locale)) { >> + case IS_NULL: >> + case IS_STRING: >> + break; >> + default: >> + convert_to_string(locale); >> + break; >> + } >> + } >> + + if (package && Z_TYPE_P(package) == IS_UNICODE) { >> + rb->ures = ures_openU(Z_USTRVAL_P(package), locale ? >> Z_STRVAL_P(locale) : NULL, &status); >> + } else { >> + rb->ures = ures_open(package ? Z_STRVAL_P(package) : NULL, locale ? >> Z_STRVAL_P(locale) : NULL, &status); >> + } >> + + if (U_SUCCESS(status)) { >> + zend_update_property_long(Z_OBJCE_P(getThis()), getThis(), >> ZEND_STRL("warning"), status TSRMLS_CC); >> + return SUCCESS; >> + } else { >> + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open resource >> bundle '%s' for '%s' locale", package && Z_STRVAL_P(package) ? >> Z_STRVAL_P(package) : "root", locale && Z_STRVAL_P(locale) ? >> *Z_STRVAL_P(locale) ? Z_STRVAL_P(locale) : "default" : "root"); >> + return FAILURE; >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto void ResourceBundle::__construct([string package[, string >> locale]]) >> + Create a new ResourceBundle object */ >> +static PHP_METHOD(ResourceBundle, __construct) >> +{ >> + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); >> + unicode_resourcebundle_factory(INTERNAL_FUNCTION_PARAM_PASSTHRU); >> + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ proto static ResourceBundle ResourceBundle::factory([string >> package[, string locale]]) >> + Create a new ResourceBundle object */ >> +static PHP_METHOD(ResourceBundle, factory) >> +{ >> + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); >> + getThis() = return_value; >> + object_init_ex(getThis(), unicode_resourcebundle_ce); >> + if (SUCCESS != >> unicode_resourcebundle_factory(INTERNAL_FUNCTION_PARAM_PASSTHRU)) { >> + zval_ptr_dtor(&getThis()); >> + RETVAL_NULL(); >> + } >> + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ proto bool ResourceBundle::open([string package[, string >> locale]) >> + Open another ResourceBundle */ >> +static PHP_METHOD(ResourceBundle, open) >> +{ >> + RETURN_BOOL(SUCCESS == >> unicode_resourcebundle_factory(INTERNAL_FUNCTION_PARAM_PASSTHRU)); >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getVersion(void) >> + Get ResourceBundle version */ >> +static PHP_METHOD(ResourceBundle, getVersion) >> +{ >> + UVersionInfo version_ptr = {0}; >> + char version_str[U_MAX_VERSION_STRING_LENGTH] = {0}; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + ures_getVersion(rb->ures, version_ptr); >> + u_versionToString(version_ptr, version_str); >> + RETURN_ASCII_STRING(version_str, ZSTR_DUPLICATE); >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto int ResourceBundle::getType(void) >> + Get the type of the RespourceBundle */ >> +static PHP_METHOD(ResourceBundle, getType) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + RETVAL_LONG(ures_getType(rb->ures)); >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getLocale(int locale_type = >> U::LOC_VALID_LOCALE) >> + Get ResourceBundle locale */ >> +static PHP_METHOD(ResourceBundle, getLocale) >> +{ >> + UErrorCode dummy; >> + long type = ULOC_VALID_LOCALE; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &type); >> + + IF_RB_INIT(rb) { >> + RETURN_ASCII_STRING(ures_getLocaleByType(rb->ures, type, &dummy), >> ZSTR_DUPLICATE); >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getKey() >> + Get any key associated eith this ResourceBundle */ >> +static PHP_METHOD(ResourceBundle, getKey) >> +{ >> + const char *key; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + if ((key = ures_getKey(rb->ures))) { >> + RETVAL_STRING(key, ZSTR_DUPLICATE); >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getString() >> + Returns the contents of a string ResourceBundle */ >> +static PHP_METHOD(ResourceBundle, getString) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + IF_RB_TYPE(rb, URES_STRING) { >> + _extract_string(rb->ures, return_value TSRMLS_CC); >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getStringByIndex(int index) >> + Returns the contents of the string at index index in the >> ResourceBundle */ >> +static PHP_METHOD(ResourceBundle, getStringByIndex) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + const UChar *str_buf; >> + int32_t str_len; >> + long index; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", >> &index)) { >> + IF_RB_INIT(rb) { >> + str_buf = ures_getStringByIndex(rb->ures, index, &str_len, &status); >> + IF_RB_SUCCESS(status) { >> + RETURN_UNICODEL(str_buf, str_len, ZSTR_DUPLICATE); >> + } >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto string ResourceBundle::getStringByKey(string key) >> + Returns the contents of the string identified by key in the >> ResourceBundle */ >> +static PHP_METHOD(ResourceBundle, getStringByKey) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + const UChar *str_buf; >> + int32_t str_len; >> + char *key_str; >> + int key_len; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", >> &key_str, &key_len)) { >> + IF_RB_INIT(rb) { >> + str_buf = ures_getStringByKey(rb->ures, key_str, &str_len, &status); >> + IF_RB_SUCCESS(status) { >> + RETURN_UNICODEL(str_buf, str_len, ZSTR_DUPLICATE); >> + } >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto binary ResourceBundle::getBinary(void) >> + Get the binary contents of the ResourceBundle of type BINARY */ >> +static PHP_METHOD(ResourceBundle, getBinary) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + IF_RB_TYPE(rb, URES_BINARY) { >> + _extract_binary(rb->ures, return_value TSRMLS_CC); >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto int ResourceBundle::getInt(void) >> + Get the integer value of a ResourceBundle of type INT */ >> +static PHP_METHOD(ResourceBundle, getInt) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + IF_RB_TYPE(rb, URES_INT) { >> + _extract_int(rb->ures, return_value TSRMLS_CC); >> + } >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto array ResourceBundle::getArray(void) >> + Get an array of the contents of the ResourceBundle of type ARRAY, >> TABLE or INT_VECTOR*/ >> +static PHP_METHOD(ResourceBundle, getArray) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + _extract(rb->ures, return_value, URES_INT_VECTOR|URES_ARRAY|URES_TABLE >> TSRMLS_CC); >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto ResourceBundle ResourceBundle::getByIndex(int index) >> + Get a child ResourceBundle by its index */ >> +static PHP_METHOD(ResourceBundle, getByIndex) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + UResourceBundle *ures; >> + long index; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); >> + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", >> &index)) { >> + IF_RB_INIT(rb) { >> + ures = ures_getByIndex(rb->ures, index, NULL, &status); >> + IF_RB_SUCCESS(status) { >> + Z_TYPE_P(return_value) = IS_OBJECT; >> + Z_OBJVAL_P(return_value) = >> unicode_resourcebundle_create_object_ex(Z_OBJCE_P(getThis()), NULL, ures >> TSRMLS_CC); >> + } >> + } >> + } >> + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ proto ResourceBundle ResourceBundle::getByKey(string key) >> + Get a child ResourceBundle by its key */ >> +static PHP_METHOD(ResourceBundle, getByKey) >> +{ >> + UErrorCode status = U_ZERO_ERROR; >> + UResourceBundle *ures; >> + char *key_str; >> + int key_len; >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + php_set_error_handling(EH_THROW, NULL TSRMLS_CC); >> + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", >> &key_str, &key_len)) { >> + IF_RB_INIT(rb) { >> + ures = ures_getByKey(rb->ures, key_str, NULL, &status); >> + IF_RB_SUCCESS(status) { >> + Z_TYPE_P(return_value) = IS_OBJECT; >> + Z_OBJVAL_P(return_value) = >> unicode_resourcebundle_create_object_ex(Z_OBJCE_P(getThis()), NULL, ures >> TSRMLS_CC); >> + } >> + } >> + } >> + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ proto mixed ResourceBundle::get() >> + Get ResourceBundles contents dependent on its type */ >> +static PHP_METHOD(ResourceBundle, get) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + _extract(rb->ures, return_value, _EXTRACT_ALL TSRMLS_CC); >> + } >> +} >> +/* }}} */ >> + >> +/* {{{ proto int ResourceBundle::count(void) */ >> +static PHP_METHOD(ResourceBundle, count) >> +{ >> + php_resourcebundle *rb = zend_object_store_get_object(getThis() >> TSRMLS_CC); >> + + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ""); >> + + IF_RB_INIT(rb) { >> + RETVAL_LONG(ures_getSize(rb->ures)); >> + } >> +} >> +/* }}} */ >> + >> +/* # */ >> + >> +/* {{{ php_init_resourcebundle */ >> +void php_init_resourcebundle(TSRMLS_D) >> +{ >> + zend_class_entry ce; >> + + memset(&ce, 0, sizeof(ce)); >> + INIT_CLASS_ENTRY(ce, "ResourceBundle", unicode_resourcebundle_fe); >> + ce.create_object = unicode_resourcebundle_create_object; >> + ce.get_iterator = unicode_resourcebundle_get_iterator; >> + + unicode_resourcebundle_ce = zend_register_internal_class_ex(&ce, >> NULL, NULL TSRMLS_CC); >> + /* TODO: implements Countable */ >> + memcpy(&unicode_resourcebundle_oh, zend_get_std_object_handlers(), >> sizeof(unicode_resourcebundle_oh)); >> + unicode_resourcebundle_oh.clone_obj = NULL; >> + + /* any warning code of ures_open() */ >> + zend_declare_property_long(unicode_resourcebundle_ce, >> ZEND_STRL("warning"), U_ZERO_ERROR, ZEND_ACC_PUBLIC TSRMLS_CC); >> + + /* type constants are in constants.c*/ >> +} >> +/* }}} */ >> + >> +/* >> + * Local variables: >> + * tab-width: 4 >> + * c-basic-offset: 4 >> + * End: >> + * vim600: noet sw=4 ts=4 fdm=marker >> + * vim<600: noet sw=4 ts=4 >> + */ >> Index: ext/unicode/unicode.c >> =================================================================== >> RCS file: /repository/php-src/ext/unicode/unicode.c,v >> retrieving revision 1.42 >> diff -u -p -d -r1.42 unicode.c >> --- ext/unicode/unicode.c 21 Sep 2006 19:30:33 -0000 1.42 >> +++ ext/unicode/unicode.c 13 Dec 2006 16:28:16 -0000 >> @@ -399,6 +399,7 @@ PHP_MINIT_FUNCTION(unicode) >> { >> php_register_unicode_iterators(TSRMLS_C); >> php_init_collation(TSRMLS_C); >> + php_init_resourcebundle(TSRMLS_C); >> php_register_unicode_constants(TSRMLS_C); >> return SUCCESS; >> Index: ext/unicode/tests/resourcebundle_001.phpt >> =================================================================== >> RCS file: ext/unicode/tests/resourcebundle_001.phpt >> diff -N ext/unicode/tests/resourcebundle_001.phpt >> --- /dev/null 1 Jan 1970 00:00:00 -0000 >> +++ ext/unicode/tests/resourcebundle_001.phpt 13 Dec 2006 16:28:16 -0000 >> @@ -0,0 +1,47 @@ >> +--TEST-- >> +Unicode: ResourceBundle >> +--FILE-- >> +<?php >> +$path = dirname(__FILE__)."/test"; >> +$rb = new ResourceBundle(dirname(__FILE__)."/test"); >> +var_dump($rb->getByIndex(0)->getString()); >> +var_dump($rb->getStringByIndex(0)); >> +var_dump($rb->getByKey("serial")->getArray()); >> +echo "--\n"; >> +foreach (new ResourceBundle($path) as $k => $r) var_dump($k, >> $r->getKey(), $r->get()); >> +?> >> +--EXPECT-- >> +unicode(5) "value" >> +unicode(5) "value" >> +array(3) { >> + [0]=> >> + int(1) >> + [1]=> >> + int(3) >> + [2]=> >> + int(5) >> +} >> +-- >> +string(4) "data" >> +string(4) "data" >> +unicode(5) "value" >> +string(4) "list" >> +string(4) "list" >> +array(3) { >> + ["one"]=> >> + int(1) >> + ["three"]=> >> + string(1) "4" >> + ["two"]=> >> + unicode(1) "2" >> +} >> +string(6) "serial" >> +string(6) "serial" >> +array(3) { >> + [0]=> >> + int(1) >> + [1]=> >> + int(3) >> + [2]=> >> + int(5) >> +} >> Index: ext/unicode/tests/test_root.res >> =================================================================== >> RCS file: ext/unicode/tests/test_root.res >> diff -N ext/unicode/tests/test_root.res >> Binary files /dev/null and test_root.res differ >> Index: ext/unicode/tests/test_root.txt >> =================================================================== >> RCS file: ext/unicode/tests/test_root.txt >> diff -N ext/unicode/tests/test_root.txt >> --- /dev/null 1 Jan 1970 00:00:00 -0000 >> +++ ext/unicode/tests/test_root.txt 13 Dec 2006 16:28:16 -0000 >> @@ -0,0 +1,9 @@ >> +root { >> + data:string { "value" } >> + serial:intvector { 1,3,5 } >> + list { >> + one:int { 1 } >> + two { 2 } >> + three:binary { 34 } >> + } >> +} >> >> -- >> PHP Unicode & I18N Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Unicode & I18N Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php