X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/fd0068a84e9996f225edba706498f6ed413d0673..46f4442e9a5a4f3b98b7c1083586332f6a8a99a4:/icuSources/common/unistr_case.cpp diff --git a/icuSources/common/unistr_case.cpp b/icuSources/common/unistr_case.cpp index 34f53d8a..617b80d0 100644 --- a/icuSources/common/unistr_case.cpp +++ b/icuSources/common/unistr_case.cpp @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1999-2005, International Business Machines +* Copyright (C) 1999-2007, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -89,19 +89,13 @@ UnicodeString::doCaseCompare(int32_t start, * Implement argument checking and buffer handling * for string case mapping as a common function. */ -enum { - TO_LOWER, - TO_UPPER, - TO_TITLE, - FOLD_CASE -}; UnicodeString & UnicodeString::caseMap(BreakIterator *titleIter, const char *locale, uint32_t options, int32_t toWhichCase) { - if(fLength <= 0) { + if(isEmpty() || !isWritable()) { // nothing to do return *this; } @@ -116,82 +110,62 @@ UnicodeString::caseMap(BreakIterator *titleIter, } // We need to allocate a new buffer for the internal string case mapping function. - // This is very similar to how doReplace() below keeps the old array pointer + // This is very similar to how doReplace() keeps the old array pointer // and deletes the old array itself after it is done. // In addition, we are forcing cloneArrayIfNeeded() to always allocate a new array. - UChar *oldArray = fArray; - int32_t oldLength = fLength; - int32_t *bufferToDelete = 0; + UChar oldStackBuffer[US_STACKBUF_SIZE]; + UChar *oldArray; + int32_t oldLength; + + if(fFlags&kUsingStackBuffer) { + // copy the stack buffer contents because it will be overwritten + u_memcpy(oldStackBuffer, fUnion.fStackBuffer, fShortLength); + oldArray = oldStackBuffer; + oldLength = fShortLength; + } else { + oldArray = getArrayStart(); + oldLength = length(); + } - // Make sure that if the string is in fStackBuffer we do not overwrite it! int32_t capacity; - if(fLength <= US_STACKBUF_SIZE) { - if(fArray == fStackBuffer) { - capacity = 2 * US_STACKBUF_SIZE; // make sure that cloneArrayIfNeeded() allocates a new buffer - } else { - capacity = US_STACKBUF_SIZE; - } + if(oldLength <= US_STACKBUF_SIZE) { + capacity = US_STACKBUF_SIZE; } else { - capacity = fLength + 20; + capacity = oldLength + 20; } + int32_t *bufferToDelete = 0; if(!cloneArrayIfNeeded(capacity, capacity, FALSE, &bufferToDelete, TRUE)) { return *this; } -#if !UCONFIG_NO_BREAK_ITERATION - // set up the titlecasing break iterator - UBreakIterator *cTitleIter = 0; - - if(toWhichCase == TO_TITLE) { - errorCode = U_ZERO_ERROR; - if(titleIter != 0) { - cTitleIter = (UBreakIterator *)titleIter; - ubrk_setText(cTitleIter, oldArray, oldLength, &errorCode); - } else { - cTitleIter = ubrk_open(UBRK_WORD, locale, - oldArray, oldLength, - &errorCode); - } - if(U_FAILURE(errorCode)) { - uprv_free(bufferToDelete); - setToBogus(); - return *this; - } - } -#endif - // Case-map, and if the result is too long, then reallocate and repeat. + int32_t newLength; do { errorCode = U_ZERO_ERROR; if(toWhichCase==TO_LOWER) { - fLength = ustr_toLower(csp, fArray, fCapacity, - oldArray, oldLength, - locale, &errorCode); + newLength = ustr_toLower(csp, getArrayStart(), getCapacity(), + oldArray, oldLength, + locale, &errorCode); } else if(toWhichCase==TO_UPPER) { - fLength = ustr_toUpper(csp, fArray, fCapacity, - oldArray, oldLength, - locale, &errorCode); + newLength = ustr_toUpper(csp, getArrayStart(), getCapacity(), + oldArray, oldLength, + locale, &errorCode); } else if(toWhichCase==TO_TITLE) { #if UCONFIG_NO_BREAK_ITERATION errorCode=U_UNSUPPORTED_ERROR; #else - fLength = ustr_toTitle(csp, fArray, fCapacity, - oldArray, oldLength, - cTitleIter, locale, &errorCode); + newLength = ustr_toTitle(csp, getArrayStart(), getCapacity(), + oldArray, oldLength, + (UBreakIterator *)titleIter, locale, options, &errorCode); #endif } else { - fLength = ustr_foldCase(csp, fArray, fCapacity, - oldArray, oldLength, - options, - &errorCode); + newLength = ustr_foldCase(csp, getArrayStart(), getCapacity(), + oldArray, oldLength, + options, + &errorCode); } - } while(errorCode==U_BUFFER_OVERFLOW_ERROR && cloneArrayIfNeeded(fLength, fLength, FALSE)); - -#if !UCONFIG_NO_BREAK_ITERATION - if(cTitleIter != 0 && titleIter == 0) { - ubrk_close(cTitleIter); - } -#endif + setLength(newLength); + } while(errorCode==U_BUFFER_OVERFLOW_ERROR && cloneArrayIfNeeded(newLength, newLength, FALSE)); if (bufferToDelete) { uprv_free(bufferToDelete); @@ -234,6 +208,11 @@ UnicodeString::toTitle(BreakIterator *titleIter, const Locale &locale) { return caseMap(titleIter, locale.getName(), 0, TO_TITLE); } +UnicodeString & +UnicodeString::toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options) { + return caseMap(titleIter, locale.getName(), options, TO_TITLE); +} + #endif UnicodeString &