Source File
parse.go
Belonging Package
golang.org/x/text/language
// Copyright 2013 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package languageimport ()// ValueError is returned by any of the parsing functions when the// input is well-formed but the respective subtag is not recognized// as a valid value.type ValueError interface {error// Subtag returns the subtag for which the error occurred.Subtag() string}// Parse parses the given BCP 47 string and returns a valid Tag. If parsing// failed it returns an error and any part of the tag that could be parsed.// If parsing succeeded but an unknown value was found, it returns// ValueError. The Tag returned in this case is just stripped of the unknown// value. All other values are preserved. It accepts tags in the BCP 47 format// and extensions to this standard defined in// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.// The resulting tag is canonicalized using the default canonicalization type.func ( string) ( Tag, error) {return Default.Parse()}// Parse parses the given BCP 47 string and returns a valid Tag. If parsing// failed it returns an error and any part of the tag that could be parsed.// If parsing succeeded but an unknown value was found, it returns// ValueError. The Tag returned in this case is just stripped of the unknown// value. All other values are preserved. It accepts tags in the BCP 47 format// and extensions to this standard defined in// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.// The resulting tag is canonicalized using the canonicalization type c.func ( CanonType) ( string) ( Tag, error) {defer func() {if recover() != nil {= Tag{}= language.ErrSyntax}}(), := language.Parse()if != nil {return makeTag(),}, := canonicalize(, )if {.RemakeString()}return makeTag(),}// Compose creates a Tag from individual parts, which may be of type Tag, Base,// Script, Region, Variant, []Variant, Extension, []Extension or error. If a// Base, Script or Region or slice of type Variant or Extension is passed more// than once, the latter will overwrite the former. Variants and Extensions are// accumulated, but if two extensions of the same type are passed, the latter// will replace the former. For -u extensions, though, the key-type pairs are// added, where later values overwrite older ones. A Tag overwrites all former// values and typically only makes sense as the first argument. The resulting// tag is returned after canonicalizing using the Default CanonType. If one or// more errors are encountered, one of the errors is returned.func ( ...interface{}) ( Tag, error) {return Default.Compose(...)}// Compose creates a Tag from individual parts, which may be of type Tag, Base,// Script, Region, Variant, []Variant, Extension, []Extension or error. If a// Base, Script or Region or slice of type Variant or Extension is passed more// than once, the latter will overwrite the former. Variants and Extensions are// accumulated, but if two extensions of the same type are passed, the latter// will replace the former. For -u extensions, though, the key-type pairs are// added, where later values overwrite older ones. A Tag overwrites all former// values and typically only makes sense as the first argument. The resulting// tag is returned after canonicalizing using CanonType c. If one or more errors// are encountered, one of the errors is returned.func ( CanonType) ( ...interface{}) ( Tag, error) {defer func() {if recover() != nil {= Tag{}= language.ErrSyntax}}()var language.Builderif = update(&, ...); != nil {return und,}.Tag, _ = canonicalize(, .Tag)return makeTag(.Make()),}var errInvalidArgument = errors.New("invalid Extension or Variant")func update( *language.Builder, ...interface{}) ( error) {for , := range {switch v := .(type) {case Tag:.SetTag(.tag())case Base:.Tag.LangID = .langIDcase Script:.Tag.ScriptID = .scriptIDcase Region:.Tag.RegionID = .regionIDcase Variant:if .variant == "" {= errInvalidArgumentbreak}.AddVariant(.variant)case Extension:if .s == "" {= errInvalidArgumentbreak}.SetExt(.s)case []Variant:.ClearVariants()for , := range {.AddVariant(.variant)}case []Extension:.ClearExtensions()for , := range {.SetExt(.s)}// TODO: support parsing of raw strings based on morphology or just extensions?case error:if != nil {=}}}return}var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight")var errTagListTooLarge = errors.New("tag list exceeds max length")// ParseAcceptLanguage parses the contents of an Accept-Language header as// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and// a list of corresponding quality weights. It is more permissive than RFC 2616// and may return non-nil slices even if the input is not valid.// The Tags will be sorted by highest weight first and then by first occurrence.// Tags with a weight of zero will be dropped. An error will be returned if the// input could not be parsed.func ( string) ( []Tag, []float32, error) {defer func() {if recover() != nil {= nil= nil= language.ErrSyntax}}()if strings.Count(, "-") > 1000 {return nil, nil, errTagListTooLarge}var stringfor != "" {if , = split(, ','); == "" {continue}, := split(, ';')// Scan the language., := Parse()if != nil {, := acceptFallback[]if ! {return nil, nil,}= makeTag(language.Tag{LangID: })}// Scan the optional weight.:= 1.0if != "" {= consume(, 'q')= consume(, '=')// consume returns the empty string when a token could not be// consumed, resulting in an error for ParseFloat.if , = strconv.ParseFloat(, 32); != nil {return nil, nil, errInvalidWeight}// Drop tags with a quality weight of 0.if <= 0 {continue}}= append(, )= append(, float32())}sort.Stable(&tagSort{, })return , , nil}// consume removes a leading token c from s and returns the result or the empty// string if there is no such token.func consume( string, byte) string {if == "" || [0] != {return ""}return strings.TrimSpace([1:])}func split( string, byte) (, string) {if := strings.IndexByte(, ); >= 0 {return strings.TrimSpace([:]), strings.TrimSpace([+1:])}return strings.TrimSpace(), ""}// Add hack mapping to deal with a small number of cases that occur// in Accept-Language (with reasonable frequency).var acceptFallback = map[string]language.Language{"english": _en,"deutsch": _de,"italian": _it,"french": _fr,"*": _mul, // defined in the spec to match all languages.}type tagSort struct {tag []Tagq []float32}func ( *tagSort) () int {return len(.q)}func ( *tagSort) (, int) bool {return .q[] > .q[]}func ( *tagSort) (, int) {.tag[], .tag[] = .tag[], .tag[].q[], .q[] = .q[], .q[]}
![]() |
The pages are generated with Golds v0.6.7. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |