1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 2002-2012, International Business Machines
5 *   Corporation and others.  All Rights Reserved.
6 *
7 *******************************************************************************
8 */
9 
10 #ifndef STRENUM_H
11 #define STRENUM_H
12 
13 #include "unicode/uobject.h"
14 #include "unicode/unistr.h"
15 
16 /**
17  * \file
18  * \brief C++ API: String Enumeration
19  */
20 
21 U_NAMESPACE_BEGIN
22 
23 /**
24  * Base class for 'pure' C++ implementations of uenum api.  Adds a
25  * method that returns the next UnicodeString since in C++ this can
26  * be a common storage format for strings.
27  *
28  * <p>The model is that the enumeration is over strings maintained by
29  * a 'service.'  At any point, the service might change, invalidating
30  * the enumerator (though this is expected to be rare).  The iterator
31  * returns an error if this has occurred.  Lack of the error is no
32  * guarantee that the service didn't change immediately after the
33  * call, so the returned string still might not be 'valid' on
34  * subsequent use.</p>
35  *
36  * <p>Strings may take the form of const char*, const UChar*, or const
37  * UnicodeString*.  The type you get is determine by the variant of
38  * 'next' that you call.  In general the StringEnumeration is
39  * optimized for one of these types, but all StringEnumerations can
40  * return all types.  Returned strings are each terminated with a NUL.
41  * Depending on the service data, they might also include embedded NUL
42  * characters, so API is provided to optionally return the true
43  * length, counting the embedded NULs but not counting the terminating
44  * NUL.</p>
45  *
46  * <p>The pointers returned by next, unext, and snext become invalid
47  * upon any subsequent call to the enumeration's destructor, next,
48  * unext, snext, or reset.</p>
49  *
50  * ICU 2.8 adds some default implementations and helper functions
51  * for subclasses.
52  *
53  * @stable ICU 2.4
54  */
55 class U_COMMON_API StringEnumeration : public UObject {
56 public:
57     /**
58      * Destructor.
59      * @stable ICU 2.4
60      */
61     virtual ~StringEnumeration();
62 
63     /**
64      * Clone this object, an instance of a subclass of StringEnumeration.
65      * Clones can be used concurrently in multiple threads.
66      * If a subclass does not implement clone(), or if an error occurs,
67      * then NULL is returned.
68      * The clone functions in all subclasses return a base class pointer
69      * because some compilers do not support covariant (same-as-this)
70      * return types; cast to the appropriate subclass if necessary.
71      * The caller must delete the clone.
72      *
73      * @return a clone of this object
74      *
75      * @see getDynamicClassID
76      * @stable ICU 2.8
77      */
78     virtual StringEnumeration *clone() const;
79 
80     /**
81      * <p>Return the number of elements that the iterator traverses.  If
82      * the iterator is out of sync with its service, status is set to
83      * U_ENUM_OUT_OF_SYNC_ERROR, and the return value is zero.</p>
84      *
85      * <p>The return value will not change except possibly as a result of
86      * a subsequent call to reset, or if the iterator becomes out of sync.</p>
87      *
88      * <p>This is a convenience function. It can end up being very
89      * expensive as all the items might have to be pre-fetched
90      * (depending on the storage format of the data being
91      * traversed).</p>
92      *
93      * @param status the error code.
94      * @return number of elements in the iterator.
95      *
96      * @stable ICU 2.4 */
97     virtual int32_t count(UErrorCode& status) const = 0;
98 
99     /**
100      * <p>Returns the next element as a NUL-terminated char*.  If there
101      * are no more elements, returns NULL.  If the resultLength pointer
102      * is not NULL, the length of the string (not counting the
103      * terminating NUL) is returned at that address.  If an error
104      * status is returned, the value at resultLength is undefined.</p>
105      *
106      * <p>The returned pointer is owned by this iterator and must not be
107      * deleted by the caller.  The pointer is valid until the next call
108      * to next, unext, snext, reset, or the enumerator's destructor.</p>
109      *
110      * <p>If the iterator is out of sync with its service, status is set
111      * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
112      *
113      * <p>If the native service string is a UChar* string, it is
114      * converted to char* with the invariant converter.  If the
115      * conversion fails (because a character cannot be converted) then
116      * status is set to U_INVARIANT_CONVERSION_ERROR and the return
117      * value is undefined (though not NULL).</p>
118      *
119      * Starting with ICU 2.8, the default implementation calls snext()
120      * and handles the conversion.
121      * Either next() or snext() must be implemented differently by a subclass.
122      *
123      * @param status the error code.
124      * @param resultLength a pointer to receive the length, can be NULL.
125      * @return a pointer to the string, or NULL.
126      *
127      * @stable ICU 2.4
128      */
129     virtual const char* next(int32_t *resultLength, UErrorCode& status);
130 
131     /**
132      * <p>Returns the next element as a NUL-terminated UChar*.  If there
133      * are no more elements, returns NULL.  If the resultLength pointer
134      * is not NULL, the length of the string (not counting the
135      * terminating NUL) is returned at that address.  If an error
136      * status is returned, the value at resultLength is undefined.</p>
137      *
138      * <p>The returned pointer is owned by this iterator and must not be
139      * deleted by the caller.  The pointer is valid until the next call
140      * to next, unext, snext, reset, or the enumerator's destructor.</p>
141      *
142      * <p>If the iterator is out of sync with its service, status is set
143      * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
144      *
145      * Starting with ICU 2.8, the default implementation calls snext()
146      * and handles the conversion.
147      *
148      * @param status the error code.
149      * @param resultLength a ponter to receive the length, can be NULL.
150      * @return a pointer to the string, or NULL.
151      *
152      * @stable ICU 2.4
153      */
154     virtual const UChar* unext(int32_t *resultLength, UErrorCode& status);
155 
156     /**
157      * <p>Returns the next element a UnicodeString*.  If there are no
158      * more elements, returns NULL.</p>
159      *
160      * <p>The returned pointer is owned by this iterator and must not be
161      * deleted by the caller.  The pointer is valid until the next call
162      * to next, unext, snext, reset, or the enumerator's destructor.</p>
163      *
164      * <p>If the iterator is out of sync with its service, status is set
165      * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
166      *
167      * Starting with ICU 2.8, the default implementation calls next()
168      * and handles the conversion.
169      * Either next() or snext() must be implemented differently by a subclass.
170      *
171      * @param status the error code.
172      * @return a pointer to the string, or NULL.
173      *
174      * @stable ICU 2.4
175      */
176     virtual const UnicodeString* snext(UErrorCode& status);
177 
178     /**
179      * <p>Resets the iterator.  This re-establishes sync with the
180      * service and rewinds the iterator to start at the first
181      * element.</p>
182      *
183      * <p>Previous pointers returned by next, unext, or snext become
184      * invalid, and the value returned by count might change.</p>
185      *
186      * @param status the error code.
187      *
188      * @stable ICU 2.4
189      */
190     virtual void reset(UErrorCode& status) = 0;
191 
192     /**
193      * Compares this enumeration to other to check if both are equal
194      *
195      * @param that The other string enumeration to compare this object to
196      * @return TRUE if the enumerations are equal. FALSE if not.
197      * @stable ICU 3.6
198      */
199     virtual UBool operator==(const StringEnumeration& that)const;
200     /**
201      * Compares this enumeration to other to check if both are not equal
202      *
203      * @param that The other string enumeration to compare this object to
204      * @return TRUE if the enumerations are equal. FALSE if not.
205      * @stable ICU 3.6
206      */
207     virtual UBool operator!=(const StringEnumeration& that)const;
208 
209 protected:
210     /**
211      * UnicodeString field for use with default implementations and subclasses.
212      * @stable ICU 2.8
213      */
214     UnicodeString unistr;
215     /**
216      * char * default buffer for use with default implementations and subclasses.
217      * @stable ICU 2.8
218      */
219     char charsBuffer[32];
220     /**
221      * char * buffer for use with default implementations and subclasses.
222      * Allocated in constructor and in ensureCharsCapacity().
223      * @stable ICU 2.8
224      */
225     char *chars;
226     /**
227      * Capacity of chars, for use with default implementations and subclasses.
228      * @stable ICU 2.8
229      */
230     int32_t charsCapacity;
231 
232     /**
233      * Default constructor for use with default implementations and subclasses.
234      * @stable ICU 2.8
235      */
236     StringEnumeration();
237 
238     /**
239      * Ensures that chars is at least as large as the requested capacity.
240      * For use with default implementations and subclasses.
241      *
242      * @param capacity Requested capacity.
243      * @param status ICU in/out error code.
244      * @stable ICU 2.8
245      */
246     void ensureCharsCapacity(int32_t capacity, UErrorCode &status);
247 
248     /**
249      * Converts s to Unicode and sets unistr to the result.
250      * For use with default implementations and subclasses,
251      * especially for implementations of snext() in terms of next().
252      * This is provided with a helper function instead of a default implementation
253      * of snext() to avoid potential infinite loops between next() and snext().
254      *
255      * For example:
256      * \code
257      * const UnicodeString* snext(UErrorCode& status) {
258      *   int32_t resultLength=0;
259      *   const char *s=next(&resultLength, status);
260      *   return setChars(s, resultLength, status);
261      * }
262      * \endcode
263      *
264      * @param s String to be converted to Unicode.
265      * @param length Length of the string.
266      * @param status ICU in/out error code.
267      * @return A pointer to unistr.
268      * @stable ICU 2.8
269      */
270     UnicodeString *setChars(const char *s, int32_t length, UErrorCode &status);
271 };
272 
273 U_NAMESPACE_END
274 
275 /* STRENUM_H */
276 #endif
277