summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2012-06-07 15:20:00 +0200
committerGustavo André dos Santos Lopes <cataphract@php.net>2012-06-10 00:04:53 +0200
commit4ec75539dba8cefef16e56f02c62755a9aa9c60b (patch)
tree21437d4d80b94eb510158b7d31fbbd34bd45ab90
parentc6593a0e9b3ea1a6045f8a52a1b9d8bce4d63773 (diff)
downloadphp-git-4ec75539dba8cefef16e56f02c62755a9aa9c60b.tar.gz
Change in BreakIterator::getPartsIterator()
BreakIterator::getPartsIterator() now returns an IntlIterator subclass with a special method, getBreakIterator(), that returns the associated BreakIterator. Any call to getRuleStatus() is forwarded to the BreakIterator.
-rw-r--r--ext/intl/breakiterator/breakiterator_iterators.cpp99
-rw-r--r--ext/intl/breakiterator/breakiterator_iterators.h16
-rw-r--r--ext/intl/common/common_enum.cpp2
-rw-r--r--ext/intl/common/common_enum.h1
-rwxr-xr-xext/intl/php_intl.c4
-rw-r--r--ext/intl/tests/breakiter_getPartsIterator_basic.phpt6
6 files changed, 115 insertions, 13 deletions
diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp
index 4a0cf1da80..66f4292259 100644
--- a/ext/intl/breakiterator/breakiterator_iterators.cpp
+++ b/ext/intl/breakiterator/breakiterator_iterators.cpp
@@ -18,7 +18,10 @@
#include "config.h"
#endif
+#include <unicode/brkiter.h>
+
#include "breakiterator_iterators.h"
+#include "../common/common_enum.h"
extern "C" {
#define USE_BREAKITERATOR_POINTER
@@ -28,6 +31,9 @@ extern "C" {
#include <zend_exceptions.h>
}
+static zend_class_entry *IntlPartsIterator_ce_ptr;
+static zend_object_handlers IntlPartsIterator_handlers;
+
/* BreakIterator's iterator */
inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter TSRMLS_DC)
@@ -201,7 +207,7 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
zval_add_ref(&break_iter_zv);
- object_init_ex(object, IntlIterator_ce_ptr);
+ object_init_ex(object, IntlPartsIterator_ce_ptr);
ii = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_break_iter_parts));
@@ -216,3 +222,94 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
zend_object_store_get_object(break_iter_zv TSRMLS_CC);
assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL);
}
+
+U_CFUNC zend_object_value IntlPartsIterator_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+
+ retval = IntlIterator_ce_ptr->create_object(ce TSRMLS_CC);
+ retval.handlers = &IntlPartsIterator_handlers;
+
+ return retval;
+}
+
+U_CFUNC zend_function *IntlPartsIterator_get_method(zval **object_ptr,
+ char *method, int method_len, const zend_literal *key TSRMLS_DC)
+{
+ zend_literal local_literal = {0};
+ zend_function *ret;
+ ALLOCA_FLAG(use_heap)
+
+ if (key == NULL) {
+ Z_STRVAL(local_literal.constant) = static_cast<char*>(
+ do_alloca(method_len + 1, use_heap));
+ zend_str_tolower_copy(Z_STRVAL(local_literal.constant),
+ method, method_len);
+ local_literal.hash_value = zend_hash_func(
+ Z_STRVAL(local_literal.constant), method_len + 1);
+ key = &local_literal;
+ }
+
+ if ((key->hash_value & 0xFFFFFFFF) == 0xA2B486A1 /* hash of getrulestatus\0 */
+ && method_len == sizeof("getrulestatus") - 1
+ && memcmp("getrulestatus", Z_STRVAL(key->constant), method_len) == 0) {
+ IntlIterator_object *obj = (IntlIterator_object*)
+ zend_object_store_get_object(*object_ptr TSRMLS_CC);
+ if (obj->iterator && obj->iterator->data) {
+ zval *break_iter_zv = static_cast<zval*>(obj->iterator->data);
+ *object_ptr = break_iter_zv;
+ ret = Z_OBJ_HANDLER_P(break_iter_zv, get_method)(object_ptr,
+ method, method_len, key TSRMLS_CC);
+ goto end;
+ }
+ }
+
+ ret = std_object_handlers.get_method(object_ptr,
+ method, method_len, key TSRMLS_CC);
+
+end:
+ if (key == &local_literal) {
+ free_alloca(Z_STRVAL(local_literal.constant), use_heap);
+ }
+
+ return ret;
+}
+
+U_CFUNC PHP_METHOD(IntlPartsIterator, getBreakIterator)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlPartsIterator::getBreakIterator: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+
+ zval *biter_zval = static_cast<zval*>(ii->iterator->data);
+ RETURN_ZVAL(biter_zval, 1, 0);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_parts_it_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry IntlPartsIterator_class_functions[] = {
+ PHP_ME(IntlPartsIterator, getBreakIterator, ainfo_parts_it_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'BreakIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlPartsIterator", IntlPartsIterator_class_functions);
+ IntlPartsIterator_ce_ptr = zend_register_internal_class_ex(&ce,
+ IntlIterator_ce_ptr, NULL TSRMLS_CC);
+ IntlPartsIterator_ce_ptr->create_object = IntlPartsIterator_object_create;
+
+ memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,
+ sizeof IntlPartsIterator_handlers);
+ IntlPartsIterator_handlers.get_method = IntlPartsIterator_get_method;
+} \ No newline at end of file
diff --git a/ext/intl/breakiterator/breakiterator_iterators.h b/ext/intl/breakiterator/breakiterator_iterators.h
index 4ef5a2f4ef..855246ff77 100644
--- a/ext/intl/breakiterator/breakiterator_iterators.h
+++ b/ext/intl/breakiterator/breakiterator_iterators.h
@@ -16,24 +16,20 @@
#ifndef INTL_BREAKITERATOR_ITERATORS_H
#define INTL_BREAKITERATOR_ITERATORS_H
-#ifndef __cplusplus
-#error Header for C++ only
-#endif
-
-#include <unicode/brkiter.h>
#include <unicode/umachine.h>
-#include "../common/common_enum.h"
-
-extern "C" {
+U_CDECL_BEGIN
#include <math.h>
#include <php.h>
-}
+U_CDECL_END
+#ifdef __cplusplus
void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
zval *object TSRMLS_DC);
+#endif
U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
- zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
+ zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
+U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D);
#endif \ No newline at end of file
diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp
index 6dfacd7e3a..da47a437a6 100644
--- a/ext/intl/common/common_enum.cpp
+++ b/ext/intl/common/common_enum.cpp
@@ -31,7 +31,7 @@ extern "C" {
}
zend_class_entry *IntlIterator_ce_ptr;
-static zend_object_handlers IntlIterator_handlers;
+zend_object_handlers IntlIterator_handlers;
void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC)
{
diff --git a/ext/intl/common/common_enum.h b/ext/intl/common/common_enum.h
index bcd9f44796..4c6abdb8f5 100644
--- a/ext/intl/common/common_enum.h
+++ b/ext/intl/common/common_enum.h
@@ -61,6 +61,7 @@ typedef struct {
} zoi_with_current;
extern zend_class_entry *IntlIterator_ce_ptr;
+extern zend_object_handlers IntlIterator_handlers;
U_CFUNC void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC);
U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC);
diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c
index 5d8aa6be95..c023ba9341 100755
--- a/ext/intl/php_intl.c
+++ b/ext/intl/php_intl.c
@@ -79,6 +79,7 @@
#include "calendar/gregoriancalendar_methods.h"
#include "breakiterator/breakiterator_class.h"
+#include "breakiterator/breakiterator_iterators.h"
#include "idn/idn.h"
@@ -963,6 +964,9 @@ PHP_MINIT_FUNCTION( intl )
/* Register 'BreakIterator' class */
breakiterator_register_BreakIterator_class( TSRMLS_C );
+ /* Register 'IntlPartsIterator' class */
+ breakiterator_register_IntlPartsIterator_class( TSRMLS_C );
+
/* Global error handling. */
intl_error_init( NULL TSRMLS_CC );
diff --git a/ext/intl/tests/breakiter_getPartsIterator_basic.phpt b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt
index 5c23bfdfa7..7a8c316258 100644
--- a/ext/intl/tests/breakiter_getPartsIterator_basic.phpt
+++ b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt
@@ -12,18 +12,22 @@ print_r(iterator_to_array($pi));
$bi->setText("foo bar");
$pi = $bi->getPartsIterator();
+var_dump(get_class($pi->getBreakIterator()));
print_r(iterator_to_array($pi));
+var_dump($pi->getRuleStatus());
?>
==DONE==
--EXPECT--
-string(12) "IntlIterator"
+string(17) "IntlPartsIterator"
Array
(
)
+string(22) "RuleBasedBreakIterator"
Array
(
[0] => foo
[1] =>
[2] => bar
)
+int(0)
==DONE== \ No newline at end of file