Skip to content

Commit 4ec7553

Browse files
committed
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.
1 parent c6593a0 commit 4ec7553

File tree

6 files changed

+115
-13
lines changed

6 files changed

+115
-13
lines changed

ext/intl/breakiterator/breakiterator_iterators.cpp

+98-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
#include "config.h"
1919
#endif
2020

21+
#include <unicode/brkiter.h>
22+
2123
#include "breakiterator_iterators.h"
24+
#include "../common/common_enum.h"
2225

2326
extern "C" {
2427
#define USE_BREAKITERATOR_POINTER
@@ -28,6 +31,9 @@ extern "C" {
2831
#include <zend_exceptions.h>
2932
}
3033

34+
static zend_class_entry *IntlPartsIterator_ce_ptr;
35+
static zend_object_handlers IntlPartsIterator_handlers;
36+
3137
/* BreakIterator's iterator */
3238

3339
inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter TSRMLS_DC)
@@ -201,7 +207,7 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
201207

202208
zval_add_ref(&break_iter_zv);
203209

204-
object_init_ex(object, IntlIterator_ce_ptr);
210+
object_init_ex(object, IntlPartsIterator_ce_ptr);
205211
ii = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
206212

207213
ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_break_iter_parts));
@@ -216,3 +222,94 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
216222
zend_object_store_get_object(break_iter_zv TSRMLS_CC);
217223
assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL);
218224
}
225+
226+
U_CFUNC zend_object_value IntlPartsIterator_object_create(zend_class_entry *ce TSRMLS_DC)
227+
{
228+
zend_object_value retval;
229+
230+
retval = IntlIterator_ce_ptr->create_object(ce TSRMLS_CC);
231+
retval.handlers = &IntlPartsIterator_handlers;
232+
233+
return retval;
234+
}
235+
236+
U_CFUNC zend_function *IntlPartsIterator_get_method(zval **object_ptr,
237+
char *method, int method_len, const zend_literal *key TSRMLS_DC)
238+
{
239+
zend_literal local_literal = {0};
240+
zend_function *ret;
241+
ALLOCA_FLAG(use_heap)
242+
243+
if (key == NULL) {
244+
Z_STRVAL(local_literal.constant) = static_cast<char*>(
245+
do_alloca(method_len + 1, use_heap));
246+
zend_str_tolower_copy(Z_STRVAL(local_literal.constant),
247+
method, method_len);
248+
local_literal.hash_value = zend_hash_func(
249+
Z_STRVAL(local_literal.constant), method_len + 1);
250+
key = &local_literal;
251+
}
252+
253+
if ((key->hash_value & 0xFFFFFFFF) == 0xA2B486A1 /* hash of getrulestatus\0 */
254+
&& method_len == sizeof("getrulestatus") - 1
255+
&& memcmp("getrulestatus", Z_STRVAL(key->constant), method_len) == 0) {
256+
IntlIterator_object *obj = (IntlIterator_object*)
257+
zend_object_store_get_object(*object_ptr TSRMLS_CC);
258+
if (obj->iterator && obj->iterator->data) {
259+
zval *break_iter_zv = static_cast<zval*>(obj->iterator->data);
260+
*object_ptr = break_iter_zv;
261+
ret = Z_OBJ_HANDLER_P(break_iter_zv, get_method)(object_ptr,
262+
method, method_len, key TSRMLS_CC);
263+
goto end;
264+
}
265+
}
266+
267+
ret = std_object_handlers.get_method(object_ptr,
268+
method, method_len, key TSRMLS_CC);
269+
270+
end:
271+
if (key == &local_literal) {
272+
free_alloca(Z_STRVAL(local_literal.constant), use_heap);
273+
}
274+
275+
return ret;
276+
}
277+
278+
U_CFUNC PHP_METHOD(IntlPartsIterator, getBreakIterator)
279+
{
280+
INTLITERATOR_METHOD_INIT_VARS;
281+
282+
if (zend_parse_parameters_none() == FAILURE) {
283+
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
284+
"IntlPartsIterator::getBreakIterator: bad arguments", 0 TSRMLS_CC);
285+
return;
286+
}
287+
288+
INTLITERATOR_METHOD_FETCH_OBJECT;
289+
290+
zval *biter_zval = static_cast<zval*>(ii->iterator->data);
291+
RETURN_ZVAL(biter_zval, 1, 0);
292+
}
293+
294+
ZEND_BEGIN_ARG_INFO_EX(ainfo_parts_it_void, 0, 0, 0)
295+
ZEND_END_ARG_INFO()
296+
297+
static const zend_function_entry IntlPartsIterator_class_functions[] = {
298+
PHP_ME(IntlPartsIterator, getBreakIterator, ainfo_parts_it_void, ZEND_ACC_PUBLIC)
299+
PHP_FE_END
300+
};
301+
302+
U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
303+
{
304+
zend_class_entry ce;
305+
306+
/* Create and register 'BreakIterator' class. */
307+
INIT_CLASS_ENTRY(ce, "IntlPartsIterator", IntlPartsIterator_class_functions);
308+
IntlPartsIterator_ce_ptr = zend_register_internal_class_ex(&ce,
309+
IntlIterator_ce_ptr, NULL TSRMLS_CC);
310+
IntlPartsIterator_ce_ptr->create_object = IntlPartsIterator_object_create;
311+
312+
memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,
313+
sizeof IntlPartsIterator_handlers);
314+
IntlPartsIterator_handlers.get_method = IntlPartsIterator_get_method;
315+
}

