Home | History | Annotate | Download | only in unicode
      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