diff --git a/icu4c/source/common/ucmpe32.c b/icu4c/source/common/ucmpe32.c index 34ac8b20a37..8d6aea44ba9 100644 --- a/icu4c/source/common/ucmpe32.c +++ b/icu4c/source/common/ucmpe32.c @@ -23,150 +23,54 @@ #include "cmemory.h" #include "cstring.h" #include "filestrm.h" -#include - - -/* tool memory helper ------------------------------------------------------- */ - -static UToolMemory * -utm_open(const char *name, uint32_t count, uint32_t size) { - UToolMemory *mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+count*size); - if(mem==NULL) { - fprintf(stderr, "error: %s - out of memory\n", name); - exit(U_MEMORY_ALLOCATION_ERROR); - } - uprv_strcpy(mem->name, name); - mem->count=count; - mem->size=size; - mem->index=0; - return mem; -} - -/* we don't use this - we don't clean up memory here... */ -static void -utm_close(UToolMemory *mem) { - if(mem!=NULL) { - uprv_free(mem); - } -} - -static void * -utm_getStart(UToolMemory *mem) { - return (char *)mem->array; -} - -static void * -utm_alloc(UToolMemory *mem) { - char *p=(char *)mem->array+mem->index*mem->size; - if(++mem->index<=mem->count) { - uprv_memset(p, 0, mem->size); - return p; - } else { - fprintf(stderr, "error: %s - trying to use more than %ld preallocated units\n", - mem->name, (long)mem->count); - exit(U_MEMORY_ALLOCATION_ERROR); - } -} - -static void * -utm_allocN(UToolMemory *mem, int32_t n) { - char *p=(char *)mem->array+mem->index*mem->size; - if((mem->index+=(uint32_t)n)<=mem->count) { - uprv_memset(p, 0, n*mem->size); - return p; - } else { - fprintf(stderr, "error: %s - trying to use more than %ld preallocated units\n", - mem->name, (long)mem->count); - exit(U_MEMORY_ALLOCATION_ERROR); - } -} /* builder data ------------------------------------------------------------- */ -CompactEIntArray* ucmpe32_open(int32_t defaultValue) +CompactEIntArray* +ucmpe32_open(int32_t defaultValue, int32_t surrogateValue, UErrorCode *status) { - uint32_t i; - int32_t *p, *p_end; - uint16_t *q, *q_end; - uint32_t *bla; + int32_t *bla; CompactEIntArray* this_obj = (CompactEIntArray*) uprv_malloc(sizeof(CompactEIntArray)); - if (this_obj == NULL) return NULL; - - /* reset stage 1 of the trie */ - uprv_memset(this_obj->stage1, 0, sizeof(this_obj->stage1)); + if (U_FAILURE(*status) || this_obj == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } - /* allocate stage 2 of the trie and reset the first block */ - this_obj->stage2Mem=utm_open("gennorm trie stage 2", 60000, sizeof(*(this_obj->stage2))); - this_obj->stage2=utm_allocN(this_obj->stage2Mem, _UCMPE32_STAGE_2_BLOCK_COUNT); - for(bla = this_obj->stage2; blastage2+_UCMPE32_STAGE_2_BLOCK_COUNT; bla++) { - *bla = 0xF0000000; - } + this_obj->fAlias = FALSE; this_obj->fStructSize = sizeof(CompactEIntArray); - this_obj->fArray = NULL; - this_obj->fIndex = NULL; - this_obj->fCount = UCMPE32_kUnicodeCount; + + this_obj->stage1Top = _UCMPE32_STAGE_1_MAX_COUNT; + this_obj->stage1 = (uint16_t *)uprv_malloc(_UCMPE32_STAGE_1_MAX_COUNT*sizeof(uint16_t)); + if(this_obj->stage1 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(this_obj); + return NULL; + } + + + /* reset stage 1 of the trie */ + uprv_memset(this_obj->stage1, 0, this_obj->stage1Top*sizeof(uint16_t)); + + /* allocate stage 2 of the trie and reset the first block */ + this_obj->stage2= (int32_t*)uprv_malloc(60000*sizeof(*(this_obj->stage2))); + if(this_obj->stage2 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(this_obj->stage1); + uprv_free(this_obj); + return NULL; + } + this_obj->fDefaultValue = defaultValue; + this_obj->fSurrogateValue = surrogateValue; + for(bla = this_obj->stage2; blastage2+_UCMPE32_STAGE_2_BLOCK_COUNT; bla++) { + *bla = this_obj->fDefaultValue; + } + this_obj->stage2Top = _UCMPE32_STAGE_2_BLOCK_COUNT; + this_obj->fCompact = FALSE; this_obj->fBogus = FALSE; - this_obj->fAlias = FALSE; - this_obj->fIAmOwned = FALSE; - -/*set up the index array and the data array. - * the index array always points into particular parts of the data array - * it is initially set up to point at regular block boundaries - * The following example uses blocks of 4 for simplicity - * Example: Expanded - * INDEX# 0 1 2 3 4 - * INDEX 0 4 8 12 16 ... - * ARRAY abcdeababcedzyabcdea... - * | | | | | |... - * whenever you set an element in the array, it unpacks to this_obj state - * After compression, the index will point to various places in the data array - * wherever there is a runs of the same elements as in the original - * Example: Compressed - * INDEX# 0 1 2 3 4 - * INDEX 0 4 1 8 2 ... - * ARRAY abcdeabazyabc... - * If you look at the example, index# 2 in the expanded version points - * to data position number 8, which has elements "bced". In the compressed - * version, index# 2 points to data position 1, which also has "bced" - */ - this_obj->fArray = (int32_t*)uprv_malloc(UCMPE32_kUnicodeCount * sizeof(int32_t)); - if (this_obj->fArray == NULL) { - this_obj->fBogus = TRUE; - return NULL; - } - - this_obj->fIndex = (uint16_t*)uprv_malloc(UCMPE32_kIndexCount * sizeof(uint16_t)); - if (!this_obj->fIndex) { - uprv_free(this_obj->fArray); - this_obj->fArray = NULL; - this_obj->fBogus = TRUE; - return NULL; - } - p = this_obj->fArray; - p_end = p + UCMPE32_kUnicodeCount; - while (p < p_end) *p++ = defaultValue; - q = this_obj->fIndex; - - q_end = q + UCMPE32_kIndexBMPCount; - i = 0; - while (q < q_end) - { - *q++ = (uint16_t)(i >> UCMPE32_kBlockShift); - i += (1 << UCMPE32_kBlockShift); - } - - q_end = this_obj->fIndex + UCMPE32_kIndexCount; - - while (q < q_end) - { - *q++ = (uint16_t)(i >> UCMPE32_kBlockShift); - i += (1 << UCMPE32_kBlockShift); - } - - return this_obj; + return this_obj; } @@ -176,7 +80,8 @@ CompactEIntArray* ucmpe32_open(int32_t defaultValue) * get or create the intermediate trie entries for it as well */ /********* THIS IS THE ADD FUNCTION ********************/ -void ucmpe32_set32(CompactEIntArray* this_obj, UChar32 code, int32_t value) +void +ucmpe32_set32(CompactEIntArray* this_obj, UChar32 code, int32_t value) { uint16_t stage2Block, k; @@ -192,12 +97,13 @@ void ucmpe32_set32(CompactEIntArray* this_obj, UChar32 code, int32_t value) j=this_obj->stage1[i]; if(j==0) { /* allocate a stage 2 block */ - uint32_t *p, *bla; - - p=(uint32_t *)utm_allocN(this_obj->stage2Mem, _UCMPE32_STAGE_2_BLOCK_COUNT); + int32_t *p, *bla; + p = this_obj->stage2+this_obj->stage2Top; for(bla = p; blafDefaultValue; } + this_obj->stage2Top += _UCMPE32_STAGE_2_BLOCK_COUNT; + this_obj->stage1[i]=j=(uint16_t)(p-this_obj->stage2); } stage2Block=j; @@ -208,7 +114,8 @@ void ucmpe32_set32(CompactEIntArray* this_obj, UChar32 code, int32_t value) this_obj->stage2[k] = value; } -void ucmpe32_setSurrogate(CompactEIntArray* this_obj, UChar lead, UChar trail, int32_t value) +void +ucmpe32_setSurrogate(CompactEIntArray* this_obj, UChar lead, UChar trail, int32_t value) { if (this_obj->fCompact == TRUE) { return; @@ -217,48 +124,20 @@ void ucmpe32_setSurrogate(CompactEIntArray* this_obj, UChar lead, UChar trail, } -int32_t ucmpe32_get32(CompactEIntArray *this_obj, UChar32 index) { - int32_t index_lookup = this_obj->stage1[index >> _UCMPE32_TRIE_SHIFT] ; - int32_t addition = (index & _UCMPE32_STAGE_2_MASK); - - return (this_obj->stage2[index_lookup + addition]); -/* - int32_t index_lookup = array->fIndex[(index >> UCMPE32_kBlockShift)] << UCMPE32_kBlockShift; - int32_t addition = (index & UCMPE32_kBlockMask); - - return (array->fArray[index_lookup + addition]); -*/ -} - -int32_t ucmpe32_getSurrogate(CompactEIntArray *array, UChar lead, UChar trail) { - return(ucmpe32_get32(array, (int32_t)UTF16_GET_PAIR_VALUE(lead, trail))); -#if 0 - int32_t leadValue32 = ucmpe32_get(array, lead); - int32_t c = ((leadValue32 & 0xffc00) | (trail & 0x3ff)); - /* Lead surrogate data needs to be in the following format: */ - /* F50XXY000 - where X mask is 1111 (F) and Y mask is 1100 (C) */ - /* The ten bits for access will be in the middle of the field */ - int32_t fixed_addition = UCMPE32_kIndexBMPCount; - int32_t index_lookup = array->fIndex[fixed_addition + (c >> UCMPE32_kBlockShift)]; - int32_t addition = (c & UCMPE32_kBlockMask); - return (stage2[index_lookup+ addition]); - /*return (array->fArray[FUNKY_CONST + array->fIndex[c >> UCMPE32_kBlockShift]+ (c & UCMPE32_kBlockMask)]);*/ -#endif -} - /* * Fold the supplementary code point data for one lead surrogate. */ static uint16_t -foldLeadSurrogate(uint16_t *parent, uint16_t parentCount, - uint32_t *stage, uint16_t *pStageCount, - uint32_t base) { +foldLeadSurrogate(uint16_t *parent, int32_t parentCount, + int32_t *stage, int32_t *pStageCount, + uint32_t base, int32_t surrogateValue) { uint32_t leadNorm32=0; uint32_t i, j, s2; uint32_t leadSurrogate=0xd7c0+(base>>10); +#if 0 printf("supplementary data for lead surrogate U+%04lx\n", (long)leadSurrogate); - +#endif /* calculate the 32-bit data word for the lead surrogate */ for(i=0; i<_UCMPE32_SURROGATE_BLOCK_COUNT; ++i) { s2=parent[(base>>_UCMPE32_TRIE_SHIFT)+i]; @@ -271,7 +150,6 @@ foldLeadSurrogate(uint16_t *parent, uint16_t parentCount, } if(leadNorm32==0) { - /* FCD: nothing to do */ return 0; } @@ -284,13 +162,13 @@ foldLeadSurrogate(uint16_t *parent, uint16_t parentCount, * this is because 16 bits in the FCD trie data do not allow for anything * but the two leading and trailing combining classes of the canonical decomposition. */ - leadNorm32=parentCount>>_UCMPE32_SURROGATE_BLOCK_BITS; + leadNorm32= surrogateValue | ((parentCount<<_UCMPE32_TRIE_SHIFT)&~_UCMPE32_STAGE_2_MASK); /* enter the lead surrogate's data */ s2=parent[leadSurrogate>>_UCMPE32_TRIE_SHIFT]; if(s2==0) { /* allocate a new stage 2 block in stage (the memory is there from makeAll32()/makeFCD()) */ - s2=parent[leadSurrogate>>_UCMPE32_TRIE_SHIFT]=*pStageCount; + s2=parent[leadSurrogate>>_UCMPE32_TRIE_SHIFT]=(uint16_t)*pStageCount; *pStageCount+=_UCMPE32_STAGE_2_BLOCK_COUNT; } stage[s2+(leadSurrogate&_UCMPE32_STAGE_2_MASK)]=leadNorm32; @@ -309,9 +187,10 @@ foldLeadSurrogate(uint16_t *parent, uint16_t parentCount, * * Use after makeAll32(). */ -static uint16_t -foldSupplementary(uint16_t *parent, uint16_t parentCount, - uint32_t *stage, uint16_t *pStageCount) { +static uint32_t +foldSupplementary(uint16_t *parent, int32_t parentCount, + int32_t *stage, int32_t *pStageCount, + int32_t surrogateValue) { uint32_t c; uint16_t i; @@ -321,38 +200,46 @@ foldSupplementary(uint16_t *parent, uint16_t parentCount, if(i!=0) { /* there is data, treat the full block for a lead surrogate */ c&=~0x3ff; - parentCount+=foldLeadSurrogate(parent, parentCount, stage, pStageCount, c); + parentCount+=foldLeadSurrogate(parent, parentCount, stage, pStageCount, c, surrogateValue); c+=0x400; } else { c+=_UCMPE32_STAGE_2_BLOCK_COUNT; } } - +#if 0 printf("trie index count: BMP %u all Unicode %lu folded %u\n", _UCMPE32_STAGE_1_BMP_COUNT, (long)_UCMPE32_STAGE_1_MAX_COUNT, parentCount); +#endif return parentCount; } -static uint16_t -compact(uint16_t *parent, uint16_t parentCount, - uint32_t *stage, uint16_t stageCount) { +void +ucmpe32_compact(CompactEIntArray* this_obj) { + + if(this_obj->fCompact == FALSE) { /* compacting can be done only once */ /* * This function is the common implementation for compacting * the stage 2 tables of 32-bit values. * It is a copy of genprops/store.c's compactStage() adapted for the 32-bit stage 2 tables. */ static uint16_t map[0x10000>>_UCMPE32_TRIE_SHIFT]; - uint32_t x; + int32_t x; uint16_t i, start, prevEnd, newStart; + /* fold supplementary code points into lead surrogates */ + this_obj->stage1Top=foldSupplementary(this_obj->stage1, _UCMPE32_STAGE_1_BMP_COUNT, + this_obj->stage2, &this_obj->stage2Top, this_obj->fSurrogateValue); + map[0]=0; newStart=_UCMPE32_STAGE_2_BLOCK_COUNT; - for(start=newStart; startstage2Top;) { prevEnd=(uint16_t)(newStart-1); - x=stage[start]; - if(x==stage[prevEnd]) { + x=this_obj->stage2[start]; + if(x==this_obj->stage2[prevEnd]) { /* overlap by at least one */ - for(i=1; i<_UCMPE32_STAGE_2_BLOCK_COUNT && x==stage[start+i] && x==stage[prevEnd-i]; ++i) {} + for(i=1; i<_UCMPE32_STAGE_2_BLOCK_COUNT + && x==this_obj->stage2[start+i] + && x==this_obj->stage2[prevEnd-i]; ++i) {} /* overlap by i */ map[start>>_UCMPE32_TRIE_SHIFT]=(uint16_t)(newStart-i); @@ -360,13 +247,13 @@ compact(uint16_t *parent, uint16_t parentCount, /* move the non-overlapping indexes to their new positions */ start+=i; for(i=(uint16_t)(_UCMPE32_STAGE_2_BLOCK_COUNT-i); i>0; --i) { - stage[newStart++]=stage[start++]; + this_obj->stage2[newStart++]=this_obj->stage2[start++]; } } else if(newStart>_UCMPE32_TRIE_SHIFT]=newStart; for(i=_UCMPE32_STAGE_2_BLOCK_COUNT; i>0; --i) { - stage[newStart++]=stage[start++]; + this_obj->stage2[newStart++]=this_obj->stage2[start++]; } } else /* no overlap && newStart==start */ { map[start>>_UCMPE32_TRIE_SHIFT]=start; @@ -375,513 +262,180 @@ compact(uint16_t *parent, uint16_t parentCount, } } - /* now adjust the parent table */ - for(i=0; i>_UCMPE32_TRIE_SHIFT]; + /* now adjust the stage1 table */ + for(i=0; istage1Top; ++i) { + this_obj->stage1[i]=map[this_obj->stage1[i]>>_UCMPE32_TRIE_SHIFT]; } - +#if 0 /* we saved some space */ printf("compacting trie: count of 32-bit words %lu->%lu\n", - (long)stageCount, (long)newStart); - return newStart; -} - -void ucmpe32_compact(CompactEIntArray* this_obj, int32_t cycle) { - uint16_t top = (uint16_t)this_obj->stage2Mem->index; - /* FCD: fold supplementary code points into lead surrogates */ - this_obj->stage1Top=foldSupplementary(this_obj->stage1, _UCMPE32_STAGE_1_BMP_COUNT, this_obj->stage2, &top); - - /* FCD: compact stage 2 */ - top=compact(this_obj->stage1, this_obj->stage1Top, this_obj->stage2, top); + (long)this_obj->stage2Top, (long)newStart); +#endif + this_obj->stage2Top = newStart; + this_obj->fCompact = TRUE; + } } - -extern void -cleanUpData(CompactEIntArray* this_obj) { - utm_close(this_obj->stage2Mem); -} - -int32_t ucmpe32_getkUnicodeCount() { return UCMPE32_kUnicodeCount;} -int32_t ucmpe32_getkBlockCount() { return UCMPE32_kBlockCount;} - -U_CAPI void ucmpe32_streamIn(CompactEIntArray* this_obj, FileStream* is) -{ -int32_t newCount, len; -char c; - if (!T_FileStream_error(is)) - { - - T_FileStream_read(is, &newCount, sizeof(newCount)); - if (this_obj->fCount != newCount) - { - this_obj->fCount = newCount; - uprv_free(this_obj->fArray); - this_obj->fArray = 0; - this_obj->fArray = (int32_t*)uprv_malloc(this_obj->fCount * sizeof(int32_t)); - if (!this_obj->fArray) { - this_obj->fBogus = TRUE; - return; - } - } - T_FileStream_read(is, this_obj->fArray, sizeof(*(this_obj->fArray)) * this_obj->fCount); - T_FileStream_read(is, &len, sizeof(len)); - if (len == 0) - { - uprv_free(this_obj->fIndex); - this_obj->fIndex = 0; - } - else if (len == UCMPE32_kIndexCount) - { - if (this_obj->fIndex == 0) - this_obj->fIndex =(uint16_t*)uprv_malloc(UCMPE32_kIndexCount * sizeof(uint16_t)); - if (!this_obj->fIndex) { - this_obj->fBogus = TRUE; - uprv_free(this_obj->fArray); - this_obj->fArray = 0; - return; - } - T_FileStream_read(is, this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMPE32_kIndexCount); - } - else - { - this_obj->fBogus = TRUE; - return; - } - /* char instead of int8_t for Mac compilation*/ - T_FileStream_read(is, (char*)&c, sizeof(c)); - this_obj->fCompact = (UBool)(c != 0); - } -} - -U_CAPI void ucmpe32_streamOut(CompactEIntArray* this_obj, FileStream* os) -{ - char c; -if (!T_FileStream_error(os)) - { - if (this_obj->fCount != 0 && this_obj->fArray != 0) - { - T_FileStream_write(os, &(this_obj->fCount), sizeof(this_obj->fCount)); - T_FileStream_write(os, this_obj->fArray, sizeof(*(this_obj->fArray)) * this_obj->fCount); - } - else - { - int32_t zero = 0; - T_FileStream_write(os, &zero, sizeof(zero)); - } - - if (this_obj->fIndex == 0) - { - int32_t len = 0; - T_FileStream_write(os, &len, sizeof(len)); - } - else - { - int32_t len = UCMPE32_kIndexCount; - T_FileStream_write(os, &len, sizeof(len)); - T_FileStream_write(os, this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMPE32_kIndexCount); - } - c = (char)(this_obj->fCompact ? 1 : 0); /* char instead of int8_t for Mac compilation*/ - T_FileStream_write(os, (const char*)&c, sizeof(c)); - } -} - -U_CAPI void ucmpe32_streamMemIn(CompactEIntArray* this_obj, UMemoryStream* is) -{ -int32_t newCount, len; -char c; - if (!uprv_mstrm_error(is)) - { - - uprv_mstrm_read(is, &newCount, sizeof(newCount)); - if (this_obj->fCount != newCount) - { - this_obj->fCount = newCount; - uprv_free(this_obj->fArray); - this_obj->fArray = 0; - this_obj->fArray = (int32_t*)uprv_malloc(this_obj->fCount * sizeof(int32_t)); - if (!this_obj->fArray) { - this_obj->fBogus = TRUE; - return; - } - } - uprv_mstrm_read(is, this_obj->fArray, sizeof(*(this_obj->fArray)) * this_obj->fCount); - uprv_mstrm_read(is, &len, sizeof(len)); - if (len == 0) - { - uprv_free(this_obj->fIndex); - this_obj->fIndex = 0; - } - else if (len == UCMPE32_kIndexCount) - { - if (this_obj->fIndex == 0) - this_obj->fIndex =(uint16_t*)uprv_malloc(UCMPE32_kIndexCount * sizeof(uint16_t)); - if (!this_obj->fIndex) { - this_obj->fBogus = TRUE; - uprv_free(this_obj->fArray); - this_obj->fArray = 0; - return; - } - uprv_mstrm_read(is, this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMPE32_kIndexCount); - } - else - { - this_obj->fBogus = TRUE; - return; - } - /* char instead of int8_t for Mac compilation*/ - uprv_mstrm_read(is, (char*)&c, sizeof(c)); - this_obj->fCompact = (UBool)(c != 0); - } -} - -U_CAPI void ucmpe32_streamMemOut(CompactEIntArray* this_obj, UMemoryStream* os) -{ - char c; -if (!uprv_mstrm_error(os)) - { - if (this_obj->fCount != 0 && this_obj->fArray != 0) - { - uprv_mstrm_write(os, (uint8_t *)&(this_obj->fCount), sizeof(this_obj->fCount)); - uprv_mstrm_write(os, (uint8_t *)this_obj->fArray, sizeof(*(this_obj->fArray)) * this_obj->fCount); - } - else - { - int32_t zero = 0; - uprv_mstrm_write(os, (uint8_t *)&zero, sizeof(zero)); - } - - if (this_obj->fIndex == 0) - { - int32_t len = 0; - uprv_mstrm_write(os, (uint8_t *)&len, sizeof(len)); - } - else - { - int32_t len = UCMPE32_kIndexCount; - uprv_mstrm_write(os, (uint8_t *)&len, sizeof(len)); - uprv_mstrm_write(os, (uint8_t *)this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMPE32_kIndexCount); - } - c = (char)(this_obj->fCompact ? 1 : 0); /* char instead of int8_t for Mac compilation*/ - uprv_mstrm_write(os, (uint8_t *)&c, sizeof(c)); - } -} - - -CompactEIntArray* ucmpe32_openAdopt(uint16_t *indexArray, - int32_t *newValues, - int32_t count) +CompactEIntArray* +ucmpe32_clone(CompactEIntArray* orig, UErrorCode *status) { CompactEIntArray* this_obj = (CompactEIntArray*) uprv_malloc(sizeof(CompactEIntArray)); + if(orig == NULL || orig->fBogus == TRUE || this_obj == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + this_obj->fAlias = FALSE; + + this_obj->fDefaultValue = orig->fDefaultValue; + this_obj->fSurrogateValue = orig->fSurrogateValue; + + this_obj->stage1Top = orig->stage1Top; + this_obj->stage1 = (uint16_t *)uprv_malloc(this_obj->stage1Top*sizeof(uint16_t)); + if(this_obj->stage1 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(this_obj); + return NULL; + } + uprv_memcpy(this_obj->stage1, orig->stage1, this_obj->stage1Top*sizeof(uint16_t)); + + this_obj->stage2Top = orig->stage2Top; + this_obj->stage2 = (int32_t*)uprv_malloc(60000*sizeof(*(this_obj->stage2))); + if(this_obj->stage2 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(this_obj->stage1); + uprv_free(this_obj); + return NULL; + } + uprv_memcpy(this_obj->stage2, orig->stage2, this_obj->stage2Top*sizeof(*(this_obj->stage2))); + + this_obj->fBogus = FALSE; + this_obj->fStructSize = sizeof(CompactEIntArray); + + this_obj->fCompact = orig->fCompact; - ucmpe32_initAdopt(this_obj, indexArray, newValues, count); - this_obj->fIAmOwned = FALSE; return this_obj; } -CompactEIntArray* ucmpe32_openAlias(uint16_t *indexArray, - int32_t *newValues, - int32_t count) -{ - CompactEIntArray* this_obj = (CompactEIntArray*) uprv_malloc(sizeof(CompactEIntArray)); - ucmpe32_initAlias(this_obj, indexArray, newValues, count); - this_obj->fIAmOwned = FALSE; - return this_obj; -} - -CompactEIntArray* ucmpe32_openFromData( const uint8_t **source, +CompactEIntArray* +ucmpe32_openFromData( const uint8_t **source, UErrorCode *status) { + uint32_t i; + const uint8_t *oldSource = *source; + CompactEIntArray* this_obj = (CompactEIntArray*) uprv_malloc(sizeof(CompactEIntArray)); - ucmpe32_initFromData(this_obj, source, status); - this_obj->fIAmOwned = FALSE; - return this_obj; -} -/*=======================================================*/ - -CompactEIntArray* ucmpe32_initAdopt(CompactEIntArray* this_obj, - uint16_t *indexArray, - int32_t *newValues, - int32_t count) -{ - if (this_obj) { - this_obj->fCount = count; - this_obj->fBogus = FALSE; - this_obj->fStructSize = sizeof(CompactEIntArray); - - this_obj->fArray = newValues; - this_obj->fIndex = indexArray; - this_obj->fCompact = (UBool)((count < UCMPE32_kUnicodeCount) ? TRUE : FALSE); - this_obj->fAlias = FALSE; - this_obj->fIAmOwned = TRUE; + if(U_FAILURE(*status) || *source == NULL || this_obj == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; } - return this_obj; -} + i = * ((const uint32_t*) *source); + (*source) += 4; -CompactEIntArray* ucmpe32_initAlias(CompactEIntArray* this_obj, - uint16_t *indexArray, - int32_t *newValues, - int32_t count) -{ - if (this_obj) { - this_obj->fCount = count; - this_obj->fBogus = FALSE; - this_obj->fStructSize = sizeof(CompactEIntArray); - - this_obj->fArray = newValues; - this_obj->fIndex = indexArray; - this_obj->fCompact = (UBool)((count < UCMPE32_kUnicodeCount) ? TRUE : FALSE); - this_obj->fAlias = TRUE; - this_obj->fIAmOwned = TRUE; + if(i != ICU_UCMPE32_VERSION) + { + *status = U_INVALID_FORMAT_ERROR; + return NULL; } + this_obj->fAlias = TRUE; + this_obj->stage1 = NULL; + this_obj->stage2 = NULL; + this_obj->fBogus = FALSE; + this_obj->fStructSize = sizeof(CompactEIntArray); + this_obj->fCompact = TRUE; + + this_obj->stage1Top = * ((const uint32_t*)*source); + (*source) += 4; + + this_obj->stage1 = (uint16_t*) *source; + (*source) += sizeof(this_obj->stage1[0])*this_obj->stage1Top; + + this_obj->stage2Top = * ((const uint32_t*)*source); + (*source) += 4; + + this_obj->stage2 = (int32_t*) *source; + (*source) += sizeof(this_obj->stage2[0])*this_obj->stage2Top; + return this_obj; } + +uint32_t +ucmpe32_flattenMem (const CompactEIntArray* this_obj, UMemoryStream *MS) +{ + /* This dumps stuff in memory */ + /* there is no padding, as there is always an even number of 16-bit values */ + /* (stage1), so everything is always 32 bit aligned */ + + int32_t size = 0; + if(this_obj->fCompact == TRUE) { + uprv_mstrm_write32(MS, ICU_UCMPE32_VERSION); + size += 4; + + uprv_mstrm_write32(MS, this_obj->stage1Top); + size += 4; + + uprv_mstrm_writeBlock(MS, this_obj->stage1, this_obj->stage1Top*sizeof(this_obj->stage1[0])); + size += this_obj->stage1Top*sizeof(this_obj->stage1[0]); + + uprv_mstrm_write32(MS, this_obj->stage2Top); + size += 4; + + uprv_mstrm_writeBlock(MS, this_obj->stage2, this_obj->stage2Top*sizeof(this_obj->stage2[0])); + size += this_obj->stage2Top*sizeof(this_obj->stage2[0]); + } + return size; +} + /*=======================================================*/ void ucmpe32_close(CompactEIntArray* this_obj) { if(this_obj != NULL) { - if(!this_obj->fAlias) { - if(this_obj->fArray != NULL) { - uprv_free(this_obj->fArray); - } - if(this_obj->fIndex != NULL) { - uprv_free(this_obj->fIndex); - } - } - if(!this_obj->fIAmOwned) { /* Called if 'init' was called instead of 'open'. */ - uprv_free(this_obj); + if(this_obj->fAlias == FALSE) { + if(this_obj->stage1 != NULL) { + uprv_free(this_obj->stage1); + } + if(this_obj->stage2 != NULL) { + uprv_free(this_obj->stage2); + } } + uprv_free(this_obj); } } -UBool ucmpe32_isBogus(const CompactEIntArray* this_obj) -{ - return (UBool)(this_obj == NULL || this_obj->fBogus); -} - -void ucmpe32_expand(CompactEIntArray* this_obj) { -/* can optimize later. - * if we have to expand, then walk through the blocks instead of using Get - * this_obj code unpacks the array by copying the blocks to the normalized position. - * Example: Compressed - * INDEX# 0 1 2 3 4 - * INDEX 0 4 1 8 2 ... - * ARRAY abcdeabazyabc... - * turns into - * Example: Expanded - * INDEX# 0 1 2 3 4 - * INDEX 0 4 8 12 16 ... - * ARRAY abcdeababcedzyabcdea... - */ - int32_t i; - int32_t* tempArray; - if (this_obj->fCompact) { - tempArray = (int32_t*)uprv_malloc(UCMPE32_kUnicodeCount * sizeof(int32_t)); - if (tempArray == NULL) { - this_obj->fBogus = TRUE; - return; - } - for (i = 0; i < UCMPE32_kUnicodeCount; ++i) { - tempArray[i] = ucmpe32_get(this_obj, (UChar)i); /* HSYS : How expand?*/ - } - for (i = 0; i < UCMPE32_kIndexCount; ++i) { - this_obj->fIndex[i] = (uint16_t)(i<fArray); - this_obj->fArray = tempArray; - this_obj->fCompact = FALSE; - } -} - -uint32_t ucmpe32_getCount(const CompactEIntArray* this_obj) -{ - return this_obj->fCount; -} - -const int32_t* ucmpe32_getArray(const CompactEIntArray* this_obj) -{ - return this_obj->fArray; -} - -const uint16_t* ucmpe32_getIndex(const CompactEIntArray* this_obj) -{ - return this_obj->fIndex; -} - - -void ucmpe32_setRange(CompactEIntArray* this_obj, UChar start, UChar end, int32_t value) -{ - int32_t i; - if (this_obj->fCompact == TRUE) { - ucmpe32_expand(this_obj); - if (this_obj->fBogus) return; - - } - for (i = start; i <= end; ++i) { - this_obj->fArray[i] = value; - } -} - -U_CAPI uint32_t U_EXPORT2 ucmpe32_flattenMem (const CompactEIntArray* array, UMemoryStream *MS) -{ - int32_t size = 0; - - uprv_mstrm_write32(MS, ICU_UCMPE32_VERSION); - size += 4; - - uprv_mstrm_write32(MS, array->fCount); - size += 4; - - uprv_mstrm_writeBlock(MS, array->fIndex, sizeof(array->fIndex[0])*UCMPE32_kIndexCount); - size += sizeof(array->fIndex[0])*UCMPE32_kIndexCount; - - uprv_mstrm_writeBlock(MS, array->fArray, sizeof(array->fArray[0])*array->fCount); - size += sizeof(array->fArray[0])*array->fCount; - - while(size%4) /* end padding */ - { - uprv_mstrm_writePadding(MS, 1); /* Pad total so far to even size */ - size += 1; +int32_t +ucmpe32_getSurrogateEx(CompactEIntArray *array, UChar lead, UChar trail) { + if(array->fCompact == FALSE) { + return(ucmpe32_get(array, (int32_t)UTF16_GET_PAIR_VALUE(lead, trail))); + } else { + return(ucmpe32_getSurrogate(array, ucmpe32_get(array, lead), trail)); } - - return size; } -U_CAPI void U_EXPORT2 ucmpe32_initFromData(CompactEIntArray *this_obj, const uint8_t **source, UErrorCode *status) -{ - uint32_t i; - const uint8_t *oldSource = *source; - - if(U_FAILURE(*status)) - return; - - this_obj->fArray = NULL; - this_obj->fIndex = NULL; - this_obj->fBogus = FALSE; - this_obj->fStructSize = sizeof(CompactEIntArray); - this_obj->fCompact = TRUE; - this_obj->fAlias = TRUE; - this_obj->fIAmOwned = TRUE; - - i = * ((const uint32_t*) *source); - (*source) += 4; - - if(i != ICU_UCMPE32_VERSION) - { - *status = U_INVALID_FORMAT_ERROR; - return; - } - - this_obj->fCount = * ((const uint32_t*)*source); - (*source) += 4; - - this_obj->fIndex = (uint16_t*) *source; - (*source) += sizeof(this_obj->fIndex[0])*UCMPE32_kIndexCount; - - this_obj->fArray = (int32_t*) *source; - (*source) += sizeof(this_obj->fArray[0])*this_obj->fCount; - - /* eat up padding */ - while((*source-(oldSource))%4) - (*source)++; -} - - -/* Stuff that might become handy later. From Markuses code*/ - +/*=======================================================*/ +/* retrieval stuff as functions */ #if 0 - extern void - generateData(const char *dataDir) { - UNewDataMemory *pData; - uint16_t *p16; - UErrorCode errorCode=U_ZERO_ERROR; - uint32_t size, dataLength; - uint16_t i; +int32_t +ucmpe32_get32(CompactEIntArray *this_obj, UChar32 index) { + int32_t index_lookup = this_obj->stage1[index >> _UCMPE32_TRIE_SHIFT] ; + int32_t addition = (index & _UCMPE32_STAGE_2_MASK); - size= - _UCMPE32_INDEX_TOP*2+ - stage1Top*2+ - norm32TableTop*4+ - extraMem->index*2+ - combiningTableTop*2+ - fcdStage1Top*2+ - fcdTableTop*2; + return (this_obj->stage2[index_lookup + addition]); +} - printf("size of " DATA_NAME "." DATA_TYPE " contents: %lu bytes\n", (long)size); - /* adjust the stage 1 indexes to offset stage 2 from the beginning of stage 1 */ - - /* stage1/norm32Table */ - for(i=0; iindex*2); - udata_writeBlock(pData, combiningTable, combiningTableTop*2); - udata_writeBlock(pData, fcdStage1, fcdStage1Top*2); - udata_writeBlock(pData, fcdTable, fcdTableTop*2); - - /* finish up */ - dataLength=udata_finish(pData, &errorCode); - if(U_FAILURE(errorCode)) { - fprintf(stderr, "gennorm: error %d writing the output file\n", errorCode); - exit(errorCode); - } - - if(dataLength!=size) { - fprintf(stderr, "gennorm: data length %lu != calculated size %lu\n", - (long)dataLength, (long)size); - exit(U_INTERNAL_PROGRAM_ERROR); - } - } - - /* get an existing Norm unit */ - static Norm * - getNorm(uint32_t code) { - uint32_t i; - uint16_t j; - - /* access stage 1 and get the stage 2 block start index */ - i=code>>_UCMPE32_TRIE_SHIFT; - j=stage1[i]; - if(j==0) { - return NULL; - } - - /* access stage 2 and get the Norm unit */ - i=(uint16_t)(j+(code&_UCMPE32_STAGE_2_MASK)); - j=stage2[i]; - if(j==0) { - return NULL; - } else { - return norms+j; - } - } +/* Lead surrogate data needs to be in the following format: */ +/* F50XXY000 - where X mask is 1111 (F) and Y mask is 1100 (C) */ +/* The ten bits for access will be in the middle of the field */ +int32_t +ucmpe32_getSurrogate(CompactEIntArray *array, int32_t leadValue32, UChar trail) { + int32_t c = ((leadValue32 & 0xffc00) | (trail & 0x3ff)); + int32_t index_lookup = array->stage1[(c >> _UCMPE32_TRIE_SHIFT)]; + int32_t addition = (c & _UCMPE32_STAGE_2_MASK); + return (array->stage2[index_lookup+ addition]); +} #endif diff --git a/icu4c/source/common/ucmpe32.h b/icu4c/source/common/ucmpe32.h index 56e575d2cad..17915216e7d 100644 --- a/icu4c/source/common/ucmpe32.h +++ b/icu4c/source/common/ucmpe32.h @@ -19,6 +19,14 @@ * nicely. */ +/** + * NOTE: This array is specifically implemented to support surrogates + * in the collation framework. It's interface is minimal and usage model + * is far from the flexible. Use at your own risk outside of collation. + * Risk is also present in the collation framework, but there is hardly + * anything you can do about it, save reimplementig the framework + */ + #ifndef UCMPE32_H #define UCMPE32_H @@ -29,24 +37,6 @@ #include "filestrm.h" #include "umemstrm.h" -/* INTERNAL CONSTANTS */ -#define UCMPE32_kBlockShift 7 - -#define UCMPE32_kBlockCount (1<>UCMPE32_kBlockShift) - -/*#define UCMPE32_kIndexBMPCount (1<<(16-UCMPE32_kBlockShift))*/ -#define UCMPE32_kIndexBMPCount (0x10000>>UCMPE32_kBlockShift) - - -#define UCMPE32_kUnicodeCount 0x110000 /* trie constants */ enum { @@ -74,161 +64,41 @@ enum { /* this may be >0xffff and may not work as an enum */ #define _UCMPE32_STAGE_1_MAX_COUNT (0x110000>>_UCMPE32_TRIE_SHIFT) -typedef struct UToolMemory { - char name[64]; - uint32_t count, size, index; - uint32_t array[1]; -} UToolMemory; - -/** - * class CompactATypeArray : use only on primitive data types - * Provides a compact way to store information that is indexed by Unicode - * values, such as character properties, types, keyboard values, etc.This - * is very useful when you have a block of Unicode data that contains - * significant values while the rest of the Unicode data is unused in the - * application or when you have a lot of redundance, such as where all 21,000 - * Han ideographs have the same value. However, lookup is much faster than a - * hash table. - *

