/* Return value is a "Win32 BOOL" (1 = true, 0 = false) */ extern "C" int32_t EndsWith( SortHandle* pSortHandle, const UChar* lpTarget, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, int32_t options) { int32_t result = FALSE; UErrorCode err = U_ZERO_ERROR; const UCollator* pColl = GetCollatorFromSortHandle(pSortHandle, options, &err); if (U_SUCCESS(err)) { UStringSearch* pSearch = usearch_openFromCollator(lpTarget, cwTargetLength, lpSource, cwSourceLength, pColl, nullptr, &err); int32_t idx = USEARCH_DONE; if (U_SUCCESS(err)) { idx = usearch_last(pSearch, &err); if (idx != USEARCH_DONE) { if ((idx + usearch_getMatchedLength(pSearch)) == cwSourceLength) { result = TRUE; } // TODO (dotnet/corefx#3467): We should do something similar to what // StartsWith does where we can ignore // some collation elements at the end of the string if they are zero. } usearch_close(pSearch); } } return result; }
/* Function: LastIndexOf */ extern "C" int32_t LastIndexOf( SortHandle* pSortHandle, const UChar* lpTarget, int32_t cwTargetLength, const UChar* lpSource, int32_t cwSourceLength, int32_t options) { static_assert(USEARCH_DONE == -1, "managed side requires -1 for not found"); int32_t result = USEARCH_DONE; UErrorCode err = U_ZERO_ERROR; const UCollator* pColl = GetCollatorFromSortHandle(pSortHandle, options, &err); if (U_SUCCESS(err)) { UStringSearch* pSearch = usearch_openFromCollator(lpTarget, cwTargetLength, lpSource, cwSourceLength, pColl, nullptr, &err); if (U_SUCCESS(err)) { result = usearch_last(pSearch, &err); usearch_close(pSearch); } } return result; }
Boolean CFStringFindWithOptionsAndLocale (CFStringRef str, CFStringRef stringToFind, CFRange rangeToSearch, CFStringCompareFlags searchOptions, CFLocaleRef locale, CFRange *result) { UniChar *pattern; UniChar *text; CFIndex patternLength; CFIndex textLength; CFIndex start; CFIndex end; CFAllocatorRef alloc; UCollator *ucol; UStringSearch *usrch; UErrorCode err = U_ZERO_ERROR; if (rangeToSearch.length == 0) return false; alloc = CFAllocatorGetDefault (); textLength = CFStringGetLength (stringToFind); if (textLength == 0) return false; patternLength = rangeToSearch.length; pattern = CFAllocatorAllocate (alloc, patternLength * sizeof(UniChar), 0); CFStringGetCharacters (str, rangeToSearch, pattern); text = CFAllocatorAllocate (alloc, textLength * sizeof(UniChar), 0); CFStringGetCharacters (stringToFind, CFRangeMake(0, textLength), text); ucol = CFStringICUCollatorOpen (searchOptions, locale); usrch = usearch_openFromCollator (text, textLength, pattern, patternLength, ucol, NULL, &err); if (U_FAILURE(err)) return false; /* FIXME: need to handle kCFCompareAnchored */ if (searchOptions & kCFCompareBackwards) { start = usearch_last (usrch, &err); } else { start = usearch_first (usrch, &err); } if (start == USEARCH_DONE) { CFAllocatorDeallocate (alloc, pattern); CFAllocatorDeallocate (alloc, text); return false; } end = usearch_getMatchedLength (usrch); usearch_close (usrch); CFStringICUCollatorClose (ucol); if (result) *result = CFRangeMake (start + rangeToSearch.location, end); CFAllocatorDeallocate (alloc, pattern); CFAllocatorDeallocate (alloc, text); return true; }
/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/ 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) { UChar *uhaystack = NULL, *uneedle = NULL; int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0; unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; UBreakIterator* bi = NULL; UErrorCode status; UStringSearch* src = NULL; UCollator *coll; if(puchar_pos) { *puchar_pos = -1; } /* convert the strings to UTF-16. */ status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, haystack, haystack_len, &status ); STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16"); status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, needle, needle_len, &status ); STRPOS_CHECK_STATUS(status, "Error converting needle string to UTF-16"); /* get a pointer to the haystack taking into account the offset */ status = U_ZERO_ERROR; bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); STRPOS_CHECK_STATUS(status, "Failed to get iterator"); status = U_ZERO_ERROR; ubrk_setText(bi, uhaystack, uhaystack_len, &status); STRPOS_CHECK_STATUS(status, "Failed to set up iterator"); status = U_ZERO_ERROR; src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len, "", bi, &status); STRPOS_CHECK_STATUS(status, "Error creating search object"); if(f_ignore_case) { coll = usearch_getCollator(src); status = U_ZERO_ERROR; ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &status); STRPOS_CHECK_STATUS(status, "Error setting collation strength"); usearch_reset(src); } if(offset != 0) { offset_pos = grapheme_get_haystack_offset(bi, offset); if(offset_pos == -1) { status = U_ILLEGAL_ARGUMENT_ERROR; STRPOS_CHECK_STATUS(status, "Invalid search offset"); } status = U_ZERO_ERROR; usearch_setOffset(src, offset_pos, &status); STRPOS_CHECK_STATUS(status, "Invalid search offset"); } if(last) { char_pos = usearch_last(src, &status); if(char_pos < offset_pos) { /* last one is beyound our start offset */ char_pos = USEARCH_DONE; } } else { char_pos = usearch_next(src, &status); } STRPOS_CHECK_STATUS(status, "Error looking up string"); if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) { ret_pos = grapheme_count_graphemes(bi, uhaystack,char_pos); if(puchar_pos) { *puchar_pos = char_pos; } } else { ret_pos = -1; } if (uhaystack) { efree( uhaystack ); } if (uneedle) { efree( uneedle ); } ubrk_close (bi); usearch_close (src); return ret_pos; }