]>
Commit | Line | Data |
---|---|---|
340931cb A |
1 | // © 2019 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html#License | |
3 | ||
4 | // localeprioritylist.h | |
5 | // created: 2019jul11 Markus W. Scherer | |
6 | ||
7 | #ifndef __LOCALEPRIORITYLIST_H__ | |
8 | #define __LOCALEPRIORITYLIST_H__ | |
9 | ||
10 | #include "unicode/utypes.h" | |
11 | #include "unicode/locid.h" | |
12 | #include "unicode/stringpiece.h" | |
13 | #include "unicode/uobject.h" | |
14 | ||
15 | struct UHashtable; | |
16 | ||
17 | U_NAMESPACE_BEGIN | |
18 | ||
19 | struct LocaleAndWeightArray; | |
20 | ||
21 | /** | |
22 | * Parses a list of locales from an accept-language string. | |
23 | * We are a bit more lenient than the spec: | |
24 | * We accept extra whitespace in more places, empty range fields, | |
25 | * and any number of qvalue fraction digits. | |
26 | * | |
27 | * https://tools.ietf.org/html/rfc2616#section-14.4 | |
28 | * 14.4 Accept-Language | |
29 | * | |
30 | * Accept-Language = "Accept-Language" ":" | |
31 | * 1#( language-range [ ";" "q" "=" qvalue ] ) | |
32 | * language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) | |
33 | * | |
34 | * Each language-range MAY be given an associated quality value which | |
35 | * represents an estimate of the user's preference for the languages | |
36 | * specified by that range. The quality value defaults to "q=1". For | |
37 | * example, | |
38 | * | |
39 | * Accept-Language: da, en-gb;q=0.8, en;q=0.7 | |
40 | * | |
41 | * https://tools.ietf.org/html/rfc2616#section-3.9 | |
42 | * 3.9 Quality Values | |
43 | * | |
44 | * HTTP content negotiation (section 12) uses short "floating point" | |
45 | * numbers to indicate the relative importance ("weight") of various | |
46 | * negotiable parameters. A weight is normalized to a real number in | |
47 | * the range 0 through 1, where 0 is the minimum and 1 the maximum | |
48 | * value. If a parameter has a quality value of 0, then content with | |
49 | * this parameter is `not acceptable' for the client. HTTP/1.1 | |
50 | * applications MUST NOT generate more than three digits after the | |
51 | * decimal point. User configuration of these values SHOULD also be | |
52 | * limited in this fashion. | |
53 | * | |
54 | * qvalue = ( "0" [ "." 0*3DIGIT ] ) | |
55 | * | ( "1" [ "." 0*3("0") ] ) | |
56 | */ | |
57 | class U_COMMON_API LocalePriorityList : public UMemory { | |
58 | public: | |
59 | class Iterator : public Locale::Iterator { | |
60 | public: | |
61 | UBool hasNext() const override { return count < length; } | |
62 | ||
63 | const Locale &next() override { | |
64 | for(;;) { | |
65 | const Locale *locale = list.localeAt(index++); | |
66 | if (locale != nullptr) { | |
67 | ++count; | |
68 | return *locale; | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
73 | private: | |
74 | friend class LocalePriorityList; | |
75 | ||
76 | Iterator(const LocalePriorityList &list) : list(list), length(list.getLength()) {} | |
77 | ||
78 | const LocalePriorityList &list; | |
79 | int32_t index = 0; | |
80 | int32_t count = 0; | |
81 | const int32_t length; | |
82 | }; | |
83 | ||
84 | LocalePriorityList(StringPiece s, UErrorCode &errorCode); | |
85 | ||
86 | ~LocalePriorityList(); | |
87 | ||
88 | int32_t getLength() const { return listLength - numRemoved; } | |
89 | ||
90 | int32_t getLengthIncludingRemoved() const { return listLength; } | |
91 | ||
92 | Iterator iterator() const { return Iterator(*this); } | |
93 | ||
94 | const Locale *localeAt(int32_t i) const; | |
95 | ||
96 | Locale *orphanLocaleAt(int32_t i); | |
97 | ||
98 | private: | |
99 | LocalePriorityList(const LocalePriorityList &) = delete; | |
100 | LocalePriorityList &operator=(const LocalePriorityList &) = delete; | |
101 | ||
102 | bool add(const Locale &locale, int32_t weight, UErrorCode &errorCode); | |
103 | ||
104 | void sort(UErrorCode &errorCode); | |
105 | ||
106 | LocaleAndWeightArray *list = nullptr; | |
107 | int32_t listLength = 0; | |
108 | int32_t numRemoved = 0; | |
109 | bool hasWeights = false; // other than 1.0 | |
110 | UHashtable *map = nullptr; | |
111 | }; | |
112 | ||
113 | U_NAMESPACE_END | |
114 | ||
115 | #endif // __LOCALEPRIORITYLIST_H__ |