Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/intl/MozLocale.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef mozilla_intl_MozLocale_h__
7
#define mozilla_intl_MozLocale_h__
8
9
#include "nsString.h"
10
#include "nsTArray.h"
11
12
namespace mozilla {
13
namespace intl {
14
15
/**
16
 * Locale class is a core representation of a single locale.
17
 *
18
 * A locale is a data object representing a combination of language, script,
19
 * region, variant and a set of regional extension preferences that may further specify
20
 * particular user choices like calendar, numbering system, etc.
21
 *
22
 * A locale can be expressed as a language tag string, like a simple "fr" for French,
23
 * or a more specific "sr-Cyrl-RS-u-hc-h12" for Serbian in Russia with a Cyrylic script,
24
 * and hour cycle selected to be `h12`.
25
 *
26
 * The format of the language tag follows BCP47 standard and implements a subset of it.
27
 * In the future we expect to extend this class to cover more subtags and extensions.
28
 *
29
 * BCP47: https://tools.ietf.org/html/bcp47
30
 *
31
 * The aim of this class it aid in validation, parsing and canonicalization of the
32
 * string.
33
 *
34
 * It allows the user to input any well-formed BCP47 language tag and operate
35
 * on its subtags in a canonicalized form.
36
 *
37
 * It should be used for all operations on language tags, and together with
38
 * LocaleService::NegotiateLanguages for language negotiation.
39
 *
40
 * Example:
41
 *
42
 *     Locale loc = Locale("de-at");
43
 *
44
 *     ASSERT_TRUE(loc.GetLanguage().Equals("de"));
45
 *     ASSERT_TRUE(loc.GetScript().IsEmpty());
46
 *     ASSERT_TRUE(loc.GetRegion().Equals("AT")); // canonicalized to upper case
47
 *
48
 *
49
 * Note: The file name is `MozLocale` to avoid compilation problems on case-insensitive
50
 * Windows. The class name is `Locale`.
51
 */
52
class Locale {
53
  public:
54
    /**
55
     * The constructor expects the input to be a well-formed BCP47-style locale string.
56
     *
57
     * Two operations are performed on the well-formed language tags:
58
     *
59
     *  * Case normalization to conform with BCP47 (e.g. "eN-uS" -> "en-US")
60
     *  * Underscore delimiters replaced with dashed (e.g. "en_US" -> "en-US")
61
     *
62
     * If the input language tag string is not well-formed, the Locale will be
63
     * created with its flag `mWellFormed` set to false which will make the Locale never match.
64
     */
65
    explicit Locale(const nsACString& aLocale);
66
    explicit Locale(const char* aLocale)
67
      : Locale(nsDependentCString(aLocale))
68
0
      { };
69
70
    const nsACString& GetLanguage() const;
71
    const nsACString& GetScript() const;
72
    const nsACString& GetRegion() const;
73
    const nsTArray<nsCString>& GetVariants() const;
74
75
    /**
76
     * Returns a `true` if the locale is well-formed, such that the
77
     * Locale object can validly be matched against others.
78
     */
79
27
    bool IsWellFormed() const {
80
27
      return mIsWellFormed;
81
27
    }
82
83
    /**
84
     * Returns a canonicalized language tag string of the locale.
85
     */
86
    const nsCString AsString() const;
87
88
    /**
89
     * Compares two locales optionally treating one or both of
90
     * the locales as a range.
91
     *
92
     * In case one of the locales is treated as a range, its
93
     * empty fields are considered to match all possible
94
     * values of the same field on the other locale.
95
     *
96
     * Example:
97
     *
98
     * Locale("en").Matches(Locale("en-US"), false, false) // false
99
     * Locale("en").Matches(Locale("en-US"), true, false)  // true
100
     *
101
     * The latter returns true because the region field on the "en"
102
     * locale is being treated as a range and matches any region field
103
     * value including "US" of the other locale.
104
     */
105
    bool Matches(const Locale& aOther, bool aThisRange, bool aOtherRange) const;
106
107
    /**
108
     * This operation uses CLDR data to build a more specific version
109
     * of a generic locale.
110
     *
111
     * Example:
112
     *
113
     * Locale("en").AddLikelySubtags().AsString(); // "en-Latn-US"
114
     */
115
    bool AddLikelySubtags();
116
117
    /**
118
     * Clears the variants field of the Locale object.
119
     */
120
    void ClearVariants();
121
122
    /**
123
     * Clears the region field of the Locale object.
124
     */
125
    void ClearRegion();
126
127
    /**
128
     * Marks the locale as invalid which in turns makes
129
     * it to be skipped by most LocaleService operations.
130
     */
131
3
    void Invalidate() {
132
3
      mIsWellFormed = false;
133
3
    }
134
135
    /**
136
     * Compares two locales expecting all fields to match each other.
137
     */
138
6
    bool operator== (const Locale& aOther) {
139
6
      // Note: non-well-formed Locale objects are never
140
6
      // treated as equal to anything
141
6
      // (even other non-well-formed ones).
142
6
      return IsWellFormed() &&
143
6
             aOther.IsWellFormed() &&
144
6
             mLanguage.Equals(aOther.mLanguage) &&
145
6
             mScript.Equals(aOther.mScript) &&
146
6
             mRegion.Equals(aOther.mRegion) &&
147
6
             mVariants == aOther.mVariants &&
148
6
             mPrivateUse == aOther.mPrivateUse;
149
6
    }
150
151
  private:
152
    nsAutoCStringN<3> mLanguage;
153
    nsAutoCStringN<4> mScript;
154
    nsAutoCStringN<2> mRegion;
155
    nsTArray<nsCString> mVariants;
156
    nsTArray<nsCString> mPrivateUse;
157
    bool mIsWellFormed = true;
158
};
159
160
} // intl
161
} // namespace mozilla
162
163
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::intl::Locale)
164
165
#endif /* mozilla_intl_MozLocale_h__ */