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

Reply via email to