mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 17:24:01 +00:00
ICU-1972 enumeration revision based on discussion with George
X-SVN-Rev: 9071
This commit is contained in:
parent
2fab4a8cb7
commit
9402e79000
4 changed files with 109 additions and 56 deletions
|
@ -15,27 +15,72 @@
|
|||
*/
|
||||
|
||||
#include "uenumimp.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
static const UEnumeration nullEnumeration = {
|
||||
NULL, /* context */
|
||||
NULL, /* close */
|
||||
NULL, /* count */
|
||||
NULL, /* uNext */
|
||||
NULL, /* next */
|
||||
NULL /* reset */
|
||||
};
|
||||
|
||||
void uenum_close(UEnumeration* en) {
|
||||
en->close(en);
|
||||
if(en->close != NULL) {
|
||||
en->close(en);
|
||||
} else { // this seems dangerous, but better kill the object
|
||||
uprv_free(en);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t uenum_count(UEnumeration* en, UErrorCode* status) {
|
||||
return en->count(en, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return -1;
|
||||
}
|
||||
if(en->count != NULL) {
|
||||
return en->count(en, status);
|
||||
} else {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const UChar* uenum_unext(UEnumeration* en,
|
||||
int32_t* resultLength,
|
||||
UErrorCode* status) {
|
||||
return en->uNext(en, resultLength, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(en->uNext != NULL) {
|
||||
return en->uNext(en, resultLength, status);
|
||||
} else {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* uenum_next(UEnumeration* en,
|
||||
int32_t* resultLength,
|
||||
UErrorCode* status) {
|
||||
return en->next(en, resultLength, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(en->next != NULL) {
|
||||
return en->next(en, resultLength, status);
|
||||
} else {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void uenum_reset(UEnumeration* en, UErrorCode* status) {
|
||||
en->reset(en, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
if(en->reset != NULL) {
|
||||
en->reset(en, status);
|
||||
} else {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
|
||||
#include "unicode/uenum.h"
|
||||
|
||||
/**
|
||||
* following are the type declarations for
|
||||
* implementations of APIs. If any of these
|
||||
* functions are NULL, U_UNSUPPORTED_ERROR
|
||||
* is returned. If close is NULL, the enumeration
|
||||
* object is going to be released.
|
||||
* Initial error checking is done in the body
|
||||
* of API function, so the implementations
|
||||
* need not to check the initial error condition.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function type declaration for uenum_close().
|
||||
*
|
||||
|
@ -89,16 +100,11 @@ UEnumReset(UEnumeration* en,
|
|||
|
||||
|
||||
struct UEnumeration {
|
||||
UChar *currentUChar;
|
||||
char *currentChar;
|
||||
/* context. Use it for what you need */
|
||||
void *context;
|
||||
|
||||
void *context1;
|
||||
void *context2;
|
||||
|
||||
int32_t int1;
|
||||
int32_t int2;
|
||||
|
||||
/* these are functions that will
|
||||
/**
|
||||
* these are functions that will
|
||||
* be used for APIs
|
||||
*/
|
||||
/* called from uenum_close */
|
||||
|
@ -113,4 +119,5 @@ struct UEnumeration {
|
|||
UEnumReset *reset;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
/** A collator.
|
||||
/** An enumeration object.
|
||||
* For usage in C programs.
|
||||
*/
|
||||
struct UEnumeration;
|
||||
/** structure representing a collator object instance */
|
||||
/** structure representing an enumeration object instance */
|
||||
typedef struct UEnumeration UEnumeration;
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,67 +26,68 @@ static const char* test1[] = {
|
|||
"fourth"
|
||||
};
|
||||
|
||||
struct chArrayContext {
|
||||
int32_t currIndex;
|
||||
int32_t maxIndex;
|
||||
char *currChar;
|
||||
UChar *currUChar;
|
||||
char **array;
|
||||
};
|
||||
|
||||
typedef struct chArrayContext chArrayContext;
|
||||
|
||||
#define cont ((chArrayContext *)en->context)
|
||||
|
||||
void chArrayClose(UEnumeration *en) {
|
||||
if(en->currentUChar != NULL) {
|
||||
uprv_free(en->currentUChar);
|
||||
if(cont->currUChar != NULL) {
|
||||
uprv_free(cont->currUChar);
|
||||
}
|
||||
uprv_free(en);
|
||||
}
|
||||
|
||||
int32_t chArrayCount(UEnumeration *en, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
return en->int1;
|
||||
return cont->maxIndex;
|
||||
}
|
||||
|
||||
const UChar* chArrayUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
|
||||
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(en->int2 >= en->int1) {
|
||||
if(cont->currIndex >= cont->maxIndex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(en->currentUChar == NULL) {
|
||||
en->currentUChar = (UChar *)uprv_malloc(1024*sizeof(UChar));
|
||||
if(cont->currUChar == NULL) {
|
||||
cont->currUChar = (UChar *)uprv_malloc(1024*sizeof(UChar));
|
||||
}
|
||||
|
||||
*resultLength = uprv_strlen(en->currentChar);
|
||||
en->currentChar = ((char **)en->context1)[en->int2];
|
||||
u_charsToUChars(en->currentChar, en->currentUChar, *resultLength);
|
||||
en->int2++;
|
||||
return en->currentUChar;
|
||||
cont->currChar = (cont->array)[cont->currIndex];
|
||||
*resultLength = uprv_strlen(cont->currChar);
|
||||
u_charsToUChars(cont->currChar, cont->currUChar, *resultLength);
|
||||
cont->currIndex++;
|
||||
return cont->currUChar;
|
||||
}
|
||||
|
||||
const char* chArrayNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(en->int2 >= en->int1) {
|
||||
if(cont->currIndex >= cont->maxIndex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
en->currentChar = ((char **)en->context1)[en->int2];
|
||||
en->int2++;
|
||||
*resultLength = uprv_strlen(en->currentChar);
|
||||
return en->currentChar;
|
||||
cont->currChar = (cont->array)[cont->currIndex];
|
||||
*resultLength = uprv_strlen(cont->currChar);
|
||||
cont->currIndex++;
|
||||
return cont->currChar;
|
||||
}
|
||||
|
||||
void chArrayReset(UEnumeration *en, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
en->int2 = 0;
|
||||
cont->currIndex = 0;
|
||||
}
|
||||
|
||||
chArrayContext myCont = {
|
||||
0, 0,
|
||||
NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
UEnumeration chEnum = {
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
0, 0,
|
||||
&myCont,
|
||||
chArrayClose,
|
||||
chArrayCount,
|
||||
chArrayUNext,
|
||||
|
@ -95,11 +96,11 @@ UEnumeration chEnum = {
|
|||
};
|
||||
|
||||
static UEnumeration *getchArrayEnum(const char** source, int32_t size) {
|
||||
UEnumeration *result = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
|
||||
memcpy(result, &chEnum, sizeof(UEnumeration));
|
||||
result->context1 = (void *)source;
|
||||
result->int1 = size;
|
||||
return result;
|
||||
UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
|
||||
memcpy(en, &chEnum, sizeof(UEnumeration));
|
||||
cont->array = (char **)source;
|
||||
cont->maxIndex = size;
|
||||
return en;
|
||||
}
|
||||
|
||||
static void EnumerationTest(void) {
|
||||
|
|
Loading…
Add table
Reference in a new issue