1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2001-2010, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: ustrcase.c 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created on: 2002feb20 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Markus W. Scherer 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Implementation file for string casing C API functions. 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Uses functions from uchar.c for basic functionality that requires access 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* to the Unicode Character Database (uprops.dat). 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uloc.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucasemap.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ubrk.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucase.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_imp.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* string casing ------------------------------------------------------------ */ 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* append a full case mapping result, see UCASE_MAX_STRING_LENGTH */ 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_INLINE int32_t 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)appendResult(UChar *dest, int32_t destIndex, int32_t destCapacity, 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t result, const UChar *s) { 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* decode the result */ 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(result<0) { 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* (not) original code point */ 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=~result; 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=-1; 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(result<=UCASE_MAX_STRING_LENGTH) { 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=U_SENTINEL; 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=result; 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=result; 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=-1; 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destIndex<destCapacity) { 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* append the result */ 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<0) { 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* code point */ 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isError=FALSE; 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_APPEND(dest, destIndex, destCapacity, c, isError); 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(isError) { 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* overflow, nothing written */ 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=U16_LENGTH(c); 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* string */ 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destIndex+length)<=destCapacity) { 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(length>0) { 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destIndex++]=*s++; 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --length; 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* overflow */ 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=length; 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* preflight */ 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<0) { 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=U16_LENGTH(c); 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=length; 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return destIndex; 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UChar32 U_CALLCONV 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)utf16_caseContextIterator(void *context, int8_t dir) { 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseContext *csc=(UCaseContext *)context; 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(dir<0) { 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reset for backward iteration */ 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->index=csc->cpStart; 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->dir=dir; 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(dir>0) { 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reset for forward iteration */ 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->index=csc->cpLimit; 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->dir=dir; 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* continue current iteration direction */ 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dir=csc->dir; 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(dir<0) { 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(csc->start<csc->index) { 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_PREV((const UChar *)csc->p, csc->start, csc->index, c); 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return c; 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(csc->index<csc->limit) { 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT((const UChar *)csc->p, csc->index, csc->limit, c); 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return c; 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return U_SENTINEL; 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Case-maps [srcStart..srcLimit[ but takes 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * context [0..srcLength[ into account. 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_caseMap(const UCaseMap *csm, UCaseMapFull *map, 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, UCaseContext *csc, 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcStart, int32_t srcLimit, 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s; 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c, c2 = 0; 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcIndex, destIndex; 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t locCache; 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) locCache=csm->locCache; 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* case mapping loop */ 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIndex=srcStart; 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=0; 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(srcIndex<srcLimit) { 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->cpStart=srcIndex; 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(src, srcIndex, srcLimit, c); 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->cpLimit=srcIndex; 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=map(csm->csp, c, utf16_caseContextIterator, csc, &s, csm->locale, &locCache); 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) { 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* fast path version of appendResult() for BMP results */ 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destIndex++]=(UChar)c2; 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=appendResult(dest, destIndex, destCapacity, c, s); 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destIndex>destCapacity) { 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return destIndex; 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)setTempCaseMapLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) { 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * We could call ucasemap_setLocale(), but here we really only care about 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the initial language subtag, we need not return the real string via 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ucasemap_getLocale(), and we don't care about only getting "x" from 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "x-some-thing" etc. 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * We ignore locales with a longer-than-3 initial subtag. 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * We also do not fill in the locCache because it is rarely used, 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and not worth setting unless we reuse it for many case mapping operations. 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * (That's why UCaseMap was created.) 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int i; 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char c; 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* the internal functions require locale!=NULL */ 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(locale==NULL) { 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) locale=uloc_getDefault(); 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<4 && (c=locale[i])!=0 && c!='-' && c!='_'; ++i) { 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->locale[i]=c; 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i<=3) { 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->locale[i]=0; /* Up to 3 non-separator characters. */ 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->locale[0]=0; /* Longer-than-3 initial subtag: Ignore. */ 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Set parameters on an empty UCaseMap, for UCaseMap-less API functions. 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Do this fast because it is called with every function call. 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_INLINE void 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)setTempCaseMap(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) { 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(csm->csp==NULL) { 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->csp=ucase_getSingleton(); 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(locale!=NULL && locale[0]==0) { 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->locale[0]=0; 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMapLocale(csm, locale, pErrorCode); 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Internal titlecasing function. 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_toTitle(UCaseMap *csm, 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, UCaseContext *csc, 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLength, 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s; 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prev, titleStart, titleLimit, idx, destIndex, length; 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isFirstIndex; 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(csm->iter!=NULL) { 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ubrk_setText(csm->iter, src, srcLength, pErrorCode); 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->iter=ubrk_open(UBRK_WORD, csm->locale, 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set up local variables */ 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=0; 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev=0; 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) isFirstIndex=TRUE; 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* titlecasing loop */ 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(prev<srcLength) { 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find next index where to titlecase */ 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(isFirstIndex) { 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) isFirstIndex=FALSE; 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idx=ubrk_first(csm->iter); 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idx=ubrk_next(csm->iter); 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(idx==UBRK_DONE || idx>srcLength) { 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idx=srcLength; 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Unicode 4 & 5 section 3.13 Default Case Operations: 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * R3 toTitlecase(X): Find the word boundaries based on Unicode Standard Annex 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #29, "Text Boundaries." Between each pair of word boundaries, find the first 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * cased character F. If F exists, map F to default_title(F); then map each 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * subsequent character C to default_lower(C). 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * In this implementation, segment [prev..index[ into 3 parts: 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a) uncased characters (copy as-is) [prev..titleStart[ 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * b) first case letter (titlecase) [titleStart..titleLimit[ 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * c) subsequent characters (lowercase) [titleLimit..index[ 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(prev<idx) { 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find and copy uncased characters [prev..titleStart[ */ 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) titleStart=titleLimit=prev; 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(src, titleLimit, idx, c); 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((csm->options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0 && UCASE_NONE==ucase_getType(csm->csp, c)) { 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Adjust the titlecasing index (titleStart) to the next cased character. */ 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) titleStart=titleLimit; 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(titleLimit==idx) { 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * only uncased characters in [prev..index[ 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * stop with titleStart==titleLimit==index 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(src, titleLimit, idx, c); 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UCASE_NONE!=ucase_getType(csm->csp, c)) { 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; /* cased letter at [titleStart..titleLimit[ */ 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=titleStart-prev; 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length>0) { 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destIndex+length)<=destCapacity) { 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest+destIndex, src+prev, length*U_SIZEOF_UCHAR); 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=length; 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(titleStart<titleLimit) { 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* titlecase c which is from [titleStart..titleLimit[ */ 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->cpStart=titleStart; 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc->cpLimit=titleLimit; 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=ucase_toFullTitle(csm->csp, c, utf16_caseContextIterator, csc, &s, csm->locale, &csm->locCache); 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=appendResult(dest, destIndex, destCapacity, c, s); 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Special case Dutch IJ titlecasing */ 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ( titleStart+1 < idx && 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucase_getCaseLocale(csm->locale,&csm->locCache) == UCASE_LOC_DUTCH && 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ( src[titleStart] == (UChar32) 0x0049 || src[titleStart] == (UChar32) 0x0069 ) && 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ( src[titleStart+1] == (UChar32) 0x004A || src[titleStart+1] == (UChar32) 0x006A )) { 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=(UChar32) 0x004A; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=appendResult(dest, destIndex, destCapacity, c, s); 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) titleLimit++; 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* lowercase [titleLimit..index[ */ 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(titleLimit<idx) { 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((csm->options&U_TITLECASE_NO_LOWERCASE)==0) { 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Normal operation: Lowercase the rest of the word. */ 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+= 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _caseMap( 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm, ucase_toFullLower, 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest+destIndex, destCapacity-destIndex, 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, csc, 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) titleLimit, idx, 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Optionally just copy the rest of the word unchanged. */ 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=idx-titleLimit; 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destIndex+length)<=destCapacity) { 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest+destIndex, src+titleLimit, length*U_SIZEOF_UCHAR); 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex+=length; 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev=idx; 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destIndex>destCapacity) { 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return destIndex; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* functions available in the common library (for unistr_case.cpp) */ 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ustr_toLower(const UCaseProps *csp, 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseContext csc={ NULL }; 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.csp=csp; 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.p=(void *)src; 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.limit=srcLength; 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return _caseMap(&csm, ucase_toFullLower, 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, 0, srcLength, 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ustr_toUpper(const UCaseProps *csp, 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseContext csc={ NULL }; 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.csp=csp; 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.p=(void *)src; 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.limit=srcLength; 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return _caseMap(&csm, ucase_toFullUpper, 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, 0, srcLength, 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ustr_toTitle(const UCaseProps *csp, 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBreakIterator *titleIter, 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, uint32_t options, 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseContext csc={ NULL }; 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.csp=csp; 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.iter=titleIter; 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.options=options; 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.p=(void *)src; 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.limit=srcLength; 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=_toTitle(&csm, 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, srcLength, 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(titleIter==NULL && csm.iter!=NULL) { 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ubrk_close(csm.iter); 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ustr_foldCase(const UCaseProps *csp, 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t options, 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcIndex, destIndex; 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s; 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c, c2 = 0; 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* case mapping loop */ 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIndex=destIndex=0; 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(srcIndex<srcLength) { 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(src, srcIndex, srcLength, c); 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=ucase_toFullFolding(csp, c, &s, options); 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) { 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* fast path version of appendResult() for BMP results */ 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destIndex++]=(UChar)c2; 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destIndex=appendResult(dest, destIndex, destCapacity, c, s); 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destIndex>destCapacity) { 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return destIndex; 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Implement argument checking and buffer handling 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * for string case mapping as a common function. 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* common internal function for public API functions */ 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)caseMap(const UCaseMap *csm, 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t toWhichCase, 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar buffer[300]; 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *temp; 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t destLength; 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check argument values */ 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( destCapacity<0 || 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (dest==NULL && destCapacity>0) || 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src==NULL || 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength<-1 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the string length */ 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength==-1) { 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength=u_strlen(src); 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check for overlapping source and destination */ 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( dest!=NULL && 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((src>=dest && src<(dest+destCapacity)) || 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (dest>=src && dest<(src+srcLength))) 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* overlap: provide a temporary destination buffer and later copy the result */ 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destCapacity<=(sizeof(buffer)/U_SIZEOF_UCHAR)) { 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* the stack buffer is large enough */ 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp=buffer; 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* allocate a buffer */ 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp=(UChar *)uprv_malloc(destCapacity*U_SIZEOF_UCHAR); 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(temp==NULL) { 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp=dest; 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=0; 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(toWhichCase==FOLD_CASE) { 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=ustr_foldCase(csm->csp, temp, destCapacity, src, srcLength, 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm->options, pErrorCode); 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseContext csc={ NULL }; 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.p=(void *)src; 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csc.limit=srcLength; 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(toWhichCase==TO_LOWER) { 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=_caseMap(csm, ucase_toFullLower, 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp, destCapacity, 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0, srcLength, 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(toWhichCase==TO_UPPER) { 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=_caseMap(csm, ucase_toFullUpper, 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) temp, destCapacity, 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0, srcLength, 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* if(toWhichCase==TO_TITLE) */ { 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if UCONFIG_NO_BREAK_ITERATION 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_UNSUPPORTED_ERROR; 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* UCaseMap is actually non-const in toTitle() APIs. */ 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=_toTitle((UCaseMap *)csm, temp, destCapacity, 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, &csc, srcLength, 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(temp!=dest) { 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy the result string to the destination buffer */ 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength>0) { 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t copyLength= destLength<=destCapacity ? destLength : destCapacity; 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(copyLength>0) { 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest, temp, copyLength*U_SIZEOF_UCHAR); 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(temp!=buffer) { 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(temp); 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, destLength, pErrorCode); 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* public API functions */ 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strToLower(UChar *dest, int32_t destCapacity, 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return caseMap(&csm, 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TO_LOWER, pErrorCode); 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strToUpper(UChar *dest, int32_t destCapacity, 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return caseMap(&csm, 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TO_UPPER, pErrorCode); 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strToTitle(UChar *dest, int32_t destCapacity, 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBreakIterator *titleIter, 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *locale, 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.iter=titleIter; 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTempCaseMap(&csm, locale, pErrorCode); 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=caseMap(&csm, 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TO_TITLE, pErrorCode); 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(titleIter==NULL && csm.iter!=NULL) { 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ubrk_close(csm.iter); 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucasemap_toTitle(UCaseMap *csm, 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return caseMap(csm, 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TO_TITLE, pErrorCode); 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strFoldCase(UChar *dest, int32_t destCapacity, 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, int32_t srcLength, 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t options, 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCaseMap csm={ NULL }; 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.csp=ucase_getSingleton(); 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csm.options=options; 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return caseMap(&csm, 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest, destCapacity, 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FOLD_CASE, pErrorCode); 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* case-insensitive string comparisons -------------------------------------- */ 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * This function is a copy of unorm_cmpEquivFold() minus the parts for 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * canonical equivalence. 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Keep the functions in sync, and see there for how this works. 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The duplication is for modularization: 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * It makes caseless (but not canonical caseless) matches independent of 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the normalization code. 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* stack element for previous-level source/decomposition pointers */ 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct CmpEquivLevel { 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *start, *s, *limit; 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct CmpEquivLevel CmpEquivLevel; 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* internal function */ 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strcmpFold(const UChar *s1, int32_t length1, 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s2, int32_t length2, 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t options, 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UCaseProps *csp; 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* current-level start/limit - s1/s2 as current */ 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *start1, *start2, *limit1, *limit2; 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* case folding variables */ 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *p; 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* stacks of previous-level start/current/limit */ 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CmpEquivLevel stack1[2], stack2[2]; 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* case folding buffers, only use current-level start/limit */ 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar fold1[UCASE_MAX_STRING_LENGTH+1], fold2[UCASE_MAX_STRING_LENGTH+1]; 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* track which is the current level per string */ 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t level1, level2; 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* current code units, and code points for lookups */ 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c1, c2, cp1, cp2; 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* no argument error checking because this itself is not an API */ 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * assume that at least the option U_COMPARE_IGNORE_CASE is set 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * otherwise this function would have to behave exactly as uprv_strCompare() 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) csp=ucase_getSingleton(); 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* initialize */ 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start1=s1; 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length1==-1) { 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit1=NULL; 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit1=s1+length1; 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start2=s2; 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length2==-1) { 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit2=NULL; 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit2=s2+length2; 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) level1=level2=0; 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1=c2=-1; 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* comparison loop */ 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * here a code unit value of -1 means "get another code unit" 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * below it will mean "this source is finished" 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c1<0) { 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get next code unit from string 1, post-increment */ 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s1==limit1 || ((c1=*s1)==0 && (limit1==NULL || (options&_STRNCMP_STYLE)))) { 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(level1==0) { 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1=-1; 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++s1; 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reached end of level buffer, pop one level */ 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --level1; 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start1=stack1[level1].start; 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while(start1==NULL); 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s1=stack1[level1].s; 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit1=stack1[level1].limit; 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c2<0) { 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get next code unit from string 2, post-increment */ 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s2==limit2 || ((c2=*s2)==0 && (limit2==NULL || (options&_STRNCMP_STYLE)))) { 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(level2==0) { 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c2=-1; 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++s2; 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reached end of level buffer, pop one level */ 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --level2; 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start2=stack2[level2].start; 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while(start2==NULL); 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s2=stack2[level2].s; 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit2=stack2[level2].limit; 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * compare c1 and c2 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * either variable c1, c2 is -1 only if the corresponding string is finished 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c1==c2) { 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c1<0) { 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; /* c1==c2==-1 indicating end of strings */ 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1=c2=-1; /* make us fetch new code units */ 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(c1<0) { 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; /* string 1 ends before string 2 */ 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(c2<0) { 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 1; /* string 2 ends before string 1 */ 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* c1!=c2 && c1>=0 && c2>=0 */ 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get complete code points for c1, c2 for lookups if either is a surrogate */ 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp1=c1; 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE(c1)) { 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c; 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE_LEAD(c1)) { 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s1!=limit1 && U16_IS_TRAIL(c=*s1)) { 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* advance ++s1; only below if cp1 decomposes/case-folds */ 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp1=U16_GET_SUPPLEMENTARY(c1, c); 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* isTrail(c1) */ { 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(start1<=(s1-2) && U16_IS_LEAD(c=*(s1-2))) { 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp1=U16_GET_SUPPLEMENTARY(c, c1); 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp2=c2; 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE(c2)) { 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c; 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE_LEAD(c2)) { 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s2!=limit2 && U16_IS_TRAIL(c=*s2)) { 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* advance ++s2; only below if cp2 decomposes/case-folds */ 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp2=U16_GET_SUPPLEMENTARY(c2, c); 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* isTrail(c2) */ { 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(start2<=(s2-2) && U16_IS_LEAD(c=*(s2-2))) { 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cp2=U16_GET_SUPPLEMENTARY(c, c2); 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * go down one level for each string 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * continue with the main loop as soon as there is a real change 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( level1==0 && 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (length=ucase_toFullFolding(csp, (UChar32)cp1, &p, options))>=0 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* cp1 case-folds to the code point "length" or to p[length] */ 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE(c1)) { 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE_LEAD(c1)) { 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* advance beyond source surrogate pair if it case-folds */ 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++s1; 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* isTrail(c1) */ { 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * we got a supplementary code point when hitting its trail surrogate, 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * therefore the lead surrogate must have been the same as in the other string; 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * compare this decomposition with the lead surrogate in the other string 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * remember that this simulates bulk text replacement: 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the decomposition would replace the entire code point 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --s2; 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c2=*(s2-1); 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* push current level pointers */ 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack1[0].start=start1; 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack1[0].s=s1; 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack1[0].limit=limit1; 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++level1; 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy the folding result to fold1[] */ 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<=UCASE_MAX_STRING_LENGTH) { 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_memcpy(fold1, p, length); 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i=0; 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_APPEND_UNSAFE(fold1, i, length); 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=i; 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set next level pointers to case folding */ 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start1=s1=fold1; 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit1=fold1+length; 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get ready to read from decomposition, continue with loop */ 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1=-1; 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( level2==0 && 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (length=ucase_toFullFolding(csp, (UChar32)cp2, &p, options))>=0 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* cp2 case-folds to the code point "length" or to p[length] */ 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE(c2)) { 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_IS_SURROGATE_LEAD(c2)) { 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* advance beyond source surrogate pair if it case-folds */ 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++s2; 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* isTrail(c2) */ { 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * we got a supplementary code point when hitting its trail surrogate, 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * therefore the lead surrogate must have been the same as in the other string; 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * compare this decomposition with the lead surrogate in the other string 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * remember that this simulates bulk text replacement: 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the decomposition would replace the entire code point 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --s1; 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1=*(s1-1); 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* push current level pointers */ 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack2[0].start=start2; 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack2[0].s=s2; 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stack2[0].limit=limit2; 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++level2; 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy the folding result to fold2[] */ 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<=UCASE_MAX_STRING_LENGTH) { 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_memcpy(fold2, p, length); 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i=0; 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_APPEND_UNSAFE(fold2, i, length); 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=i; 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set next level pointers to case folding */ 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start2=s2=fold2; 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit2=fold2+length; 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get ready to read from decomposition, continue with loop */ 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c2=-1; 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * no decomposition/case folding, max level for both sides: 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * return difference result 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * code point order comparison must not just return cp1-cp2 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * because when single surrogates are present then the surrogate pairs 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * that formed cp1 and cp2 may be from different string indexes 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * example: { d800 d800 dc01 } vs. { d800 dc00 }, compare at second code units 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * c1=d800 cp1=10001 c2=dc00 cp2=10000 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * cp1-cp2>0 but c1-c2<0 and in fact in UTF-32 it is { d800 10001 } < { 10000 } 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * therefore, use same fix-up as in ustring.c/uprv_strCompare() 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * except: uprv_strCompare() fetches c=*s while this functions fetches c=*s++ 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * so we have slightly different pointer/start/limit comparisons here 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c1>=0xd800 && c2>=0xd800 && (options&U_COMPARE_CODE_POINT_ORDER)) { 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* subtract 0x2800 from BMP code points to make them smaller than supplementary ones */ 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (c1<=0xdbff && s1!=limit1 && U16_IS_TRAIL(*s1)) || 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (U16_IS_TRAIL(c1) && start1!=(s1-1) && U16_IS_LEAD(*(s1-2))) 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* part of a surrogate pair, leave >=d800 */ 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* BMP code point - may be surrogate code point - make <d800 */ 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1-=0x2800; 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (c2<=0xdbff && s2!=limit2 && U16_IS_TRAIL(*s2)) || 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (U16_IS_TRAIL(c2) && start2!=(s2-1) && U16_IS_LEAD(*(s2-2))) 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* part of a surrogate pair, leave >=d800 */ 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* BMP code point - may be surrogate code point - make <d800 */ 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c2-=0x2800; 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return c1-c2; 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* public API functions */ 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strCaseCompare(const UChar *s1, int32_t length1, 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s2, int32_t length2, 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t options, 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* argument checking */ 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==0 || U_FAILURE(*pErrorCode)) { 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s1==NULL || length1<-1 || s2==NULL || length2<-1) { 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_strcmpFold(s1, length1, s2, length2, 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options|U_COMPARE_IGNORE_CASE, 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strcasecmp(const UChar *s1, const UChar *s2, uint32_t options) { 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_strcmpFold(s1, -1, s2, -1, 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options|U_COMPARE_IGNORE_CASE, 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_memcasecmp(const UChar *s1, const UChar *s2, int32_t length, uint32_t options) { 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_strcmpFold(s1, length, s2, length, 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options|U_COMPARE_IGNORE_CASE, 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strncasecmp(const UChar *s1, const UChar *s2, int32_t n, uint32_t options) { 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_strcmpFold(s1, n, s2, n, 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options|(U_COMPARE_IGNORE_CASE|_STRNCMP_STYLE), 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 988