mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 22:15:31 +00:00
ICU-2397 allow to stack-allocate UNormIterator
X-SVN-Rev: 11338
This commit is contained in:
parent
f2b1b64dc1
commit
026f023227
3 changed files with 43 additions and 10 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue