25#include <unicode/utypes.h>
26#include <unicode/ucol.h>
27#include <unicode/ustring.h>
28#include <unicode/ubrk.h>
29#include <unicode/usearch.h>
41 if (
NULL != global_break_iterator ) {
42 ubrk_close(global_break_iterator);
48void grapheme_substr_ascii(
char *str,
size_t str_len, int32_t f, int32_t l,
char **sub_str, int32_t *sub_str_len)
50 int32_t str_len2 = (int32_t)str_len;
53 if(str_len > INT32_MAX) {
66 }
else if (f > str_len2) {
74 l = (str_len2 - f) + l;
78 }
else if (l > str_len2 - f) {
87#define STRPOS_CHECK_STATUS(status, error) \
88 if ( U_FAILURE( (status) ) ) { \
89 intl_error_set_code( NULL, (status) ); \
90 intl_error_set_custom_msg( NULL, (error), 0 ); \
97int32_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)
99 UChar *uhaystack =
NULL, *uneedle =
NULL;
100 int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0;
101 unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
102 UBreakIterator* bi =
NULL;
104 UStringSearch* src =
NULL;
124 ubrk_setText(bi, uhaystack, uhaystack_len, &
status);
127 if (uneedle_len == 0) {
129 if (offset_pos == -1) {
134 ret_pos =
last &&
offset >= 0 ? uhaystack_len : offset_pos;
139 src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len,
"", bi, &
status);
143 UCollator *coll = usearch_getCollator(src);
145 ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &
status);
152 if (offset_pos == -1) {
158 usearch_setOffset(src,
last ? 0 : offset_pos, &
status);
165 char_pos = usearch_last(src, &
status);
166 if(char_pos < offset_pos) {
168 char_pos = USEARCH_DONE;
172 int32_t prev_pos = USEARCH_DONE;
174 char_pos = usearch_next(src, &
status);
175 if (char_pos == USEARCH_DONE || char_pos > offset_pos) {
183 char_pos = usearch_next(src, &
status);
186 if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) {
189 *puchar_pos = char_pos;
219 if ( *day++ > 0x7f || (*day ==
'\n' && *(day - 1) ==
'\r') )
231 unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
246 for ( ret_len = 0;
pos != UBRK_DONE; ) {
250 if (
pos != UBRK_DONE ) {
252 if (
NULL != boundary_array && ret_len < boundary_array_len ) {
253 boundary_array[ret_len] =
pos;
273 ubrk_setText(bi,
string, string_len, &
status);
279 if ( UBRK_DONE !=
pos ) {
283 }
while ( UBRK_DONE !=
pos );
294 int32_t (*iter_op)(UBreakIterator* bi);
302 iter_op = ubrk_previous;
313 while (
pos != UBRK_DONE &&
offset != 0 ) {
317 if ( UBRK_DONE !=
pos ) {
337 e = haystack + haystack_len - needle_len;
340 if (needle_len > (
size_t)-
offset) {
341 e = haystack + haystack_len - needle_len;
343 e = haystack + haystack_len +
offset;
347 if (needle_len == 1) {
359 if (memcmp(e, needle, needle_len) == 0) {
375 if (
NULL == global_break_iterator ) {
377 global_break_iterator = ubrk_open(UBRK_CHARACTER,
386#if U_ICU_VERSION_MAJOR_NUM >= 69
387 return ubrk_clone(global_break_iterator,
status);
389 int32_t buffer_size = U_BRK_SAFECLONE_BUFFERSIZE;
391 return ubrk_safeClone(global_break_iterator, stack_buffer, &buffer_size,
status);
zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset)
int32_t grapheme_get_haystack_offset(UBreakIterator *bi, int32_t offset)
#define STRPOS_CHECK_STATUS(status, error)
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)
int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len)
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)
void grapheme_close_global_iterator(void)
UBreakIterator * grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status)
zend_long grapheme_ascii_check(const unsigned char *day, size_t len)
void intl_convert_utf8_to_utf16(UChar **target, int32_t *target_len, const char *src, size_t src_len, UErrorCode *status)
unsigned const char * pos
unsigned const char * text
UBreakIterator * grapheme_iterator
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)