From dd8f01c15e0e51044f6f8f9607fc04340d2f8167 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Sun, 7 Oct 2012 04:52:16 +0000 Subject: [PATCH] ICU-9194 test Calendar::getKeywordValuesForLocale(), in ulist_next_keyword_value() set *resultLength, add further enumeration default implementations & shortcuts X-SVN-Rev: 32543 --- icu4c/source/common/ulist.c | 13 +++++--- icu4c/source/common/unicode/strenum.h | 9 +++-- icu4c/source/common/ustrenum.cpp | 23 +++++++++---- icu4c/source/common/ustrenum.h | 2 ++ icu4c/source/test/intltest/caltest.cpp | 46 +++++++++++++++++++++++--- 5 files changed, 75 insertions(+), 18 deletions(-) diff --git a/icu4c/source/common/ulist.c b/icu4c/source/common/ulist.c index 1ef3704f936..aa506584e71 100644 --- a/icu4c/source/common/ulist.c +++ b/icu4c/source/common/ulist.c @@ -1,6 +1,6 @@ /* ****************************************************************************** -* Copyright (C) 2009, International Business Machines +* Copyright (C) 2009-2012, International Business Machines * Corporation and others. All Rights Reserved. ****************************************************************************** */ @@ -210,13 +210,16 @@ U_CAPI int32_t U_EXPORT2 ulist_count_keyword_values(UEnumeration *en, UErrorCode } U_CAPI const char * U_EXPORT2 ulist_next_keyword_value(UEnumeration *en, int32_t *resultLength, UErrorCode *status) { + const char *s; if (U_FAILURE(*status)) { return NULL; } - - /* TODO: resultLength; */ - - return (const char *)ulist_getNext((UList *)(en->context)); + + s = (const char *)ulist_getNext((UList *)(en->context)); + if (s != NULL && resultLength != NULL) { + *resultLength = uprv_strlen(s); + } + return s; } U_CAPI void U_EXPORT2 ulist_reset_keyword_values_iterator(UEnumeration *en, UErrorCode *status) { diff --git a/icu4c/source/common/unicode/strenum.h b/icu4c/source/common/unicode/strenum.h index ce42195a4f2..3dbe21c6b2d 100644 --- a/icu4c/source/common/unicode/strenum.h +++ b/icu4c/source/common/unicode/strenum.h @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2002-2007, International Business Machines +* Copyright (C) 2002-2012, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -118,6 +118,7 @@ public: * * Starting with ICU 2.8, the default implementation calls snext() * and handles the conversion. + * Either next() or snext() must be implemented differently by a subclass. * * @param status the error code. * @param resultLength a pointer to receive the length, can be NULL. @@ -163,12 +164,16 @@ public: *

If the iterator is out of sync with its service, status is set * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.

* + * Starting with ICU 2.8, the default implementation calls next() + * and handles the conversion. + * Either next() or snext() must be implemented differently by a subclass. + * * @param status the error code. * @return a pointer to the string, or NULL. * * @stable ICU 2.4 */ - virtual const UnicodeString* snext(UErrorCode& status) = 0; + virtual const UnicodeString* snext(UErrorCode& status); /** *

Resets the iterator. This re-establishes sync with the diff --git a/icu4c/source/common/ustrenum.cpp b/icu4c/source/common/ustrenum.cpp index 01b6a6fbd10..dd7fe78a3a2 100644 --- a/icu4c/source/common/ustrenum.cpp +++ b/icu4c/source/common/ustrenum.cpp @@ -41,7 +41,7 @@ StringEnumeration::clone() const { const char * StringEnumeration::next(int32_t *resultLength, UErrorCode &status) { const UnicodeString *s=snext(status); - if(s!=NULL) { + if(U_SUCCESS(status) && s!=NULL) { unistr=*s; ensureCharsCapacity(unistr.length()+1, status); if(U_SUCCESS(status)) { @@ -59,19 +59,24 @@ StringEnumeration::next(int32_t *resultLength, UErrorCode &status) { const UChar * StringEnumeration::unext(int32_t *resultLength, UErrorCode &status) { const UnicodeString *s=snext(status); - if(s!=NULL) { + if(U_SUCCESS(status) && s!=NULL) { unistr=*s; - if(U_SUCCESS(status)) { - if(resultLength!=NULL) { - *resultLength=unistr.length(); - } - return unistr.getTerminatedBuffer(); + if(resultLength!=NULL) { + *resultLength=unistr.length(); } + return unistr.getTerminatedBuffer(); } return NULL; } +const UnicodeString * +StringEnumeration::snext(UErrorCode &status) { + int32_t length; + const char *s=next(&length, status); + return setChars(s, length, status); +} + void StringEnumeration::ensureCharsCapacity(int32_t capacity, UErrorCode &status) { if(U_SUCCESS(status) && capacity>charsCapacity) { @@ -138,6 +143,10 @@ int32_t UStringEnumeration::count(UErrorCode& status) const { return uenum_count(uenum, &status); } +const char *UStringEnumeration::next(int32_t *resultLength, UErrorCode &status) { + return uenum_next(uenum, resultLength, &status); +} + const UnicodeString* UStringEnumeration::snext(UErrorCode& status) { int32_t length; const UChar* str = uenum_unext(uenum, &length, &status); diff --git a/icu4c/source/common/ustrenum.h b/icu4c/source/common/ustrenum.h index ef5863aed01..ffa2c329642 100644 --- a/icu4c/source/common/ustrenum.h +++ b/icu4c/source/common/ustrenum.h @@ -47,6 +47,8 @@ public: */ virtual int32_t count(UErrorCode& status) const; + virtual const char* next(int32_t *resultLength, UErrorCode& status); + /** * Returns the next element a UnicodeString*. If there are no * more elements, returns NULL. diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index 018c90f961a..53e778ca84d 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -11,6 +11,7 @@ #include "caltest.h" #include "unicode/dtfmtsym.h" #include "unicode/gregocal.h" +#include "unicode/localpointer.h" #include "hebrwcal.h" #include "unicode/smpdtfmt.h" #include "unicode/simpletz.h" @@ -555,11 +556,48 @@ CalendarTest::TestGenericAPI() cal->roll(Calendar::MONTH, (int32_t)100, status); } - StringEnumeration *en = Calendar::getKeywordValuesForLocale(NULL, Locale::getDefault(),FALSE, status); - if (en == NULL || U_FAILURE(status)) { - dataerrln("FAIL: getKeywordValuesForLocale for Calendar. : %s", u_errorName(status)); + LocalPointer values( + Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE, status)); + if (values.isNull() || U_FAILURE(status)) { + dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status)); + } + UBool containsHebrew = FALSE; + const char *charValue; + int32_t valueLength; + while ((charValue = values->next(&valueLength, status)) != NULL) { + if (valueLength == 6 && strcmp(charValue, "hebrew") == 0) { + containsHebrew = TRUE; + } + } + if (!containsHebrew) { + errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\""); + } + + values->reset(status); + containsHebrew = FALSE; + UnicodeString hebrew = UNICODE_STRING_SIMPLE("hebrew"); + const UChar *ucharValue; + while ((ucharValue = values->unext(&valueLength, status)) != NULL) { + UnicodeString value(FALSE, ucharValue, valueLength); + if (value == hebrew) { + containsHebrew = TRUE; + } + } + if (!containsHebrew) { + errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\""); + } + + values->reset(status); + containsHebrew = FALSE; + const UnicodeString *stringValue; + while ((stringValue = values->snext(status)) != NULL) { + if (*stringValue == hebrew) { + containsHebrew = TRUE; + } + } + if (!containsHebrew) { + errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\""); } - delete en; delete cal; }