From 2366cc93f28823cb6de5b5c2a0b6c58b035f34a6 Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Thu, 13 Jul 2006 07:21:15 +0000 Subject: [PATCH] ICU-5261 Solaris 10 doesn't like U_MAX_PTR. X-SVN-Rev: 19833 --- icu4c/source/common/unistr_cnv.cpp | 459 +++++++++++++++-------------- 1 file changed, 231 insertions(+), 228 deletions(-) diff --git a/icu4c/source/common/unistr_cnv.cpp b/icu4c/source/common/unistr_cnv.cpp index 72afc3f4c1..1d15229256 100644 --- a/icu4c/source/common/unistr_cnv.cpp +++ b/icu4c/source/common/unistr_cnv.cpp @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1999-2004, International Business Machines +* Copyright (C) 1999-2006, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -43,9 +43,9 @@ UnicodeString::UnicodeString(const char *codepageData, fArray(fStackBuffer), fFlags(kShortString) { - if(codepageData != 0) { - doCodepageCreate(codepageData, (int32_t)uprv_strlen(codepageData), codepage); - } + if(codepageData != 0) { + doCodepageCreate(codepageData, (int32_t)uprv_strlen(codepageData), codepage); + } } @@ -57,9 +57,9 @@ UnicodeString::UnicodeString(const char *codepageData, fArray(fStackBuffer), fFlags(kShortString) { - if(codepageData != 0) { - doCodepageCreate(codepageData, dataLength, codepage); - } + if(codepageData != 0) { + doCodepageCreate(codepageData, dataLength, codepage); + } } UnicodeString::UnicodeString(const char *src, int32_t srcLength, @@ -70,35 +70,35 @@ UnicodeString::UnicodeString(const char *src, int32_t srcLength, fArray(fStackBuffer), fFlags(kShortString) { - if(U_SUCCESS(errorCode)) { - // check arguments - if(src==NULL) { - // treat as an empty string, do nothing more - } else if(srcLength<-1) { - errorCode=U_ILLEGAL_ARGUMENT_ERROR; - } else { - // get input length - if(srcLength==-1) { - srcLength=(int32_t)uprv_strlen(src); - } - if(srcLength>0) { - if(cnv!=0) { - // use the provided converter - ucnv_resetToUnicode(cnv); - doCodepageCreate(src, srcLength, cnv, errorCode); + if(U_SUCCESS(errorCode)) { + // check arguments + if(src==NULL) { + // treat as an empty string, do nothing more + } else if(srcLength<-1) { + errorCode=U_ILLEGAL_ARGUMENT_ERROR; } else { - // use the default converter - cnv=u_getDefaultConverter(&errorCode); - doCodepageCreate(src, srcLength, cnv, errorCode); - u_releaseDefaultConverter(cnv); + // get input length + if(srcLength==-1) { + srcLength=(int32_t)uprv_strlen(src); + } + if(srcLength>0) { + if(cnv!=0) { + // use the provided converter + ucnv_resetToUnicode(cnv); + doCodepageCreate(src, srcLength, cnv, errorCode); + } else { + // use the default converter + cnv=u_getDefaultConverter(&errorCode); + doCodepageCreate(src, srcLength, cnv, errorCode); + u_releaseDefaultConverter(cnv); + } + } } - } - } - if(U_FAILURE(errorCode)) { - setToBogus(); + if(U_FAILURE(errorCode)) { + setToBogus(); + } } - } } //======================================== @@ -111,257 +111,260 @@ UnicodeString::extract(int32_t start, uint32_t dstSize, const char *codepage) const { - // if the arguments are illegal, then do nothing - if(/*dstSize < 0 || */(dstSize > 0 && target == 0)) { - return 0; - } - - // pin the indices to legal values - pinIndices(start, length); - - // create the converter - UConverter *converter; - UErrorCode status = U_ZERO_ERROR; - - // just write the NUL if the string length is 0 - if(length == 0) { - if(dstSize >= 0x80000000) { - // careful: dstSize is unsigned! (0xffffffff means "unlimited") - // make sure that the NUL-termination works (takes int32_t) - dstSize=0x7fffffff; - } - return u_terminateChars(target, dstSize, 0, &status); - } - - // if the codepage is the default, use our cache - // if it is an empty string, then use the "invariant character" conversion - if (codepage == 0) { - converter = u_getDefaultConverter(&status); - } else if (*codepage == 0) { - // use the "invariant characters" conversion - int32_t destLength; - // careful: dstSize is unsigned! (0xffffffff means "unlimited") - if(dstSize >= 0x80000000) { - destLength = length; - // make sure that the NUL-termination works (takes int32_t) - dstSize=0x7fffffff; - } else if(length <= (int32_t)dstSize) { - destLength = length; - } else { - destLength = (int32_t)dstSize; + // if the arguments are illegal, then do nothing + if(/*dstSize < 0 || */(dstSize > 0 && target == 0)) { + return 0; } - u_UCharsToChars(getArrayStart() + start, target, destLength); - return u_terminateChars(target, (int32_t)dstSize, length, &status); - } else { - converter = ucnv_open(codepage, &status); - } - length = doExtract(start, length, target, (int32_t)dstSize, converter, status); + // pin the indices to legal values + pinIndices(start, length); - // close the converter - if (codepage == 0) { - u_releaseDefaultConverter(converter); - } else { - ucnv_close(converter); - } + // create the converter + UConverter *converter; + UErrorCode status = U_ZERO_ERROR; - return length; + // just write the NUL if the string length is 0 + if(length == 0) { + if(dstSize >= 0x80000000) { + // careful: dstSize is unsigned! (0xffffffff means "unlimited") + // make sure that the NUL-termination works (takes int32_t) + dstSize=0x7fffffff; + } + return u_terminateChars(target, dstSize, 0, &status); + } + + // if the codepage is the default, use our cache + // if it is an empty string, then use the "invariant character" conversion + if (codepage == 0) { + converter = u_getDefaultConverter(&status); + } else if (*codepage == 0) { + // use the "invariant characters" conversion + int32_t destLength; + // careful: dstSize is unsigned! (0xffffffff means "unlimited") + if(dstSize >= 0x80000000) { + destLength = length; + // make sure that the NUL-termination works (takes int32_t) + dstSize=0x7fffffff; + } else if(length <= (int32_t)dstSize) { + destLength = length; + } else { + destLength = (int32_t)dstSize; + } + u_UCharsToChars(getArrayStart() + start, target, destLength); + return u_terminateChars(target, (int32_t)dstSize, length, &status); + } else { + converter = ucnv_open(codepage, &status); + } + + length = doExtract(start, length, target, (int32_t)dstSize, converter, status); + + // close the converter + if (codepage == 0) { + u_releaseDefaultConverter(converter); + } else { + ucnv_close(converter); + } + + return length; } int32_t UnicodeString::extract(char *dest, int32_t destCapacity, UConverter *cnv, - UErrorCode &errorCode) const { - if(U_FAILURE(errorCode)) { - return 0; - } - - if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { - errorCode=U_ILLEGAL_ARGUMENT_ERROR; - return 0; - } - - // nothing to do? - if(fLength<=0) { - return u_terminateChars(dest, destCapacity, 0, &errorCode); - } - - // get the converter - UBool isDefaultConverter; - if(cnv==0) { - isDefaultConverter=TRUE; - cnv=u_getDefaultConverter(&errorCode); + UErrorCode &errorCode) const +{ if(U_FAILURE(errorCode)) { - return 0; + return 0; } - } else { - isDefaultConverter=FALSE; - ucnv_resetFromUnicode(cnv); - } - // convert - int32_t length=doExtract(0, fLength, dest, destCapacity, cnv, errorCode); + if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { + errorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } - // release the converter - if(isDefaultConverter) { - u_releaseDefaultConverter(cnv); - } + // nothing to do? + if(fLength<=0) { + return u_terminateChars(dest, destCapacity, 0, &errorCode); + } - return length; + // get the converter + UBool isDefaultConverter; + if(cnv==0) { + isDefaultConverter=TRUE; + cnv=u_getDefaultConverter(&errorCode); + if(U_FAILURE(errorCode)) { + return 0; + } + } else { + isDefaultConverter=FALSE; + ucnv_resetFromUnicode(cnv); + } + + // convert + int32_t length=doExtract(0, fLength, dest, destCapacity, cnv, errorCode); + + // release the converter + if(isDefaultConverter) { + u_releaseDefaultConverter(cnv); + } + + return length; } int32_t UnicodeString::doExtract(int32_t start, int32_t length, char *dest, int32_t destCapacity, UConverter *cnv, - UErrorCode &errorCode) const { - if(U_FAILURE(errorCode)) { - if(destCapacity!=0) { - *dest=0; + UErrorCode &errorCode) const +{ + if(U_FAILURE(errorCode)) { + if(destCapacity!=0) { + *dest=0; + } + return 0; } - return 0; - } - const UChar *src=fArray+start, *srcLimit=src+length; - char *originalDest=dest; - const char *destLimit; + const UChar *src=fArray+start, *srcLimit=src+length; + char *originalDest=dest; + const char *destLimit; - if(destCapacity==0) { - destLimit=dest=0; - } else if(destCapacity==-1) { - // Pin the limit to U_MAX_PTR if the "magic" destCapacity is used. - destLimit=(char*)U_MAX_PTR(dest); - // for NUL-termination, translate into highest int32_t - destCapacity=0x7fffffff; - } else { - destLimit=dest+destCapacity; - } + if(destCapacity==0) { + destLimit=dest=0; + } else { + if(destCapacity==-1) { + // Pin the limit to the max bytes per UChar if the "magic" destCapacity is used. + // +2 for the NULL and ending shifts. + destCapacity=ucnv_getMaxCharSize(cnv)*(length+2); + } + destLimit=dest+destCapacity; + } - // perform the conversion - ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, &errorCode); - length=(int32_t)(dest-originalDest); + // perform the conversion + ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, &errorCode); + length=(int32_t)(dest-originalDest); - // if an overflow occurs, then get the preflighting length - if(errorCode==U_BUFFER_OVERFLOW_ERROR) { - char buffer[1024]; + // if an overflow occurs, then get the preflighting length + if(errorCode==U_BUFFER_OVERFLOW_ERROR) { + char buffer[1024]; - destLimit=buffer+sizeof(buffer); - do { - dest=buffer; - errorCode=U_ZERO_ERROR; - ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, &errorCode); - length+=(int32_t)(dest-buffer); - } while(errorCode==U_BUFFER_OVERFLOW_ERROR); - } + destLimit=buffer+sizeof(buffer); + do { + dest=buffer; + errorCode=U_ZERO_ERROR; + ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, &errorCode); + length+=(int32_t)(dest-buffer); + } while(errorCode==U_BUFFER_OVERFLOW_ERROR); + } - return u_terminateChars(originalDest, destCapacity, length, &errorCode); + return u_terminateChars(originalDest, destCapacity, length, &errorCode); } void UnicodeString::doCodepageCreate(const char *codepageData, - int32_t dataLength, - const char *codepage) + int32_t dataLength, + const char *codepage) { - // if there's nothing to convert, do nothing - if(codepageData == 0 || dataLength == 0 || dataLength < -1) { - return; - } - if(dataLength == -1) { - dataLength = (int32_t)uprv_strlen(codepageData); - } + // if there's nothing to convert, do nothing + if(codepageData == 0 || dataLength == 0 || dataLength < -1) { + return; + } + if(dataLength == -1) { + dataLength = (int32_t)uprv_strlen(codepageData); + } - UErrorCode status = U_ZERO_ERROR; + UErrorCode status = U_ZERO_ERROR; - // create the converter - // if the codepage is the default, use our cache - // if it is an empty string, then use the "invariant character" conversion - UConverter *converter = (codepage == 0 ? + // create the converter + // if the codepage is the default, use our cache + // if it is an empty string, then use the "invariant character" conversion + UConverter *converter = (codepage == 0 ? u_getDefaultConverter(&status) : *codepage == 0 ? 0 : ucnv_open(codepage, &status)); - // if we failed, set the appropriate flags and return - if(U_FAILURE(status)) { - setToBogus(); - return; - } - - // perform the conversion - if(converter == 0) { - // use the "invariant characters" conversion - if(cloneArrayIfNeeded(dataLength, dataLength, FALSE)) { - u_charsToUChars(codepageData, getArrayStart(), dataLength); - fLength = dataLength; - } else { - setToBogus(); + // if we failed, set the appropriate flags and return + if(U_FAILURE(status)) { + setToBogus(); + return; } - return; - } - // convert using the real converter - doCodepageCreate(codepageData, dataLength, converter, status); - if(U_FAILURE(status)) { - setToBogus(); - } + // perform the conversion + if(converter == 0) { + // use the "invariant characters" conversion + if(cloneArrayIfNeeded(dataLength, dataLength, FALSE)) { + u_charsToUChars(codepageData, getArrayStart(), dataLength); + fLength = dataLength; + } else { + setToBogus(); + } + return; + } - // close the converter - if(codepage == 0) { - u_releaseDefaultConverter(converter); - } else { - ucnv_close(converter); - } + // convert using the real converter + doCodepageCreate(codepageData, dataLength, converter, status); + if(U_FAILURE(status)) { + setToBogus(); + } + + // close the converter + if(codepage == 0) { + u_releaseDefaultConverter(converter); + } else { + ucnv_close(converter); + } } void UnicodeString::doCodepageCreate(const char *codepageData, int32_t dataLength, UConverter *converter, - UErrorCode &status) { - if(U_FAILURE(status)) { - return; - } - - // set up the conversion parameters - const char *mySource = codepageData; - const char *mySourceEnd = mySource + dataLength; - UChar *myTarget; - - // estimate the size needed: - // 1.25 UChar's per source byte should cover most cases - int32_t arraySize = dataLength + (dataLength >> 2); - - // we do not care about the current contents - UBool doCopyArray = FALSE; - for(;;) { - if(!cloneArrayIfNeeded(arraySize, arraySize, doCopyArray)) { - setToBogus(); - break; + UErrorCode &status) +{ + if(U_FAILURE(status)) { + return; } - // perform the conversion - myTarget = fArray + fLength; - ucnv_toUnicode(converter, &myTarget, fArray + fCapacity, - &mySource, mySourceEnd, 0, TRUE, &status); + // set up the conversion parameters + const char *mySource = codepageData; + const char *mySourceEnd = mySource + dataLength; + UChar *myTarget; - // update the conversion parameters - fLength = (int32_t)(myTarget - fArray); + // estimate the size needed: + // 1.25 UChar's per source byte should cover most cases + int32_t arraySize = dataLength + (dataLength >> 2); - // allocate more space and copy data, if needed - if(status == U_BUFFER_OVERFLOW_ERROR) { - // reset the error code - status = U_ZERO_ERROR; + // we do not care about the current contents + UBool doCopyArray = FALSE; + for(;;) { + if(!cloneArrayIfNeeded(arraySize, arraySize, doCopyArray)) { + setToBogus(); + break; + } - // keep the previous conversion results - doCopyArray = TRUE; + // perform the conversion + myTarget = fArray + fLength; + ucnv_toUnicode(converter, &myTarget, fArray + fCapacity, + &mySource, mySourceEnd, 0, TRUE, &status); - // estimate the new size needed, larger than before - // try 2 UChar's per remaining source byte - arraySize = (int32_t)(fLength + 2 * (mySourceEnd - mySource)); - } else { - break; + // update the conversion parameters + fLength = (int32_t)(myTarget - fArray); + + // allocate more space and copy data, if needed + if(status == U_BUFFER_OVERFLOW_ERROR) { + // reset the error code + status = U_ZERO_ERROR; + + // keep the previous conversion results + doCopyArray = TRUE; + + // estimate the new size needed, larger than before + // try 2 UChar's per remaining source byte + arraySize = (int32_t)(fLength + 2 * (mySourceEnd - mySource)); + } else { + break; + } } - } } U_NAMESPACE_END