1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/uenum.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,187 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 2002-2012, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +* file name: uenum.c 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:2 1.15 +* 1.16 +* created on: 2002jul08 1.17 +* created by: Vladimir Weinstein 1.18 +*/ 1.19 + 1.20 +#include "unicode/putil.h" 1.21 +#include "uenumimp.h" 1.22 +#include "cmemory.h" 1.23 + 1.24 +/* Layout of the baseContext buffer. */ 1.25 +typedef struct { 1.26 + int32_t len; /* number of bytes available starting at 'data' */ 1.27 + char data; /* actual data starts here */ 1.28 +} _UEnumBuffer; 1.29 + 1.30 +/* Extra bytes to allocate in the baseContext buffer. */ 1.31 +static const int32_t PAD = 8; 1.32 + 1.33 +/* Return a pointer to the baseContext buffer, possibly allocating 1.34 + or reallocating it if at least 'capacity' bytes are not available. */ 1.35 +static void* _getBuffer(UEnumeration* en, int32_t capacity) { 1.36 + 1.37 + if (en->baseContext != NULL) { 1.38 + if (((_UEnumBuffer*) en->baseContext)->len < capacity) { 1.39 + capacity += PAD; 1.40 + en->baseContext = uprv_realloc(en->baseContext, 1.41 + sizeof(int32_t) + capacity); 1.42 + if (en->baseContext == NULL) { 1.43 + return NULL; 1.44 + } 1.45 + ((_UEnumBuffer*) en->baseContext)->len = capacity; 1.46 + } 1.47 + } else { 1.48 + capacity += PAD; 1.49 + en->baseContext = uprv_malloc(sizeof(int32_t) + capacity); 1.50 + if (en->baseContext == NULL) { 1.51 + return NULL; 1.52 + } 1.53 + ((_UEnumBuffer*) en->baseContext)->len = capacity; 1.54 + } 1.55 + 1.56 + return (void*) & ((_UEnumBuffer*) en->baseContext)->data; 1.57 +} 1.58 + 1.59 +U_CAPI void U_EXPORT2 1.60 +uenum_close(UEnumeration* en) 1.61 +{ 1.62 + if (en) { 1.63 + if (en->close != NULL) { 1.64 + if (en->baseContext) { 1.65 + uprv_free(en->baseContext); 1.66 + } 1.67 + en->close(en); 1.68 + } else { /* this seems dangerous, but we better kill the object */ 1.69 + uprv_free(en); 1.70 + } 1.71 + } 1.72 +} 1.73 + 1.74 +U_CAPI int32_t U_EXPORT2 1.75 +uenum_count(UEnumeration* en, UErrorCode* status) 1.76 +{ 1.77 + if (!en || U_FAILURE(*status)) { 1.78 + return -1; 1.79 + } 1.80 + if (en->count != NULL) { 1.81 + return en->count(en, status); 1.82 + } else { 1.83 + *status = U_UNSUPPORTED_ERROR; 1.84 + return -1; 1.85 + } 1.86 +} 1.87 + 1.88 +/* Don't call this directly. Only uenum_unext should be calling this. */ 1.89 +U_CAPI const UChar* U_EXPORT2 1.90 +uenum_unextDefault(UEnumeration* en, 1.91 + int32_t* resultLength, 1.92 + UErrorCode* status) 1.93 +{ 1.94 + UChar *ustr = NULL; 1.95 + int32_t len = 0; 1.96 + if (en->next != NULL) { 1.97 + const char *cstr = en->next(en, &len, status); 1.98 + if (cstr != NULL) { 1.99 + ustr = (UChar*) _getBuffer(en, (len+1) * sizeof(UChar)); 1.100 + if (ustr == NULL) { 1.101 + *status = U_MEMORY_ALLOCATION_ERROR; 1.102 + } else { 1.103 + u_charsToUChars(cstr, ustr, len+1); 1.104 + } 1.105 + } 1.106 + } else { 1.107 + *status = U_UNSUPPORTED_ERROR; 1.108 + } 1.109 + if (resultLength) { 1.110 + *resultLength = len; 1.111 + } 1.112 + return ustr; 1.113 +} 1.114 + 1.115 +/* Don't call this directly. Only uenum_next should be calling this. */ 1.116 +U_CAPI const char* U_EXPORT2 1.117 +uenum_nextDefault(UEnumeration* en, 1.118 + int32_t* resultLength, 1.119 + UErrorCode* status) 1.120 +{ 1.121 + if (en->uNext != NULL) { 1.122 + char *tempCharVal; 1.123 + const UChar *tempUCharVal = en->uNext(en, resultLength, status); 1.124 + if (tempUCharVal == NULL) { 1.125 + return NULL; 1.126 + } 1.127 + tempCharVal = (char*) 1.128 + _getBuffer(en, (*resultLength+1) * sizeof(char)); 1.129 + if (!tempCharVal) { 1.130 + *status = U_MEMORY_ALLOCATION_ERROR; 1.131 + return NULL; 1.132 + } 1.133 + u_UCharsToChars(tempUCharVal, tempCharVal, *resultLength + 1); 1.134 + return tempCharVal; 1.135 + } else { 1.136 + *status = U_UNSUPPORTED_ERROR; 1.137 + return NULL; 1.138 + } 1.139 +} 1.140 + 1.141 +U_CAPI const UChar* U_EXPORT2 1.142 +uenum_unext(UEnumeration* en, 1.143 + int32_t* resultLength, 1.144 + UErrorCode* status) 1.145 +{ 1.146 + if (!en || U_FAILURE(*status)) { 1.147 + return NULL; 1.148 + } 1.149 + if (en->uNext != NULL) { 1.150 + return en->uNext(en, resultLength, status); 1.151 + } else { 1.152 + *status = U_UNSUPPORTED_ERROR; 1.153 + return NULL; 1.154 + } 1.155 +} 1.156 + 1.157 +U_CAPI const char* U_EXPORT2 1.158 +uenum_next(UEnumeration* en, 1.159 + int32_t* resultLength, 1.160 + UErrorCode* status) 1.161 +{ 1.162 + if (!en || U_FAILURE(*status)) { 1.163 + return NULL; 1.164 + } 1.165 + if (en->next != NULL) { 1.166 + if (resultLength != NULL) { 1.167 + return en->next(en, resultLength, status); 1.168 + } 1.169 + else { 1.170 + int32_t dummyLength=0; 1.171 + return en->next(en, &dummyLength, status); 1.172 + } 1.173 + } else { 1.174 + *status = U_UNSUPPORTED_ERROR; 1.175 + return NULL; 1.176 + } 1.177 +} 1.178 + 1.179 +U_CAPI void U_EXPORT2 1.180 +uenum_reset(UEnumeration* en, UErrorCode* status) 1.181 +{ 1.182 + if (!en || U_FAILURE(*status)) { 1.183 + return; 1.184 + } 1.185 + if (en->reset != NULL) { 1.186 + en->reset(en, status); 1.187 + } else { 1.188 + *status = U_UNSUPPORTED_ERROR; 1.189 + } 1.190 +}