ext/intl/breakiterator/breakiterator_iterators.h

+6-10
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,20 @@
1616
#ifndef INTL_BREAKITERATOR_ITERATORS_H
1717
#define INTL_BREAKITERATOR_ITERATORS_H
1818

19-
#ifndef __cplusplus
20-
#error Header for C++ only
21-
#endif
22-
23-
#include <unicode/brkiter.h>
2419
#include <unicode/umachine.h>
2520

26-
#include "../common/common_enum.h"
27-
28-
extern "C" {
21+
U_CDECL_BEGIN
2922
#include <math.h>
3023
#include <php.h>
31-
}
24+
U_CDECL_END
3225

26+
#ifdef __cplusplus
3327
void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
3428
zval *object TSRMLS_DC);
29+
#endif
3530

3631
U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
37-
zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
32+
zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
33+
U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D);
3834

3935
#endif

ext/intl/common/common_enum.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extern "C" {
3131
}
3232

3333
zend_class_entry *IntlIterator_ce_ptr;
34-
static zend_object_handlers IntlIterator_handlers;
34+
zend_object_handlers IntlIterator_handlers;
3535

3636
void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC)
3737
{

ext/intl/common/common_enum.h

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct {
6161
} zoi_with_current;
6262

6363
extern zend_class_entry *IntlIterator_ce_ptr;
64+
extern zend_object_handlers IntlIterator_handlers;
6465

6566
U_CFUNC void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC);
6667
U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC);

ext/intl/php_intl.c

+4
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include "calendar/gregoriancalendar_methods.h"
8080

8181
#include "breakiterator/breakiterator_class.h"
82+
#include "breakiterator/breakiterator_iterators.h"
8283

8384
#include "idn/idn.h"
8485

@@ -963,6 +964,9 @@ PHP_MINIT_FUNCTION( intl )
963964
/* Register 'BreakIterator' class */
964965
breakiterator_register_BreakIterator_class( TSRMLS_C );
965966

967+
/* Register 'IntlPartsIterator' class */
968+
breakiterator_register_IntlPartsIterator_class( TSRMLS_C );
969+
966970
/* Global error handling. */
967971
intl_error_init( NULL TSRMLS_CC );
968972

ext/intl/tests/breakiter_getPartsIterator_basic.phpt

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ print_r(iterator_to_array($pi));
1212

1313
$bi->setText("foo bar");
1414
$pi = $bi->getPartsIterator();
15+
var_dump(get_class($pi->getBreakIterator()));
1516
print_r(iterator_to_array($pi));
17+
var_dump($pi->getRuleStatus());
1618
?>
1719
==DONE==
1820
--EXPECT--
19-
string(12) "IntlIterator"
21+
string(17) "IntlPartsIterator"
2022
Array
2123
(
2224
)
25+
string(22) "RuleBasedBreakIterator"
2326
Array
2427
(
2528
[0] => foo
2629
[1] =>
2730
[2] => bar
2831
)
32+
int(0)
2933
==DONE==

0 commit comments

Comments
 (0)