Re: [PHP-I18N] [PATCH] ICU ResourceBundles for ext/unicode
[email protected] (Andrei Zmievski)
| Newsgroups | php.i18n |
|---|---|
| Message-ID | <[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