Exemple #1
0
/*
 * 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 */
}
Exemple #3
0
static U_INLINE uint32_t
getWeightByte(uint32_t weight, int32_t index) {
    return getWeightTrail(weight, index); /* same calculation */
}