16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2002-2012, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: uenum.c 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:2 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2002jul08 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Vladimir Weinstein 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/putil.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uenumimp.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Layout of the baseContext buffer. */ 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct { 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len; /* number of bytes available starting at 'data' */ 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char data; /* actual data starts here */ 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} _UEnumBuffer; 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Extra bytes to allocate in the baseContext buffer. */ 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t PAD = 8; 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Return a pointer to the baseContext buffer, possibly allocating 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org or reallocating it if at least 'capacity' bytes are not available. */ 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void* _getBuffer(UEnumeration* en, int32_t capacity) { 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->baseContext != NULL) { 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (((_UEnumBuffer*) en->baseContext)->len < capacity) { 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org capacity += PAD; 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org en->baseContext = uprv_realloc(en->baseContext, 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(int32_t) + capacity); 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->baseContext == NULL) { 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((_UEnumBuffer*) en->baseContext)->len = capacity; 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org capacity += PAD; 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org en->baseContext = uprv_malloc(sizeof(int32_t) + capacity); 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->baseContext == NULL) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((_UEnumBuffer*) en->baseContext)->len = capacity; 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (void*) & ((_UEnumBuffer*) en->baseContext)->data; 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_close(UEnumeration* en) 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en) { 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->close != NULL) { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->baseContext) { 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(en->baseContext); 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org en->close(en); 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { /* this seems dangerous, but we better kill the object */ 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(en); 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_count(UEnumeration* en, UErrorCode* status) 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!en || U_FAILURE(*status)) { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->count != NULL) { 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return en->count(en, status); 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Don't call this directly. Only uenum_unext should be calling this. */ 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const UChar* U_EXPORT2 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_unextDefault(UEnumeration* en, 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t* resultLength, 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status) 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *ustr = NULL; 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = 0; 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->next != NULL) { 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *cstr = en->next(en, &len, status); 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cstr != NULL) { 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ustr = (UChar*) _getBuffer(en, (len+1) * sizeof(UChar)); 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ustr == NULL) { 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_charsToUChars(cstr, ustr, len+1); 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (resultLength) { 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *resultLength = len; 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ustr; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Don't call this directly. Only uenum_next should be calling this. */ 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_nextDefault(UEnumeration* en, 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t* resultLength, 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status) 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->uNext != NULL) { 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *tempCharVal; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *tempUCharVal = en->uNext(en, resultLength, status); 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tempUCharVal == NULL) { 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempCharVal = (char*) 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _getBuffer(en, (*resultLength+1) * sizeof(char)); 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!tempCharVal) { 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(tempUCharVal, tempCharVal, *resultLength + 1); 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return tempCharVal; 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const UChar* U_EXPORT2 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_unext(UEnumeration* en, 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t* resultLength, 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status) 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!en || U_FAILURE(*status)) { 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->uNext != NULL) { 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return en->uNext(en, resultLength, status); 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_next(UEnumeration* en, 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t* resultLength, 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status) 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!en || U_FAILURE(*status)) { 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->next != NULL) { 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (resultLength != NULL) { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return en->next(en, resultLength, status); 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t dummyLength=0; 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return en->next(en, &dummyLength, status); 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguenum_reset(UEnumeration* en, UErrorCode* status) 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!en || U_FAILURE(*status)) { 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (en->reset != NULL) { 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org en->reset(en, status); 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_UNSUPPORTED_ERROR; 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 188