24#include <unicode/utypes.h>
25#include <unicode/utf8.h>
26#include <unicode/ucol.h>
27#include <unicode/ustring.h>
28#include <unicode/ubrk.h>
37 UChar* ustring =
NULL;
55 if ( U_FAILURE(
status ) ) {
84 char *haystack, *needle;
85 size_t haystack_len, needle_len;
105 offset = (int32_t) loffset;
114 found =
php_memnstr(haystack + noffset, needle, needle_len, haystack + haystack_len);
126 if ( ret_pos >= 0 ) {
137 char *haystack, *needle;
138 size_t haystack_len, needle_len;
158 offset = (int32_t) loffset;
165 char *haystack_dup, *needle_dup;
167 needle_dup =
estrndup(needle, needle_len);
169 haystack_dup =
estrndup(haystack, haystack_len);
172 found =
php_memnstr(haystack_dup + noffset, needle_dup, needle_len, haystack_dup + haystack_len);
190 if ( ret_pos >= 0 ) {
202 char *haystack, *needle;
203 size_t haystack_len, needle_len;
222 offset = (int32_t) loffset;
232 if ( ret_pos >= 0 ) {
247 if ( ret_pos >= 0 ) {
260 char *haystack, *needle;
261 size_t haystack_len, needle_len;
280 offset = (int32_t) loffset;
287 char *needle_dup, *haystack_dup;
289 needle_dup =
estrndup(needle, needle_len);
291 haystack_dup =
estrndup(haystack, haystack_len);
299 if ( ret_pos >= 0 ) {
314 if ( ret_pos >= 0 ) {
336 unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
337 UBreakIterator* bi =
NULL;
338 int sub_str_start_pos, sub_str_end_pos;
339 int32_t (*iter_func)(UBreakIterator *);
340 bool no_length =
true;
349 if (lstart < INT32_MIN || lstart > INT32_MAX) {
354 start = (int32_t) lstart;
360 if (length < INT32_MIN || length > INT32_MAX) {
368 int32_t asub_str_len;
372 if (
NULL == sub_str ) {
385 if ( U_FAILURE(
status ) ) {
403 ubrk_setText(bi, ustr, ustr_len, &
status);
406 iter_func = ubrk_previous;
411 iter_func = ubrk_next;
415 sub_str_start_pos = 0;
418 sub_str_start_pos = iter_func(bi);
420 if ( UBRK_DONE == sub_str_start_pos ) {
436 sub_str_start_pos = 0;
441 if (length >= (int32_t)str_len) {
480 iter_func = ubrk_previous;
485 iter_func = ubrk_next;
492 sub_str_end_pos = iter_func(bi);
494 if ( UBRK_DONE == sub_str_end_pos ) {
503 if ( UBRK_DONE == sub_str_end_pos) {
508 sub_str_end_pos = ustr_len;
512 if (sub_str_start_pos > sub_str_end_pos) {
540 char *haystack, *needle;
542 size_t haystack_len, needle_len;
543 int32_t ret_pos, uchar_pos;
553 if ( !f_ignore_case ) {
556 found =
php_memnstr(haystack, needle, needle_len, haystack + haystack_len);
565 size_t found_offset = found - haystack;
577 ret_pos =
grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, 0, &uchar_pos, f_ignore_case, 0 );
586 U8_FWD_N(haystack, ret_pos, haystack_len, uchar_pos);
613grapheme_extract_charcount_iter(UBreakIterator *bi, int32_t csize,
unsigned char *pstr, int32_t str_len)
617 int break_pos, prev_break_pos;
623 if ( UBRK_DONE ==
pos ) {
627 for ( break_pos = ret_pos; break_pos <
pos; ) {
629 prev_break_pos = break_pos;
630 U8_FWD_1(pstr, break_pos, str_len);
632 if ( prev_break_pos == break_pos ) {
640 if (
count > csize ) {
653grapheme_extract_bytecount_iter(UBreakIterator *bi, int32_t bsize,
unsigned char *pstr, int32_t str_len)
661 if ( UBRK_DONE ==
pos ) {
678grapheme_extract_count_iter(UBreakIterator *bi, int32_t
size,
unsigned char *pstr, int32_t str_len)
684 next_pos = ubrk_next(bi);
686 if ( UBRK_DONE == next_pos ) {
701 &grapheme_extract_count_iter,
702 &grapheme_extract_bytecount_iter,
703 &grapheme_extract_charcount_iter,
711 UText ut = UTEXT_INITIALIZER;
718 unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
719 UBreakIterator* bi =
NULL;
749 if ( lstart > INT32_MAX || lstart < 0 || (
size_t)lstart >= str_len ) {
759 if (
size > INT32_MAX) {
769 start = (int32_t) lstart;
774 if ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
775 char *str_end = str + str_len;
777 while ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
779 if ( pstr >= str_end ) {
781 "grapheme_extract: invalid input string", 0 );
788 str_len -= (pstr - str);
795 size_t nsize =
MIN(
size, str_len);
803 utext_openUTF8(&ut, pstr, str_len, &
status);
805 if ( U_FAILURE(
status ) ) {
819 ubrk_setUText(bi, &ut, &
status);
825 ret_pos = (*grapheme_extract_iters[extract_type])(bi,
size, (
unsigned char *)pstr, (int32_t)str_len);
843 unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
855 if (split_len <= 0 || split_len > UINT_MAX / 4) {
865 ut = utext_openUTF8(ut, pstr,
ZSTR_LEN(str), &ustatus);
867 if ( U_FAILURE( ustatus ) ) {
881 if( U_FAILURE(ustatus) ) {
885 ubrk_setUText(bi, ut, &ustatus);
894 if (i == split_len - 1) {
895 if (
pos != UBRK_DONE ) {
907 if (i != 0 && end_len != 0) {
count(Countable|array $value, int $mode=COUNT_NORMAL)
const U_ILLEGAL_ARGUMENT_ERROR
#define GRAPHEME_EXTRACT_TYPE_MAX
#define GRAPHEME_EXTRACT_TYPE_COUNT
int32_t(* grapheme_extract_iter)(UBreakIterator *, int32_t, unsigned char *, int32_t)
zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset)
int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case, int last)
void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char **sub_str, int32_t *sub_str_len)
int32_t grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len)
UBreakIterator * grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status)
zend_long grapheme_ascii_check(const unsigned char *day, size_t len)
#define OUTSIDE_STRING(offset, max_len)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
void intl_convert_utf8_to_utf16(UChar **target, int32_t *target_len, const char *src, size_t src_len, UErrorCode *status)
zend_string * intl_convert_utf16_to_utf8(const UChar *src, int32_t src_len, UErrorCode *status)
void intl_error_set(intl_error *err, UErrorCode code, const char *msg, int copyMsg)
void intl_error_set_code(intl_error *err, UErrorCode err_code)
void intl_error_set_custom_msg(intl_error *err, const char *msg, int copyMsg)
unsigned const char * end
unsigned const char * pos
grapheme_substr(string $string, int $offset, ?int $length=null)
grapheme_extract(string $haystack, int $size, int $type=GRAPHEME_EXTR_COUNT, int $offset=0, &$next=null)
grapheme_strstr(string $haystack, string $needle, bool $beforeNeedle=false)
grapheme_stristr(string $haystack, string $needle, bool $beforeNeedle=false)
grapheme_strlen(string $string)
grapheme_strripos(string $haystack, string $needle, int $offset=0)
grapheme_stripos(string $haystack, string $needle, int $offset=0)
grapheme_strpos(string $haystack, string $needle, int $offset=0)
grapheme_str_split(string $string, int $length=1)
grapheme_strrpos(string $haystack, string $needle, int $offset=0)
#define INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
#define RETURN_STRINGL(s, l)
#define ZEND_PARSE_PARAMETERS_END()
#define RETVAL_NEW_STR(s)
#define Z_PARAM_STRING(dest, dest_len)
#define Z_PARAM_STR(dest)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
#define Z_PARAM_LONG(dest)
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
#define Z_PARAM_BOOL(dest)
#define RETURN_EMPTY_ARRAY()
#define RETURN_EMPTY_STRING()
#define Z_PARAM_ZVAL(dest)
#define estrndup(s, length)
struct _zend_string zend_string
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
#define UNEXPECTED(condition)
#define Z_ISREF_P(zval_p)