ICU-2397 allow to stack-allocate UNormIterator

X-SVN-Rev: 11338
This commit is contained in:
Markus Scherer 2003-03-17 18:32:54 +00:00
parent f2b1b64dc1
commit 026f023227
3 changed files with 43 additions and 10 deletions

View file

@ -55,7 +55,7 @@ struct UNormIterator {
uint32_t state;
/* there are UChars available before start or after limit? */
UBool hasPrevious, hasNext;
UBool hasPrevious, hasNext, isStackAllocated;
UNormalizationMode mode;
@ -548,7 +548,7 @@ static const UCharIterator unormIterator={
/* Setup functions ---------------------------------------------------------- */
U_CAPI UNormIterator * U_EXPORT2
unorm_openIter(UErrorCode *pErrorCode) {
unorm_openIter(void *stackMem, int32_t stackMemSize, UErrorCode *pErrorCode) {
UNormIterator *uni;
/* argument checking */
@ -557,14 +557,33 @@ unorm_openIter(UErrorCode *pErrorCode) {
}
/* allocate */
uni=(UNormIterator *)uprv_malloc(sizeof(UNormIterator));
if(uni==NULL) {
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
return NULL;
uni=NULL;
if(stackMem!=NULL && stackMemSize>=sizeof(UNormIterator)) {
size_t align=U_ALIGNMENT_OFFSET(stackMem);
if(align==0) {
/* already aligned */
uni=(UNormIterator *)stackMem;
} else if((stackMemSize-=align)>=sizeof(UNormIterator)) {
/* needs alignment */
uni=(UNormIterator *)((char *)stackMem+align);
} else {
/* does not fit */
}
}
if(uni!=NULL) {
uprv_memset(uni, 0, sizeof(UNormIterator));
uni->isStackAllocated=TRUE;
} else {
uni=(UNormIterator *)uprv_malloc(sizeof(UNormIterator));
if(uni==NULL) {
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
uprv_memset(uni, 0, sizeof(UNormIterator));
}
/* initialize */
uprv_memset(uni, 0, sizeof(UNormIterator));
uni->chars=uni->charsBuffer;
uni->states=uni->statesBuffer;
uni->capacity=initialCapacity;
@ -581,7 +600,9 @@ unorm_closeIter(UNormIterator *uni) {
/* chars and states are allocated in the same memory block */
uprv_free(uni->states);
}
uprv_free(uni);
if(!uni->isStackAllocated) {
uprv_free(uni);
}
}
}

View file

@ -82,16 +82,28 @@
struct UNormIterator;
typedef struct UNormIterator UNormIterator;
/**
* Size of a stack buffer to hold a UNormIterator, see the stackMem parameter
* of unorm_openIter().
*
* @internal
*/
#define UNORM_ITER_SIZE 1024
/**
* Open a normalizing iterator. Must be closed later.
* Use unorm_setIter().
*
* @param stackMem Pointer to preallocated (stack-allocated) buffer to hold
* the UNormIterator if possible; can be NULL.
* @param stackMemSize Number of bytes at stackMem; can be 0,
* or should be >= UNORM_ITER_SIZE for a non-NULL stackMem.
* @param pErrorCode ICU error code
* @return an allocated and pre-initialized UNormIterator
* @internal
*/
U_CAPI UNormIterator * U_EXPORT2
unorm_openIter(UErrorCode *pErrorCode);
unorm_openIter(void *stackMem, int32_t stackMemSize, UErrorCode *pErrorCode);
/**
* Close a normalizing iterator.

View file

@ -1696,7 +1696,7 @@ testUNormIteratorWithText(const UChar *text, int32_t textLength, int32_t middle,
/* open a normalizing iterator */
errorCode=U_ZERO_ERROR;
uni=unorm_openIter(&errorCode);
uni=unorm_openIter(NULL, 0, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("unorm_openIter() fails: %s\n", u_errorName(errorCode));
return;