2 *******************************************************************************
4 * Copyright (C) 2002-2012, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
10 * tab size: 8 (not used)
13 * created on: 2002jul08
14 * created by: Vladimir Weinstein
17 #include "unicode/putil.h"
21 /* Layout of the baseContext buffer. */
23 int32_t len
; /* number of bytes available starting at 'data' */
24 char data
; /* actual data starts here */
27 /* Extra bytes to allocate in the baseContext buffer. */
28 static const int32_t PAD
= 8;
30 /* Return a pointer to the baseContext buffer, possibly allocating
31 or reallocating it if at least 'capacity' bytes are not available. */
32 static void* _getBuffer(UEnumeration
* en
, int32_t capacity
) {
34 if (en
->baseContext
!= NULL
) {
35 if (((_UEnumBuffer
*) en
->baseContext
)->len
< capacity
) {
37 en
->baseContext
= uprv_realloc(en
->baseContext
,
38 sizeof(int32_t) + capacity
);
39 if (en
->baseContext
== NULL
) {
42 ((_UEnumBuffer
*) en
->baseContext
)->len
= capacity
;
46 en
->baseContext
= uprv_malloc(sizeof(int32_t) + capacity
);
47 if (en
->baseContext
== NULL
) {
50 ((_UEnumBuffer
*) en
->baseContext
)->len
= capacity
;
53 return (void*) & ((_UEnumBuffer
*) en
->baseContext
)->data
;
57 uenum_close(UEnumeration
* en
)
60 if (en
->close
!= NULL
) {
61 if (en
->baseContext
) {
62 uprv_free(en
->baseContext
);
65 } else { /* this seems dangerous, but we better kill the object */
71 U_CAPI
int32_t U_EXPORT2
72 uenum_count(UEnumeration
* en
, UErrorCode
* status
)
74 if (!en
|| U_FAILURE(*status
)) {
77 if (en
->count
!= NULL
) {
78 return en
->count(en
, status
);
80 *status
= U_UNSUPPORTED_ERROR
;
85 /* Don't call this directly. Only uenum_unext should be calling this. */
86 U_CAPI
const UChar
* U_EXPORT2
87 uenum_unextDefault(UEnumeration
* en
,
88 int32_t* resultLength
,
93 if (en
->next
!= NULL
) {
94 const char *cstr
= en
->next(en
, &len
, status
);
96 ustr
= (UChar
*) _getBuffer(en
, (len
+1) * sizeof(UChar
));
98 *status
= U_MEMORY_ALLOCATION_ERROR
;
100 u_charsToUChars(cstr
, ustr
, len
+1);
104 *status
= U_UNSUPPORTED_ERROR
;
112 /* Don't call this directly. Only uenum_next should be calling this. */
113 U_CAPI
const char* U_EXPORT2
114 uenum_nextDefault(UEnumeration
* en
,
115 int32_t* resultLength
,
118 if (en
->uNext
!= NULL
) {
120 const UChar
*tempUCharVal
= en
->uNext(en
, resultLength
, status
);
121 if (tempUCharVal
== NULL
) {
124 tempCharVal
= (char*)
125 _getBuffer(en
, (*resultLength
+1) * sizeof(char));
127 *status
= U_MEMORY_ALLOCATION_ERROR
;
130 u_UCharsToChars(tempUCharVal
, tempCharVal
, *resultLength
+ 1);
133 *status
= U_UNSUPPORTED_ERROR
;
138 U_CAPI
const UChar
* U_EXPORT2
139 uenum_unext(UEnumeration
* en
,
140 int32_t* resultLength
,
143 if (!en
|| U_FAILURE(*status
)) {
146 if (en
->uNext
!= NULL
) {
147 return en
->uNext(en
, resultLength
, status
);
149 *status
= U_UNSUPPORTED_ERROR
;
154 U_CAPI
const char* U_EXPORT2
155 uenum_next(UEnumeration
* en
,
156 int32_t* resultLength
,
159 if (!en
|| U_FAILURE(*status
)) {
162 if (en
->next
!= NULL
) {
163 if (resultLength
!= NULL
) {
164 return en
->next(en
, resultLength
, status
);
167 int32_t dummyLength
=0;
168 return en
->next(en
, &dummyLength
, status
);
171 *status
= U_UNSUPPORTED_ERROR
;
176 U_CAPI
void U_EXPORT2
177 uenum_reset(UEnumeration
* en
, UErrorCode
* status
)
179 if (!en
|| U_FAILURE(*status
)) {
182 if (en
->reset
!= NULL
) {
183 en
->reset(en
, status
);
185 *status
= U_UNSUPPORTED_ERROR
;