ICU-170 fix doCompare()

X-SVN-Rev: 325
This commit is contained in:
Markus Scherer 1999-12-07 00:12:31 +00:00
parent ce89f70176
commit bf3a6d7f22
2 changed files with 74 additions and 49 deletions

View File

@ -68,12 +68,6 @@ print(const UChar *s,
// Local function definitions for now
// move u_arrayCompare to utypes.h ??
inline int8_t
u_arrayCompare(const UChar *src, int32_t srcStart,
const UChar *dst, int32_t dstStart, int32_t count)
{return icu_memcmp(src+srcStart, dst+dstStart, (size_t)(count*sizeof(*src)));}
// need to copy areas that may overlap
inline void
us_arrayCopy(const UChar *src, int32_t srcStart,
@ -299,23 +293,6 @@ UnicodeString::operator[] (UTextOffset pos)
//========================================
// Read-only implementation
//========================================
int8_t
UnicodeString::doCompare( UTextOffset start,
int32_t length,
const UnicodeString& src,
UTextOffset srcStart,
int32_t srcLength) const
{
// pin indices to legal values
pinIndices(start, length);
// get the correct pointer
const UChar *chars = getArrayStart();
// compare the characters
return (src.compare(srcStart, srcLength, chars, start, length) * -1);
}
int8_t
UnicodeString::doCompare( UTextOffset start,
int32_t length,
@ -323,41 +300,72 @@ UnicodeString::doCompare( UTextOffset start,
UTextOffset srcStart,
int32_t srcLength) const
{
// compare illegal string values
if(isBogus()) {
if(srcChars==0) {
return 0;
} else {
return -1;
}
} else if(srcChars==0) {
return 1;
}
// pin indices to legal values
pinIndices(start, length);
// get the correct pointer
const UChar *chars = getArrayStart();
// we're comparing different lengths
UTextOffset minLength;
int8_t lengthResult;
// are we comparing different lengths?
if(length != srcLength) {
// compare the minimum # of characters
int32_t minLength = (length < srcLength ? length : srcLength);
const UChar *minLimit = chars + minLength;
const UChar *limit = chars + length;
int8_t result;
// adjust for starting offsets
chars += start;
srcChars += srcStart;
while(chars < minLimit) {
result = (*chars - *srcChars);
if(result != 0)
return result;
++chars;
++srcChars;
if(length < srcLength) {
minLength = length;
lengthResult = -1;
} else {
minLength = srcLength;
lengthResult = 1;
}
// if we got here, the leading portions are identical
return (chars < limit ? 1 : -1);
} else {
minLength = length;
lengthResult = 0;
}
// compare two identical lengths, use u_arrayCompare
else
return u_arrayCompare(chars, start, srcChars, srcStart, length);
/*
* note that icu_memcmp() returns an int but we return an int8_t;
* we need to take care not to truncate the result -
* one way to do this is to right-shift the value to
* move the sign bit into the lower 8 bits and making sure that this
* does not become 0 itself
*/
if(minLength > 0) {
int32_t result;
if(U_IS_BIG_ENDIAN) {
// big-endian: byte comparison works
result = icu_memcmp(chars + start, srcChars + srcStart, minLength * sizeof(UChar));
if(result != 0) {
return (int8_t)(result >> 15 | 1);
}
} else {
// little-endian: compare UChar units
chars += start;
srcChars += srcStart;
do {
result = ((int32_t)*chars - (int32_t)*srcChars);
if(result != 0) {
return (int8_t)(result >> 15 | 1);
}
++chars;
++srcChars;
} while(--minLength > 0);
}
}
return lengthResult;
}
void

View File

@ -1684,6 +1684,23 @@ UnicodeString::compareBetween(UTextOffset start,
{ return doCompare(start, limit - start,
srcText, srcStart, srcLimit - srcStart); }
inline int8_t
UnicodeString::doCompare(UTextOffset start,
int32_t length,
const UnicodeString& srcText,
UTextOffset srcStart,
int32_t srcLength) const
{
const UChar *srcChars;
if(!srcText.isBogus()) {
srcText.pinIndices(srcStart, srcLength);
srcChars=srcText.getArrayStart();
} else {
srcChars=0;
}
return doCompare(start, length, srcChars, srcStart, srcLength);
}
inline UTextOffset
UnicodeString::indexOf(const UnicodeString& text) const
{ return indexOf(text, 0, text.fLength, 0, fLength); }