ICU-740 This code isn't used anymore
X-SVN-Rev: 5811
This commit is contained in:
parent
e21eac69b6
commit
69467d4959
@ -1,658 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2001, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/*============================================================================
|
||||
*
|
||||
* File cmpshrta.cpp
|
||||
*
|
||||
* Modification History:
|
||||
*
|
||||
* Date Name Description
|
||||
* 2/5/97 aliu Added CompactIntArray streamIn and streamOut methods.
|
||||
* 3/4/97 aliu Tuned performance of CompactIntArray constructor,
|
||||
* 05/07/97 helena Added isBogus()
|
||||
* based on performance data indicating that this_obj was slow.
|
||||
* 07/15/98 erm Synched with Java 1.2 CompactShortArray.java.
|
||||
* 07/30/98 erm Added changes from 07/29/98 code review.
|
||||
* 11/01/99 weiv Added getArray, getIndex and getCount based on Jitterbug 4
|
||||
*============================================================================
|
||||
*/
|
||||
#include "ucmp16.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define arrayRegionMatches(source, sourceStart, target, targetStart, len) (uprv_memcmp(&source[sourceStart], &target[targetStart], len * sizeof(int16_t)) != 0)
|
||||
|
||||
static const int32_t UCMP16_kMaxUnicode = UCMP16_kMaxUnicode_int;
|
||||
static const int32_t UCMP16_kUnicodeCount = UCMP16_kUnicodeCount_int;
|
||||
static const int32_t UCMP16_kBlockShift = UCMP16_kBlockShift_int;
|
||||
static const int32_t UCMP16_kBlockCount = UCMP16_kBlockCount_int;
|
||||
static const int32_t UCMP16_kBlockBytes = UCMP16_kBlockBytes_int;
|
||||
static const int32_t UCMP16_kIndexShift = UCMP16_kIndexShift_int;
|
||||
static const int32_t UCMP16_kIndexCount = UCMP16_kIndexCount_int;
|
||||
static const uint32_t UCMP16_kBlockMask = UCMP16_kBlockMask_int;
|
||||
|
||||
/**
|
||||
* Sets the array to the invalid memory state.
|
||||
*/
|
||||
static CompactShortArray* setToBogus(CompactShortArray* array);
|
||||
static void touchBlock(CompactShortArray* this_obj,
|
||||
int32_t i,
|
||||
int16_t value);
|
||||
static UBool blockTouched(const CompactShortArray* this_obj,
|
||||
int32_t i);
|
||||
|
||||
|
||||
/* debug flags*/
|
||||
/*=======================================================*/
|
||||
|
||||
int32_t ucmp16_getkUnicodeCount()
|
||||
{return UCMP16_kUnicodeCount;}
|
||||
|
||||
int32_t ucmp16_getkBlockCount()
|
||||
{return UCMP16_kBlockCount;}
|
||||
|
||||
CompactShortArray* ucmp16_open(int16_t defaultValue)
|
||||
{
|
||||
int32_t i;
|
||||
CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
|
||||
if (this_obj == NULL)
|
||||
return NULL;
|
||||
|
||||
this_obj->fArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
|
||||
if (this_obj->fArray == NULL)
|
||||
{
|
||||
uprv_free(this_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this_obj->fIndex = (uint16_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(uint16_t));
|
||||
if (this_obj->fIndex == NULL)
|
||||
{
|
||||
uprv_free(this_obj->fArray);
|
||||
uprv_free(this_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
|
||||
if (this_obj->fHashes == NULL)
|
||||
{
|
||||
uprv_free(this_obj->fArray);
|
||||
uprv_free(this_obj->fIndex);
|
||||
uprv_free(this_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->fCount = UCMP16_kUnicodeCount;
|
||||
this_obj->fCompact = FALSE;
|
||||
this_obj->fBogus = FALSE;
|
||||
this_obj->fAlias = FALSE;
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
this_obj->fDefaultValue = defaultValue;
|
||||
this_obj->kBlockShift = UCMP16_kBlockShift;
|
||||
this_obj->kBlockMask = UCMP16_kBlockMask;
|
||||
|
||||
for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
|
||||
{
|
||||
this_obj->fArray[i] = defaultValue;
|
||||
}
|
||||
|
||||
for (i = 0; i < UCMP16_kIndexCount; i += 1)
|
||||
{
|
||||
this_obj->fIndex[i] = (uint16_t)(i << UCMP16_kBlockShift);
|
||||
this_obj->fHashes[i] = 0;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
void ucmp16_initBogus(CompactShortArray *this_obj)
|
||||
{
|
||||
if (this_obj == NULL)
|
||||
return;
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->fCount = UCMP16_kUnicodeCount;
|
||||
this_obj->fCompact = FALSE;
|
||||
this_obj->fBogus = TRUE;
|
||||
this_obj->fArray = NULL;
|
||||
this_obj->fAlias = FALSE;
|
||||
this_obj->fIndex = NULL;
|
||||
this_obj->fHashes = NULL;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
this_obj->fDefaultValue = 0;
|
||||
}
|
||||
|
||||
void ucmp16_init(CompactShortArray *this_obj, int16_t defaultValue)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if (this_obj == NULL)
|
||||
return;
|
||||
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->fCount = UCMP16_kUnicodeCount;
|
||||
this_obj->fCompact = FALSE;
|
||||
this_obj->fBogus = FALSE;
|
||||
this_obj->fArray = NULL;
|
||||
this_obj->fAlias = FALSE;
|
||||
this_obj->fIndex = NULL;
|
||||
this_obj->fHashes = NULL;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
this_obj->fDefaultValue = defaultValue;
|
||||
|
||||
this_obj->fArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
|
||||
if (this_obj->fArray == NULL)
|
||||
{
|
||||
setToBogus(this_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->fIndex = (uint16_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(uint16_t));
|
||||
if (this_obj->fIndex == NULL)
|
||||
{
|
||||
setToBogus(this_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
|
||||
if (this_obj->fHashes == NULL)
|
||||
{
|
||||
setToBogus(this_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->kBlockShift = UCMP16_kBlockShift;
|
||||
this_obj->kBlockMask = UCMP16_kBlockMask;
|
||||
for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
|
||||
{
|
||||
this_obj->fArray[i] = defaultValue;
|
||||
}
|
||||
|
||||
for (i = 0; i < UCMP16_kIndexCount; i += 1)
|
||||
{
|
||||
this_obj->fIndex[i] = (uint16_t)(i << UCMP16_kBlockShift);
|
||||
this_obj->fHashes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CompactShortArray* ucmp16_openAdopt(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue)
|
||||
{
|
||||
CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
|
||||
if (this_obj == NULL)
|
||||
return NULL;
|
||||
|
||||
ucmp16_initAdopt(this_obj, indexArray, newValues, count, defaultValue);
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactShortArray* ucmp16_openAdoptWithBlockShift(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift)
|
||||
{
|
||||
CompactShortArray* this_obj = ucmp16_openAdopt(indexArray,
|
||||
newValues,
|
||||
count,
|
||||
defaultValue);
|
||||
if (this_obj) {
|
||||
this_obj->kBlockShift = blockShift;
|
||||
this_obj->kBlockMask = (uint32_t) (((uint32_t)1 << (uint32_t)blockShift) - (uint32_t)1);
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactShortArray* ucmp16_openAlias(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue)
|
||||
{
|
||||
CompactShortArray* this_obj = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
|
||||
if (this_obj == NULL)
|
||||
return NULL;
|
||||
|
||||
ucmp16_initAlias(this_obj, indexArray, newValues, count, defaultValue);
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
/*=======================================================*/
|
||||
|
||||
CompactShortArray* ucmp16_initAdopt(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue)
|
||||
{
|
||||
if (this_obj) {
|
||||
this_obj->fHashes = NULL;
|
||||
this_obj->fCount = count;
|
||||
this_obj->fDefaultValue = defaultValue;
|
||||
this_obj->fBogus = FALSE;
|
||||
this_obj->fArray = newValues;
|
||||
this_obj->fIndex = indexArray;
|
||||
this_obj->fCompact = (UBool)(count < UCMP16_kUnicodeCount);
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->kBlockShift = UCMP16_kBlockShift;
|
||||
this_obj->kBlockMask = UCMP16_kBlockMask;
|
||||
this_obj->fAlias = FALSE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactShortArray* ucmp16_initAdoptWithBlockShift(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift)
|
||||
{
|
||||
ucmp16_initAdopt(this_obj, indexArray, newValues, count, defaultValue);
|
||||
|
||||
if (this_obj) {
|
||||
this_obj->kBlockShift = blockShift;
|
||||
this_obj->kBlockMask = (uint32_t) (((uint32_t)1 << (uint32_t)blockShift) - (uint32_t)1);
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
|
||||
CompactShortArray* ucmp16_initAlias(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue)
|
||||
{
|
||||
if (this_obj) {
|
||||
this_obj->fHashes = NULL;
|
||||
this_obj->fCount = count;
|
||||
this_obj->fDefaultValue = defaultValue;
|
||||
this_obj->fBogus = FALSE;
|
||||
this_obj->fArray = newValues;
|
||||
this_obj->fIndex = indexArray;
|
||||
this_obj->fCompact = (UBool)(count < UCMP16_kUnicodeCount);
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->kBlockShift = UCMP16_kBlockShift;
|
||||
this_obj->kBlockMask = UCMP16_kBlockMask;
|
||||
this_obj->fAlias = TRUE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactShortArray* ucmp16_initAliasWithBlockShift(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift)
|
||||
{
|
||||
ucmp16_initAlias(this_obj, indexArray, newValues, count, defaultValue);
|
||||
|
||||
if (this_obj) {
|
||||
this_obj->kBlockShift = blockShift;
|
||||
this_obj->kBlockMask = (uint32_t) (((uint32_t)1 << (uint32_t)blockShift) - (uint32_t)1);
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
|
||||
/*=======================================================*/
|
||||
|
||||
void ucmp16_close(CompactShortArray* this_obj)
|
||||
{
|
||||
if(this_obj != NULL) {
|
||||
setToBogus(this_obj);
|
||||
if(!this_obj->fIAmOwned)
|
||||
{
|
||||
uprv_free(this_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CompactShortArray* setToBogus(CompactShortArray* this_obj)
|
||||
{
|
||||
if(this_obj != NULL) {
|
||||
if(!this_obj->fAlias) {
|
||||
if (this_obj->fArray != NULL) {
|
||||
uprv_free(this_obj->fArray);
|
||||
this_obj->fArray = NULL;
|
||||
}
|
||||
|
||||
if (this_obj->fIndex != NULL) {
|
||||
uprv_free(this_obj->fIndex);
|
||||
this_obj->fIndex = NULL;
|
||||
}
|
||||
}
|
||||
if (this_obj->fHashes != NULL) {
|
||||
uprv_free(this_obj->fHashes);
|
||||
this_obj->fHashes = NULL;
|
||||
}
|
||||
|
||||
this_obj->fCount = 0;
|
||||
this_obj->fCompact = FALSE;
|
||||
this_obj->fBogus = TRUE;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
UBool ucmp16_isBogus(const CompactShortArray* this_obj)
|
||||
{
|
||||
return (UBool)(this_obj == NULL || this_obj->fBogus);
|
||||
}
|
||||
|
||||
void ucmp16_expand(CompactShortArray* this_obj)
|
||||
{
|
||||
if (this_obj->fCompact)
|
||||
{
|
||||
int32_t i;
|
||||
int16_t *tempArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
|
||||
|
||||
if (tempArray == NULL)
|
||||
{
|
||||
setToBogus(this_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
|
||||
if (this_obj->fHashes == NULL)
|
||||
{
|
||||
setToBogus(this_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
|
||||
{
|
||||
tempArray[i] = ucmp16_get(this_obj, (UChar)i); /* HSYS : How expand?*/
|
||||
}
|
||||
|
||||
for (i = 0; i < (1 << (16 - this_obj->kBlockShift)); i += 1)
|
||||
{
|
||||
this_obj->fIndex[i] = (uint16_t)(i<<this_obj->kBlockShift);
|
||||
}
|
||||
|
||||
uprv_free(this_obj->fArray);
|
||||
this_obj->fArray = tempArray;
|
||||
this_obj->fCompact = FALSE;
|
||||
|
||||
/* Since we don't know if the fIndex is also an alias, we allow tempArray to leak. */
|
||||
/* this_obj->fAlias = FALSE; */
|
||||
}
|
||||
}
|
||||
|
||||
void ucmp16_set(CompactShortArray* this_obj,
|
||||
UChar c,
|
||||
int16_t value)
|
||||
{
|
||||
if (this_obj->fCompact)
|
||||
{
|
||||
ucmp16_expand(this_obj);
|
||||
if (this_obj->fBogus)
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->fArray[(int32_t)c] = value;
|
||||
|
||||
if (value != this_obj->fDefaultValue)
|
||||
{
|
||||
touchBlock(this_obj, c >> this_obj->kBlockShift, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ucmp16_setRange(CompactShortArray* this_obj,
|
||||
UChar start,
|
||||
UChar end,
|
||||
int16_t value)
|
||||
{
|
||||
int32_t i;
|
||||
if (this_obj->fCompact)
|
||||
{
|
||||
ucmp16_expand(this_obj);
|
||||
if (this_obj->fBogus)
|
||||
return;
|
||||
}
|
||||
if (value != this_obj->fDefaultValue)
|
||||
{
|
||||
for (i = start; i <= end; i += 1)
|
||||
{
|
||||
this_obj->fArray[i] = value;
|
||||
touchBlock(this_obj, i >> this_obj->kBlockShift, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = start; i <= end; i += 1)
|
||||
this_obj->fArray[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=======================================================*/
|
||||
void ucmp16_compact(CompactShortArray* this_obj)
|
||||
{
|
||||
if (!this_obj->fCompact)
|
||||
{
|
||||
int32_t limitCompacted = 0;
|
||||
int32_t i, iBlockStart;
|
||||
int16_t iUntouched = -1;
|
||||
|
||||
for (i = 0, iBlockStart = 0; i < (1 << (16 - this_obj->kBlockShift)); i += 1, iBlockStart += (1 << this_obj->kBlockShift))
|
||||
{
|
||||
UBool touched = blockTouched(this_obj, i);
|
||||
|
||||
this_obj->fIndex[i] = 0xFFFF;
|
||||
|
||||
if (!touched && iUntouched != -1)
|
||||
{
|
||||
/* If no values in this_obj block were set, we can just set its
|
||||
* index to be the same as some other block with no values
|
||||
* set, assuming we've seen one yet.
|
||||
*/
|
||||
this_obj->fIndex[i] = iUntouched;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t j, jBlockStart;
|
||||
|
||||
for (j = 0, jBlockStart = 0;
|
||||
j < limitCompacted;
|
||||
j += 1, jBlockStart += (1 << this_obj->kBlockShift))
|
||||
{
|
||||
if (this_obj->fHashes[i] == this_obj->fHashes[j] &&
|
||||
arrayRegionMatches(this_obj->fArray,
|
||||
iBlockStart,
|
||||
this_obj->fArray,
|
||||
jBlockStart,
|
||||
(1 << this_obj->kBlockShift)))
|
||||
{
|
||||
this_obj->fIndex[i] = (int16_t)jBlockStart;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: verify this_obj is correct*/
|
||||
if (this_obj->fIndex[i] == 0xFFFF)
|
||||
{
|
||||
/* we didn't match, so copy & update*/
|
||||
uprv_memcpy(&(this_obj->fArray[jBlockStart]),
|
||||
&(this_obj->fArray[iBlockStart]),
|
||||
(1 << this_obj->kBlockShift)*sizeof(int16_t));
|
||||
|
||||
this_obj->fIndex[i] = (int16_t)jBlockStart;
|
||||
this_obj->fHashes[j] = this_obj->fHashes[i];
|
||||
limitCompacted += 1;
|
||||
|
||||
if (!touched)
|
||||
{
|
||||
/* If this_obj is the first untouched block we've seen,*/
|
||||
/* remember its index.*/
|
||||
iUntouched = (int16_t)jBlockStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we are done compacting, so now make the array shorter*/
|
||||
/* TODO: uprv_realloc should be used instead.
|
||||
What if uprv_malloc returns NULL [grhoten] */
|
||||
{
|
||||
int32_t newSize = limitCompacted * (1 << this_obj->kBlockShift);
|
||||
int16_t *result = (int16_t*) uprv_malloc(sizeof(int16_t) * newSize);
|
||||
|
||||
uprv_memcpy(result, this_obj->fArray, newSize * sizeof(int16_t));
|
||||
|
||||
uprv_free(this_obj->fArray);
|
||||
this_obj->fArray = result;
|
||||
this_obj->fCount = newSize;
|
||||
uprv_free(this_obj->fHashes);
|
||||
this_obj->fHashes = NULL;
|
||||
|
||||
this_obj->fCompact = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query whether a specified block was "touched", i.e. had a value set.
|
||||
* Untouched blocks can be skipped when compacting the array
|
||||
*/
|
||||
|
||||
int16_t ucmp16_getDefaultValue(const CompactShortArray* this_obj)
|
||||
{
|
||||
return this_obj->fDefaultValue;
|
||||
}
|
||||
|
||||
|
||||
static void touchBlock(CompactShortArray* this_obj,
|
||||
int32_t i,
|
||||
int16_t value)
|
||||
{
|
||||
this_obj->fHashes[i] = (this_obj->fHashes[i] + (value << 1)) | 1;
|
||||
}
|
||||
|
||||
static UBool blockTouched(const CompactShortArray* this_obj, int32_t i)
|
||||
{
|
||||
return (UBool)(this_obj->fHashes[i] != 0);
|
||||
}
|
||||
|
||||
uint32_t ucmp16_getCount(const CompactShortArray* this_obj)
|
||||
{
|
||||
return this_obj->fCount;
|
||||
}
|
||||
|
||||
const int16_t* ucmp16_getArray(const CompactShortArray* this_obj)
|
||||
{
|
||||
return this_obj->fArray;
|
||||
}
|
||||
|
||||
const uint16_t* ucmp16_getIndex(const CompactShortArray* this_obj)
|
||||
{
|
||||
return this_obj->fIndex;
|
||||
}
|
||||
|
||||
U_CAPI uint32_t U_EXPORT2 ucmp16_flattenMem (const CompactShortArray* array, UMemoryStream *MS)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uprv_mstrm_write32(MS, ICU_UCMP16_VERSION);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_write32(MS, array->fCount);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_write32(MS, array->kBlockShift);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_write32(MS, array->kBlockMask);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_writeBlock(MS, array->fIndex, sizeof(array->fIndex[0])*UCMP16_kIndexCount);
|
||||
size += sizeof(array->fIndex[0])*UCMP16_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;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* We use sizeof(*array), etc so that this code can be as portable as
|
||||
possible between the ucmpX_ family. Check lines marked 'SIZE'.
|
||||
*/
|
||||
|
||||
U_CAPI void U_EXPORT2 ucmp16_initFromData(CompactShortArray *this_obj, const uint8_t **source, UErrorCode *status)
|
||||
{
|
||||
uint32_t i;
|
||||
const uint8_t *oldSource = *source;
|
||||
|
||||
if(U_FAILURE(*status))
|
||||
return;
|
||||
|
||||
this_obj->fBogus = FALSE;
|
||||
this_obj->fStructSize = sizeof(CompactShortArray);
|
||||
this_obj->fCompact = TRUE;
|
||||
this_obj->fAlias = TRUE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
this_obj->fHashes = NULL;
|
||||
this_obj->fDefaultValue = 0x0000; /* not used */
|
||||
|
||||
i = * ((const uint32_t*) *source);
|
||||
(*source) += 4;
|
||||
|
||||
if(i != ICU_UCMP16_VERSION)
|
||||
{
|
||||
this_obj->fArray = NULL;
|
||||
this_obj->fIndex = NULL;
|
||||
this_obj->fBogus = TRUE;
|
||||
this_obj->fCount = 0;
|
||||
*status = U_INVALID_FORMAT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
this_obj->fCount = * ((const uint32_t*)*source);
|
||||
(*source) += 4;
|
||||
|
||||
this_obj->kBlockShift = * ((const uint32_t*)*source);
|
||||
(*source) += 4;
|
||||
|
||||
this_obj->kBlockMask = * ((const uint32_t*)*source);
|
||||
(*source) += 4;
|
||||
|
||||
this_obj->fIndex = (uint16_t*) *source;
|
||||
(*source) += sizeof(this_obj->fIndex[0])*UCMP16_kIndexCount;
|
||||
|
||||
this_obj->fArray = (int16_t*) *source;
|
||||
(*source) += sizeof(this_obj->fArray[0])*this_obj->fCount;
|
||||
|
||||
/* eat up padding */
|
||||
while((*source-(oldSource))%4)
|
||||
(*source)++;
|
||||
}
|
||||
|
||||
|
@ -1,424 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1995-2001, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* @version 1.0 23/10/96
|
||||
* @author Helena Shih
|
||||
* Based on Taligent international support for java
|
||||
* Modification History :
|
||||
*
|
||||
* 05/07/97 helena Added isBogus()
|
||||
* 07/15/98 erm Synched with Java 1.2 CompactShortArray.java.
|
||||
* 07/30/98 erm Added 07/29/98 code review changes.
|
||||
* 04/21/99 Damiba Port to C/New API faster ucmp16_get
|
||||
*/
|
||||
|
||||
#ifndef UCMP16_H
|
||||
#define UCMP16_H
|
||||
|
||||
|
||||
#include "umemstrm.h"
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
/* 32-bits.
|
||||
Bump this whenever the internal structure changes.
|
||||
*/
|
||||
#define ICU_UCMP16_VERSION 0x01270000
|
||||
|
||||
/* internal constants*/
|
||||
#define UCMP16_kMaxUnicode_int 65535
|
||||
#define UCMP16_kUnicodeCount_int (UCMP16_kMaxUnicode_int + 1)
|
||||
#define UCMP16_kBlockShift_int 7
|
||||
#define UCMP16_kBlockCount_int (1 << UCMP16_kBlockShift_int)
|
||||
#define UCMP16_kBlockBytes_int (UCMP16_kBlockCount_int * sizeof(int16_t))
|
||||
#define UCMP16_kIndexShift_int (16 - UCMP16_kBlockShift_int)
|
||||
#define UCMP16_kIndexCount_int (1 << UCMP16_kIndexShift_int)
|
||||
#define UCMP16_kBlockMask_int (UCMP16_kBlockCount_int - 1)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <P>
|
||||
* A compact array of any primitive data type serves two purposes:
|
||||
* <UL type = round>
|
||||
* <LI>Fast access of the indexed values.
|
||||
* <LI>Smaller memory footprint.
|
||||
* </UL>
|
||||
* <P>
|
||||
* 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
|
||||
* <PRE>
|
||||
* Example: Expanded
|
||||
* BLOCK 0 1 2 3 4
|
||||
* INDEX 0 4 8 12 16 ...
|
||||
* ARRAY abcdeababcdezyabcdea...
|
||||
* | | | | | |...
|
||||
* </PRE>
|
||||
* <P>
|
||||
* 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
|
||||
* <PRE>
|
||||
* Example: Compressed
|
||||
* BLOCK 0 1 2 3 4
|
||||
* INDEX 0 4 1 8 2 ...
|
||||
* ARRAY abcdeabazyabc...
|
||||
* </PRE>
|
||||
* <P>
|
||||
* 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 CompactIntArray
|
||||
* @see CompactCharArray
|
||||
* @see CompactStringArray
|
||||
* @version $Revision: 1.18 $ 8/25/98
|
||||
* @author Helena Shih
|
||||
*/
|
||||
|
||||
typedef struct CompactShortArray {
|
||||
int32_t fStructSize;
|
||||
int16_t* fArray;
|
||||
uint16_t* fIndex;
|
||||
int32_t* fHashes;
|
||||
int32_t fCount;
|
||||
int16_t fDefaultValue;
|
||||
UBool fCompact;
|
||||
UBool fBogus;
|
||||
UBool fAlias;
|
||||
int32_t kBlockShift;
|
||||
int32_t kBlockMask;
|
||||
UBool fIAmOwned; /* don't free CSA on close */
|
||||
} CompactShortArray;
|
||||
|
||||
|
||||
U_CAPI int32_t U_EXPORT2 ucmp16_getkUnicodeCount(void);
|
||||
U_CAPI int32_t U_EXPORT2 ucmp16_getkBlockCount(void);
|
||||
|
||||
/**
|
||||
* Construct an empty CompactShortArray with uprv_malloc(). Do not call any of the
|
||||
* ucmp16_init*() functions after using this function. They will cause a memory
|
||||
* leak.
|
||||
*
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initBogus
|
||||
* @return The initialized array.
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_open(int16_t defaultValue);
|
||||
|
||||
/**
|
||||
* Construct a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactShortArray. 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. Do not call any of the
|
||||
* ucmp16_init*() functions after using this function. They will cause a memory
|
||||
* leak. 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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initBogus
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_openAdopt(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue);
|
||||
|
||||
/**
|
||||
* Construct a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactShortArray. 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. Do not call any of the
|
||||
* ucmp16_init*() functions after using this function. They will cause a memory
|
||||
* leak. 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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initBogus
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_openAdoptWithBlockShift(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift);
|
||||
|
||||
/**
|
||||
* Construct a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be aliased by the CompactShortArray. 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. Do not call any of the
|
||||
* ucmp16_init*() functions after using this function. They will cause a memory
|
||||
* leak.
|
||||
*
|
||||
* @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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initBogus
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_openAlias(uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue );
|
||||
|
||||
/**
|
||||
* Initialize an empty CompactShortArray. Do not call this function if
|
||||
* you created the array with any of the ucmp16_open*() funcitons because it
|
||||
* will cause a memory leak.
|
||||
*
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @param array An uninitialized CompactShortArray
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_initAdopt
|
||||
* @see ucmp16_initAlias
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_init(CompactShortArray* array, int16_t defaultValue);
|
||||
|
||||
/**
|
||||
* Initialize an empty CompactShortArray to the bogus value. Do not call
|
||||
* this function if you created the array with ucmp16_open() because it
|
||||
* will cause a memory leak.
|
||||
*
|
||||
* @param array An uninitialized CompactShortArray
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_isBogus
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initAdopt
|
||||
* @see ucmp16_initAlias
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_initBogus(CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Initialize a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactShortArray. 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 this_obj the CompactShortArray to be initialized
|
||||
* @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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initAlias
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_initAdopt(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue );
|
||||
|
||||
/**
|
||||
* Initialize a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactShortArray. 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 this_obj the CompactShortArray to be initialized
|
||||
* @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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @return The initialized array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initAlias
|
||||
* @see ucmp16_initAdopt
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_initAdoptWithBlockShift(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift);
|
||||
|
||||
/**
|
||||
* Initialize a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be aliased by the CompactShortArray. 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 this_obj the CompactShortArray to be initialized
|
||||
* @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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @return The initialized array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initAdopt
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_initAlias(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue );
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a CompactShortArray from a pre-computed index and values array. The values
|
||||
* will be aliased by the CompactShortArray. 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 this_obj the CompactShortArray to be initialized
|
||||
* @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
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
* @return The initialized array
|
||||
* @see compact
|
||||
* @see ucmp16_open
|
||||
* @see ucmp16_openAdopt
|
||||
* @see ucmp16_openAlias
|
||||
* @see ucmp16_init
|
||||
* @see ucmp16_initAdopt
|
||||
*/
|
||||
U_CAPI CompactShortArray* U_EXPORT2 ucmp16_initAliasWithBlockShift(CompactShortArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int16_t *newValues,
|
||||
int32_t count,
|
||||
int16_t defaultValue,
|
||||
int32_t blockShift);
|
||||
|
||||
/**
|
||||
* Free up any allocated memory associated with this compact array.
|
||||
* The memory that is uprv_free'd depends on how the array was initialized
|
||||
* or opened.
|
||||
*
|
||||
* @param array The array to close
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_close(CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Returns TRUE if the creation of the compact array fails.
|
||||
*/
|
||||
U_CAPI UBool U_EXPORT2 ucmp16_isBogus(const CompactShortArray* 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 ucmp16_get(array, index) (array->fArray[(array->fIndex[(index >> array->kBlockShift)] )+ \
|
||||
(index & array->kBlockMask)])
|
||||
|
||||
#define ucmp16_getu(array, index) (uint16_t)ucmp16_get(array, index)
|
||||
|
||||
|
||||
/**
|
||||
* Set a new value for a Unicode character.
|
||||
* Set automatically expands the array if it is compacted.
|
||||
*
|
||||
* @param character the character to set the mapped value with
|
||||
* @param value the new mapped value
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_set(CompactShortArray *array,
|
||||
UChar character,
|
||||
int16_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
|
||||
* @param value the new mapped value
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_setRange(CompactShortArray* array,
|
||||
UChar start,
|
||||
UChar end,
|
||||
int16_t value);
|
||||
|
||||
|
||||
/**
|
||||
* Compact the array. For efficency, this method will only re-use
|
||||
* blocks in the values array that are on a block bounday. If you
|
||||
* want better compaction, you can do your own compaction and use
|
||||
* the constructor that lets you pass in the pre-computed arrays.
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_compact(CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Get the default value.
|
||||
*/
|
||||
U_CAPI int16_t U_EXPORT2 ucmp16_getDefaultValue(const CompactShortArray* 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 ucmp16_getCount(const CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Get the address of the value array.
|
||||
* @return the address of the value array
|
||||
*/
|
||||
U_CAPI const int16_t* U_EXPORT2 ucmp16_getArray(const CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Get the address of the index array.
|
||||
* @return the address of the index array
|
||||
*/
|
||||
U_CAPI const uint16_t* U_EXPORT2 ucmp16_getIndex(const CompactShortArray* array);
|
||||
|
||||
/**
|
||||
* Expands the compacted array.
|
||||
* Takes the array back to a 65536 element array
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp16_expand(CompactShortArray* this_obj);
|
||||
|
||||
/** INTERNAL USE ONLY **/
|
||||
U_CAPI uint32_t U_EXPORT2 ucmp16_flattenMem(const CompactShortArray* array, UMemoryStream *MS);
|
||||
/** INTERNAL USE ONLY **/
|
||||
U_CAPI void U_EXPORT2 ucmp16_initFromData(CompactShortArray* array, const uint8_t **source, UErrorCode *status);
|
||||
|
||||
#endif
|
||||
|
@ -1,620 +0,0 @@
|
||||
/*============================================================================
|
||||
* Copyright (C) 1997-2001, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*
|
||||
* File cmpshrta.cpp
|
||||
*
|
||||
* Modification History:
|
||||
*
|
||||
* Date Name Description
|
||||
* 2/5/97 aliu Added CompactIntArray streamIn and streamOut methods.
|
||||
* 3/4/97 aliu Tuned performance of CompactIntArray constructor,
|
||||
* based on performance data indicating that this_obj was slow.
|
||||
* 05/07/97 helena Added isBogus()
|
||||
* 04/26/99 Madhu Ported to C for C Implementation
|
||||
* 11/12/99 srl macroized ucmp32_get()
|
||||
* 11/07/00 weiv aligned implementation with ucmp8
|
||||
*============================================================================
|
||||
*/
|
||||
#include "ucmp32.h"
|
||||
#include "cmemory.h"
|
||||
#include "filestrm.h"
|
||||
|
||||
|
||||
|
||||
static int32_t ucmp32_findOverlappingPosition(CompactIntArray* this_obj, uint32_t start,
|
||||
const UChar *tempIndex,
|
||||
int32_t tempIndexCount,
|
||||
uint32_t cycle);
|
||||
|
||||
static UBool debugSmall = FALSE;
|
||||
static uint32_t debugSmallLimit = 30000;
|
||||
|
||||
/** debug flags
|
||||
*=======================================================
|
||||
*/
|
||||
|
||||
int32_t ucmp32_getkUnicodeCount() { return UCMP32_kUnicodeCount;}
|
||||
int32_t ucmp32_getkBlockCount() { return UCMP32_kBlockCount;}
|
||||
|
||||
U_CAPI void ucmp32_streamIn(CompactIntArray* 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 == UCMP32_kIndexCount)
|
||||
{
|
||||
if (this_obj->fIndex == 0)
|
||||
this_obj->fIndex =(uint16_t*)uprv_malloc(UCMP32_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)) * UCMP32_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 ucmp32_streamOut(CompactIntArray* 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 = UCMP32_kIndexCount;
|
||||
T_FileStream_write(os, &len, sizeof(len));
|
||||
T_FileStream_write(os, this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMP32_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 ucmp32_streamMemIn(CompactIntArray* 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 == UCMP32_kIndexCount)
|
||||
{
|
||||
if (this_obj->fIndex == 0)
|
||||
this_obj->fIndex =(uint16_t*)uprv_malloc(UCMP32_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)) * UCMP32_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 ucmp32_streamMemOut(CompactIntArray* 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 = UCMP32_kIndexCount;
|
||||
uprv_mstrm_write(os, (uint8_t *)&len, sizeof(len));
|
||||
uprv_mstrm_write(os, (uint8_t *)this_obj->fIndex, sizeof(*(this_obj->fIndex)) * UCMP32_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));
|
||||
}
|
||||
}
|
||||
|
||||
CompactIntArray* ucmp32_open(int32_t defaultValue)
|
||||
{
|
||||
uint16_t i;
|
||||
int32_t *p, *p_end;
|
||||
uint16_t *q, *q_end;
|
||||
CompactIntArray* this_obj = (CompactIntArray*) uprv_malloc(sizeof(CompactIntArray));
|
||||
if (this_obj == NULL) return NULL;
|
||||
|
||||
this_obj->fStructSize = sizeof(CompactIntArray);
|
||||
this_obj->fArray = NULL;
|
||||
this_obj->fIndex = NULL;
|
||||
this_obj->fCount = UCMP32_kUnicodeCount;
|
||||
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(UCMP32_kUnicodeCount * sizeof(int32_t));
|
||||
if (this_obj->fArray == NULL) {
|
||||
this_obj->fBogus = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this_obj->fIndex = (uint16_t*)uprv_malloc(UCMP32_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 + UCMP32_kUnicodeCount;
|
||||
while (p < p_end) *p++ = defaultValue;
|
||||
|
||||
q = this_obj->fIndex;
|
||||
q_end = q + UCMP32_kIndexCount;
|
||||
i = 0;
|
||||
while (q < q_end)
|
||||
{
|
||||
*q++ = i;
|
||||
i += (1 << UCMP32_kBlockShift);
|
||||
}
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactIntArray* ucmp32_openAdopt(uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count)
|
||||
{
|
||||
CompactIntArray* this_obj = (CompactIntArray*) uprv_malloc(sizeof(CompactIntArray));
|
||||
|
||||
ucmp32_initAdopt(this_obj, indexArray, newValues, count);
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactIntArray* ucmp32_openAlias(uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count)
|
||||
{
|
||||
CompactIntArray* this_obj = (CompactIntArray*) uprv_malloc(sizeof(CompactIntArray));
|
||||
|
||||
ucmp32_initAlias(this_obj, indexArray, newValues, count);
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactIntArray* ucmp32_openFromData( const uint8_t **source,
|
||||
UErrorCode *status)
|
||||
{
|
||||
CompactIntArray* this_obj = (CompactIntArray*) uprv_malloc(sizeof(CompactIntArray));
|
||||
|
||||
ucmp32_initFromData(this_obj, source, status);
|
||||
this_obj->fIAmOwned = FALSE;
|
||||
return this_obj;
|
||||
}
|
||||
/*=======================================================*/
|
||||
|
||||
CompactIntArray* ucmp32_initAdopt(CompactIntArray* 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(CompactIntArray);
|
||||
|
||||
this_obj->fArray = newValues;
|
||||
this_obj->fIndex = indexArray;
|
||||
this_obj->fCompact = (UBool)((count < UCMP32_kUnicodeCount) ? TRUE : FALSE);
|
||||
this_obj->fAlias = FALSE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
|
||||
CompactIntArray* ucmp32_initAlias(CompactIntArray* 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(CompactIntArray);
|
||||
|
||||
this_obj->fArray = newValues;
|
||||
this_obj->fIndex = indexArray;
|
||||
this_obj->fCompact = (UBool)((count < UCMP32_kUnicodeCount) ? TRUE : FALSE);
|
||||
this_obj->fAlias = TRUE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
}
|
||||
|
||||
return this_obj;
|
||||
}
|
||||
/*=======================================================*/
|
||||
|
||||
void ucmp32_close(CompactIntArray* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UBool ucmp32_isBogus(const CompactIntArray* this_obj)
|
||||
{
|
||||
return (UBool)(this_obj == NULL || this_obj->fBogus);
|
||||
}
|
||||
|
||||
void ucmp32_expand(CompactIntArray* 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(UCMP32_kUnicodeCount * sizeof(int32_t));
|
||||
if (tempArray == NULL) {
|
||||
this_obj->fBogus = TRUE;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < UCMP32_kUnicodeCount; ++i) {
|
||||
tempArray[i] = ucmp32_get(this_obj, (UChar)i); /* HSYS : How expand?*/
|
||||
}
|
||||
for (i = 0; i < UCMP32_kIndexCount; ++i) {
|
||||
this_obj->fIndex[i] = (uint16_t)(i<<UCMP32_kBlockShift);
|
||||
}
|
||||
uprv_free(this_obj->fArray);
|
||||
this_obj->fArray = tempArray;
|
||||
this_obj->fCompact = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ucmp32_getCount(const CompactIntArray* this_obj)
|
||||
{
|
||||
return this_obj->fCount;
|
||||
}
|
||||
|
||||
const int32_t* ucmp32_getArray(const CompactIntArray* this_obj)
|
||||
{
|
||||
return this_obj->fArray;
|
||||
}
|
||||
|
||||
const uint16_t* ucmp32_getIndex(const CompactIntArray* this_obj)
|
||||
{
|
||||
return this_obj->fIndex;
|
||||
}
|
||||
|
||||
void ucmp32_set(CompactIntArray* this_obj, UChar c, int32_t value)
|
||||
{
|
||||
if (this_obj->fCompact == TRUE) {
|
||||
ucmp32_expand(this_obj);
|
||||
if (this_obj->fBogus) return;
|
||||
}
|
||||
this_obj->fArray[(int32_t)c] = value;
|
||||
}
|
||||
|
||||
|
||||
void ucmp32_setRange(CompactIntArray* this_obj, UChar start, UChar end, int32_t value)
|
||||
{
|
||||
int32_t i;
|
||||
if (this_obj->fCompact == TRUE) {
|
||||
ucmp32_expand(this_obj);
|
||||
if (this_obj->fBogus) return;
|
||||
|
||||
}
|
||||
for (i = start; i <= end; ++i) {
|
||||
this_obj->fArray[i] = value;
|
||||
}
|
||||
}
|
||||
/*=======================================================
|
||||
* this_obj->fArray: an array to be overlapped
|
||||
* start and count: specify the block to be overlapped
|
||||
* tempIndex: the overlapped array (actually indices back into inputContents)
|
||||
* inputHash: an index of hashes for tempIndex, where
|
||||
* inputHash[i] = XOR of values from i-count+1 to i
|
||||
*/
|
||||
|
||||
static int32_t ucmp32_findOverlappingPosition(CompactIntArray* this_obj,
|
||||
uint32_t start,
|
||||
const UChar* tempIndex,
|
||||
int32_t tempIndexCount,
|
||||
uint32_t cycle) {
|
||||
/* this_obj is a utility routine for finding blocks that overlap.
|
||||
* IMPORTANT: the cycle number is very important. Small cycles take a lot
|
||||
* longer to work. In some cases, they may be able to get better compaction.
|
||||
*/
|
||||
int32_t i;
|
||||
int32_t j;
|
||||
int32_t currentCount;
|
||||
|
||||
|
||||
for (i = 0; i < tempIndexCount; i += cycle) {
|
||||
currentCount = UCMP32_kBlockCount;
|
||||
if (i + UCMP32_kBlockCount > tempIndexCount) {
|
||||
currentCount = tempIndexCount - i;
|
||||
}
|
||||
for (j = 0; j < currentCount; ++j) {
|
||||
if (this_obj->fArray[start + j] != this_obj->fArray[tempIndex[i + j]]) break;
|
||||
}
|
||||
if (j == currentCount) break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
/*=======================================================*/
|
||||
|
||||
void ucmp32_compact(CompactIntArray* this_obj, int32_t cycle) {
|
||||
/* this_obj actually does the compaction.
|
||||
* it walks throught the contents of the expanded array, finding the
|
||||
* first block in the data that matches the contents of the current index.
|
||||
* As it works, it keeps an updated pointer to the last position,
|
||||
* so that it knows how big to make the final array
|
||||
* If the matching succeeds, then the index will point into the data
|
||||
* at some earlier position.
|
||||
* If the matching fails, then last position pointer will be bumped,
|
||||
* and the index will point to that last block of data.
|
||||
*/
|
||||
UChar* tempIndex;
|
||||
int32_t tempIndexCount;
|
||||
int32_t* tempArray;
|
||||
int32_t iBlock, iIndex;
|
||||
int32_t newCount, firstPosition;
|
||||
uint32_t block;
|
||||
if (!this_obj->fCompact) {
|
||||
|
||||
/* fix cycle, must be 0 < cycle <= blockcount*/
|
||||
if (cycle < 0) cycle = 1;
|
||||
else if (cycle > UCMP32_kBlockCount)
|
||||
cycle = UCMP32_kBlockCount;
|
||||
|
||||
/* make temp storage, larger than we need*/
|
||||
tempIndex =(UChar*)uprv_malloc(UCMP32_kUnicodeCount * sizeof(uint32_t));
|
||||
if (tempIndex == NULL) {
|
||||
this_obj->fBogus = TRUE;
|
||||
return;
|
||||
}
|
||||
/* set up first block.*/
|
||||
tempIndexCount = UCMP32_kBlockCount;
|
||||
for (iIndex = 0; iIndex < UCMP32_kBlockCount; ++iIndex) {
|
||||
tempIndex[iIndex] = (uint16_t)iIndex;
|
||||
}; /* endfor (iIndex = 0; .....)*/
|
||||
this_obj->fIndex[0] = 0;
|
||||
|
||||
/* for each successive block, find out its first position in the compacted array*/
|
||||
for (iBlock = 1; iBlock < UCMP32_kIndexCount; ++iBlock) {
|
||||
|
||||
block = iBlock<<UCMP32_kBlockShift;
|
||||
if (debugSmall) if (block > debugSmallLimit) break;
|
||||
firstPosition = ucmp32_findOverlappingPosition(this_obj, block, tempIndex, tempIndexCount, cycle);
|
||||
|
||||
/* if not contained in the current list, copy the remainder
|
||||
* invariant; cumulativeHash[iBlock] = XOR of values from iBlock-kBlockCount+1 to iBlock
|
||||
* we do this_obj by XORing out cumulativeHash[iBlock-kBlockCount]
|
||||
*/
|
||||
newCount = firstPosition + UCMP32_kBlockCount;
|
||||
if (newCount > tempIndexCount) {
|
||||
for (iIndex = tempIndexCount; iIndex < newCount; ++iIndex) {
|
||||
tempIndex[iIndex] = (uint16_t)(iIndex - firstPosition + block);
|
||||
} /* endfor (iIndex = tempIndexCount....)*/
|
||||
tempIndexCount = newCount;
|
||||
} /*endif (newCount > tempIndexCount)*/
|
||||
this_obj->fIndex[iBlock] = (uint16_t)firstPosition;
|
||||
} /* endfor (iBlock = 1.....)*/
|
||||
|
||||
|
||||
|
||||
/* now allocate and copy the items into the array*/
|
||||
tempArray = (int32_t*)uprv_malloc(tempIndexCount * sizeof(uint32_t));
|
||||
if (tempArray == NULL) {
|
||||
this_obj->fBogus = TRUE;
|
||||
uprv_free(tempIndex);
|
||||
return;
|
||||
}
|
||||
for (iIndex = 0; iIndex < tempIndexCount; ++iIndex) {
|
||||
tempArray[iIndex] = this_obj->fArray[tempIndex[iIndex]];
|
||||
}
|
||||
uprv_free(this_obj->fArray);
|
||||
this_obj->fArray = tempArray;
|
||||
this_obj->fCount = tempIndexCount;
|
||||
|
||||
|
||||
|
||||
/* free up temp storage*/
|
||||
uprv_free(tempIndex);
|
||||
this_obj->fCompact = TRUE;
|
||||
|
||||
#ifdef _DEBUG
|
||||
/*the following line is useful for specific debugging purposes*/
|
||||
/*fprintf(stderr, "Compacted to %ld with cycle %d\n", fCount, cycle);*/
|
||||
#endif
|
||||
} /* endif (!this_obj->fCompact)*/
|
||||
}
|
||||
|
||||
U_CAPI uint32_t U_EXPORT2 ucmp32_flattenMem (const CompactIntArray* array, UMemoryStream *MS)
|
||||
{
|
||||
int32_t size = 0;
|
||||
|
||||
uprv_mstrm_write32(MS, ICU_UCMP32_VERSION);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_write32(MS, array->fCount);
|
||||
size += 4;
|
||||
|
||||
uprv_mstrm_writeBlock(MS, array->fIndex, sizeof(array->fIndex[0])*UCMP32_kIndexCount);
|
||||
size += sizeof(array->fIndex[0])*UCMP32_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;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2 ucmp32_initFromData(CompactIntArray *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(CompactIntArray);
|
||||
this_obj->fCompact = TRUE;
|
||||
this_obj->fAlias = TRUE;
|
||||
this_obj->fIAmOwned = TRUE;
|
||||
|
||||
i = * ((const uint32_t*) *source);
|
||||
(*source) += 4;
|
||||
|
||||
if(i != ICU_UCMP32_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])*UCMP32_kIndexCount;
|
||||
|
||||
this_obj->fArray = (int32_t*) *source;
|
||||
(*source) += sizeof(this_obj->fArray[0])*this_obj->fCount;
|
||||
|
||||
/* eat up padding */
|
||||
while((*source-(oldSource))%4)
|
||||
(*source)++;
|
||||
}
|
@ -1,275 +0,0 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1995-2001, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* and others. All Rights Reserved.
|
||||
* @version 1.0 23/10/96
|
||||
* @author Helena Shih
|
||||
* Based on Taligent international support for java
|
||||
* Modification History :
|
||||
*
|
||||
* Date Name Description
|
||||
* 2/5/97 aliu Added CompactIntArray streamIn and streamOut methods.
|
||||
* 05/07/97 helena Added isBogus()
|
||||
* 04/26/99 Madhu Ported to C for C Implementation
|
||||
* 11/21/99 srl macroized ucmp32_get()
|
||||
*/
|
||||
|
||||
#ifndef UCMP32_H
|
||||
#define UCMP32_H
|
||||
|
||||
#define ICU_UCMP32_VERSION 0x01260000
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#include "filestrm.h"
|
||||
#include "umemstrm.h"
|
||||
|
||||
/* INTERNAL CONSTANTS */
|
||||
#define UCMP32_kBlockShift 7
|
||||
#define UCMP32_kBlockCount (1<<UCMP32_kBlockShift)
|
||||
#define UCMP32_kIndexShift (16-UCMP32_kBlockShift)
|
||||
#define UCMP32_kIndexCount (1<<UCMP32_kIndexShift)
|
||||
#define UCMP32_kBlockMask (UCMP32_kBlockCount-1)
|
||||
#define UCMP32_kUnicodeCount 65536
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <P>
|
||||
* A compact array of any primitive data type serves two purposes:
|
||||
* <UL type = round>
|
||||
* <LI>Fast access of the indexed values.
|
||||
* <LI>Smaller memory footprint.
|
||||
* </UL>
|
||||
* <P>
|
||||
* 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
|
||||
* <PRE>
|
||||
* Example: Expanded
|
||||
* BLOCK 0 1 2 3 4
|
||||
* INDEX 0 4 8 12 16 ...
|
||||
* ARRAY abcdeababcdezyabcdea...
|
||||
* | | | | | |...
|
||||
* </PRE>
|
||||
* <P>
|
||||
* 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
|
||||
* <PRE>
|
||||
* Example: Compressed
|
||||
* BLOCK 0 1 2 3 4
|
||||
* INDEX 0 4 1 8 2 ...
|
||||
* ARRAY abcdeabazyabc...
|
||||
* </PRE>
|
||||
* <P>
|
||||
* 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 CompactIntArray
|
||||
* @see CompactCharArray
|
||||
* @see CompactStringArray
|
||||
* @version $Revision: 1.17 $ 8/25/98
|
||||
* @author Helena Shih
|
||||
*/
|
||||
/*====================================
|
||||
*CompactIntArray
|
||||
* 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 CompactIntArray{
|
||||
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 */
|
||||
} CompactIntArray;
|
||||
|
||||
U_CAPI int32_t U_EXPORT2 ucmp32_getkUnicodeCount(void);
|
||||
U_CAPI int32_t U_EXPORT2 ucmp32_getkBlockCount(void);
|
||||
|
||||
|
||||
/**
|
||||
* Construct an empty CompactIntArray.
|
||||
*
|
||||
* @param defaultValue the default value for all characters not explicitly in the array
|
||||
*/
|
||||
U_CAPI CompactIntArray* U_EXPORT2 ucmp32_open(int32_t defaultValue);
|
||||
|
||||
/**
|
||||
* Construct a CompactIntArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactIntArray. 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
|
||||
*/
|
||||
U_CAPI CompactIntArray* U_EXPORT2 ucmp32_openAdopt(uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count);
|
||||
|
||||
/**
|
||||
* Construct a CompactIntArray from a pre-computed index and values array. The values
|
||||
* will be aliased by the CompactIntArray. 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
|
||||
*/
|
||||
U_CAPI CompactIntArray* U_EXPORT2 ucmp32_openAlias(uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count);
|
||||
|
||||
/**
|
||||
* Initialize a CompactIntArray from a pre-computed index and values array. The values
|
||||
* will be adopted by the CompactIntArray. 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 CompactIntArray* U_EXPORT2 ucmp32_initAdopt(CompactIntArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count);
|
||||
|
||||
/**
|
||||
* Initialize a CompactIntArray from a pre-computed index and values array. The values
|
||||
* will be aliased by the CompactIntArray. 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 CompactIntArray* U_EXPORT2 ucmp32_initAlias(CompactIntArray *this_obj,
|
||||
uint16_t *indexArray,
|
||||
int32_t *newValues,
|
||||
int32_t count);
|
||||
|
||||
/**
|
||||
* Free up any allocated memory associated with this compact array.
|
||||
* The memory that is uprv_free'd depends on how the array was initialized
|
||||
* or opened.
|
||||
*
|
||||
* @param array The compact array to close
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp32_close(CompactIntArray* array);
|
||||
|
||||
/**
|
||||
* Returns TRUE if the creation of the compact array fails.
|
||||
*/
|
||||
U_CAPI UBool U_EXPORT2 ucmp32_isBogus(const CompactIntArray* 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 ucmp32_get(array, index) (array->fArray[(array->fIndex[(index >> UCMP32_kBlockShift)] )+ \
|
||||
(index & UCMP32_kBlockMask)])
|
||||
|
||||
#define ucmp32_getu(array, index) (uint16_t)ucmp32_get(array, index)
|
||||
|
||||
/**
|
||||
* Set a new value for a Unicode character.
|
||||
* Set automatically expands the array if it is compacted.
|
||||
* @param character the character to set the mapped value with
|
||||
* @param value the new mapped value
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp32_set(CompactIntArray *array,
|
||||
UChar character,
|
||||
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
|
||||
* @param value the new mapped value
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp32_setRange(CompactIntArray* 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 ucmp32_compact(CompactIntArray* array, int32_t cycle);
|
||||
|
||||
/**
|
||||
* Expands the compacted array.
|
||||
* Takes the array back to a 65536 element array
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 ucmp32_expand(CompactIntArray* 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 ucmp32_getCount(const CompactIntArray* array);
|
||||
|
||||
/**
|
||||
* Get the address of the value array.
|
||||
*
|
||||
* @return the address of the value array
|
||||
*/
|
||||
U_CAPI const int32_t* U_EXPORT2 ucmp32_getArray(const CompactIntArray* array);
|
||||
|
||||
/**
|
||||
* Get the address of the index array.
|
||||
*
|
||||
* @return the address of the index array
|
||||
*/
|
||||
U_CAPI const uint16_t* U_EXPORT2 ucmp32_getIndex(const CompactIntArray* array);
|
||||
|
||||
U_CAPI void U_EXPORT2 ucmp32_streamIn( CompactIntArray* array, FileStream* is);
|
||||
U_CAPI void U_EXPORT2 ucmp32_streamOut(CompactIntArray* array, FileStream* os);
|
||||
|
||||
U_CAPI void U_EXPORT2 ucmp32_streamMemIn( CompactIntArray* array, UMemoryStream* is);
|
||||
U_CAPI void U_EXPORT2 ucmp32_streamMemOut(CompactIntArray* array, UMemoryStream* os);
|
||||
|
||||
U_CAPI uint32_t U_EXPORT2 ucmp32_flattenMem(const CompactIntArray* array, UMemoryStream *MS);
|
||||
|
||||
U_CAPI CompactIntArray* U_EXPORT2 ucmp32_openFromData( const uint8_t **source, UErrorCode *status);
|
||||
U_CAPI void U_EXPORT2 ucmp32_initFromData(CompactIntArray *this_obj, const uint8_t **source, UErrorCode *status);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user