1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius* Copyright (C) 2002-2012, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file name: uenum.c 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* encoding: US-ASCII 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* tab size: 8 (not used) 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* indentation:2 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 2002jul08 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Vladimir Weinstein 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uenumimp.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Layout of the baseContext buffer. */ 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct { 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len; /* number of bytes available starting at 'data' */ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char data; /* actual data starts here */ 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} _UEnumBuffer; 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Extra bytes to allocate in the baseContext buffer. */ 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const int32_t PAD = 8; 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Return a pointer to the baseContext buffer, possibly allocating 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru or reallocating it if at least 'capacity' bytes are not available. */ 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void* _getBuffer(UEnumeration* en, int32_t capacity) { 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->baseContext != NULL) { 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (((_UEnumBuffer*) en->baseContext)->len < capacity) { 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity += PAD; 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru en->baseContext = uprv_realloc(en->baseContext, 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(int32_t) + capacity); 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->baseContext == NULL) { 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((_UEnumBuffer*) en->baseContext)->len = capacity; 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity += PAD; 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru en->baseContext = uprv_malloc(sizeof(int32_t) + capacity); 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->baseContext == NULL) { 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((_UEnumBuffer*) en->baseContext)->len = capacity; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (void*) & ((_UEnumBuffer*) en->baseContext)->data; 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_close(UEnumeration* en) 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en) { 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->close != NULL) { 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->baseContext) { 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(en->baseContext); 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru en->close(en); 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { /* this seems dangerous, but we better kill the object */ 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(en); 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_count(UEnumeration* en, UErrorCode* status) 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!en || U_FAILURE(*status)) { 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->count != NULL) { 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return en->count(en, status); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Don't call this directly. Only uenum_unext should be calling this. */ 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const UChar* U_EXPORT2 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_unextDefault(UEnumeration* en, 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* status) 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *ustr = NULL; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->next != NULL) { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *cstr = en->next(en, &len, status); 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cstr != NULL) { 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ustr = (UChar*) _getBuffer(en, (len+1) * sizeof(UChar)); 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ustr == NULL) { 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_charsToUChars(cstr, ustr, len+1); 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (resultLength) { 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *resultLength = len; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ustr; 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Don't call this directly. Only uenum_next should be calling this. */ 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_nextDefault(UEnumeration* en, 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* status) 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->uNext != NULL) { 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *tempCharVal; 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *tempUCharVal = en->uNext(en, resultLength, status); 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tempUCharVal == NULL) { 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempCharVal = (char*) 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _getBuffer(en, (*resultLength+1) * sizeof(char)); 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!tempCharVal) { 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_UCharsToChars(tempUCharVal, tempCharVal, *resultLength + 1); 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tempCharVal; 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const UChar* U_EXPORT2 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_unext(UEnumeration* en, 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* status) 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!en || U_FAILURE(*status)) { 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->uNext != NULL) { 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return en->uNext(en, resultLength, status); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_next(UEnumeration* en, 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* status) 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!en || U_FAILURE(*status)) { 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->next != NULL) { 16354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (resultLength != NULL) { 16454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return en->next(en, resultLength, status); 16554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 16654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius else { 16754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t dummyLength=0; 16854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return en->next(en, &dummyLength, status); 16954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuenum_reset(UEnumeration* en, UErrorCode* status) 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!en || U_FAILURE(*status)) { 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (en->reset != NULL) { 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru en->reset(en, status); 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 188