mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
add ICU resource bundle support, contributed by Hans-Peter Oeri
This commit is contained in:
parent
795f716832
commit
8f4337f255
24 changed files with 1268 additions and 7 deletions
|
@ -52,6 +52,9 @@ if test "$PHP_INTL" != "no"; then
|
|||
msgformat/msgformat_parse.c \
|
||||
grapheme/grapheme_string.c \
|
||||
grapheme/grapheme_util.c \
|
||||
resourcebundle/resourcebundle.c \
|
||||
resourcebundle/resourcebundle_class.c \
|
||||
resourcebundle/resourcebundle_iterator.c \
|
||||
idn/idn.c, $ext_shared,,$ICU_INCS)
|
||||
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/collator)
|
||||
|
@ -62,5 +65,6 @@ if test "$PHP_INTL" != "no"; then
|
|||
PHP_ADD_BUILD_DIR($ext_builddir/locale)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/msgformat)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/grapheme)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/resourcebundle)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/idn)
|
||||
fi
|
||||
|
|
|
@ -66,6 +66,11 @@ if (PHP_INTL != "no") {
|
|||
ADD_SOURCES(configure_module_dirname + "/idn", "\
|
||||
idn.c",
|
||||
"intl");
|
||||
ADD_SOURCES(configure_module_dirname + "/resourcebundle", "\
|
||||
resourcebundle.c \
|
||||
resourcebundle_class.c \
|
||||
resourcebundle_iterator.c",
|
||||
"intl");
|
||||
ADD_FLAG("LIBS_INTL", "icudt.lib icuin.lib icuio.lib icule.lib iculx.lib");
|
||||
AC_DEFINE("HAVE_INTL", 1, "Internationalization support enabled");
|
||||
} else {
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include "dateformat/dateformat_parse.h"
|
||||
#include "dateformat/dateformat_data.h"
|
||||
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
|
||||
#include "idn/idn.h"
|
||||
|
||||
#include "msgformat/msgformat.h"
|
||||
|
@ -74,11 +76,11 @@
|
|||
#define INTL_MODULE_VERSION PHP_INTL_VERSION
|
||||
|
||||
/*
|
||||
* locale_get_default has a conflict since ICU also has
|
||||
* locale_get_default has a conflict since ICU also has
|
||||
* a function with the same name
|
||||
* in fact ICU appends the version no. to it also
|
||||
* Hence the following undef for ICU version
|
||||
* Same true for the locale_set_default function
|
||||
* Same true for the locale_set_default function
|
||||
*/
|
||||
#undef locale_get_default
|
||||
#undef locale_set_default
|
||||
|
@ -330,6 +332,36 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_idn_to_utf8, 0, 0, 1)
|
|||
ZEND_ARG_INFO(0, option)
|
||||
ZEND_ARG_INFO(0, status)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_create_proc, 0, 0, 2 )
|
||||
ZEND_ARG_INFO( 0, locale )
|
||||
ZEND_ARG_INFO( 0, bundlename )
|
||||
ZEND_ARG_INFO( 0, fallback )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_proc, 0, 0, 2 )
|
||||
ZEND_ARG_INFO( 0, bundle )
|
||||
ZEND_ARG_INFO( 0, index )
|
||||
ZEND_ARG_INFO( 0, fallback )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_count_proc, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, bundle )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_locales_proc, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, bundlename )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_code_proc, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, bundle )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_message_proc, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, bundle )
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ intl_functions
|
||||
|
@ -422,7 +454,7 @@ zend_function_entry intl_functions[] = {
|
|||
PHP_FE( datefmt_set_lenient, arginfo_msgfmt_get_locale )
|
||||
PHP_FE( datefmt_format, arginfo_datefmt_format )
|
||||
PHP_FE( datefmt_parse, datefmt_parse_args )
|
||||
PHP_FE( datefmt_localtime , datefmt_parse_args )
|
||||
PHP_FE( datefmt_localtime , datefmt_parse_args )
|
||||
PHP_FE( datefmt_get_error_code, arginfo_msgfmt_get_error_code )
|
||||
PHP_FE( datefmt_get_error_message, arginfo_msgfmt_get_error_message )
|
||||
|
||||
|
@ -438,8 +470,16 @@ zend_function_entry intl_functions[] = {
|
|||
PHP_FE( grapheme_extract, grapheme_extract_args )
|
||||
|
||||
/* IDN functions */
|
||||
PHP_FE(idn_to_ascii, arginfo_idn_to_ascii)
|
||||
PHP_FE(idn_to_utf8, arginfo_idn_to_ascii)
|
||||
PHP_FE( idn_to_ascii, arginfo_idn_to_ascii)
|
||||
PHP_FE( idn_to_utf8, arginfo_idn_to_ascii)
|
||||
|
||||
/* ResourceBundle functions */
|
||||
PHP_FE( resourcebundle_create, arginfo_resourcebundle_create_proc )
|
||||
PHP_FE( resourcebundle_get, arginfo_resourcebundle_get_proc )
|
||||
PHP_FE( resourcebundle_count, arginfo_resourcebundle_count_proc )
|
||||
PHP_FE( resourcebundle_locales, arginfo_resourcebundle_locales_proc )
|
||||
PHP_FE( resourcebundle_get_error_code, arginfo_resourcebundle_get_error_code_proc )
|
||||
PHP_FE( resourcebundle_get_error_message, arginfo_resourcebundle_get_error_message_proc )
|
||||
|
||||
/* common functions */
|
||||
PHP_FE( intl_get_error_code, intl_0_args )
|
||||
|
@ -521,7 +561,7 @@ PHP_MINIT_FUNCTION( intl )
|
|||
|
||||
/* Expose Normalizer constants to PHP scripts */
|
||||
normalizer_register_constants( INIT_FUNC_ARGS_PASSTHRU );
|
||||
|
||||
|
||||
/* Register 'Locale' PHP class */
|
||||
locale_register_Locale_class( TSRMLS_C );
|
||||
|
||||
|
@ -538,6 +578,9 @@ PHP_MINIT_FUNCTION( intl )
|
|||
/* Expose DateFormat constants to PHP scripts */
|
||||
dateformat_register_constants( INIT_FUNC_ARGS_PASSTHRU );
|
||||
|
||||
/* Register 'ResourceBundle' PHP class */
|
||||
resourcebundle_register_class( TSRMLS_C);
|
||||
|
||||
/* Expose ICU error codes to PHP scripts. */
|
||||
intl_expose_icu_error_codes( INIT_FUNC_ARGS_PASSTHRU );
|
||||
|
||||
|
|
1
ext/intl/resourcebundle/TODO
Executable file
1
ext/intl/resourcebundle/TODO
Executable file
|
@ -0,0 +1 @@
|
|||
- var_dump support
|
93
ext/intl/resourcebundle/resourcebundle.c
Normal file
93
ext/intl/resourcebundle/resourcebundle.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <unicode/ures.h>
|
||||
|
||||
#include <zend.h>
|
||||
#include <zend_API.h>
|
||||
|
||||
#include "intl_convert.h"
|
||||
#include "intl_data.h"
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
|
||||
/* {{{ ResourceBundle_extract_value */
|
||||
void resourcebundle_extract_value( zval *return_value, ResourceBundle_object *source TSRMLS_DC )
|
||||
{
|
||||
UResType restype;
|
||||
const UChar* ufield;
|
||||
const uint8_t* bfield;
|
||||
char * cfield;
|
||||
const int32_t* vfield;
|
||||
int32_t ilen;
|
||||
int i;
|
||||
long lfield;
|
||||
ResourceBundle_object* newrb;
|
||||
|
||||
restype = ures_getType( source->child );
|
||||
switch (restype)
|
||||
{
|
||||
case URES_STRING:
|
||||
ufield = ures_getString( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
|
||||
INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve string value");
|
||||
INTL_METHOD_RETVAL_UTF8(source, ufield, ilen, 0);
|
||||
break;
|
||||
|
||||
case URES_BINARY:
|
||||
bfield = ures_getBinary( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
|
||||
INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve binary value");
|
||||
ZVAL_STRINGL( return_value, (char *) bfield, ilen, 1 );
|
||||
break;
|
||||
|
||||
case URES_INT:
|
||||
lfield = ures_getInt( source->child, &INTL_DATA_ERROR_CODE(source) );
|
||||
INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve integer value");
|
||||
ZVAL_LONG( return_value, lfield );
|
||||
break;
|
||||
|
||||
case URES_INT_VECTOR:
|
||||
vfield = ures_getIntVector( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
|
||||
INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve vector value");
|
||||
array_init( return_value );
|
||||
for (i=0; i<ilen; i++) {
|
||||
add_next_index_long( return_value, vfield[i] );
|
||||
}
|
||||
break;
|
||||
|
||||
case URES_ARRAY:
|
||||
case URES_TABLE:
|
||||
object_init_ex( return_value, ResourceBundle_ce_ptr );
|
||||
newrb = (ResourceBundle_object *) zend_object_store_get_object( return_value TSRMLS_CC );
|
||||
newrb->me = source->child;
|
||||
source->child = NULL;
|
||||
intl_errors_reset(INTL_DATA_ERROR_P(source) TSRMLS_CC);
|
||||
break;
|
||||
|
||||
default:
|
||||
intl_errors_set(INTL_DATA_ERROR_P(source), U_ILLEGAL_ARGUMENT_ERROR, "Unknown resource type", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
28
ext/intl/resourcebundle/resourcebundle.h
Normal file
28
ext/intl/resourcebundle/resourcebundle.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RESOURCEBUNDLE_H
|
||||
#define RESOURCEBUNDLE_H
|
||||
|
||||
#include <unicode/ures.h>
|
||||
|
||||
#include <zend.h>
|
||||
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
|
||||
void resourcebundle_extract_value( zval *target, ResourceBundle_object *source TSRMLS_DC);
|
||||
|
||||
#endif // #ifndef RESOURCEBUNDLE_CLASS_H
|
434
ext/intl/resourcebundle/resourcebundle_class.c
Normal file
434
ext/intl/resourcebundle/resourcebundle_class.c
Normal file
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unicode/ures.h>
|
||||
#include <unicode/uenum.h>
|
||||
|
||||
#include <zend.h>
|
||||
#include <Zend/zend_exceptions.h>
|
||||
#include <Zend/zend_interfaces.h>
|
||||
#include <php.h>
|
||||
|
||||
#include "php_intl.h"
|
||||
#include "intl_data.h"
|
||||
|
||||
#include "resourcebundle/resourcebundle.h"
|
||||
#include "resourcebundle/resourcebundle_iterator.h"
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
|
||||
zend_class_entry *ResourceBundle_ce_ptr = NULL;
|
||||
|
||||
static zend_object_handlers ResourceBundle_object_handlers;
|
||||
|
||||
/* {{{ ResourceBundle_object_dtor */
|
||||
static void ResourceBundle_object_destroy( void *object, zend_object_handle handle TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_object *rb = (ResourceBundle_object *) object;
|
||||
|
||||
// only free local errors
|
||||
intl_error_reset( INTL_DATA_ERROR_P(rb) TSRMLS_CC );
|
||||
|
||||
if (rb->me) {
|
||||
ures_close( rb->me );
|
||||
}
|
||||
if (rb->child) {
|
||||
ures_close( rb->child );
|
||||
}
|
||||
|
||||
zend_object_std_dtor( object TSRMLS_CC );
|
||||
efree(object);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ResourceBundle_object_create */
|
||||
static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRMLS_DC )
|
||||
{
|
||||
zend_object_value retval;
|
||||
ResourceBundle_object *rb;
|
||||
|
||||
rb = ecalloc( 1, sizeof(ResourceBundle_object) );
|
||||
|
||||
zend_object_std_init( (zend_object *) rb, ce TSRMLS_CC );
|
||||
|
||||
intl_error_init( INTL_DATA_ERROR_P(rb) TSRMLS_CC );
|
||||
rb->me = NULL;
|
||||
rb->child = NULL;
|
||||
|
||||
retval.handlers = &ResourceBundle_object_handlers;
|
||||
retval.handle = zend_objects_store_put( rb, ResourceBundle_object_destroy, NULL, NULL TSRMLS_CC );
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ResourceBundle_ctor */
|
||||
static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
char * bundlename;
|
||||
int bundlename_len = 0;
|
||||
char * locale;
|
||||
int locale_len = 0;
|
||||
zend_bool fallback = 1;
|
||||
|
||||
char * pbuf;
|
||||
|
||||
zval *object = return_value;
|
||||
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object );
|
||||
|
||||
intl_error_reset( NULL TSRMLS_CC );
|
||||
|
||||
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss|b",
|
||||
&locale, &locale_len, &bundlename, &bundlename_len, &fallback ) == FAILURE )
|
||||
{
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_ctor: unable to parse input parameters", 0 TSRMLS_CC );
|
||||
zval_dtor( return_value );
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
|
||||
|
||||
rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
|
||||
|
||||
INTL_CTOR_CHECK_STATUS(rb, "resourcebundle_ctor: Cannot load libICU resource bundle");
|
||||
|
||||
if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
|
||||
intl_errors_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
|
||||
spprintf( &pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource '%s' without fallback from %s to %s",
|
||||
bundlename, locale, ures_getLocale( rb->me, &INTL_DATA_ERROR_CODE(rb)) );
|
||||
intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
|
||||
efree(pbuf);
|
||||
zval_dtor( return_value );
|
||||
RETURN_NULL();
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo_resourcebundle__construct */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle___construct, 0, 0, 2 )
|
||||
ZEND_ARG_INFO( 0, locale )
|
||||
ZEND_ARG_INFO( 0, bundlename )
|
||||
ZEND_ARG_INFO( 0, fallback )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void ResourceBundle::__construct( string $bundlename [, string $locale [, bool $fallback = true ]] )
|
||||
* ResourceBundle object constructor
|
||||
*/
|
||||
PHP_METHOD( ResourceBundle, __construct )
|
||||
{
|
||||
return_value = getThis();
|
||||
resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto ResourceBundle ResourceBundle::create( string $bundlename [, string $locale [, bool $fallback = true ]] )
|
||||
proto ResourceBundle resourcebundle_create( string $bundlename [, string $locale [, bool $fallback = true ]] ) */
|
||||
PHP_FUNCTION( resourcebundle_create )
|
||||
{
|
||||
object_init_ex( return_value, ResourceBundle_ce_ptr );
|
||||
resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_array_fetch */
|
||||
static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC)
|
||||
{
|
||||
int32_t meindex;
|
||||
char * mekey;
|
||||
long mekeylen;
|
||||
zend_bool is_numeric = 0;
|
||||
char *pbuf;
|
||||
ResourceBundle_object *rb;
|
||||
|
||||
intl_error_reset( NULL TSRMLS_CC );
|
||||
RESOURCEBUNDLE_METHOD_FETCH_OBJECT;
|
||||
|
||||
if(Z_TYPE_P(offset) == IS_LONG) {
|
||||
is_numeric = 1;
|
||||
meindex = Z_LVAL_P(offset);
|
||||
rb->child = ures_getByIndex( rb->me, meindex, rb->child, &INTL_DATA_ERROR_CODE(rb) );
|
||||
} else if(Z_TYPE_P(offset) == IS_STRING) {
|
||||
mekey = Z_STRVAL_P(offset);
|
||||
mekeylen = Z_STRLEN_P(offset);
|
||||
rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) );
|
||||
} else {
|
||||
intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_get: index should be integer or string", 0 TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) {
|
||||
if (is_numeric) {
|
||||
spprintf( &pbuf, 0, "Cannot load resource element %d", meindex );
|
||||
} else {
|
||||
spprintf( &pbuf, 0, "Cannot load resource element '%s'", mekey );
|
||||
}
|
||||
intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
|
||||
efree(pbuf);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
|
||||
UErrorCode icuerror;
|
||||
const char * locale = ures_getLocale( rb->me, &icuerror );
|
||||
if (is_numeric) {
|
||||
spprintf( &pbuf, 0, "Cannot load element %d without fallback from to %s", meindex, locale );
|
||||
} else {
|
||||
spprintf( &pbuf, 0, "Cannot load element '%s' without fallback from to %s", mekey, locale );
|
||||
}
|
||||
intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 TSRMLS_CC );
|
||||
efree(pbuf);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
resourcebundle_extract_value( return_value, rb TSRMLS_CC );
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_array_get */
|
||||
zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
{
|
||||
zval *retval;
|
||||
|
||||
if(offset == NULL) {
|
||||
php_error( E_ERROR, "Cannot apply [] to ResourceBundle object" );
|
||||
}
|
||||
MAKE_STD_ZVAL(retval);
|
||||
|
||||
resourcebundle_array_fetch(object, offset, retval, 1 TSRMLS_CC);
|
||||
Z_DELREF_P(retval);
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo_resourcebundle_get */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, index )
|
||||
ZEND_ARG_INFO( 0, fallback )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto mixed ResourceBundle::get( integer|string $resindex [, bool $fallback = true ] )
|
||||
* proto mixed resourcebundle_get( ResourceBundle $rb, integer|string $resindex [, bool $fallback = true ] )
|
||||
* Get resource identified by numerical index or key name.
|
||||
*/
|
||||
PHP_FUNCTION( resourcebundle_get )
|
||||
{
|
||||
zend_bool fallback = 1;
|
||||
zval * offset;
|
||||
zval * object;
|
||||
|
||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz|b", &object, ResourceBundle_ce_ptr, &offset, &fallback ) == FAILURE) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_get: unable to parse input params", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
resourcebundle_array_fetch(object, offset, return_value, fallback TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_array_count */
|
||||
int resourcebundle_array_count(zval *object, long *count TSRMLS_DC)
|
||||
{
|
||||
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object );
|
||||
|
||||
*count = ures_getSize( rb->me );
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo_resourcebundle_count */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_count, 0, 0, 0 )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int ResourceBundle::count()
|
||||
* proto int resourcebundle_count( ResourceBundle $bundle )
|
||||
* Get resources count
|
||||
*/
|
||||
PHP_FUNCTION( resourcebundle_count )
|
||||
{
|
||||
int32_t len;
|
||||
RESOURCEBUNDLE_METHOD_INIT_VARS;
|
||||
|
||||
if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_count: unable to parse input params", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
RESOURCEBUNDLE_METHOD_FETCH_OBJECT;
|
||||
|
||||
len = ures_getSize( rb->me );
|
||||
RETURN_LONG( len );
|
||||
}
|
||||
|
||||
/* {{{ arginfo_resourcebundle_getlocales */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_getlocales, 0, 0, 1 )
|
||||
ZEND_ARG_INFO( 0, bundlename )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array ResourceBundle::getLocales( string $bundlename )
|
||||
* proto array resourcebundle_locales( string $bundlename )
|
||||
* Get available locales from ResourceBundle name
|
||||
*/
|
||||
PHP_FUNCTION( resourcebundle_locales )
|
||||
{
|
||||
char * bundlename;
|
||||
int bundlename_len = 0;
|
||||
const char * entry;
|
||||
int entry_len;
|
||||
UEnumeration *icuenum;
|
||||
UErrorCode icuerror = U_ZERO_ERROR;
|
||||
|
||||
intl_errors_reset( NULL TSRMLS_CC );
|
||||
|
||||
if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &bundlename, &bundlename_len ) == FAILURE )
|
||||
{
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_locales: unable to parse input params", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if(bundlename_len == 0) {
|
||||
// fetch default locales list
|
||||
bundlename = NULL;
|
||||
}
|
||||
|
||||
icuenum = ures_openAvailableLocales( bundlename, &icuerror );
|
||||
INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");
|
||||
|
||||
uenum_reset( icuenum, &icuerror );
|
||||
INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");
|
||||
|
||||
array_init( return_value );
|
||||
while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) {
|
||||
add_next_index_stringl( return_value, (char *) entry, entry_len, 1 );
|
||||
}
|
||||
uenum_close( icuenum );
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo_resourcebundle_get_error_code */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_code, 0, 0, 0 )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string ResourceBundle::getErrorCode( )
|
||||
* proto string resourcebundle_get_error_code( ResourceBundle $bundle )
|
||||
* Get text description for ResourceBundle's last error code.
|
||||
*/
|
||||
PHP_FUNCTION( resourcebundle_get_error_code )
|
||||
{
|
||||
RESOURCEBUNDLE_METHOD_INIT_VARS;
|
||||
|
||||
if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
|
||||
&object, ResourceBundle_ce_ptr ) == FAILURE )
|
||||
{
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_get_error_code: unable to parse input params", 0 TSRMLS_CC );
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
|
||||
|
||||
RETURN_LONG(INTL_DATA_ERROR_CODE(rb));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo_resourcebundle_get_error_message */
|
||||
ZEND_BEGIN_ARG_INFO_EX( arginfo_resourcebundle_get_error_message, 0, 0, 0 )
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string ResourceBundle::getErrorMessage( )
|
||||
* proto string resourcebundle_get_error_message( ResourceBundle $bundle )
|
||||
* Get text description for ResourceBundle's last error.
|
||||
*/
|
||||
PHP_FUNCTION( resourcebundle_get_error_message )
|
||||
{
|
||||
char* message = NULL;
|
||||
RESOURCEBUNDLE_METHOD_INIT_VARS;
|
||||
|
||||
if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
|
||||
&object, ResourceBundle_ce_ptr ) == FAILURE )
|
||||
{
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"resourcebundle_get_error_message: unable to parse input params", 0 TSRMLS_CC );
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
|
||||
message = (char *)intl_error_get_message(INTL_DATA_ERROR_P(rb) TSRMLS_CC);
|
||||
RETURN_STRING(message, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ResourceBundle_class_functions
|
||||
* Every 'ResourceBundle' class method has an entry in this table
|
||||
*/
|
||||
static function_entry ResourceBundle_class_functions[] = {
|
||||
PHP_ME( ResourceBundle, __construct, arginfo_resourcebundle___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR )
|
||||
ZEND_NAMED_ME( create, ZEND_FN( resourcebundle_create ), arginfo_resourcebundle___construct, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC )
|
||||
ZEND_NAMED_ME( get, ZEND_FN(resourcebundle_get), arginfo_resourcebundle_get, ZEND_ACC_PUBLIC )
|
||||
ZEND_NAMED_ME( count, ZEND_FN(resourcebundle_count), arginfo_resourcebundle_count, ZEND_ACC_PUBLIC )
|
||||
ZEND_NAMED_ME( getLocales, ZEND_FN(resourcebundle_locales), arginfo_resourcebundle_getlocales, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
|
||||
ZEND_NAMED_ME( getErrorCode, ZEND_FN(resourcebundle_get_error_code), arginfo_resourcebundle_get_error_code, ZEND_ACC_PUBLIC )
|
||||
ZEND_NAMED_ME( getErrorMessage, ZEND_FN(resourcebundle_get_error_message), arginfo_resourcebundle_get_error_message, ZEND_ACC_PUBLIC )
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_register_class
|
||||
* Initialize 'ResourceBundle' class
|
||||
*/
|
||||
void resourcebundle_register_class( TSRMLS_D )
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY( ce, "ResourceBundle", ResourceBundle_class_functions );
|
||||
|
||||
ce.create_object = ResourceBundle_object_create;
|
||||
ce.get_iterator = resourcebundle_get_iterator;
|
||||
|
||||
ResourceBundle_ce_ptr = zend_register_internal_class( &ce TSRMLS_CC );
|
||||
|
||||
if( !ResourceBundle_ce_ptr )
|
||||
{
|
||||
zend_error(E_ERROR, "Failed to register ResourceBundle class");
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceBundle_object_handlers = std_object_handlers;
|
||||
ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get;
|
||||
ResourceBundle_object_handlers.count_elements = resourcebundle_array_count;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
48
ext/intl/resourcebundle/resourcebundle_class.h
Normal file
48
ext/intl/resourcebundle/resourcebundle_class.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RESOURCEBUNDLE_CLASS_H
|
||||
#define RESOURCEBUNDLE_CLASS_H
|
||||
|
||||
#include <unicode/ures.h>
|
||||
|
||||
#include <zend.h>
|
||||
|
||||
#include "intl_error.h"
|
||||
|
||||
typedef struct {
|
||||
zend_object zend;
|
||||
intl_error error;
|
||||
|
||||
UResourceBundle *me;
|
||||
UResourceBundle *child;
|
||||
} ResourceBundle_object;
|
||||
|
||||
#define RESOURCEBUNDLE_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(ResourceBundle, rb)
|
||||
#define RESOURCEBUNDLE_METHOD_FETCH_OBJECT INTL_METHOD_FETCH_OBJECT(ResourceBundle, rb)
|
||||
#define RESOURCEBUNDLE_OBJECT(rb) (rb)->me
|
||||
|
||||
void resourcebundle_register_class( TSRMLS_D );
|
||||
extern zend_class_entry *ResourceBundle_ce_ptr;
|
||||
|
||||
PHP_FUNCTION( resourcebundle_create );
|
||||
PHP_FUNCTION( resourcebundle_get );
|
||||
PHP_FUNCTION( resourcebundle_count );
|
||||
PHP_FUNCTION( resourcebundle_locales );
|
||||
PHP_FUNCTION( resourcebundle_get_error_code );
|
||||
PHP_FUNCTION( resourcebundle_get_error_message );
|
||||
|
||||
#endif // #ifndef RESOURCEBUNDLE_CLASS_H
|
192
ext/intl/resourcebundle/resourcebundle_iterator.c
Normal file
192
ext/intl/resourcebundle/resourcebundle_iterator.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <php.h>
|
||||
#include <zend.h>
|
||||
#include <zend_API.h>
|
||||
|
||||
#include "resourcebundle/resourcebundle.h"
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
#include "resourcebundle/resourcebundle_iterator.h"
|
||||
|
||||
/*
|
||||
* Although libicu offers iterator functions, they are not used here: libicu does iterate
|
||||
* irrespective of array indices. Those cannot be recreated afterwards. Arrays as well as tables
|
||||
* can however be accessed by numerical index, with table keys readable ex post.
|
||||
*/
|
||||
|
||||
/* {{{ resourcebundle_iterator_read */
|
||||
static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator TSRMLS_DC )
|
||||
{
|
||||
UErrorCode icuerror = U_ZERO_ERROR;
|
||||
ResourceBundle_object *rb = iterator->subject;
|
||||
|
||||
rb->child = ures_getByIndex( rb->me, iterator->i, rb->child, &icuerror );
|
||||
|
||||
if (U_SUCCESS(icuerror)) {
|
||||
/* ATTN: key extraction must be the first thing to do... rb->child might be reset in read! */
|
||||
if (iterator->is_table) {
|
||||
iterator->currentkey = estrdup( ures_getKey( rb->child ) );
|
||||
}
|
||||
MAKE_STD_ZVAL( iterator->current );
|
||||
resourcebundle_extract_value( iterator->current, rb TSRMLS_CC );
|
||||
}
|
||||
else {
|
||||
// zend_throw_exception( spl_ce_OutOfRangeException, "Running past end of ResourceBundle", 0 TSRMLS_CC);
|
||||
iterator->current = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_invalidate */
|
||||
static void resourcebundle_iterator_invalidate( zend_object_iterator *iter TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
|
||||
if (iterator->current) {
|
||||
zval_ptr_dtor( &iterator->current );
|
||||
iterator->current = NULL;
|
||||
}
|
||||
if (iterator->currentkey) {
|
||||
efree( iterator->currentkey );
|
||||
iterator->currentkey = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_dtor */
|
||||
static void resourcebundle_iterator_dtor( zend_object_iterator *iter TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
zval *object = (zval *)iterator->intern.data;
|
||||
|
||||
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
|
||||
|
||||
Z_DELREF_P(object);
|
||||
|
||||
efree(iterator);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_has_more */
|
||||
static int resourcebundle_iterator_has_more( zend_object_iterator *iter TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
return (iterator->i < iterator->length) ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_current */
|
||||
static void resourcebundle_iterator_current( zend_object_iterator *iter, zval ***data TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
if (!iterator->current) {
|
||||
resourcebundle_iterator_read( iterator );
|
||||
}
|
||||
*data = &iterator->current;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_key */
|
||||
static int resourcebundle_iterator_key( zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
|
||||
if (!iterator->current) {
|
||||
resourcebundle_iterator_read( iterator );
|
||||
}
|
||||
if (iterator->is_table) {
|
||||
*str_key = estrdup( iterator->currentkey );
|
||||
*str_key_len = strlen( iterator->currentkey ) + 1;
|
||||
return HASH_KEY_IS_STRING;
|
||||
}
|
||||
else {
|
||||
*int_key = iterator->i;
|
||||
return HASH_KEY_IS_LONG;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_has_more */
|
||||
static void resourcebundle_iterator_step( zend_object_iterator *iter TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
|
||||
iterator->i++;
|
||||
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_has_reset */
|
||||
static void resourcebundle_iterator_reset( zend_object_iterator *iter TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
|
||||
|
||||
iterator->i = 0;
|
||||
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_iterator_funcs */
|
||||
static zend_object_iterator_funcs resourcebundle_iterator_funcs = {
|
||||
resourcebundle_iterator_dtor,
|
||||
resourcebundle_iterator_has_more,
|
||||
resourcebundle_iterator_current,
|
||||
resourcebundle_iterator_key,
|
||||
resourcebundle_iterator_step,
|
||||
resourcebundle_iterator_reset,
|
||||
resourcebundle_iterator_invalidate
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resourcebundle_get_iterator */
|
||||
zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref TSRMLS_DC )
|
||||
{
|
||||
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
|
||||
ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) );
|
||||
|
||||
if (byref) {
|
||||
php_error( E_ERROR, "ResourceBundle does not support writable iterators" );
|
||||
}
|
||||
|
||||
Z_ADDREF_P(object);
|
||||
iterator->intern.data = (void *) object;
|
||||
iterator->intern.funcs = &resourcebundle_iterator_funcs;
|
||||
|
||||
iterator->subject = rb;
|
||||
|
||||
/* The iterated rb can only be either URES_TABLE or URES_ARRAY
|
||||
* All other types are returned as php primitives!
|
||||
*/
|
||||
iterator->is_table = (ures_getType( rb->me ) == URES_TABLE);
|
||||
iterator->length = ures_getSize( rb->me );
|
||||
|
||||
iterator->current = NULL;
|
||||
iterator->currentkey = NULL;
|
||||
iterator->i = 0;
|
||||
|
||||
return (zend_object_iterator *) iterator;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
36
ext/intl/resourcebundle/resourcebundle_iterator.h
Normal file
36
ext/intl/resourcebundle/resourcebundle_iterator.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef RESOURCEBUNDLE_ITERATOR_H
|
||||
#define RESOURCEBUNDLE_ITERATOR_H
|
||||
|
||||
#include <zend.h>
|
||||
|
||||
#include "resourcebundle/resourcebundle_class.h"
|
||||
|
||||
typedef struct {
|
||||
zend_object_iterator intern;
|
||||
ResourceBundle_object *subject;
|
||||
zend_bool is_table;
|
||||
long length;
|
||||
zval *current;
|
||||
char *currentkey;
|
||||
long i;
|
||||
} ResourceBundle_iterator;
|
||||
|
||||
zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref TSRMLS_DC );
|
||||
|
||||
#endif // #ifndef RESOURCEBUNDLE_ITERATOR_H
|
21
ext/intl/tests/_files/es-bundle.txt
Executable file
21
ext/intl/tests/_files/es-bundle.txt
Executable file
|
@ -0,0 +1,21 @@
|
|||
es {
|
||||
teststring:string { "Hola Mundo!" }
|
||||
|
||||
testint:int { 2 }
|
||||
|
||||
testvector:intvector { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
|
||||
|
||||
testbin:bin { a1b2c3d4e5f67890 }
|
||||
|
||||
testtable:table {
|
||||
major:int { 3 }
|
||||
minor:int { 4 }
|
||||
patch:int { 7 }
|
||||
}
|
||||
|
||||
testarray:array {
|
||||
"cadena 1",
|
||||
"cadena 2",
|
||||
"cadena 3"
|
||||
}
|
||||
}
|
6
ext/intl/tests/_files/res_index.txt
Executable file
6
ext/intl/tests/_files/res_index.txt
Executable file
|
@ -0,0 +1,6 @@
|
|||
res_index:table(nofallback) {
|
||||
InstalledLocales {
|
||||
es {""}
|
||||
root {""}
|
||||
}
|
||||
}
|
21
ext/intl/tests/_files/resourcebundle.txt
Executable file
21
ext/intl/tests/_files/resourcebundle.txt
Executable file
|
@ -0,0 +1,21 @@
|
|||
root {
|
||||
teststring:string { "Hello World!" }
|
||||
|
||||
testint:int { 2 }
|
||||
|
||||
testvector:intvector { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
|
||||
|
||||
testbin:bin { a1b2c3d4e5f67890 }
|
||||
|
||||
testtable:table {
|
||||
major:int { 3 }
|
||||
minor:int { 4 }
|
||||
patch:int { 7 }
|
||||
}
|
||||
|
||||
testarray:array {
|
||||
"string 1",
|
||||
"string 2",
|
||||
"string 3"
|
||||
}
|
||||
}
|
BIN
ext/intl/tests/_files/resourcebundle/es.res
Executable file
BIN
ext/intl/tests/_files/resourcebundle/es.res
Executable file
Binary file not shown.
BIN
ext/intl/tests/_files/resourcebundle/res_index.res
Executable file
BIN
ext/intl/tests/_files/resourcebundle/res_index.res
Executable file
Binary file not shown.
BIN
ext/intl/tests/_files/resourcebundle/root.res
Executable file
BIN
ext/intl/tests/_files/resourcebundle/root.res
Executable file
Binary file not shown.
33
ext/intl/tests/rb_build.php
Executable file
33
ext/intl/tests/rb_build.php
Executable file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
// THIS SCRIPT WILL REBUILD ResourceBundle bundles from source files
|
||||
|
||||
// DEFINE YOUR ICU TOOLS PATH HERE
|
||||
define("ICU_DIR", "C:/PROJECTS/ICU40/BIN/");
|
||||
|
||||
$here = dirname(__FILE__);
|
||||
|
||||
$dir = new GlobIterator("$here/_files/*.txt", FilesystemIterator::KEY_AS_FILENAME);
|
||||
|
||||
foreach($dir as $file) {
|
||||
passthru( ICU_DIR."genrb -s $here/_files/ -d $here/_files/resourcebundle ".$file->getFileName());
|
||||
}
|
||||
|
||||
$dir = new GlobIterator("$here/_files/resourcebundle/*.res", FilesystemIterator::KEY_AS_FILENAME);
|
||||
foreach($dir as $file) {
|
||||
if($file->getFileName() == "res_index.res") continue;
|
||||
$list[] = str_replace(".res", "", $file->getFileName());
|
||||
}
|
||||
|
||||
$filelist = join(" {\"\"}\n", $list);
|
||||
$res_index = <<<END
|
||||
res_index:table(nofallback) {
|
||||
InstalledLocales {
|
||||
$filelist {""}
|
||||
}
|
||||
}
|
||||
END;
|
||||
file_put_contents("$here/_files/res_index.txt", $res_index);
|
||||
|
||||
passthru( ICU_DIR."genrb -s $here/_files/ -d $here/_files/resourcebundle res_index.txt");
|
||||
|
||||
// passthru(ICU_DIR."icupkg -tl -a $here/rb.txt -s $here/_files -d $here/_files new $here/_files/resourcebundle.dat");
|
13
ext/intl/tests/resourcebundle.inc
Normal file
13
ext/intl/tests/resourcebundle.inc
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
define('BUNDLE', dirname(__FILE__)."/_files/resourcebundle");
|
||||
|
||||
function debug( $res ) {
|
||||
if (is_null( $res )) {
|
||||
$ret = "NULL\n";
|
||||
}
|
||||
else {
|
||||
$ret = print_r( $res, true ). "\n";
|
||||
}
|
||||
return $ret . sprintf( "%5d: %s\n", intl_get_error_code(), intl_get_error_message() );
|
||||
}
|
||||
|
48
ext/intl/tests/resourcebundle_arrayaccess.phpt
Normal file
48
ext/intl/tests/resourcebundle_arrayaccess.phpt
Normal file
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
Test ResourceBundle array access and count - existing/missing keys
|
||||
--FILE--
|
||||
<?php
|
||||
include "resourcebundle.inc";
|
||||
|
||||
// fall back
|
||||
$r = new ResourceBundle( 'en_US', BUNDLE );
|
||||
|
||||
printf( "length: %d\n", count($r) );
|
||||
printf( "teststring: %s\n", $r['teststring'] );
|
||||
printf( "testint: %d\n", $r['testint'] );
|
||||
|
||||
print_r( $r['testvector'] );
|
||||
|
||||
printf( "testbin: %s\n", bin2hex($r['testbin']) );
|
||||
|
||||
$r2 = $r['testtable'];
|
||||
printf( "testtable: %d\n", $r2['major'] );
|
||||
|
||||
$r2 = $r['testarray'];
|
||||
printf( "testarray: %s\n", $r2[2] );
|
||||
|
||||
$t = $r['nonexisting'];
|
||||
echo debug( $t );
|
||||
?>
|
||||
--EXPECT--
|
||||
length: 6
|
||||
teststring: Hello World!
|
||||
testint: 2
|
||||
Array
|
||||
(
|
||||
[0] => 1
|
||||
[1] => 2
|
||||
[2] => 3
|
||||
[3] => 4
|
||||
[4] => 5
|
||||
[5] => 6
|
||||
[6] => 7
|
||||
[7] => 8
|
||||
[8] => 9
|
||||
[9] => 0
|
||||
)
|
||||
testbin: a1b2c3d4e5f67890
|
||||
testtable: 3
|
||||
testarray: string 3
|
||||
NULL
|
||||
2: Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR
|
62
ext/intl/tests/resourcebundle_create.phpt
Normal file
62
ext/intl/tests/resourcebundle_create.phpt
Normal file
|
@ -0,0 +1,62 @@
|
|||
--TEST--
|
||||
Test ResourceBundle::__construct() - existing/missing bundles/locales
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "resourcebundle.inc";
|
||||
|
||||
function ut_main() {
|
||||
$str_res = '';
|
||||
// all fine
|
||||
$r1 = ut_resourcebundle_create( 'root', BUNDLE );
|
||||
$str_res .= debug( $r1 );
|
||||
$str_res .= print_r( $r1['teststring'], true)."\n";
|
||||
|
||||
// non-root one
|
||||
$r1 = ut_resourcebundle_create( 'es', BUNDLE );
|
||||
$str_res .= debug( $r1 );
|
||||
$str_res .= print_r( $r1['teststring'], true)."\n";
|
||||
|
||||
// fall back
|
||||
$r1 = ut_resourcebundle_create( 'en_US', BUNDLE );
|
||||
$str_res .= debug( $r1 );
|
||||
$str_res .= print_r( $r1['testsring'], true);
|
||||
|
||||
// fall out
|
||||
$r2 = ut_resourcebundle_create( 'en_US', BUNDLE, false );
|
||||
$str_res .= debug( $r2 );
|
||||
|
||||
// missing
|
||||
$r3 = ut_resourcebundle_create( 'en_US', 'nonexisting' );
|
||||
$str_res .= debug( $r3 );
|
||||
|
||||
return $str_res;
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
?>
|
||||
--EXPECTF--
|
||||
ResourceBundle Object
|
||||
(
|
||||
)
|
||||
|
||||
0: U_ZERO_ERROR
|
||||
Hello World!
|
||||
ResourceBundle Object
|
||||
(
|
||||
)
|
||||
|
||||
0: U_ZERO_ERROR
|
||||
Hola Mundo!
|
||||
ResourceBundle Object
|
||||
(
|
||||
)
|
||||
|
||||
-127: U_USING_DEFAULT_WARNING
|
||||
NULL
|
||||
-127: resourcebundle_ctor: Cannot load libICU resource '%s/resourcebundle' without fallback from en_US to root: U_USING_DEFAULT_WARNING
|
||||
NULL
|
||||
2: resourcebundle_ctor: Cannot load libICU resource bundle: U_MISSING_RESOURCE_ERROR
|
55
ext/intl/tests/resourcebundle_individual.phpt
Normal file
55
ext/intl/tests/resourcebundle_individual.phpt
Normal file
|
@ -0,0 +1,55 @@
|
|||
--TEST--
|
||||
Test ResourceBundle::get() and length() - existing/missing keys
|
||||
--FILE--
|
||||
<?php
|
||||
include "resourcebundle.inc";
|
||||
|
||||
function ut_main() {
|
||||
$str_res = '';
|
||||
// fall back
|
||||
$r = ut_resourcebundle_create( 'en_US', BUNDLE );
|
||||
|
||||
$str_res .= sprintf( "length: %d\n", ut_resourcebundle_count($r) );
|
||||
$str_res .= sprintf( "teststring: %s\n", ut_resourcebundle_get($r, 'teststring' ) );
|
||||
$str_res .= sprintf( "testint: %d\n", ut_resourcebundle_get($r, 'testint' ) );
|
||||
|
||||
$str_res .= print_r( ut_resourcebundle_get($r, 'testvector' ), true );
|
||||
|
||||
$str_res .= sprintf( "testbin: %s\n", bin2hex(ut_resourcebundle_get( $r,'testbin' )) );
|
||||
|
||||
$r2 = ut_resourcebundle_get($r, 'testtable' );
|
||||
$str_res .= sprintf( "testtable: %d\n", ut_resourcebundle_get($r2, 'major' ) );
|
||||
|
||||
$r2 = ut_resourcebundle_get($r,'testarray' );
|
||||
$str_res .= sprintf( "testarray: %s\n", ut_resourcebundle_get($r2, 2 ) );
|
||||
|
||||
$t = ut_resourcebundle_get( $r, 'nonexisting' );
|
||||
$str_res .= debug( $t );
|
||||
|
||||
return $str_res;
|
||||
}
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
?>
|
||||
--EXPECT--
|
||||
length: 6
|
||||
teststring: Hello World!
|
||||
testint: 2
|
||||
Array
|
||||
(
|
||||
[0] => 1
|
||||
[1] => 2
|
||||
[2] => 3
|
||||
[3] => 4
|
||||
[4] => 5
|
||||
[5] => 6
|
||||
[6] => 7
|
||||
[7] => 8
|
||||
[8] => 9
|
||||
[9] => 0
|
||||
)
|
||||
testbin: a1b2c3d4e5f67890
|
||||
testtable: 3
|
||||
testarray: string 3
|
||||
NULL
|
||||
2: Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR
|
71
ext/intl/tests/resourcebundle_iterator.phpt
Normal file
71
ext/intl/tests/resourcebundle_iterator.phpt
Normal file
|
@ -0,0 +1,71 @@
|
|||
--TEST--
|
||||
Test ResourceBundle iterator
|
||||
--FILE--
|
||||
<?php
|
||||
include "resourcebundle.inc";
|
||||
|
||||
// fall back
|
||||
$r = new ResourceBundle( 'en_US', BUNDLE );
|
||||
|
||||
foreach ($r as $onekey => $oneval) {
|
||||
echo "Here comes $onekey:\n";
|
||||
switch (gettype($oneval)) {
|
||||
case 'string':
|
||||
echo bin2hex( $oneval ) . "\n";
|
||||
break;
|
||||
|
||||
case 'integer':
|
||||
echo "$oneval\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
print_r( $oneval );
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "Testarray Contents:\n";
|
||||
$r = $r->get( 'testarray' );
|
||||
foreach ($r as $onekey => $oneval) {
|
||||
echo "$onekey => $oneval\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Here comes testarray:
|
||||
ResourceBundle Object
|
||||
(
|
||||
)
|
||||
|
||||
Here comes testbin:
|
||||
a1b2c3d4e5f67890
|
||||
|
||||
Here comes testint:
|
||||
2
|
||||
|
||||
Here comes teststring:
|
||||
48656c6c6f20576f726c6421
|
||||
|
||||
Here comes testtable:
|
||||
ResourceBundle Object
|
||||
(
|
||||
)
|
||||
|
||||
Here comes testvector:
|
||||
Array
|
||||
(
|
||||
[0] => 1
|
||||
[1] => 2
|
||||
[2] => 3
|
||||
[3] => 4
|
||||
[4] => 5
|
||||
[5] => 6
|
||||
[6] => 7
|
||||
[7] => 8
|
||||
[8] => 9
|
||||
[9] => 0
|
||||
)
|
||||
|
||||
Testarray Contents:
|
||||
0 => string 1
|
||||
1 => string 2
|
||||
2 => string 3
|
23
ext/intl/tests/resourcebundle_locales.phpt
Executable file
23
ext/intl/tests/resourcebundle_locales.phpt
Executable file
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
Test ResourceBundle::getLocales
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "resourcebundle.inc";
|
||||
|
||||
function ut_main() {
|
||||
$str_res = '';
|
||||
|
||||
$str_res .= join("\n", ut_resourcebundle_locales(BUNDLE));
|
||||
|
||||
return $str_res;
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
?>
|
||||
--EXPECT--
|
||||
es
|
||||
root
|
|
@ -389,4 +389,28 @@ function ut_datefmt_localtime( $fmt , $value , &$parse_pos=0 )
|
|||
{
|
||||
return $GLOBALS['oo-mode'] ? $fmt->localtime( $value , $parse_pos ) : datefmt_localtime( $fmt , $value , $parse_pos );
|
||||
}
|
||||
?>
|
||||
|
||||
function ut_resourcebundle_create( $locale, $bundle, $fallback=true )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? new ResourceBundle($locale, $bundle, $fallback): resourcebundle_create($locale, $bundle, $fallback);
|
||||
}
|
||||
function ut_resourcebundle_count($bundle )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? $bundle->count():resourcebundle_count($bundle);
|
||||
}
|
||||
function ut_resourcebundle_locales($bundle )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? ResourceBundle::getLocales($bundle):resourcebundle_locales($bundle);
|
||||
}
|
||||
function ut_resourcebundle_get($bundle, $idx )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? $bundle->get($idx):resourcebundle_get($bundle, $idx);
|
||||
}
|
||||
function ut_resourcebundle_get_error_code($bundle )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? $bundle->getErrorCode():resourcebundle_get_error_code($bundle);
|
||||
}
|
||||
function ut_resourcebundle_get_error_message($bundle )
|
||||
{
|
||||
return $GLOBALS['oo-mode'] ? $bundle->getErrorMessage():resourcebundle_get_error_message($bundle);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue