Path: blob/master/thirdparty/icu4c/common/localeprioritylist.h
9902 views
// © 2019 and later: Unicode, Inc. and others.1// License & terms of use: http://www.unicode.org/copyright.html23// localeprioritylist.h4// created: 2019jul11 Markus W. Scherer56#ifndef __LOCALEPRIORITYLIST_H__7#define __LOCALEPRIORITYLIST_H__89#include "unicode/utypes.h"10#include "unicode/locid.h"11#include "unicode/stringpiece.h"12#include "unicode/uobject.h"1314struct UHashtable;1516U_NAMESPACE_BEGIN1718struct LocaleAndWeightArray;1920/**21* Parses a list of locales from an accept-language string.22* We are a bit more lenient than the spec:23* We accept extra whitespace in more places, empty range fields,24* and any number of qvalue fraction digits.25*26* https://tools.ietf.org/html/rfc2616#section-14.427* 14.4 Accept-Language28*29* Accept-Language = "Accept-Language" ":"30* 1#( language-range [ ";" "q" "=" qvalue ] )31* language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )32*33* Each language-range MAY be given an associated quality value which34* represents an estimate of the user's preference for the languages35* specified by that range. The quality value defaults to "q=1". For36* example,37*38* Accept-Language: da, en-gb;q=0.8, en;q=0.739*40* https://tools.ietf.org/html/rfc2616#section-3.941* 3.9 Quality Values42*43* HTTP content negotiation (section 12) uses short "floating point"44* numbers to indicate the relative importance ("weight") of various45* negotiable parameters. A weight is normalized to a real number in46* the range 0 through 1, where 0 is the minimum and 1 the maximum47* value. If a parameter has a quality value of 0, then content with48* this parameter is `not acceptable' for the client. HTTP/1.149* applications MUST NOT generate more than three digits after the50* decimal point. User configuration of these values SHOULD also be51* limited in this fashion.52*53* qvalue = ( "0" [ "." 0*3DIGIT ] )54* | ( "1" [ "." 0*3("0") ] )55*/56class U_COMMON_API LocalePriorityList : public UMemory {57public:58class Iterator : public Locale::Iterator {59public:60UBool hasNext() const override { return count < length; }6162const Locale &next() override {63for(;;) {64const Locale *locale = list.localeAt(index++);65if (locale != nullptr) {66++count;67return *locale;68}69}70}7172private:73friend class LocalePriorityList;7475Iterator(const LocalePriorityList &list) : list(list), length(list.getLength()) {}7677const LocalePriorityList &list;78int32_t index = 0;79int32_t count = 0;80const int32_t length;81};8283LocalePriorityList(StringPiece s, UErrorCode &errorCode);8485~LocalePriorityList();8687int32_t getLength() const { return listLength - numRemoved; }8889int32_t getLengthIncludingRemoved() const { return listLength; }9091Iterator iterator() const { return Iterator(*this); }9293const Locale *localeAt(int32_t i) const;9495Locale *orphanLocaleAt(int32_t i);9697private:98LocalePriorityList(const LocalePriorityList &) = delete;99LocalePriorityList &operator=(const LocalePriorityList &) = delete;100101bool add(const Locale &locale, int32_t weight, UErrorCode &errorCode);102103void sort(UErrorCode &errorCode);104105LocaleAndWeightArray *list = nullptr;106int32_t listLength = 0;107int32_t numRemoved = 0;108bool hasWeights = false; // other than 1.0109UHashtable *map = nullptr;110};111112U_NAMESPACE_END113114#endif // __LOCALEPRIORITYLIST_H__115116117