1 // © 2019 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html#License
4 // localeprioritylist.h
5 // created: 2019jul11 Markus W. Scherer
7 #ifndef __LOCALEPRIORITYLIST_H__
8 #define __LOCALEPRIORITYLIST_H__
10 #include "unicode/utypes.h"
11 #include "unicode/locid.h"
12 #include "unicode/stringpiece.h"
13 #include "unicode/uobject.h"
19 struct LocaleAndWeightArray
;
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.
27 * https://tools.ietf.org/html/rfc2616#section-14.4
28 * 14.4 Accept-Language
30 * Accept-Language = "Accept-Language" ":"
31 * 1#( language-range [ ";" "q" "=" qvalue ] )
32 * language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
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
39 * Accept-Language: da, en-gb;q=0.8, en;q=0.7
41 * https://tools.ietf.org/html/rfc2616#section-3.9
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.
54 * qvalue = ( "0" [ "." 0*3DIGIT ] )
55 * | ( "1" [ "." 0*3("0") ] )
57 class U_COMMON_API LocalePriorityList
: public UMemory
{
59 class Iterator
: public Locale::Iterator
{
61 UBool
hasNext() const override
{ return count
< length
; }
63 const Locale
&next() override
{
65 const Locale
*locale
= list
.localeAt(index
++);
66 if (locale
!= nullptr) {
74 friend class LocalePriorityList
;
76 Iterator(const LocalePriorityList
&list
) : list(list
), length(list
.getLength()) {}
78 const LocalePriorityList
&list
;
84 LocalePriorityList(StringPiece s
, UErrorCode
&errorCode
);
86 ~LocalePriorityList();
88 int32_t getLength() const { return listLength
- numRemoved
; }
90 int32_t getLengthIncludingRemoved() const { return listLength
; }
92 Iterator
iterator() const { return Iterator(*this); }
94 const Locale
*localeAt(int32_t i
) const;
96 Locale
*orphanLocaleAt(int32_t i
);
99 LocalePriorityList(const LocalePriorityList
&) = delete;
100 LocalePriorityList
&operator=(const LocalePriorityList
&) = delete;
102 bool add(const Locale
&locale
, int32_t weight
, UErrorCode
&errorCode
);
104 void sort(UErrorCode
&errorCode
);
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;
115 #endif // __LOCALEPRIORITYLIST_H__