Coverage Report

Created: 2026-09-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/icu/icu4c/source/i18n/collation.cpp
Line
Count
Source
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
*******************************************************************************
5
* Copyright (C) 2010-2014, International Business Machines
6
* Corporation and others.  All Rights Reserved.
7
*******************************************************************************
8
* collation.cpp
9
*
10
* created on: 2010oct27
11
* created by: Markus W. Scherer
12
*/
13
14
#include "unicode/utypes.h"
15
16
#if !UCONFIG_NO_COLLATION
17
18
#include "collation.h"
19
#include "uassert.h"
20
21
U_NAMESPACE_BEGIN
22
23
uint32_t
24
0
Collation::incTwoBytePrimaryByOffset(uint32_t basePrimary, UBool isCompressible, int32_t offset) {
25
    // Extract the second byte, minus the minimum byte value,
26
    // plus the offset, modulo the number of usable byte values, plus the minimum.
27
    // Reserve the PRIMARY_COMPRESSION_LOW_BYTE and high byte if necessary.
28
0
    uint32_t primary;
29
0
    if(isCompressible) {
30
0
        offset += (static_cast<int32_t>(basePrimary >> 16) & 0xff) - 4;
31
0
        primary = static_cast<uint32_t>((offset % 251) + 4) << 16;
32
0
        offset /= 251;
33
0
    } else {
34
0
        offset += (static_cast<int32_t>(basePrimary >> 16) & 0xff) - 2;
35
0
        primary = static_cast<uint32_t>((offset % 254) + 2) << 16;
36
0
        offset /= 254;
37
0
    }
38
    // First byte, assume no further overflow.
39
0
    return primary | ((basePrimary & 0xff000000) + static_cast<uint32_t>(offset << 24));
40
0
}
41
42
uint32_t
43
0
Collation::incThreeBytePrimaryByOffset(uint32_t basePrimary, UBool isCompressible, int32_t offset) {
44
    // Extract the third byte, minus the minimum byte value,
45
    // plus the offset, modulo the number of usable byte values, plus the minimum.
46
0
    offset += (static_cast<int32_t>(basePrimary >> 8) & 0xff) - 2;
47
0
    uint32_t primary = static_cast<uint32_t>((offset % 254) + 2) << 8;
48
0
    offset /= 254;
49
    // Same with the second byte,
50
    // but reserve the PRIMARY_COMPRESSION_LOW_BYTE and high byte if necessary.
51
0
    if(isCompressible) {
52
0
        offset += (static_cast<int32_t>(basePrimary >> 16) & 0xff) - 4;
53
0
        primary |= static_cast<uint32_t>((offset % 251) + 4) << 16;
54
0
        offset /= 251;
55
0
    } else {
56
0
        offset += (static_cast<int32_t>(basePrimary >> 16) & 0xff) - 2;
57
0
        primary |= static_cast<uint32_t>((offset % 254) + 2) << 16;
58
0
        offset /= 254;
59
0
    }
60
    // First byte, assume no further overflow.
61
0
    return primary | ((basePrimary & 0xff000000) + static_cast<uint32_t>(offset << 24));
62
0
}
63
64
uint32_t
65
0
Collation::decTwoBytePrimaryByOneStep(uint32_t basePrimary, UBool isCompressible, int32_t step) {
66
    // Extract the second byte, minus the minimum byte value,
67
    // minus the step, modulo the number of usable byte values, plus the minimum.
68
    // Reserve the PRIMARY_COMPRESSION_LOW_BYTE and high byte if necessary.
69
    // Assume no further underflow for the first byte.
70
0
    U_ASSERT(0 < step && step <= 0x7f);
71
0
    int32_t byte2 = (static_cast<int32_t>(basePrimary >> 16) & 0xff) - step;
72
0
    if(isCompressible) {
73
0
        if(byte2 < 4) {
74
0
            byte2 += 251;
75
0
            basePrimary -= 0x1000000;
76
0
        }
77
0
    } else {
78
0
        if(byte2 < 2) {
79
0
            byte2 += 254;
80
0
            basePrimary -= 0x1000000;
81
0
        }
82
0
    }
83
0
    return (basePrimary & 0xff000000) | (static_cast<uint32_t>(byte2) << 16);
84
0
}
85
86
uint32_t
87
0
Collation::decThreeBytePrimaryByOneStep(uint32_t basePrimary, UBool isCompressible, int32_t step) {
88
    // Extract the third byte, minus the minimum byte value,
89
    // minus the step, modulo the number of usable byte values, plus the minimum.
90
0
    U_ASSERT(0 < step && step <= 0x7f);
91
0
    int32_t byte3 = (static_cast<int32_t>(basePrimary >> 8) & 0xff) - step;
92
0
    if(byte3 >= 2) {
93
0
        return (basePrimary & 0xffff0000) | (static_cast<uint32_t>(byte3) << 8);
94
0
    }
95
0
    byte3 += 254;
96
    // Same with the second byte,
97
    // but reserve the PRIMARY_COMPRESSION_LOW_BYTE and high byte if necessary.
98
0
    int32_t byte2 = (static_cast<int32_t>(basePrimary >> 16) & 0xff) - 1;
99
0
    if(isCompressible) {
100
0
        if(byte2 < 4) {
101
0
            byte2 = 0xfe;
102
0
            basePrimary -= 0x1000000;
103
0
        }
104
0
    } else {
105
0
        if(byte2 < 2) {
106
0
            byte2 = 0xff;
107
0
            basePrimary -= 0x1000000;
108
0
        }
109
0
    }
110
    // First byte, assume no further underflow.
111
0
    return (basePrimary & 0xff000000) | (static_cast<uint32_t>(byte2) << 16) | (static_cast<uint32_t>(byte3) << 8);
112
0
}
113
114
uint32_t
115
0
Collation::getThreeBytePrimaryForOffsetData(UChar32 c, int64_t dataCE) {
116
0
    uint32_t p = static_cast<uint32_t>(dataCE >> 32); // three-byte primary pppppp00
117
0
    int32_t lower32 = static_cast<int32_t>(dataCE); // base code point b & step s: bbbbbbss (bit 7: isCompressible)
118
0
    int32_t offset = (c - (lower32 >> 8)) * (lower32 & 0x7f);  // delta * increment
119
0
    UBool isCompressible = (lower32 & 0x80) != 0;
120
0
    return Collation::incThreeBytePrimaryByOffset(p, isCompressible, offset);
121
0
}
122
123
uint32_t
124
0
Collation::unassignedPrimaryFromCodePoint(UChar32 c) {
125
    // Create a gap before U+0000. Use c=-1 for [first unassigned].
126
0
    ++c;
127
    // Fourth byte: 18 values, every 14th byte value (gap of 13).
128
0
    uint32_t primary = 2 + (c % 18) * 14;
129
0
    c /= 18;
130
    // Third byte: 254 values.
131
0
    primary |= (2 + (c % 254)) << 8;
132
0
    c /= 254;
133
    // Second byte: 251 values 04..FE excluding the primary compression bytes.
134
0
    primary |= (4 + (c % 251)) << 16;
135
    // One lead byte covers all code points (c < 0x1182B4 = 1*251*254*18).
136
0
    return primary | (UNASSIGNED_IMPLICIT_BYTE << 24);
137
0
}
138
139
U_NAMESPACE_END
140
141
#endif  // !UCONFIG_NO_COLLATION