ICU-5261 Solaris 10 doesn't like U_MAX_PTR.
X-SVN-Rev: 19833
This commit is contained in:
parent
31f8cf39d7
commit
2366cc93f2
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user