mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 22:15:31 +00:00
ICU-699 add StringEnumeration default implementations
X-SVN-Rev: 13595
This commit is contained in:
parent
9de47b7b54
commit
e7251a2b04
3 changed files with 160 additions and 29 deletions
|
@ -1176,30 +1176,7 @@ public:
|
|||
|
||||
const UnicodeString* snext(UErrorCode& status) {
|
||||
int32_t resultLength = 0;
|
||||
const char* starter = next(&resultLength, status);
|
||||
if(starter != NULL) {
|
||||
UChar *buffer = currUSKey.getBuffer(resultLength+1);
|
||||
if(buffer != NULL) {
|
||||
u_charsToUChars(starter, buffer, resultLength);
|
||||
buffer[resultLength] = 0;
|
||||
currUSKey.releaseBuffer(resultLength);
|
||||
return &currUSKey;
|
||||
} else {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const UChar* unext(int32_t* resultLength, UErrorCode& status) {
|
||||
if(snext(status) != NULL) {
|
||||
if(resultLength != NULL) {
|
||||
*resultLength = currUSKey.length();
|
||||
}
|
||||
return currUSKey.getTerminatedBuffer();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return setChars(next(&resultLength, status), resultLength, status);
|
||||
}
|
||||
|
||||
void reset(UErrorCode& /*status*/) {
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
#define STRENUM_H
|
||||
|
||||
#include "unicode/uobject.h"
|
||||
#include "unicode/unistr.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class UnicodeString;
|
||||
|
||||
/**
|
||||
* Base class for 'pure' C++ implementations of uenum api. Adds a
|
||||
* method that returns the next UnicodeString since in C++ this can
|
||||
|
@ -43,6 +42,9 @@ class UnicodeString;
|
|||
* upon any subsequent call to the enumeration's destructor, next,
|
||||
* unext, snext, or reset.</p>
|
||||
*
|
||||
* ICU 2.8 adds some default implementations and helper functions
|
||||
* for subclasses.
|
||||
*
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
class U_COMMON_API StringEnumeration : public UObject {
|
||||
|
@ -109,13 +111,16 @@ public:
|
|||
* status is set to U_INVARIANT_CONVERSION_ERROR and the return
|
||||
* value is undefined (though not NULL).</p>
|
||||
*
|
||||
* Starting with ICU 2.8, the default implementation calls snext()
|
||||
* and handles the conversion.
|
||||
*
|
||||
* @param status the error code.
|
||||
* @param resultLength a pointer to receive the length, can be NULL.
|
||||
* @return a pointer to the string, or NULL.
|
||||
*
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
virtual const char* next(int32_t *resultLength, UErrorCode& status) = 0;
|
||||
virtual const char* next(int32_t *resultLength, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* <p>Returns the next element as a NUL-terminated UChar*. If there
|
||||
|
@ -131,13 +136,16 @@ public:
|
|||
* <p>If the iterator is out of sync with its service, status is set
|
||||
* to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
|
||||
*
|
||||
* Starting with ICU 2.8, the default implementation calls snext()
|
||||
* and handles the conversion.
|
||||
*
|
||||
* @param status the error code.
|
||||
* @param resultLength a ponter to receive the length, can be NULL.
|
||||
* @return a pointer to the string, or NULL.
|
||||
*
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
virtual const UChar* unext(int32_t *resultLength, UErrorCode& status) = 0;
|
||||
virtual const UChar* unext(int32_t *resultLength, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* <p>Returns the next element a UnicodeString*. If there are no
|
||||
|
@ -170,6 +178,68 @@ public:
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
virtual void reset(UErrorCode& status) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* UnicodeString field for use with default implementations and subclasses.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
UnicodeString unistr;
|
||||
/**
|
||||
* char * default buffer for use with default implementations and subclasses.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
char charsBuffer[32];
|
||||
/**
|
||||
* char * buffer for use with default implementations and subclasses.
|
||||
* Allocated in constructor and in ensureCharsCapacity().
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
char *chars;
|
||||
/**
|
||||
* Capacity of chars, for use with default implementations and subclasses.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
int32_t charsCapacity;
|
||||
|
||||
/**
|
||||
* Default constructor for use with default implementations and subclasses.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
StringEnumeration();
|
||||
|
||||
/**
|
||||
* Ensures that chars is at least as large as the requested capacity.
|
||||
* For use with default implementations and subclasses.
|
||||
*
|
||||
* @param capacity Requested capacity.
|
||||
* @param status ICU in/out error code.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
void ensureCharsCapacity(int32_t capacity, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Converts s to Unicode and sets unistr to the result.
|
||||
* For use with default implementations and subclasses,
|
||||
* especially for implementations of snext() in terms of next().
|
||||
* This is provided with a helper function instead of a default implementation
|
||||
* of snext() to avoid potential infinite loops between next() and snext().
|
||||
*
|
||||
* For example:
|
||||
* \code
|
||||
* const UnicodeString* snext(UErrorCode& status) {
|
||||
* int32_t resultLength=0;
|
||||
* return setChars(next(&resultLength, status), resultLength, status);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @param s String to be converted to Unicode.
|
||||
* @param length Length of the string.
|
||||
* @param status ICU in/out error code.
|
||||
* @return A pointer to unistr.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
UnicodeString *setChars(const char *s, int32_t length, UErrorCode &status);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
#include "cstring.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
#define THIS(en) ((StringEnumeration*)(en->context))
|
||||
// StringEnumeration implementation ---------------------------------------- ***
|
||||
|
||||
StringEnumeration::StringEnumeration()
|
||||
: chars(charsBuffer), charsCapacity(sizeof(charsBuffer)) {
|
||||
}
|
||||
|
||||
StringEnumeration::~StringEnumeration() {}
|
||||
|
||||
|
@ -25,6 +29,86 @@ StringEnumeration::clone() const {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
StringEnumeration::next(int32_t *resultLength, UErrorCode &status) {
|
||||
const UnicodeString *s=snext(status);
|
||||
if(s!=NULL) {
|
||||
unistr=*s;
|
||||
ensureCharsCapacity(unistr.length()+1, status);
|
||||
if(U_SUCCESS(status)) {
|
||||
if(resultLength!=NULL) {
|
||||
*resultLength=unistr.length();
|
||||
}
|
||||
unistr.extract(0, INT32_MAX, chars, charsCapacity, "");
|
||||
return chars;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const UChar *
|
||||
StringEnumeration::unext(int32_t *resultLength, UErrorCode &status) {
|
||||
const UnicodeString *s=snext(status);
|
||||
if(s!=NULL) {
|
||||
unistr=*s;
|
||||
if(U_SUCCESS(status)) {
|
||||
if(resultLength!=NULL) {
|
||||
*resultLength=unistr.length();
|
||||
}
|
||||
return unistr.getTerminatedBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
StringEnumeration::ensureCharsCapacity(int32_t capacity, UErrorCode &status) {
|
||||
if(U_SUCCESS(status) && capacity>charsCapacity) {
|
||||
if(capacity<(charsCapacity+charsCapacity/2)) {
|
||||
// avoid allocation thrashing
|
||||
capacity=charsCapacity+charsCapacity/2;
|
||||
}
|
||||
if(chars!=charsBuffer) {
|
||||
uprv_free(chars);
|
||||
}
|
||||
chars=(char *)uprv_malloc(capacity);
|
||||
if(chars==NULL) {
|
||||
chars=charsBuffer;
|
||||
charsCapacity=sizeof(charsBuffer);
|
||||
status=U_MEMORY_ALLOCATION_ERROR;
|
||||
} else {
|
||||
charsCapacity=capacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnicodeString *
|
||||
StringEnumeration::setChars(const char *s, int32_t length, UErrorCode &status) {
|
||||
if(U_SUCCESS(status) && s!=NULL) {
|
||||
if(length<0) {
|
||||
length=uprv_strlen(s);
|
||||
}
|
||||
|
||||
UChar *buffer=unistr.getBuffer(length+1);
|
||||
if(buffer!=NULL) {
|
||||
u_charsToUChars(s, buffer, length);
|
||||
buffer[length]=0;
|
||||
unistr.releaseBuffer(length);
|
||||
return &unistr;
|
||||
} else {
|
||||
status=U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// C wrapper --------------------------------------------------------------- ***
|
||||
|
||||
#define THIS(en) ((StringEnumeration*)(en->context))
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue