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.
This commit is contained in:
Gustavo André dos Santos Lopes 2012-06-07 15:20:00 +02:00
parent c6593a0e9b
commit 4ec75539db
6 changed files with 115 additions and 13 deletions

View file

@ -18,7 +18,10 @@
#include "config.h" #include "config.h"
#endif #endif
#include <unicode/brkiter.h>
#include "breakiterator_iterators.h" #include "breakiterator_iterators.h"
#include "../common/common_enum.h"
extern "C" { extern "C" {
#define USE_BREAKITERATOR_POINTER #define USE_BREAKITERATOR_POINTER
@ -28,6 +31,9 @@ extern "C" {
#include <zend_exceptions.h> #include <zend_exceptions.h>
} }
static zend_class_entry *IntlPartsIterator_ce_ptr;
static zend_object_handlers IntlPartsIterator_handlers;
/* BreakIterator's iterator */ /* BreakIterator's iterator */
inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter TSRMLS_DC) 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); 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 = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_break_iter_parts)); 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); zend_object_store_get_object(break_iter_zv TSRMLS_CC);
assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL); 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;
}

View file

@ -16,24 +16,20 @@
#ifndef INTL_BREAKITERATOR_ITERATORS_H #ifndef INTL_BREAKITERATOR_ITERATORS_H
#define 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 <unicode/umachine.h>
#include "../common/common_enum.h" U_CDECL_BEGIN
extern "C" {
#include <math.h> #include <math.h>
#include <php.h> #include <php.h>
} U_CDECL_END
#ifdef __cplusplus
void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv, void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
zval *object TSRMLS_DC); zval *object TSRMLS_DC);
#endif
U_CFUNC zend_object_iterator *_breakiterator_get_iterator( 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 #endif

View file

@ -31,7 +31,7 @@ extern "C" {
} }
zend_class_entry *IntlIterator_ce_ptr; 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) void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC)
{ {

View file

@ -61,6 +61,7 @@ typedef struct {
} zoi_with_current; } zoi_with_current;
extern zend_class_entry *IntlIterator_ce_ptr; 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 void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC);
U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC); U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC);

View file

@ -79,6 +79,7 @@
#include "calendar/gregoriancalendar_methods.h" #include "calendar/gregoriancalendar_methods.h"
#include "breakiterator/breakiterator_class.h" #include "breakiterator/breakiterator_class.h"
#include "breakiterator/breakiterator_iterators.h"
#include "idn/idn.h" #include "idn/idn.h"
@ -963,6 +964,9 @@ PHP_MINIT_FUNCTION( intl )
/* Register 'BreakIterator' class */ /* Register 'BreakIterator' class */
breakiterator_register_BreakIterator_class( TSRMLS_C ); breakiterator_register_BreakIterator_class( TSRMLS_C );
/* Register 'IntlPartsIterator' class */
breakiterator_register_IntlPartsIterator_class( TSRMLS_C );
/* Global error handling. */ /* Global error handling. */
intl_error_init( NULL TSRMLS_CC ); intl_error_init( NULL TSRMLS_CC );

View file

@ -12,18 +12,22 @@ print_r(iterator_to_array($pi));
$bi->setText("foo bar"); $bi->setText("foo bar");
$pi = $bi->getPartsIterator(); $pi = $bi->getPartsIterator();
var_dump(get_class($pi->getBreakIterator()));
print_r(iterator_to_array($pi)); print_r(iterator_to_array($pi));
var_dump($pi->getRuleStatus());
?> ?>
==DONE== ==DONE==
--EXPECT-- --EXPECT--
string(12) "IntlIterator" string(17) "IntlPartsIterator"
Array Array
( (
) )
string(22) "RuleBasedBreakIterator"
Array Array
( (
[0] => foo [0] => foo
[1] => [1] =>
[2] => bar [2] => bar
) )
int(0)
==DONE== ==DONE==