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