- * A compact array of any primitive data type serves two purposes: - *

    - *
  • Fast access of the indexed values. - *
  • Smaller memory footprint. - *
- *

- * The index array always points into particular parts of the data array - * it is initially set up to point at regular block boundaries - * The following example uses blocks of 4 for simplicity - *

- * Example: Expanded
- * BLOCK  0   1   2   3   4
- * INDEX  0   4   8   12  16 ...
- * ARRAY  abcdeababcdezyabcdea...
- *        |   |   |   |   |   |...
- * 
- *

- * After compression, the index will point to various places in the data array - * wherever there is a runs of the same elements as in the original - *

- * Example: Compressed
- * BLOCK  0   1   2   3   4
- * INDEX  0   4   1   8   2 ...
- * ARRAY  abcdeabazyabc...
- * 
- *

- * If you look at the example, index number 2 in the expanded version points - * to data position number 8, which has elements "bcde". In the compressed - * version, index number 2 points to data position 1, which also has "bcde" - * @see CompactByteArray - * @see CompactEIntArray - * @see CompactCharArray - * @see CompactStringArray - * @version $Revision: 1.1 $ 8/25/98 - * @author Helena Shih - */ -/*==================================== - *CompactEIntArray - * Provides a compact way to store information that is indexed by Unicode values, - * such as character properties, types, keyboard values, etc. - * The ATypes are used by value, so should be small, integers or pointers. - *==================================== - */ - typedef struct CompactEIntArray{ - uint32_t fStructSize; - int32_t* fArray; - uint16_t* fIndex; - int32_t fCount; - UBool fCompact; - UBool fBogus; - UBool fAlias; - UBool fIAmOwned; /* don't free CBA on close */ - - UToolMemory *stage2Mem; - uint16_t stage1[_UCMPE32_STAGE_1_MAX_COUNT]; - uint32_t *stage2; - uint16_t stage1Top; + uint32_t fStructSize; + UBool fCompact; + UBool fAlias; + UBool fBogus; + uint16_t *stage1; + int32_t *stage2; + int32_t stage1Top; + int32_t stage2Top; + int32_t fDefaultValue; + int32_t fSurrogateValue; } CompactEIntArray; - U_CAPI int32_t U_EXPORT2 ucmpe32_getkUnicodeCount(void); - U_CAPI int32_t U_EXPORT2 ucmpe32_getkBlockCount(void); - /** * Construct an empty CompactEIntArray. * * @param defaultValue the default value for all characters not explicitly in the array */ -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_open(int32_t defaultValue); +U_CAPI CompactEIntArray* U_EXPORT2 +ucmpe32_open(int32_t defaultValue, int32_t surrogateValue, UErrorCode *status); /** - * Construct a CompactEIntArray from a pre-computed index and values array. The values - * will be adopted by the CompactEIntArray. Memory is allocated with uprv_malloc. - * Note: for speed, the compact method will only re-use blocks in the values array - * that are on a block boundary. The pre-computed arrays passed in to this constructor - * may re-use blocks at any position in the values array. The indexArray and - * newValues will be uprv_free'd when ucmp16_close() is called. - * - * @param indexArray the index array to be adopted - * @param newValues the value array to be adopted - * @param count the number of entries in the value array - * @see compact + * Opens a compacted read-only array from + * a block in memory. */ -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_openAdopt(uint16_t *indexArray, - int32_t *newValues, - int32_t count); +U_CAPI CompactEIntArray* U_EXPORT2 +ucmpe32_openFromData( const uint8_t **source, UErrorCode *status); /** - * Construct a CompactEIntArray from a pre-computed index and values array. The values - * will be aliased by the CompactEIntArray. Memory is allocated with uprv_malloc. - * Note: for speed, the compact method will only re-use blocks in the values array - * that are on a block boundary. The pre-computed arrays passed in to this constructor - * may re-use blocks at any position in the values array. - * - * @param indexArray the index array to be adopted - * @param newValues the value array to be adopted - * @param count the number of entries in the value array - * @see compact + * Clones an array. It can be either compacted or expanded */ -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_openAlias(uint16_t *indexArray, - int32_t *newValues, - int32_t count); - -/** - * Initialize a CompactEIntArray from a pre-computed index and values array. The values - * will be adopted by the CompactEIntArray. No memory is allocated. Note: for speed, - * the compact method will only re-use blocks in the values array that are on a block - * boundary. The pre-computed arrays passed in to this constructor may re-use blocks - * at any position in the values array. The indexArray and - * newValues will be uprv_free'd when ucmp16_close() is called. - * - * @param indexArray the index array to be adopted - * @param newValues the value array to be adopted - * @param count the number of entries in the value array - * @see compact - */ -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_initAdopt(CompactEIntArray *this_obj, - uint16_t *indexArray, - int32_t *newValues, - int32_t count); - -/** - * Initialize a CompactEIntArray from a pre-computed index and values array. The values - * will be aliased by the CompactEIntArray. No memory is allocated. Note: for speed, - * the compact method will only re-use blocks in the values array that are on a block - * boundary. The pre-computed arrays passed in to this constructor may re-use blocks - * at any position in the values array. - * - * @param indexArray the index array to be adopted - * @param newValues the value array to be adopted - * @param count the number of entries in the value array - * @see compact - */ -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_initAlias(CompactEIntArray *this_obj, - uint16_t *indexArray, - int32_t *newValues, - int32_t count); +U_CAPI CompactEIntArray* U_EXPORT2 +ucmpe32_clone(CompactEIntArray* orig, UErrorCode *status); /** * Free up any allocated memory associated with this compact array. @@ -239,33 +109,39 @@ U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_initAlias(CompactEIntArray *this_obj, */ U_CAPI void U_EXPORT2 ucmpe32_close(CompactEIntArray* array); -/** - * Returns TRUE if the creation of the compact array fails. - */ -U_CAPI UBool U_EXPORT2 ucmpe32_isBogus(const CompactEIntArray* array); - /** * Get the mapped value of a Unicode character. * * @param index the character to get the mapped value with * @return the mapped value of the given character */ +#define ucmpe32_get(this_obj, index) (this_obj->stage2[(this_obj->stage1[(index >> _UCMPE32_TRIE_SHIFT)] )+ \ + (index & _UCMPE32_STAGE_2_MASK)]) -#if 0 -#define ucmpe32_get(array, index) (array->fArray[(array->fIndex[(index >> UCMPE32_kBlockShift)<< UCMPE32_kBlockShift] )+ \ - (index & UCMPE32_kBlockMask)]) -#endif +/** + * Get the mapped value of a confirmed surrogate. First value already comes + * from the trie and is combined with the following value in order to get + * the value. THIS CAN BE ONLY USED ON A COMPACTED TRIE. You will get wrong + * results if you try it on the expanded one + * NO ERROR CHECKING IS PERFORMED! PREPARE YOUR DATA CAREFULLY! + * @param leadValue32 the mapping of the leading surrogate. + * @param trail the trailing surrogate + * @return the mapped value of the given character + */ -U_CAPI int32_t U_EXPORT2 ucmpe32_get32(CompactEIntArray *array, UChar32 index); -#define ucmpe32_get(array, index) ucmpe32_get32((array), (UChar32)(index)) -#define ucmpe32_getu(array, index) (uint16_t)ucmpe32_get(array, index) +#define ucmpe32_getSurrogate(this_obj, leadValue32, trail) ucmpe32_get(this_obj, \ + ((leadValue32 & 0xffc00) | (trail & 0x3ff))) +/** + * This is a slow function that takes lead and trail surrogate and gets + * the mapping regardless of the compaction status. + */ +U_CAPI int32_t U_EXPORT2 +ucmpe32_getSurrogateEx(CompactEIntArray *array, UChar lead, UChar trail); -U_CAPI int32_t ucmpe32_getSurrogate(CompactEIntArray *array, UChar lead, UChar trail); - - /** +/** * Set a new value for a Unicode character. - * Set automatically expands the array if it is compacted. + * Do not set if the array is compacted - nothing will happen. * @param character the character to set the mapped value with * @param value the new mapped value */ @@ -273,69 +149,42 @@ U_CAPI void U_EXPORT2 ucmpe32_set32(CompactEIntArray *array, UChar32 character, int32_t value); +/** + * alias for compatibility + */ #define ucmpe32_set(array, character, value) ucmpe32_set32((array), (UChar32)(character), (value)) -U_CAPI void U_EXPORT2 ucmpe32_setSurrogate(CompactEIntArray* this_obj, UChar lead, - UChar trail, int32_t value); /** - * - * Set new values for a range of Unicode character. - * @param start the starting offset of the range - * @param end the ending offset of the range + * Set a new value for a surrogate character. + * Do not set if the array is compacted - nothing will happen. + * Set automatically expands the array if it is compacted. + * Alternatively you can put the surrogate code point together + * yourself and use set32. + * @param lead leading surrogate unit + * @param trail trailing surrogate unit * @param value the new mapped value */ -U_CAPI void U_EXPORT2 ucmpe32_setRange(CompactEIntArray* array, - UChar start, - UChar end, - int32_t value); - -/** - * Compact the array. The value of cycle determines how large the overlap can be. - * A cycle of 1 is the most compacted, but takes the most time to do. - * If values stored in the array tend to repeat in cycles of, say, 16, - * then using that will be faster than cycle = 1, and get almost the - * same compression. +U_CAPI void U_EXPORT2 +ucmpe32_setSurrogate(CompactEIntArray* this_obj, UChar lead, + UChar trail, int32_t value); +/** + * compacts the array. + * This folds the surrogates and compacts the array. + * no setting will succeed after the array is compacted. + * Array have to be compacted in order to be flattened. */ -U_CAPI void U_EXPORT2 ucmpe32_compact(CompactEIntArray* array, int32_t cycle); +U_CAPI void U_EXPORT2 +ucmpe32_compact(CompactEIntArray* this_object); -/** - * Expands the compacted array. - * Takes the array back to a 65536 element array +/** + * Flattens the array to an memory stream. + * Array has to be compacted beforehand. + * @param MS memory stream to flatten to + * @return number of bytes written. */ -U_CAPI void U_EXPORT2 ucmpe32_expand(CompactEIntArray* array); - -/** - * Get the number of elements in the value array. - * - * @return the number of elements in the value array. - */ -U_CAPI uint32_t U_EXPORT2 ucmpe32_getCount(const CompactEIntArray* array); - -/** - * Get the address of the value array. - * - * @return the address of the value array - */ -U_CAPI const int32_t* U_EXPORT2 ucmpe32_getArray(const CompactEIntArray* array); - -/** - * Get the address of the index array. - * - * @return the address of the index array - */ -U_CAPI const uint16_t* U_EXPORT2 ucmpe32_getIndex(const CompactEIntArray* array); - -U_CAPI void U_EXPORT2 ucmpe32_streamIn( CompactEIntArray* array, FileStream* is); -U_CAPI void U_EXPORT2 ucmpe32_streamOut(CompactEIntArray* array, FileStream* os); - -U_CAPI void U_EXPORT2 ucmpe32_streamMemIn( CompactEIntArray* array, UMemoryStream* is); -U_CAPI void U_EXPORT2 ucmpe32_streamMemOut(CompactEIntArray* array, UMemoryStream* os); - -U_CAPI uint32_t U_EXPORT2 ucmpe32_flattenMem(const CompactEIntArray* array, UMemoryStream *MS); - -U_CAPI CompactEIntArray* U_EXPORT2 ucmpe32_openFromData( const uint8_t **source, UErrorCode *status); -U_CAPI void U_EXPORT2 ucmpe32_initFromData(CompactEIntArray *this_obj, const uint8_t **source, UErrorCode *status); +U_CAPI uint32_t U_EXPORT2 +ucmpe32_flattenMem(const CompactEIntArray* this_object, UMemoryStream *MS); #endif