derick Sun Mar 26 11:06:24 2006 UTC Added files: /php-src/ext/unicode collator.c
Modified files: /php-src/ext/standard array.c php_array.h /php-src/ext/unicode config.m4 config.w32 php_unicode.h unicode.c Log: - Implemented basic collation support. For some reason "new Collator" gives segfaults when the object's collation resource is used. - The following example shows what is implemented: <?php $orig = $strings = array( 'côte', 'cote', 'côté', 'coté', 'fluÃe', 'flüÃe', ); echo "German phonebook:\n"; $c = collator_create( "[EMAIL PROTECTED]" ); foreach($c->sort($strings) as $string) { echo $string, "\n"; } echo $c->getAttribute(Collator::FRENCH_COLLATION) == Collator::ON ? "With" : "Without", " french accent sorting order\n"; echo "\nFrench with options:\n"; $c = collator_create( "fr" ); $c->setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST); $c->setAttribute(Collator::CASE_LEVEL, Collator::ON); $c->setStrength(Collator::SECONDARY); foreach($c->sort($strings) as $string) { echo $string, "\n"; } echo $c->getAttribute(Collator::FRENCH_COLLATION) == Collator::ON ? "With" : "Without", " french accent sorting order\n"; ?>
http://cvs.php.net/viewcvs.cgi/php-src/ext/standard/array.c?r1=1.346&r2=1.347&diff_format=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.346 php-src/ext/standard/array.c:1.347 --- php-src/ext/standard/array.c:1.346 Wed Mar 22 22:06:08 2006 +++ php-src/ext/standard/array.c Sun Mar 26 11:06:24 2006 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.346 2006/03/22 22:06:08 tony2001 Exp $ */ +/* $Id: array.c,v 1.347 2006/03/26 11:06:24 derick Exp $ */ #include "php.h" #include "php_ini.h" @@ -60,11 +60,6 @@ #define EXTR_REFS 0x100 -#define SORT_REGULAR 0 -#define SORT_NUMERIC 1 -#define SORT_STRING 2 -#define SORT_LOCALE_STRING 5 - #define SORT_DESC 3 #define SORT_ASC 4 @@ -139,7 +134,7 @@ return SUCCESS; } -static void set_compare_func(int sort_type TSRMLS_DC) +PHPAPI void php_set_compare_func(int sort_type TSRMLS_DC) { switch (sort_type) { case SORT_NUMERIC: @@ -241,7 +236,7 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(target_hash, zend_qsort, array_reverse_key_compare, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; @@ -263,7 +258,7 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(target_hash, zend_qsort, array_key_compare, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; @@ -346,7 +341,7 @@ * * This is not correct any more, depends on what compare_func is set to. */ -static int array_data_compare(const void *a, const void *b TSRMLS_DC) +PHPAPI int php_array_data_compare(const void *a, const void *b TSRMLS_DC) { Bucket *f; Bucket *s; @@ -387,7 +382,7 @@ static int array_reverse_data_compare(const void *a, const void *b TSRMLS_DC) { - return array_data_compare(a, b TSRMLS_CC)*-1; + return php_array_data_compare(a, b TSRMLS_CC)*-1; } static int array_natural_general_compare(const void *a, const void *b, int fold_case) @@ -493,9 +488,9 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); - if (zend_hash_sort(target_hash, zend_qsort, array_data_compare, 0 TSRMLS_CC) == FAILURE) { + if (zend_hash_sort(target_hash, zend_qsort, php_array_data_compare, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } RETURN_TRUE; @@ -515,7 +510,7 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(target_hash, zend_qsort, array_reverse_data_compare, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; @@ -537,9 +532,9 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); - if (zend_hash_sort(target_hash, zend_qsort, array_data_compare, 1 TSRMLS_CC) == FAILURE) { + if (zend_hash_sort(target_hash, zend_qsort, php_array_data_compare, 1 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } RETURN_TRUE; @@ -559,7 +554,7 @@ } target_hash = HASH_OF(array); - set_compare_func(sort_type TSRMLS_CC); + php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(target_hash, zend_qsort, array_reverse_data_compare, 1 TSRMLS_CC) == FAILURE) { RETURN_FALSE; @@ -968,14 +963,14 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Atleast one value should be passed"); RETURN_NULL(); } - set_compare_func(SORT_REGULAR TSRMLS_CC); + php_set_compare_func(SORT_REGULAR TSRMLS_CC); if (argc == 1) { zval **arr; if (zend_get_parameters_ex(1, &arr) == FAILURE || Z_TYPE_PP(arr) != IS_ARRAY) { WRONG_PARAM_COUNT; } - if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 0, (void **) &result TSRMLS_CC) == SUCCESS) { + if (zend_hash_minmax(Z_ARRVAL_PP(arr), php_array_data_compare, 0, (void **) &result TSRMLS_CC) == SUCCESS) { RETVAL_ZVAL(*result, 1, 0); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain atleast one element"); @@ -1018,14 +1013,14 @@ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Atleast one value should be passed"); RETURN_NULL(); } - set_compare_func(SORT_REGULAR TSRMLS_CC); + php_set_compare_func(SORT_REGULAR TSRMLS_CC); if (argc == 1) { zval **arr; if (zend_get_parameters_ex(1, &arr) == FAILURE || Z_TYPE_PP(arr) != IS_ARRAY) { WRONG_PARAM_COUNT; } - if (zend_hash_minmax(Z_ARRVAL_PP(arr), array_data_compare, 1, (void **) &result TSRMLS_CC) == SUCCESS) { + if (zend_hash_minmax(Z_ARRVAL_PP(arr), php_array_data_compare, 1, (void **) &result TSRMLS_CC) == SUCCESS) { RETVAL_ZVAL(*result, 1, 0); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain atleast one element"); @@ -3026,13 +3021,13 @@ arTmp[i].i = i; } arTmp[i].b = NULL; - set_compare_func(SORT_STRING TSRMLS_CC); - zend_qsort((void *) arTmp, i, sizeof(struct bucketindex), array_data_compare TSRMLS_CC); + php_set_compare_func(SORT_STRING TSRMLS_CC); + zend_qsort((void *) arTmp, i, sizeof(struct bucketindex), php_array_data_compare TSRMLS_CC); /* go through the sorted array and delete duplicates from the copy */ lastkept = arTmp; for (cmpdata = arTmp + 1; cmpdata->b; cmpdata++) { - if (array_data_compare(lastkept, cmpdata TSRMLS_CC)) { + if (php_array_data_compare(lastkept, cmpdata TSRMLS_CC)) { lastkept = cmpdata; } else { if (lastkept->i > cmpdata->i) { @@ -3091,7 +3086,7 @@ WRONG_PARAM_COUNT; } arr_argc = argc; - intersect_data_compare_func = array_data_compare; + intersect_data_compare_func = php_array_data_compare; } else if (data_compare_type == INTERSECT_COMP_DATA_USER) { /* array_uintersect() */ if (argc < 3) { @@ -3130,7 +3125,7 @@ } arr_argc = argc; intersect_key_compare_func = array_key_compare; - intersect_data_compare_func = array_data_compare; + intersect_data_compare_func = php_array_data_compare; } else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) { @@ -3168,7 +3163,7 @@ } zval_dtor(&callback_name); intersect_key_compare_func = array_user_key_compare; - intersect_data_compare_func = array_data_compare; + intersect_data_compare_func = php_array_data_compare; BG(user_compare_func_name) = args[arr_argc]; } else if (data_compare_type == INTERSECT_COMP_DATA_USER && @@ -3210,7 +3205,7 @@ /* for each argument, create and sort list with pointers to the hash buckets */ lists = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0); ptrs = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0); - set_compare_func(SORT_STRING TSRMLS_CC); + php_set_compare_func(SORT_STRING TSRMLS_CC); for (i = 0; i < arr_argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i+1); @@ -3476,7 +3471,7 @@ WRONG_PARAM_COUNT; } arr_argc = argc; - diff_data_compare_func = array_data_compare; + diff_data_compare_func = php_array_data_compare; } else if (data_compare_type == DIFF_COMP_DATA_USER) { /* array_udiff */ if (argc < 3) { @@ -3515,7 +3510,7 @@ } arr_argc = argc; diff_key_compare_func = array_key_compare; - diff_data_compare_func = array_data_compare; + diff_data_compare_func = php_array_data_compare; } else if (data_compare_type == DIFF_COMP_DATA_USER && key_compare_type == DIFF_COMP_KEY_INTERNAL) { @@ -3553,7 +3548,7 @@ } zval_dtor(&callback_name); diff_key_compare_func = array_user_key_compare; - diff_data_compare_func = array_data_compare; + diff_data_compare_func = php_array_data_compare; BG(user_compare_func_name) = args[arr_argc]; } else if (data_compare_type == DIFF_COMP_DATA_USER && @@ -3595,7 +3590,7 @@ /* for each argument, create and sort list with pointers to the hash buckets */ lists = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0); ptrs = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0); - set_compare_func(SORT_STRING TSRMLS_CC); + php_set_compare_func(SORT_STRING TSRMLS_CC); for (i = 0; i < arr_argc; i++) { if (Z_TYPE_PP(args[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1); @@ -3841,7 +3836,7 @@ r = 0; do { - set_compare_func(ARRAYG(multisort_flags)[MULTISORT_TYPE][r] TSRMLS_CC); + php_set_compare_func(ARRAYG(multisort_flags)[MULTISORT_TYPE][r] TSRMLS_CC); ARRAYG(compare_func)(&temp, *((zval **)ab[r]->pData), *((zval **)bb[r]->pData) TSRMLS_CC); result = ARRAYG(multisort_flags)[MULTISORT_ORDER][r] * Z_LVAL(temp); http://cvs.php.net/viewcvs.cgi/php-src/ext/standard/php_array.h?r1=1.52&r2=1.53&diff_format=u Index: php-src/ext/standard/php_array.h diff -u php-src/ext/standard/php_array.h:1.52 php-src/ext/standard/php_array.h:1.53 --- php-src/ext/standard/php_array.h:1.52 Tue Feb 7 17:54:52 2006 +++ php-src/ext/standard/php_array.h Sun Mar 26 11:06:24 2006 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_array.h,v 1.52 2006/02/07 17:54:52 andrei Exp $ */ +/* $Id: php_array.h,v 1.53 2006/03/26 11:06:24 derick Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -102,6 +102,14 @@ HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **); PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC); int multisort_compare(const void *a, const void *b TSRMLS_DC); +PHPAPI int php_array_data_compare(const void *a, const void *b TSRMLS_DC); +PHPAPI void php_set_compare_func(int sort_type TSRMLS_DC); + +#define SORT_REGULAR 0 +#define SORT_NUMERIC 1 +#define SORT_STRING 2 +#define SORT_LOCALE_STRING 5 + ZEND_BEGIN_MODULE_GLOBALS(array) int *multisort_flags[2]; http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/config.m4?r1=1.5&r2=1.6&diff_format=u Index: php-src/ext/unicode/config.m4 diff -u php-src/ext/unicode/config.m4:1.5 php-src/ext/unicode/config.m4:1.6 --- php-src/ext/unicode/config.m4:1.5 Tue Mar 21 13:56:50 2006 +++ php-src/ext/unicode/config.m4 Sun Mar 26 11:06:24 2006 @@ -1,7 +1,7 @@ dnl -dnl $Id: config.m4,v 1.5 2006/03/21 13:56:50 derick Exp $ +dnl $Id: config.m4,v 1.6 2006/03/26 11:06:24 derick Exp $ dnl PHP_SUBST(UNICODE_SHARED_LIBADD) AC_DEFINE(HAVE_UNICODE, 1, [ ]) -PHP_NEW_EXTENSION(unicode, unicode.c locale.c unicode_filter.c unicode_iterators.c, $ext_shared) +PHP_NEW_EXTENSION(unicode, unicode.c locale.c unicode_filter.c unicode_iterators.c collator.c, $ext_shared) http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/config.w32?r1=1.5&r2=1.6&diff_format=u Index: php-src/ext/unicode/config.w32 diff -u php-src/ext/unicode/config.w32:1.5 php-src/ext/unicode/config.w32:1.6 --- php-src/ext/unicode/config.w32:1.5 Tue Mar 21 13:57:16 2006 +++ php-src/ext/unicode/config.w32 Sun Mar 26 11:06:24 2006 @@ -1,5 +1,5 @@ -// $Id: config.w32,v 1.5 2006/03/21 13:57:16 derick Exp $ +// $Id: config.w32,v 1.6 2006/03/26 11:06:24 derick Exp $ // vim:ft=javascript -EXTENSION("unicode", "unicode.c unicode_filter.c unicode_iterators.c locale.c"); +EXTENSION("unicode", "unicode.c unicode_filter.c unicode_iterators.c collator.c locale.c"); AC_DEFINE('HAVE_UNICODE', 1, 'ICU API extension'); http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/php_unicode.h?r1=1.5&r2=1.6&diff_format=u Index: php-src/ext/unicode/php_unicode.h diff -u php-src/ext/unicode/php_unicode.h:1.5 php-src/ext/unicode/php_unicode.h:1.6 --- php-src/ext/unicode/php_unicode.h:1.5 Wed Mar 22 10:20:20 2006 +++ php-src/ext/unicode/php_unicode.h Sun Mar 26 11:06:24 2006 @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_unicode.h,v 1.5 2006/03/22 10:20:20 derick Exp $ */ +/* $Id: php_unicode.h,v 1.6 2006/03/26 11:06:24 derick Exp $ */ #ifndef PHP_UNICODE_H #define PHP_UNICODE_H @@ -57,7 +57,16 @@ PHP_FUNCTION(i18n_loc_get_default); PHP_FUNCTION(i18n_loc_set_default); +PHP_FUNCTION(collator_create); +PHP_FUNCTION(collator_compare); +PHP_FUNCTION(collator_sort); +PHP_FUNCTION(collator_set_strength); +PHP_FUNCTION(collator_set_attribute); +PHP_FUNCTION(collator_get_strength); +PHP_FUNCTION(collator_get_attribute); +PHP_METHOD(collator, __construct); +void php_init_collation(TSRMLS_D); extern php_stream_filter_factory php_unicode_filter_factory; #ifdef __cplusplus http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/unicode.c?r1=1.15&r2=1.16&diff_format=u Index: php-src/ext/unicode/unicode.c diff -u php-src/ext/unicode/unicode.c:1.15 php-src/ext/unicode/unicode.c:1.16 --- php-src/ext/unicode/unicode.c:1.15 Sun Mar 26 06:19:24 2006 +++ php-src/ext/unicode/unicode.c Sun Mar 26 11:06:24 2006 @@ -15,7 +15,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: unicode.c,v 1.15 2006/03/26 06:19:24 andrei Exp $ */ +/* $Id: unicode.c,v 1.16 2006/03/26 11:06:24 derick Exp $ */ #include "php_unicode.h" #if HAVE_UNICODE @@ -184,6 +184,8 @@ PHP_FE(unicode_encode, NULL) PHP_FE(unicode_set_error_mode, NULL) PHP_FE(unicode_set_subst_char, NULL) + PHP_FE(collator_create, NULL) + PHP_FE(collator_compare, NULL) { NULL, NULL, NULL } }; /* }}} */ @@ -217,7 +219,8 @@ } php_register_unicode_iterators(TSRMLS_C); - + php_init_collation(TSRMLS_C); + return SUCCESS; } /* }}} */ http://cvs.php.net/viewcvs.cgi/php-src/ext/unicode/collator.c?view=markup&rev=1.1 Index: php-src/ext/unicode/collator.c +++ php-src/ext/unicode/collator.c /* +----------------------------------------------------------------------+ | 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: Derick Rethans <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ /* $Id: collator.c,v 1.1 2006/03/26 11:06:24 derick Exp $ */ #include "php.h" #include "ext/standard/php_array.h" #include "zend_interfaces.h" #include "zend_exceptions.h" #include "php_unicode.h" #include <unicode/ucol.h> zend_function_entry collator_funcs_collator[] = { ZEND_ME(collator, __construct, NULL, ZEND_ACC_PUBLIC) ZEND_NAMED_FE(compare, ZEND_FN(collator_compare), NULL) ZEND_NAMED_FE(setStrength, ZEND_FN(collator_set_strength), NULL) ZEND_NAMED_FE(setAttribute, ZEND_FN(collator_set_attribute), NULL) ZEND_NAMED_FE(getStrength, ZEND_FN(collator_get_strength), NULL) ZEND_NAMED_FE(getAttribute, ZEND_FN(collator_get_attribute), NULL) ZEND_NAMED_FE(sort, ZEND_FN(collator_sort), NULL) {NULL, NULL, NULL} }; zend_class_entry *unicode_ce_collator; static zend_object_handlers unicode_object_handlers_collator; typedef struct _php_collator_obj php_collator_obj; struct _php_collator_obj { zend_object std; UCollator *col; }; #define COLLATOR_SET_CONTEXT \ zval *object; \ object = getThis(); \ #define COLLATOR_FETCH_OBJECT \ php_collator_obj *obj; \ COLLATOR_SET_CONTEXT; \ if (object) { \ if (ZEND_NUM_ARGS()) { \ WRONG_PARAM_COUNT; \ } \ } else { \ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "O", &object, unicode_ce_collator) == FAILURE) { \ RETURN_FALSE; \ } \ } \ obj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); static zend_object_value collator_object_new(zend_class_entry *class_type TSRMLS_DC); static void collator_object_free_storage(void *object TSRMLS_DC); static void collator_register_class(TSRMLS_D) { zend_class_entry ce_collator; INIT_CLASS_ENTRY(ce_collator, "Collator", collator_funcs_collator); ce_collator.create_object = collator_object_new; unicode_ce_collator = zend_register_internal_class_ex(&ce_collator, NULL, NULL TSRMLS_CC); memcpy(&unicode_object_handlers_collator, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); unicode_object_handlers_collator.clone_obj = NULL; #define REGISTER_COLLATOR_CLASS_CONST_STRING(const_name, value) \ zend_declare_class_constant_stringl(unicode_ce_collator, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); #define REGISTER_COLLATOR_CLASS_CONST_LONG(const_name, value) \ zend_declare_class_constant_long(unicode_ce_collator, const_name, sizeof(const_name)-1, value TSRMLS_CC); /* Attributes */ REGISTER_COLLATOR_CLASS_CONST_LONG("FRENCH_COLLATION", UCOL_FRENCH_COLLATION); REGISTER_COLLATOR_CLASS_CONST_LONG("ALTERNATE_HANDLING", UCOL_ALTERNATE_HANDLING); REGISTER_COLLATOR_CLASS_CONST_LONG("CASE_FIRST", UCOL_CASE_FIRST); REGISTER_COLLATOR_CLASS_CONST_LONG("CASE_LEVEL", UCOL_CASE_LEVEL); REGISTER_COLLATOR_CLASS_CONST_LONG("NORMALIZATION_MODE", UCOL_NORMALIZATION_MODE); REGISTER_COLLATOR_CLASS_CONST_LONG("STRENGTH", UCOL_STRENGTH); REGISTER_COLLATOR_CLASS_CONST_LONG("HIRAGANA_QUARTERNARY_MODE", UCOL_HIRAGANA_QUATERNARY_MODE); REGISTER_COLLATOR_CLASS_CONST_LONG("NUMERIC_COLLATION", UCOL_NUMERIC_COLLATION); /* Attribute value constants */ REGISTER_COLLATOR_CLASS_CONST_LONG("DEFAULT_VALUE", UCOL_DEFAULT); REGISTER_COLLATOR_CLASS_CONST_LONG("PRIMARY", UCOL_PRIMARY); REGISTER_COLLATOR_CLASS_CONST_LONG("SECONDARY", UCOL_SECONDARY); REGISTER_COLLATOR_CLASS_CONST_LONG("TERTIARY", UCOL_TERTIARY); REGISTER_COLLATOR_CLASS_CONST_LONG("DEFAULT_STRENGHT", UCOL_DEFAULT_STRENGTH); REGISTER_COLLATOR_CLASS_CONST_LONG("QUARTERNARY", UCOL_QUATERNARY); REGISTER_COLLATOR_CLASS_CONST_LONG("IDENTICAL", UCOL_IDENTICAL); REGISTER_COLLATOR_CLASS_CONST_LONG("ON", UCOL_ON); REGISTER_COLLATOR_CLASS_CONST_LONG("OFF", UCOL_OFF); REGISTER_COLLATOR_CLASS_CONST_LONG("SHIFTED", UCOL_SHIFTED); REGISTER_COLLATOR_CLASS_CONST_LONG("NON_IGNORABLE", UCOL_NON_IGNORABLE); REGISTER_COLLATOR_CLASS_CONST_LONG("LOWER_FIRST", UCOL_LOWER_FIRST); REGISTER_COLLATOR_CLASS_CONST_LONG("UPPER_FIRST", UCOL_UPPER_FIRST); } void php_init_collation(TSRMLS_D) { collator_register_class(TSRMLS_C); } static zend_object_value collator_object_new(zend_class_entry *class_type TSRMLS_DC) { php_collator_obj *intern; zend_object_value retval; zval *tmp; intern = emalloc(sizeof(php_collator_obj)); memset(intern, 0, sizeof(php_collator_obj)); intern->std.ce = class_type; ALLOC_HASHTABLE(intern->std.properties); zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) collator_object_free_storage, NULL TSRMLS_CC); retval.handlers = &unicode_object_handlers_collator; return retval; } static void collator_object_free_storage(void *object TSRMLS_DC) { php_collator_obj *intern = (php_collator_obj *)object; if (intern->col) { ucol_close(intern->col); } if (intern->std.properties) { zend_hash_destroy(intern->std.properties); efree(intern->std.properties); intern->std.properties = NULL; } efree(object); } static zval* collator_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) { if (!object) { ALLOC_ZVAL(object); } Z_TYPE_P(object) = IS_OBJECT; object_init_ex(object, pce); object->refcount = 1; object->is_ref = 1; return object; } PHP_METHOD(collator, __construct) { zif_collator_create(INTERNAL_FUNCTION_PARAM_PASSTHRU); } PHP_FUNCTION(collator_create) { php_collator_obj *collatorobj; UErrorCode error; char *collator_name; int collator_name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &collator_name, &collator_name_len) == FAILURE) { RETURN_FALSE; } collator_instanciate(unicode_ce_collator, return_value TSRMLS_CC); collatorobj = (php_collator_obj *) zend_object_store_get_object(return_value TSRMLS_CC); error = U_ZERO_ERROR; collatorobj->col = ucol_open(collator_name, &error); } PHP_FUNCTION(collator_compare) { zval *object; php_collator_obj *collatorobj; UChar *string1, *string2; int string1_len, string2_len; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ouu", &object, unicode_ce_collator, &string1, &string1_len, &string2, &string2_len) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); RETURN_LONG(ucol_strcoll(collatorobj->col, string1, string1_len, string2, string2_len)); } PHP_FUNCTION(collator_sort) { zval *object; php_collator_obj *collatorobj; zval *array; HashTable *target_hash; UCollator *orig_collator; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oa/", &object, unicode_ce_collator, &array) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); target_hash = HASH_OF(array); php_set_compare_func(SORT_LOCALE_STRING TSRMLS_CC); orig_collator = UG(default_collator); UG(default_collator) = collatorobj->col; if (zend_hash_sort(target_hash, zend_qsort, php_array_data_compare, 1 TSRMLS_CC) == FAILURE) { RETVAL_FALSE; } else { RETVAL_ZVAL(array, 1, 0); } UG(default_collator) = orig_collator; } PHP_FUNCTION(collator_set_strength) { zval *object; php_collator_obj *collatorobj; long strength; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, unicode_ce_collator, &strength) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); ucol_setStrength(collatorobj->col, strength); } PHP_FUNCTION(collator_get_strength) { zval *object; php_collator_obj *collatorobj; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, unicode_ce_collator) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); RETURN_LONG(ucol_getStrength(collatorobj->col)); } PHP_FUNCTION(collator_set_attribute) { zval *object; php_collator_obj *collatorobj; long attribute, value; UErrorCode error; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &object, unicode_ce_collator, &attribute, &value) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); error = U_ZERO_ERROR; ucol_setAttribute(collatorobj->col, attribute, value, &error); RETURN_BOOL(error == U_ZERO_ERROR ? 1 : 0); } PHP_FUNCTION(collator_get_attribute) { zval *object; php_collator_obj *collatorobj; long attribute, value; UErrorCode error; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, unicode_ce_collator, &attribute) == FAILURE) { RETURN_FALSE; } collatorobj = (php_collator_obj *) zend_object_store_get_object(object TSRMLS_CC); error = U_ZERO_ERROR; value = ucol_getAttribute(collatorobj->col, attribute, &error); if (error != U_ZERO_ERROR) { RETURN_FALSE; } RETURN_LONG(value); }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php