OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / text / internal / colltab / colltab.go
diff --git a/vendor/golang.org/x/text/internal/colltab/colltab.go b/vendor/golang.org/x/text/internal/colltab/colltab.go
new file mode 100644 (file)
index 0000000..02f2247
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright 2015 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 colltab contains functionality related to collation tables.
+// It is only to be used by the collate and search packages.
+package colltab // import "golang.org/x/text/internal/colltab"
+
+import (
+       "sort"
+
+       "golang.org/x/text/language"
+)
+
+// MatchLang finds the index of t in tags, using a matching algorithm used for
+// collation and search. tags[0] must be language.Und, the remaining tags should
+// be sorted alphabetically.
+//
+// Language matching for collation and search is different from the matching
+// defined by language.Matcher: the (inferred) base language must be an exact
+// match for the relevant fields. For example, "gsw" should not match "de".
+// Also the parent relation is different, as a parent may have a different
+// script. So usually the parent of zh-Hant is und, whereas for MatchLang it is
+// zh.
+func MatchLang(t language.Tag, tags []language.Tag) int {
+       // Canonicalize the values, including collapsing macro languages.
+       t, _ = language.All.Canonicalize(t)
+
+       base, conf := t.Base()
+       // Estimate the base language, but only use high-confidence values.
+       if conf < language.High {
+               // The root locale supports "search" and "standard". We assume that any
+               // implementation will only use one of both.
+               return 0
+       }
+
+       // Maximize base and script and normalize the tag.
+       if _, s, r := t.Raw(); (r != language.Region{}) {
+               p, _ := language.Raw.Compose(base, s, r)
+               // Taking the parent forces the script to be maximized.
+               p = p.Parent()
+               // Add back region and extensions.
+               t, _ = language.Raw.Compose(p, r, t.Extensions())
+       } else {
+               // Set the maximized base language.
+               t, _ = language.Raw.Compose(base, s, t.Extensions())
+       }
+
+       // Find start index of the language tag.
+       start := 1 + sort.Search(len(tags)-1, func(i int) bool {
+               b, _, _ := tags[i+1].Raw()
+               return base.String() <= b.String()
+       })
+       if start < len(tags) {
+               if b, _, _ := tags[start].Raw(); b != base {
+                       return 0
+               }
+       }
+
+       // Besides the base language, script and region, only the collation type and
+       // the custom variant defined in the 'u' extension are used to distinguish a
+       // locale.
+       // Strip all variants and extensions and add back the custom variant.
+       tdef, _ := language.Raw.Compose(t.Raw())
+       tdef, _ = tdef.SetTypeForKey("va", t.TypeForKey("va"))
+
+       // First search for a specialized collation type, if present.
+       try := []language.Tag{tdef}
+       if co := t.TypeForKey("co"); co != "" {
+               tco, _ := tdef.SetTypeForKey("co", co)
+               try = []language.Tag{tco, tdef}
+       }
+
+       for _, tx := range try {
+               for ; tx != language.Und; tx = parent(tx) {
+                       for i, t := range tags[start:] {
+                               if b, _, _ := t.Raw(); b != base {
+                                       break
+                               }
+                               if tx == t {
+                                       return start + i
+                               }
+                       }
+               }
+       }
+       return 0
+}
+
+// parent computes the structural parent. This means inheritance may change
+// script. So, unlike the CLDR parent, parent(zh-Hant) == zh.
+func parent(t language.Tag) language.Tag {
+       if t.TypeForKey("va") != "" {
+               t, _ = t.SetTypeForKey("va", "")
+               return t
+       }
+       result := language.Und
+       if b, s, r := t.Raw(); (r != language.Region{}) {
+               result, _ = language.Raw.Compose(b, s, t.Extensions())
+       } else if (s != language.Script{}) {
+               result, _ = language.Raw.Compose(b, t.Extensions())
+       } else if (b != language.Base{}) {
+               result, _ = language.Raw.Compose(t.Extensions())
+       }
+       return result
+}