aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/common/lsr.cpp
blob: 43500edf4037ce28182f417605c84ba519094598 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// © 2019 and later: Unicode, Inc. and others. 
// License & terms of use: http://www.unicode.org/copyright.html#License 
 
// lsr.cpp 
// created: 2019may08 Markus W. Scherer 
 
#include "unicode/utypes.h" 
#include "charstr.h" 
#include "cmemory.h" 
#include "cstring.h" 
#include "lsr.h" 
#include "uinvchar.h" 
#include "ustr_imp.h" 
 
U_NAMESPACE_BEGIN 
 
LSR::LSR(char prefix, const char *lang, const char *scr, const char *r, int32_t f, 
         UErrorCode &errorCode) : 
        language(nullptr), script(nullptr), region(r), 
        regionIndex(indexForRegion(region)), flags(f) { 
    if (U_SUCCESS(errorCode)) { 
        CharString langScript; 
        langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode); 
        int32_t scriptOffset = langScript.length(); 
        langScript.append(prefix, errorCode).append(scr, errorCode); 
        owned = langScript.cloneData(errorCode); 
        if (U_SUCCESS(errorCode)) { 
            language = owned; 
            script = owned + scriptOffset; 
        } 
    } 
} 
 
LSR::LSR(LSR &&other) U_NOEXCEPT : 
        language(other.language), script(other.script), region(other.region), owned(other.owned), 
        regionIndex(other.regionIndex), flags(other.flags), 
        hashCode(other.hashCode) { 
    if (owned != nullptr) { 
        other.language = other.script = ""; 
        other.owned = nullptr; 
        other.hashCode = 0; 
    } 
} 
 
void LSR::deleteOwned() { 
    uprv_free(owned); 
} 
 
LSR &LSR::operator=(LSR &&other) U_NOEXCEPT { 
    this->~LSR(); 
    language = other.language; 
    script = other.script; 
    region = other.region; 
    regionIndex = other.regionIndex; 
    flags = other.flags; 
    owned = other.owned; 
    hashCode = other.hashCode; 
    if (owned != nullptr) { 
        other.language = other.script = ""; 
        other.owned = nullptr; 
        other.hashCode = 0; 
    } 
    return *this; 
} 
 
UBool LSR::isEquivalentTo(const LSR &other) const { 
    return 
        uprv_strcmp(language, other.language) == 0 && 
        uprv_strcmp(script, other.script) == 0 && 
        regionIndex == other.regionIndex && 
        // Compare regions if both are ill-formed (and their indexes are 0). 
        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0); 
} 
 
UBool LSR::operator==(const LSR &other) const { 
    return 
        uprv_strcmp(language, other.language) == 0 && 
        uprv_strcmp(script, other.script) == 0 && 
        regionIndex == other.regionIndex && 
        // Compare regions if both are ill-formed (and their indexes are 0). 
        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0) && 
        flags == other.flags; 
} 
 
int32_t LSR::indexForRegion(const char *region) { 
    int32_t c = region[0]; 
    int32_t a = c - '0'; 
    if (0 <= a && a <= 9) {  // digits: "419" 
        int32_t b = region[1] - '0'; 
        if (b < 0 || 9 < b) { return 0; } 
        c = region[2] - '0'; 
        if (c < 0 || 9 < c || region[3] != 0) { return 0; } 
        return (10 * a + b) * 10 + c + 1; 
    } else {  // letters: "DE" 
        a = uprv_upperOrdinal(c); 
        if (a < 0 || 25 < a) { return 0; } 
        int32_t b = uprv_upperOrdinal(region[1]); 
        if (b < 0 || 25 < b || region[2] != 0) { return 0; } 
        return 26 * a + b + 1001; 
    } 
    return 0; 
} 
 
LSR &LSR::setHashCode() { 
    if (hashCode == 0) { 
        uint32_t h = ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language))); 
        h = h * 37 + ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script))); 
        h = h * 37 + regionIndex; 
        hashCode = h * 37 + flags; 
    } 
    return *this; 
} 
 
U_NAMESPACE_END