/* * take two CE weights and calculate the * possible ranges of weights between the two limits, excluding them * for weights with up to 4 bytes there are up to 2*4-1=7 ranges */ static U_INLINE int32_t getWeightRanges(uint32_t lowerLimit, uint32_t upperLimit, uint32_t maxByte, uint32_t countBytes, WeightRange ranges[7]) { WeightRange lower[5], middle, upper[5]; /* [0] and [1] are not used - this simplifies indexing */ uint32_t weight, trail; int32_t length, lowerLength, upperLength, rangeCount; /* assume that both lowerLimit & upperLimit are not 0 */ /* get the lengths of the limits */ lowerLength=lengthOfWeight(lowerLimit); upperLength=lengthOfWeight(upperLimit); #ifdef UCOL_DEBUG printf("length of lower limit 0x%08lx is %ld\n", lowerLimit, lowerLength); printf("length of upper limit 0x%08lx is %ld\n", upperLimit, upperLength); #endif if(lowerLimit>=upperLimit) { #ifdef UCOL_DEBUG printf("error: no space between lower & upper limits\n"); #endif return 0; } /* check that neither is a prefix of the other */ if(lowerLength<upperLength) { if(lowerLimit==truncateWeight(upperLimit, lowerLength)) { #ifdef UCOL_DEBUG printf("error: lower limit 0x%08lx is a prefix of upper limit 0x%08lx\n", lowerLimit, upperLimit); #endif return 0; } } /* if the upper limit is a prefix of the lower limit then the earlier test lowerLimit>=upperLimit has caught it */ /* reset local variables */ uprv_memset(lower, 0, sizeof(lower)); uprv_memset(&middle, 0, sizeof(middle)); uprv_memset(upper, 0, sizeof(upper)); /* * With the limit lengths of 1..4, there are up to 7 ranges for allocation: * range minimum length * lower[4] 4 * lower[3] 3 * lower[2] 2 * middle 1 * upper[2] 2 * upper[3] 3 * upper[4] 4 * * We are now going to calculate up to 7 ranges. * Some of them will typically overlap, so we will then have to merge and eliminate ranges. */ weight=lowerLimit; for(length=lowerLength; length>=2; --length) { trail=getWeightTrail(weight, length); if(trail<maxByte) { lower[length].start=incWeightTrail(weight, length); lower[length].end=setWeightTrail(weight, length, maxByte); lower[length].length=length; lower[length].count=maxByte-trail; } weight=truncateWeight(weight, length-1); } middle.start=incWeightTrail(weight, 1); weight=upperLimit; for(length=upperLength; length>=2; --length) { trail=getWeightTrail(weight, length); if(trail>UCOL_BYTE_FIRST_TAILORED) { upper[length].start=setWeightTrail(weight, length, UCOL_BYTE_FIRST_TAILORED); upper[length].end=decWeightTrail(weight, length); upper[length].length=length; upper[length].count=trail-UCOL_BYTE_FIRST_TAILORED; } weight=truncateWeight(weight, length-1); } middle.end=decWeightTrail(weight, 1); /* set the middle range */ middle.length=1; if(middle.end>=middle.start) { middle.count=(int32_t)((middle.end-middle.start)>>24)+1; } else {
static inline uint32_t getWeightByte(uint32_t weight, int32_t idx) { return getWeightTrail(weight, idx); /* same calculation */ }
static U_INLINE uint32_t getWeightByte(uint32_t weight, int32_t index) { return getWeightTrail(weight, index); /* same calculation */ }