ICU-699 add StringEnumeration default implementations
X-SVN-Rev: 13612
This commit is contained in:
parent
8830b45fa5
commit
cc21ef7ba4
@ -691,9 +691,6 @@ private:
|
||||
int32_t _timestamp;
|
||||
UVector _ids;
|
||||
int32_t _pos;
|
||||
char *_bufp;
|
||||
int32_t _buflen;
|
||||
char _buf[32];
|
||||
|
||||
private:
|
||||
ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
|
||||
@ -701,8 +698,6 @@ private:
|
||||
, _timestamp(service->getTimestamp())
|
||||
, _ids(uhash_deleteUnicodeString, NULL, status)
|
||||
, _pos(0)
|
||||
, _bufp(_buf)
|
||||
, _buflen(sizeof(_buf))
|
||||
{
|
||||
_service->getVisibleIDs(_ids, status);
|
||||
}
|
||||
@ -712,8 +707,6 @@ private:
|
||||
, _timestamp(other._timestamp)
|
||||
, _ids(uhash_deleteUnicodeString, NULL, status)
|
||||
, _pos(0)
|
||||
, _bufp(_buf)
|
||||
, _buflen(sizeof(_buf))
|
||||
{
|
||||
if(U_SUCCESS(status)) {
|
||||
int32_t i, length;
|
||||
@ -740,11 +733,7 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual ~ServiceEnumeration() {
|
||||
if(_bufp != _buf) {
|
||||
uprv_free(_bufp);
|
||||
}
|
||||
}
|
||||
virtual ~ServiceEnumeration() {}
|
||||
|
||||
virtual StringEnumeration *clone() const {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
@ -760,32 +749,6 @@ public:
|
||||
return upToDate(status) ? _ids.size() : 0;
|
||||
}
|
||||
|
||||
const char* next(int32_t* resultLength, UErrorCode& status) {
|
||||
const UnicodeString* us = snext(status);
|
||||
if (us) {
|
||||
int32_t newlen = us->length();
|
||||
if (newlen >= _buflen) {
|
||||
resizeBuffer(newlen + 1);
|
||||
}
|
||||
us->extract(0, INT32_MAX, _bufp, _buflen, "");
|
||||
if (resultLength) {
|
||||
*resultLength = newlen;
|
||||
}
|
||||
return _bufp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const UChar* unext(int32_t* resultLength, UErrorCode& status) {
|
||||
const UnicodeString* us = snext(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
// the cast to a writable UnicodeString is safe because
|
||||
// ICUService::getVisibleIDs() clones each string
|
||||
return ((UnicodeString *)us)->getTerminatedBuffer();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const UnicodeString* snext(UErrorCode& status) {
|
||||
if (upToDate(status) && (_pos < _ids.size())) {
|
||||
return (const UnicodeString*)_ids[_pos++];
|
||||
@ -793,15 +756,6 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void resizeBuffer(int32_t newlen) {
|
||||
if (_bufp != _buf) {
|
||||
_bufp = (char *)uprv_realloc(_bufp, newlen);
|
||||
} else {
|
||||
_bufp = (char *)uprv_malloc(newlen);
|
||||
}
|
||||
_buflen = newlen;
|
||||
}
|
||||
|
||||
UBool upToDate(UErrorCode& status) const {
|
||||
if (U_SUCCESS(status)) {
|
||||
if (_timestamp == _service->getTimestamp()) {
|
||||
|
@ -471,7 +471,7 @@ Locale& Locale::init(const char* localeID)
|
||||
// "canonicalize" the locale ID to ICU/Java format
|
||||
err = U_ZERO_ERROR;
|
||||
length = uloc_getName(localeID, fullName, sizeof(fullNameBuffer), &err);
|
||||
if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
if(err == U_BUFFER_OVERFLOW_ERROR || length >= sizeof(fullNameBuffer)) {
|
||||
/*Go to heap for the fullName if necessary*/
|
||||
fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
|
||||
if(fullName == 0) {
|
||||
@ -1176,7 +1176,8 @@ public:
|
||||
|
||||
const UnicodeString* snext(UErrorCode& status) {
|
||||
int32_t resultLength = 0;
|
||||
return setChars(next(&resultLength, status), resultLength, status);
|
||||
const char *s = next(&resultLength, status);
|
||||
return setChars(s, resultLength, status);
|
||||
}
|
||||
|
||||
void reset(UErrorCode& /*status*/) {
|
||||
|
@ -229,7 +229,8 @@ protected:
|
||||
* \code
|
||||
* const UnicodeString* snext(UErrorCode& status) {
|
||||
* int32_t resultLength=0;
|
||||
* return setChars(next(&resultLength, status), resultLength, status);
|
||||
* const char *s=next(&resultLength, status);
|
||||
* return setChars(s, resultLength, status);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
|
@ -1510,6 +1510,7 @@ LocaleTest::TestKeywordVariants(void) {
|
||||
StringEnumeration *keywords;
|
||||
int32_t keyCount = 0;
|
||||
const char *keyword = NULL;
|
||||
const UnicodeString *keywordString;
|
||||
int32_t keywordLen = 0;
|
||||
|
||||
for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
|
||||
@ -1527,10 +1528,21 @@ LocaleTest::TestKeywordVariants(void) {
|
||||
err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
|
||||
}
|
||||
if(keyCount) {
|
||||
j = 0;
|
||||
while(keyword = keywords->next(&keywordLen, status)) {
|
||||
if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
|
||||
err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
|
||||
for(j = 0;;) {
|
||||
if((j&1)==0) {
|
||||
if((keyword = keywords->next(&keywordLen, status)) == NULL) {
|
||||
break;
|
||||
}
|
||||
if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
|
||||
err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
|
||||
}
|
||||
} else {
|
||||
if((keywordString = keywords->snext(status)) == NULL) {
|
||||
break;
|
||||
}
|
||||
if(*keywordString != UnicodeString(testCases[i].expectedKeywords[j], "")) {
|
||||
err("Expected to get keyword UnicodeString %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
|
||||
}
|
||||
}
|
||||
j++;
|
||||
|
||||
|
@ -380,7 +380,11 @@ TimeZoneTest::TestGetAvailableIDs913()
|
||||
s_length = s->count(ec);
|
||||
for (i = 0; i < s_length;++i) {
|
||||
if (i > 0) *buf += ", ";
|
||||
*buf += *s->snext(ec);
|
||||
if ((i & 1) == 0) {
|
||||
*buf += *s->snext(ec);
|
||||
} else {
|
||||
*buf += UnicodeString(s->next(NULL, ec), "");
|
||||
}
|
||||
|
||||
if((i % 5) == 4) {
|
||||
// replace s with a clone of itself
|
||||
|
@ -54,6 +54,7 @@ void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* &
|
||||
case 12: name = "TestStackAllocation"; if (exec) TestStackAllocation(); break;
|
||||
case 13: name = "TestUnescape"; if (exec) TestUnescape(); break;
|
||||
case 14: name = "TestCountChar32"; if (exec) TestCountChar32(); break;
|
||||
case 15: name = "TestStringEnumeration"; if (exec) TestStringEnumeration(); break;
|
||||
|
||||
default: name = ""; break; //needed to end loop
|
||||
}
|
||||
@ -1521,3 +1522,97 @@ UnicodeStringTest::TestBogus() {
|
||||
errln("bogus<empty failed");
|
||||
}
|
||||
}
|
||||
|
||||
// StringEnumeration ------------------------------------------------------- ***
|
||||
// most of StringEnumeration is tested elsewhere
|
||||
// this test improves code coverage
|
||||
|
||||
static const char *const
|
||||
testEnumStrings[]={
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"this is a long string which helps us test some buffer limits",
|
||||
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
};
|
||||
|
||||
class TestEnumeration : public StringEnumeration {
|
||||
public:
|
||||
TestEnumeration() : i(0) {}
|
||||
|
||||
virtual int32_t count(UErrorCode& status) const {
|
||||
return LENGTHOF(testEnumStrings);
|
||||
}
|
||||
|
||||
virtual const UnicodeString *snext(UErrorCode &status) {
|
||||
if(U_SUCCESS(status) && i<LENGTHOF(testEnumStrings)) {
|
||||
unistr=UnicodeString(testEnumStrings[i++], "");
|
||||
return &unistr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual void reset(UErrorCode &status) {
|
||||
i=0;
|
||||
}
|
||||
|
||||
static inline UClassID getStaticClassID() {
|
||||
return (UClassID)&fgClassID;
|
||||
}
|
||||
virtual UClassID getDynamicClassID() const {
|
||||
return getStaticClassID();
|
||||
}
|
||||
|
||||
private:
|
||||
static const char fgClassID;
|
||||
|
||||
int32_t i, length;
|
||||
};
|
||||
|
||||
const char TestEnumeration::fgClassID=0;
|
||||
|
||||
void
|
||||
UnicodeStringTest::TestStringEnumeration() {
|
||||
UnicodeString s;
|
||||
TestEnumeration ten;
|
||||
int32_t i, length;
|
||||
UErrorCode status;
|
||||
|
||||
const UChar *pu;
|
||||
const char *pc;
|
||||
|
||||
// test the next() default implementation and ensureCharsCapacity()
|
||||
for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
|
||||
status=U_ZERO_ERROR;
|
||||
pc=ten.next(&length, status);
|
||||
s=UnicodeString(testEnumStrings[i], "");
|
||||
if(U_FAILURE(status) || pc==NULL || length!=s.length() || UnicodeString(pc, length, "")!=s) {
|
||||
errln("StringEnumeration.next(%d) failed", i);
|
||||
}
|
||||
}
|
||||
status=U_ZERO_ERROR;
|
||||
if(ten.next(&length, status)!=NULL) {
|
||||
errln("StringEnumeration.next(done)!=NULL");
|
||||
}
|
||||
|
||||
// test the unext() default implementation
|
||||
ten.reset(status);
|
||||
for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
|
||||
status=U_ZERO_ERROR;
|
||||
pu=ten.unext(&length, status);
|
||||
s=UnicodeString(testEnumStrings[i], "");
|
||||
if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
|
||||
errln("StringEnumeration.unext(%d) failed", i);
|
||||
}
|
||||
}
|
||||
status=U_ZERO_ERROR;
|
||||
if(ten.unext(&length, status)!=NULL) {
|
||||
errln("StringEnumeration.unext(done)!=NULL");
|
||||
}
|
||||
|
||||
// test that the default clone() implementation works, and returns NULL
|
||||
if(ten.clone()!=NULL) {
|
||||
errln("StringEnumeration.clone()!=NULL");
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
void _testUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number);
|
||||
void TestCountChar32(void);
|
||||
void TestBogus();
|
||||
void TestStringEnumeration();
|
||||
};
|
||||
|
||||
class StringCaseTest: public IntlTest {
|
||||
|
Loading…
Reference in New Issue
Block a user