Coverage Report

Created: 2026-03-31 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/icu/icu4c/source/common/lsr.cpp
Line
Count
Source
1
// © 2019 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
4
// lsr.cpp
5
// created: 2019may08 Markus W. Scherer
6
7
#include "unicode/utypes.h"
8
#include "charstr.h"
9
#include "cmemory.h"
10
#include "cstring.h"
11
#include "lsr.h"
12
#include "uinvchar.h"
13
#include "ustr_imp.h"
14
15
U_NAMESPACE_BEGIN
16
17
LSR::LSR(char prefix, const char *lang, const char *scr, const char *r, int32_t f,
18
         UErrorCode &errorCode) :
19
0
        language(nullptr), script(nullptr), region(r),
20
0
        regionIndex(indexForRegion(region)), flags(f) {
21
0
    if (U_SUCCESS(errorCode)) {
22
0
        CharString langScript;
23
0
        langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode);
24
0
        int32_t scriptOffset = langScript.length();
25
0
        langScript.append(prefix, errorCode).append(scr, errorCode);
26
0
        owned = langScript.cloneData(errorCode);
27
0
        if (U_SUCCESS(errorCode)) {
28
0
            language = owned;
29
0
            script = owned + scriptOffset;
30
0
        }
31
0
    }
32
0
}
33
34
LSR::LSR(StringPiece lang, StringPiece scr, StringPiece r, int32_t f,
35
         UErrorCode &errorCode) :
36
110k
        language(nullptr), script(nullptr), region(nullptr),
37
110k
        regionIndex(indexForRegion(r.data())), flags(f) {
38
110k
    if (U_SUCCESS(errorCode)) {
39
110k
        CharString data;
40
110k
        data.append(lang, errorCode).append('\0', errorCode);
41
110k
        int32_t scriptOffset = data.length();
42
110k
        data.append(scr, errorCode).append('\0', errorCode);
43
110k
        int32_t regionOffset = data.length();
44
110k
        data.append(r, errorCode);
45
110k
        owned = data.cloneData(errorCode);
46
110k
        if (U_SUCCESS(errorCode)) {
47
110k
            language = owned;
48
110k
            script = owned + scriptOffset;
49
110k
            region = owned + regionOffset;
50
110k
        }
51
110k
    }
52
110k
}
53
54
LSR::LSR(LSR &&other) noexcept :
55
39.0k
        language(other.language), script(other.script), region(other.region), owned(other.owned),
56
39.0k
        regionIndex(other.regionIndex), flags(other.flags),
57
39.0k
        hashCode(other.hashCode) {
58
39.0k
    if (owned != nullptr) {
59
23.6k
        other.language = other.script = "";
60
23.6k
        other.owned = nullptr;
61
23.6k
        other.hashCode = 0;
62
23.6k
    }
63
39.0k
}
64
65
110k
void LSR::deleteOwned() {
66
110k
    uprv_free(owned);
67
110k
}
68
69
75.0k
LSR &LSR::operator=(LSR &&other) noexcept {
70
75.0k
    this->~LSR();
71
75.0k
    language = other.language;
72
75.0k
    script = other.script;
73
75.0k
    region = other.region;
74
75.0k
    regionIndex = other.regionIndex;
75
75.0k
    flags = other.flags;
76
75.0k
    owned = other.owned;
77
75.0k
    hashCode = other.hashCode;
78
75.0k
    if (owned != nullptr) {
79
7.16k
        other.language = other.script = "";
80
7.16k
        other.owned = nullptr;
81
7.16k
        other.hashCode = 0;
82
7.16k
    }
83
75.0k
    return *this;
84
75.0k
}
85
86
23.4k
UBool LSR::isEquivalentTo(const LSR &other) const {
87
23.4k
    return
88
23.4k
        uprv_strcmp(language, other.language) == 0 &&
89
23.4k
        uprv_strcmp(script, other.script) == 0 &&
90
21.3k
        regionIndex == other.regionIndex &&
91
        // Compare regions if both are ill-formed (and their indexes are 0).
92
15.9k
        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0);
93
23.4k
}
94
95
0
bool LSR::operator==(const LSR &other) const {
96
0
    return
97
0
        uprv_strcmp(language, other.language) == 0 &&
98
0
        uprv_strcmp(script, other.script) == 0 &&
99
0
        regionIndex == other.regionIndex &&
100
        // Compare regions if both are ill-formed (and their indexes are 0).
101
0
        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0) &&
102
0
        flags == other.flags;
103
0
}
104
105
195k
int32_t LSR::indexForRegion(const char *region) {
106
195k
    int32_t c = region[0];
107
195k
    int32_t a = c - '0';
108
195k
    if (0 <= a && a <= 9) {  // digits: "419"
109
1.76k
        int32_t b = region[1] - '0';
110
1.76k
        if (b < 0 || 9 < b) { return 0; }
111
1.48k
        c = region[2] - '0';
112
1.48k
        if (c < 0 || 9 < c || region[3] != 0) { return 0; }
113
1.19k
        return (10 * a + b) * 10 + c + 1;
114
194k
    } else {  // letters: "DE"
115
194k
        a = uprv_upperOrdinal(c);
116
194k
        if (a < 0 || 25 < a) { return 0; }
117
151k
        int32_t b = uprv_upperOrdinal(region[1]);
118
151k
        if (b < 0 || 25 < b || region[2] != 0) { return 0; }
119
149k
        return 26 * a + b + 1001;
120
151k
    }
121
0
    return 0;
122
195k
}
123
124
0
LSR &LSR::setHashCode() {
125
0
    if (hashCode == 0) {
126
0
        uint32_t h = ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language)));
127
0
        h = h * 37 + ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script)));
128
0
        h = h * 37 + regionIndex;
129
0
        hashCode = h * 37 + flags;
130
0
    }
131
0
    return *this;
132
0
}
133
134
U_NAMESPACE_END