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

Reply via email to