ICU-1972 enumeration revision based on discussion with George

X-SVN-Rev: 9071
This commit is contained in:
Vladimir Weinstein 2002-07-09 18:19:16 +00:00
parent 2fab4a8cb7
commit 9402e79000
4 changed files with 109 additions and 56 deletions

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;
/**

View file

@ -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) {