tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lsr.cpp (4331B)


      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        language(nullptr), script(nullptr), region(r),
     20        regionIndex(indexForRegion(region)), flags(f) {
     21    if (U_SUCCESS(errorCode)) {
     22        CharString langScript;
     23        langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode);
     24        int32_t scriptOffset = langScript.length();
     25        langScript.append(prefix, errorCode).append(scr, errorCode);
     26        owned = langScript.cloneData(errorCode);
     27        if (U_SUCCESS(errorCode)) {
     28            language = owned;
     29            script = owned + scriptOffset;
     30        }
     31    }
     32 }
     33 
     34 LSR::LSR(StringPiece lang, StringPiece scr, StringPiece r, int32_t f,
     35         UErrorCode &errorCode) :
     36        language(nullptr), script(nullptr), region(nullptr),
     37        regionIndex(indexForRegion(r.data())), flags(f) {
     38    if (U_SUCCESS(errorCode)) {
     39        CharString data;
     40        data.append(lang, errorCode).append('\0', errorCode);
     41        int32_t scriptOffset = data.length();
     42        data.append(scr, errorCode).append('\0', errorCode);
     43        int32_t regionOffset = data.length();
     44        data.append(r, errorCode);
     45        owned = data.cloneData(errorCode);
     46        if (U_SUCCESS(errorCode)) {
     47            language = owned;
     48            script = owned + scriptOffset;
     49            region = owned + regionOffset;
     50        }
     51    }
     52 }
     53 
     54 LSR::LSR(LSR &&other) noexcept :
     55        language(other.language), script(other.script), region(other.region), owned(other.owned),
     56        regionIndex(other.regionIndex), flags(other.flags),
     57        hashCode(other.hashCode) {
     58    if (owned != nullptr) {
     59        other.language = other.script = "";
     60        other.owned = nullptr;
     61        other.hashCode = 0;
     62    }
     63 }
     64 
     65 void LSR::deleteOwned() {
     66    uprv_free(owned);
     67 }
     68 
     69 LSR &LSR::operator=(LSR &&other) noexcept {
     70    this->~LSR();
     71    language = other.language;
     72    script = other.script;
     73    region = other.region;
     74    regionIndex = other.regionIndex;
     75    flags = other.flags;
     76    owned = other.owned;
     77    hashCode = other.hashCode;
     78    if (owned != nullptr) {
     79        other.language = other.script = "";
     80        other.owned = nullptr;
     81        other.hashCode = 0;
     82    }
     83    return *this;
     84 }
     85 
     86 UBool LSR::isEquivalentTo(const LSR &other) const {
     87    return
     88        uprv_strcmp(language, other.language) == 0 &&
     89        uprv_strcmp(script, other.script) == 0 &&
     90        regionIndex == other.regionIndex &&
     91        // Compare regions if both are ill-formed (and their indexes are 0).
     92        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0);
     93 }
     94 
     95 bool LSR::operator==(const LSR &other) const {
     96    return
     97        uprv_strcmp(language, other.language) == 0 &&
     98        uprv_strcmp(script, other.script) == 0 &&
     99        regionIndex == other.regionIndex &&
    100        // Compare regions if both are ill-formed (and their indexes are 0).
    101        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0) &&
    102        flags == other.flags;
    103 }
    104 
    105 int32_t LSR::indexForRegion(const char *region) {
    106    int32_t c = region[0];
    107    int32_t a = c - '0';
    108    if (0 <= a && a <= 9) {  // digits: "419"
    109        int32_t b = region[1] - '0';
    110        if (b < 0 || 9 < b) { return 0; }
    111        c = region[2] - '0';
    112        if (c < 0 || 9 < c || region[3] != 0) { return 0; }
    113        return (10 * a + b) * 10 + c + 1;
    114    } else {  // letters: "DE"
    115        a = uprv_upperOrdinal(c);
    116        if (a < 0 || 25 < a) { return 0; }
    117        int32_t b = uprv_upperOrdinal(region[1]);
    118        if (b < 0 || 25 < b || region[2] != 0) { return 0; }
    119        return 26 * a + b + 1001;
    120    }
    121    return 0;
    122 }
    123 
    124 LSR &LSR::setHashCode() {
    125    if (hashCode == 0) {
    126        uint32_t h = ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language)));
    127        h = h * 37 + ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script)));
    128        h = h * 37 + regionIndex;
    129        hashCode = h * 37 + flags;
    130    }
    131    return *this;
    132 }
    133 
    134 U_NAMESPACE_END