Commit: 77daa3482d5592181560e0e6076c1e3291620e7b
Author: Gustavo André dos Santos Lopes <cataphr...@php.net> Fri, 22
Jun 2012 18:28:19 +0200
Parents: 0a7ae87e91368fe17c52767cfb31dabf3a94e38f
Branches: master
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=77daa3482d5592181560e0e6076c1e3291620e7b
Log:
BreakIterator::getPartsIterator: new optional arg
Can take one of:
* IntlPartsIterator::KEY_SEQUENTIAL (keys are 0, 1, ...)
* IntlPartsIterator::KEY_LEFT (keys are left boundaries)
* IntlPartsIterator::KEY_LEFT (keys are right boundaries)
The default is IntlPartsIterator::KEY_SEQUENTIAL (the previous behavior).
Changed paths:
M ext/intl/breakiterator/breakiterator_class.cpp
M ext/intl/breakiterator/breakiterator_iterators.cpp
M ext/intl/breakiterator/breakiterator_iterators.h
M ext/intl/breakiterator/breakiterator_methods.cpp
A ext/intl/tests/breakiter_getPartsIterator_error.phpt
A ext/intl/tests/breakiter_getPartsIterator_var1.phpt
diff --git a/ext/intl/breakiterator/breakiterator_class.cpp
b/ext/intl/breakiterator/breakiterator_class.cpp
index 6335502..d193fc4 100644
--- a/ext/intl/breakiterator/breakiterator_class.cpp
+++ b/ext/intl/breakiterator/breakiterator_class.cpp
@@ -264,6 +264,10 @@ ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_get_locale, 0, 0, 1)
ZEND_ARG_INFO(0, "locale_type")
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_getPartsIterator, 0, 0, 0)
+ ZEND_ARG_INFO(0, "key_type")
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(ainfo_rbbi___construct, 0, 0, 1)
ZEND_ARG_INFO(0, "rules")
ZEND_ARG_INFO(0, "areCompiled")
@@ -293,7 +297,7 @@ static const zend_function_entry
BreakIterator_class_functions[] = {
PHP_ME_MAPPING(preceding,
breakiter_preceding, ainfo_biter_offset,
ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(isBoundary,
breakiter_is_boundary, ainfo_biter_offset,
ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(getLocale,
breakiter_get_locale, ainfo_biter_void,
ZEND_ACC_PUBLIC)
- PHP_ME_MAPPING(getPartsIterator,
breakiter_get_parts_iterator, ainfo_biter_void,
ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getPartsIterator,
breakiter_get_parts_iterator, ainfo_biter_getPartsIterator,
ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(getErrorCode,
breakiter_get_error_code, ainfo_biter_void,
ZEND_ACC_PUBLIC)
PHP_ME_MAPPING(getErrorMessage,
breakiter_get_error_message, ainfo_biter_void,
ZEND_ACC_PUBLIC)
diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp
b/ext/intl/breakiterator/breakiterator_iterators.cpp
index d3ad050..d88ad8a 100644
--- a/ext/intl/breakiterator/breakiterator_iterators.cpp
+++ b/ext/intl/breakiterator/breakiterator_iterators.cpp
@@ -130,6 +130,7 @@ U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
typedef struct zoi_break_iter_parts {
zoi_with_current zoi_cur;
+ parts_iter_key_type key_type;
BreakIterator_object *bio; /* so we don't have to fetch it all the time
*/
} zoi_break_iter_parts;
@@ -138,6 +139,16 @@ static void
_breakiterator_parts_destroy_it(zend_object_iterator *iter TSRMLS_DC
zval_ptr_dtor(reinterpret_cast<zval**>(&iter->data));
}
+static int _breakiterator_parts_get_current_key(zend_object_iterator *iter,
+
char **str_key,
+
uint *str_key_len,
+
ulong *int_key TSRMLS_DC)
+{
+ /* the actual work is done in move_forward and rewind */
+ *int_key = iter->index;
+ return HASH_KEY_IS_LONG;
+}
+
static void _breakiterator_parts_move_forward(zend_object_iterator *iter
TSRMLS_DC)
{
zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
@@ -157,6 +168,14 @@ static void
_breakiterator_parts_move_forward(zend_object_iterator *iter TSRMLS_
return;
}
+ if (zoi_bit->key_type == PARTS_ITERATOR_KEY_LEFT) {
+ iter->index = cur;
+ } else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) {
+ iter->index = next;
+ }
+ /* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL
+ * No need to do anything, the engine increments ->index */
+
const char *s = Z_STRVAL_P(bio->text);
int32_t slen = Z_STRLEN_P(bio->text),
len;
@@ -194,14 +213,15 @@ static zend_object_iterator_funcs
breakiterator_parts_it_funcs = {
zoi_with_current_dtor,
zoi_with_current_valid,
zoi_with_current_get_current_data,
- NULL,
+ _breakiterator_parts_get_current_key,
_breakiterator_parts_move_forward,
_breakiterator_parts_rewind,
zoi_with_current_invalidate_current
};
void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
-
zval *object TSRMLS_DC)
+
zval *object,
+
parts_iter_key_type key_type TSRMLS_DC)
{
IntlIterator_object *ii;
@@ -221,6 +241,7 @@ void IntlIterator_from_BreakIterator_parts(zval
*break_iter_zv,
((zoi_break_iter_parts*)ii->iterator)->bio = (BreakIterator_object*)
zend_object_store_get_object(break_iter_zv TSRMLS_CC);
assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL);
+ ((zoi_break_iter_parts*)ii->iterator)->key_type = key_type;
}
U_CFUNC zend_object_value IntlPartsIterator_object_create(zend_class_entry *ce
TSRMLS_DC)
@@ -312,4 +333,14 @@ U_CFUNC void
breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,
sizeof IntlPartsIterator_handlers);
IntlPartsIterator_handlers.get_method = IntlPartsIterator_get_method;
+
+#define PARTSITER_DECL_LONG_CONST(name) \
+ zend_declare_class_constant_long(IntlPartsIterator_ce_ptr, #name, \
+ sizeof(#name) - 1, PARTS_ITERATOR_ ## name TSRMLS_CC)
+
+ PARTSITER_DECL_LONG_CONST(KEY_SEQUENTIAL);
+ PARTSITER_DECL_LONG_CONST(KEY_LEFT);
+ PARTSITER_DECL_LONG_CONST(KEY_RIGHT);
+
+#undef PARTSITER_DECL_LONG_CONST
}
\ No newline at end of file
diff --git a/ext/intl/breakiterator/breakiterator_iterators.h
b/ext/intl/breakiterator/breakiterator_iterators.h
index 855246f..7162072 100644
--- a/ext/intl/breakiterator/breakiterator_iterators.h
+++ b/ext/intl/breakiterator/breakiterator_iterators.h
@@ -23,9 +23,16 @@ U_CDECL_BEGIN
#include <php.h>
U_CDECL_END
+typedef enum {
+ PARTS_ITERATOR_KEY_SEQUENTIAL,
+ PARTS_ITERATOR_KEY_LEFT,
+ PARTS_ITERATOR_KEY_RIGHT,
+} parts_iter_key_type;
+
#ifdef __cplusplus
void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
-
zval *object TSRMLS_DC);
+
zval *object,
+
parts_iter_key_type key_type TSRMLS_DC);
#endif
U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
diff --git a/ext/intl/breakiterator/breakiterator_methods.cpp
b/ext/intl/breakiterator/breakiterator_methods.cpp
index e9e6b19..7b50252 100644
--- a/ext/intl/breakiterator/breakiterator_methods.cpp
+++ b/ext/intl/breakiterator/breakiterator_methods.cpp
@@ -384,18 +384,28 @@ U_CFUNC PHP_FUNCTION(breakiter_get_locale)
U_CFUNC PHP_FUNCTION(breakiter_get_parts_iterator)
{
+ long key_type = 0;
BREAKITER_METHOD_INIT_VARS;
object = getThis();
- if (zend_parse_parameters_none() == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &key_type)
== FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_parts_iterator: bad arguments", 0
TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (key_type != PARTS_ITERATOR_KEY_SEQUENTIAL
+ && key_type != PARTS_ITERATOR_KEY_LEFT
+ && key_type != PARTS_ITERATOR_KEY_RIGHT) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "breakiter_get_parts_iterator: bad arguments",
0 TSRMLS_CC);
+ "breakiter_get_parts_iterator: bad key type", 0
TSRMLS_CC);
RETURN_FALSE;
}
BREAKITER_METHOD_FETCH_OBJECT;
- IntlIterator_from_BreakIterator_parts(object, return_value TSRMLS_CC);
+ IntlIterator_from_BreakIterator_parts(
+ object, return_value, (parts_iter_key_type)key_type TSRMLS_CC);
}
U_CFUNC PHP_FUNCTION(breakiter_get_error_code)
diff --git a/ext/intl/tests/breakiter_getPartsIterator_error.phpt
b/ext/intl/tests/breakiter_getPartsIterator_error.phpt
new file mode 100644
index 0000000..9737618
--- /dev/null
+++ b/ext/intl/tests/breakiter_getPartsIterator_error.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlBreakIterator::getPartsIterator(): bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$it = IntlBreakIterator::createWordInstance(NULL);
+var_dump($it->getPartsIterator(array()));
+var_dump($it->getPartsIterator(1, 2));
+var_dump($it->getPartsIterator(-1));
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlBreakIterator::getPartsIterator() expects parameter 1 to be long,
array given in %s on line %d
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator:
bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getPartsIterator() expects at most 1 parameter, 2
given in %s on line %d
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator:
bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator:
bad key type in %s on line %d
+bool(false)
+==DONE==
diff --git a/ext/intl/tests/breakiter_getPartsIterator_var1.phpt
b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt
new file mode 100644
index 0000000..7bbd27e
--- /dev/null
+++ b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt
@@ -0,0 +1,60 @@
+--TEST--
+IntlBreakIterator::getPartsIterator(): argument variations
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'foo bar tao';
+
+$it = IntlBreakIterator::createWordInstance(NULL);
+$it->setText($text);
+
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_SEQUENTIAL)));
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_LEFT)));
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_RIGHT)));
+
+?>
+==DONE==
+--EXPECT--
+array(5) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(1) " "
+ [2]=>
+ string(3) "bar"
+ [3]=>
+ string(1) " "
+ [4]=>
+ string(3) "tao"
+}
+array(5) {
+ [0]=>
+ string(3) "foo"
+ [4]=>
+ string(1) " "
+ [5]=>
+ string(3) "bar"
+ [8]=>
+ string(1) " "
+ [9]=>
+ string(3) "tao"
+}
+array(5) {
+ [3]=>
+ string(3) "foo"
+ [5]=>
+ string(1) " "
+ [8]=>
+ string(3) "bar"
+ [9]=>
+ string(1) " "
+ [12]=>
+ string(3) "tao"
+}
+==DONE==
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php