mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-7197 add API for constructing UEnumerations.
X-SVN-Rev: 32137
This commit is contained in:
parent
9107a7bb38
commit
b68d2f41fb
4 changed files with 241 additions and 12 deletions
|
@ -171,4 +171,39 @@ uenum_openFromStringEnumeration(icu::StringEnumeration* adopted, UErrorCode* ec)
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef U_HIDE_DRAFT_API
|
||||
/**
|
||||
* Given an array of const UChar* strings, return a UEnumeration. String pointers from 0..count-1 must not be null.
|
||||
* Do not free or modify either the string array or the characters it points to until this object has been destroyed with uenum_close.
|
||||
* \snippet test/cintltst/uenumtst.c uenum_openUCharStringsEnumeration
|
||||
* @param strings array of const UChar* strings (each null terminated). All storage is owned by the caller.
|
||||
* @param count length of the array
|
||||
* @param ec error code
|
||||
* @return the new UEnumeration object. Caller is responsible for calling uenum_close to free memory.
|
||||
* @see uenum_close
|
||||
* @draft ICU 50
|
||||
*/
|
||||
U_CAPI UEnumeration* U_EXPORT2
|
||||
uenum_openUCharStringsEnumeration(const UChar* const strings[], int32_t count,
|
||||
UErrorCode* ec);
|
||||
#endif
|
||||
|
||||
/* Note: next function is not hidden as draft, as it is used internally (it was formerly an internal function). */
|
||||
|
||||
/**
|
||||
* Given an array of const char* strings (invariant chars only), return a UEnumeration. String pointers from 0..count-1 must not be null.
|
||||
* Do not free or modify either the string array or the characters it points to until this object has been destroyed with uenum_close.
|
||||
* \snippet test/cintltst/uenumtst.c uenum_openCharStringsEnumeration
|
||||
* @param strings array of char* strings (each null terminated). All storage is owned by the caller.
|
||||
* @param count length of the array
|
||||
* @param ec error code
|
||||
* @return the new UEnumeration object. Caller is responsible for calling uenum_close to free memory
|
||||
* @see uenum_close
|
||||
* @draft ICU 50
|
||||
*/
|
||||
U_CAPI UEnumeration* U_EXPORT2
|
||||
uenum_openCharStringsEnumeration(const char* const strings[], int32_t count,
|
||||
UErrorCode* ec);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -270,6 +270,22 @@ ucharstrenum_count(UEnumeration* en,
|
|||
return ((UCharStringEnumeration*)en)->count;
|
||||
}
|
||||
|
||||
static const UChar* U_CALLCONV
|
||||
ucharstrenum_unext(UEnumeration* en,
|
||||
int32_t* resultLength,
|
||||
UErrorCode* /*ec*/) {
|
||||
UCharStringEnumeration *e = (UCharStringEnumeration*) en;
|
||||
if (e->index >= e->count) {
|
||||
return NULL;
|
||||
}
|
||||
const UChar* result = ((const UChar**)e->uenum.context)[e->index++];
|
||||
if (resultLength) {
|
||||
*resultLength = (int32_t)u_strlen(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static const char* U_CALLCONV
|
||||
ucharstrenum_next(UEnumeration* en,
|
||||
int32_t* resultLength,
|
||||
|
@ -301,10 +317,20 @@ static const UEnumeration UCHARSTRENUM_VT = {
|
|||
ucharstrenum_reset
|
||||
};
|
||||
|
||||
static const UEnumeration UCHARSTRENUM_U_VT = {
|
||||
NULL,
|
||||
NULL, // store StringEnumeration pointer here
|
||||
ucharstrenum_close,
|
||||
ucharstrenum_count,
|
||||
ucharstrenum_unext,
|
||||
uenum_nextDefault,
|
||||
ucharstrenum_reset
|
||||
};
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
U_CAPI UEnumeration* U_EXPORT2
|
||||
uenum_openCharStringsEnumeration(const char* const* strings, int32_t count,
|
||||
uenum_openCharStringsEnumeration(const char* const strings[], int32_t count,
|
||||
UErrorCode* ec) {
|
||||
UCharStringEnumeration* result = NULL;
|
||||
if (U_SUCCESS(*ec) && count >= 0 && (count == 0 || strings != 0)) {
|
||||
|
@ -322,4 +348,24 @@ uenum_openCharStringsEnumeration(const char* const* strings, int32_t count,
|
|||
return (UEnumeration*) result;
|
||||
}
|
||||
|
||||
U_CAPI UEnumeration* U_EXPORT2
|
||||
uenum_openUCharStringsEnumeration(const UChar* const strings[], int32_t count,
|
||||
UErrorCode* ec) {
|
||||
UCharStringEnumeration* result = NULL;
|
||||
if (U_SUCCESS(*ec) && count >= 0 && (count == 0 || strings != 0)) {
|
||||
result = (UCharStringEnumeration*) uprv_malloc(sizeof(UCharStringEnumeration));
|
||||
if (result == NULL) {
|
||||
*ec = U_MEMORY_ALLOCATION_ERROR;
|
||||
} else {
|
||||
U_ASSERT((char*)result==(char*)(&result->uenum));
|
||||
uprv_memcpy(result, &UCHARSTRENUM_U_VT, sizeof(UCHARSTRENUM_U_VT));
|
||||
result->uenum.context = (void*)strings;
|
||||
result->index = 0;
|
||||
result->count = count;
|
||||
}
|
||||
}
|
||||
return (UEnumeration*) result;
|
||||
}
|
||||
|
||||
|
||||
// end C Wrapper
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2002-2009, International Business Machines
|
||||
* Copyright (c) 2002-2012, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
|
@ -14,15 +14,6 @@
|
|||
#include "unicode/uenum.h"
|
||||
#include "unicode/strenum.h"
|
||||
|
||||
/**
|
||||
* Given an array of const char* strings (invariant chars only),
|
||||
* return a UEnumeration. Must have strings[i] != 0 for i in
|
||||
* 0..count-1.
|
||||
*/
|
||||
U_CAPI UEnumeration* U_EXPORT2
|
||||
uenum_openCharStringsEnumeration(const char* const* strings, int32_t count,
|
||||
UErrorCode* ec);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002-2003, International Business Machines
|
||||
* Copyright (C) 2002-2012, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -297,6 +297,161 @@ static void DefaultNextTest(void) {
|
|||
uenum_close(en);
|
||||
}
|
||||
|
||||
static void verifyEnumeration(int line, UEnumeration *u, const char * const * compareToChar, const UChar * const * compareToUChar, int32_t expect_count) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t got_count,i,len;
|
||||
const char *c;
|
||||
UChar buf[1024];
|
||||
|
||||
log_verbose("%s:%d: verifying enumeration..\n", __FILE__, line);
|
||||
|
||||
uenum_reset(u, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("%s:%d: FAIL: could not reset char strings enumeration: %s\n", __FILE__, line, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
got_count = uenum_count(u, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("%s:%d: FAIL: could not count char strings enumeration: %s\n", __FILE__, line, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
if(got_count!=expect_count) {
|
||||
log_err("%s:%d: FAIL: expect count %d got %d\n", __FILE__, line, expect_count, got_count);
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: got count %d\n", __FILE__, line, got_count);
|
||||
}
|
||||
|
||||
if(compareToChar!=NULL) { /* else, not invariant */
|
||||
for(i=0;i<got_count;i++) {
|
||||
c = uenum_next(u,&len, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("%s:%d: FAIL: could not iterate to next after %d: %s\n", __FILE__, line, i, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
if(c==NULL) {
|
||||
log_err("%s:%d: FAIL: got NULL for next after %d: %s\n", __FILE__, line, i, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcmp(c,compareToChar[i])) {
|
||||
log_err("%s:%d: FAIL: string #%d expected '%s' got '%s'\n", __FILE__, line, i, compareToChar[i], c);
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: string #%d got '%s'\n", __FILE__, line, i, c);
|
||||
}
|
||||
|
||||
if(len!=strlen(compareToChar[i])) {
|
||||
log_err("%s:%d: FAIL: string #%d expected len %d got %d\n", __FILE__, line, i, strlen(compareToChar[i]), len);
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: string #%d got len %d\n", __FILE__, line, i, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now try U */
|
||||
uenum_reset(u, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("%s:%d: FAIL: could not reset again char strings enumeration: %s\n", __FILE__, line, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0;i<got_count;i++) {
|
||||
const UChar *ustr = uenum_unext(u,&len, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("%s:%d: FAIL: could not iterate to unext after %d: %s\n", __FILE__, line, i, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
if(ustr==NULL) {
|
||||
log_err("%s:%d: FAIL: got NULL for unext after %d: %s\n", __FILE__, line, i, u_errorName(status));
|
||||
return;
|
||||
}
|
||||
if(compareToChar!=NULL) {
|
||||
u_charsToUChars(compareToChar[i], buf, strlen(compareToChar[i])+1);
|
||||
if(u_strncmp(ustr,buf,len)) {
|
||||
int j;
|
||||
log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__, line, i, compareToChar[i], austrdup(ustr));
|
||||
for(j=0;ustr[j]&&buf[j];j++) {
|
||||
log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j, ustr[j],buf[j]);
|
||||
}
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, compareToChar[i]);
|
||||
}
|
||||
|
||||
if(len!=strlen(compareToChar[i])) {
|
||||
log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__, line, i, strlen(compareToChar[i]), len);
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len);
|
||||
}
|
||||
}
|
||||
|
||||
if(compareToUChar!=NULL) {
|
||||
if(u_strcmp(ustr,compareToUChar[i])) {
|
||||
int j;
|
||||
log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__, line, i, austrdup(compareToUChar[i]), austrdup(ustr));
|
||||
for(j=0;ustr[j]&&compareToUChar[j];j++) {
|
||||
log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j, ustr[j],compareToUChar[j]);
|
||||
}
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, austrdup(compareToUChar[i]));
|
||||
}
|
||||
|
||||
if(len!=u_strlen(compareToUChar[i])) {
|
||||
log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__, line, i, u_strlen(compareToUChar[i]), len);
|
||||
} else {
|
||||
log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void TestCharStringsEnumeration(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
/* //! [uenum_openCharStringsEnumeration] */
|
||||
const char* strings[] = { "Firstly", "Secondly", "Thirdly", "Fourthly" };
|
||||
UEnumeration *u = uenum_openCharStringsEnumeration(strings, 4, &status);
|
||||
/* //! [uenum_openCharStringsEnumeration] */
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("FAIL: could not open char strings enumeration: %s\n", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
verifyEnumeration(__LINE__, u, strings, NULL, 4);
|
||||
|
||||
uenum_close(u);
|
||||
}
|
||||
|
||||
static void TestUCharStringsEnumeration(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
/* //! [uenum_openUCharStringsEnumeration] */
|
||||
static const UChar nko_1[] = {0x07c1,0}, nko_2[] = {0x07c2}, nko_3[] = {0x07c3,0}, nko_4[] = {0x07c4,0};
|
||||
static const UChar* ustrings[] = { nko_1, nko_2, nko_3, nko_4 };
|
||||
UEnumeration *u = uenum_openUCharStringsEnumeration(ustrings, 4, &status);
|
||||
/* //! [uenum_openUCharStringsEnumeration] */
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("FAIL: could not open uchar strings enumeration: %s\n", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
verifyEnumeration(__LINE__, u, NULL, ustrings, 4);
|
||||
uenum_close(u);
|
||||
|
||||
|
||||
u = uenum_openUCharStringsEnumeration(test2, 4, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err("FAIL: could not reopen uchar strings enumeration: %s\n", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
verifyEnumeration(__LINE__, u, test1, NULL, 4); /* same string */
|
||||
uenum_close(u);
|
||||
|
||||
}
|
||||
|
||||
void addEnumerationTest(TestNode** root);
|
||||
|
||||
void addEnumerationTest(TestNode** root)
|
||||
|
@ -304,4 +459,6 @@ void addEnumerationTest(TestNode** root)
|
|||
addTest(root, &EnumerationTest, "tsutil/uenumtst/EnumerationTest");
|
||||
addTest(root, &EmptyEnumerationTest, "tsutil/uenumtst/EmptyEnumerationTest");
|
||||
addTest(root, &DefaultNextTest, "tsutil/uenumtst/DefaultNextTest");
|
||||
addTest(root, &TestCharStringsEnumeration, "tsutil/uenumtst/TestCharStringsEnumeration");
|
||||
addTest(root, &TestUCharStringsEnumeration, "tsutil/uenumtst/TestUCharStringsEnumeration");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue