all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/text/internal/language/compose.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
// Copyright 2018 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
5
package language
6
7
import (
8
	"sort"
9
	"strings"
10
)
11
12
// A Builder allows constructing a Tag from individual components.
13
// Its main user is Compose in the top-level language package.
14
type Builder struct {
15
	Tag Tag
16
17
	private    string // the x extension
18
	variants   []string
19
	extensions []string
20
}
21
22
// Make returns a new Tag from the current settings.
23
func (b *Builder) Make() Tag {
24
	t := b.Tag
25
26
	if len(b.extensions) > 0 || len(b.variants) > 0 {
27
		sort.Sort(sortVariants(b.variants))
28
		sort.Strings(b.extensions)
29
30
		if b.private != "" {
31
			b.extensions = append(b.extensions, b.private)
32
		}
33
		n := maxCoreSize + tokenLen(b.variants...) + tokenLen(b.extensions...)
34
		buf := make([]byte, n)
35
		p := t.genCoreBytes(buf)
36
		t.pVariant = byte(p)
37
		p += appendTokens(buf[p:], b.variants...)
38
		t.pExt = uint16(p)
39
		p += appendTokens(buf[p:], b.extensions...)
40
		t.str = string(buf[:p])
41
		// We may not always need to remake the string, but when or when not
42
		// to do so is rather tricky.
43
		scan := makeScanner(buf[:p])
44
		t, _ = parse(&scan, "")
45
		return t
46
47
	} else if b.private != "" {
48
		t.str = b.private
49
		t.RemakeString()
50
	}
51
	return t
52
}
53
54
// SetTag copies all the settings from a given Tag. Any previously set values
55
// are discarded.
56
func (b *Builder) SetTag(t Tag) {
57
	b.Tag.LangID = t.LangID
58
	b.Tag.RegionID = t.RegionID
59
	b.Tag.ScriptID = t.ScriptID
60
	// TODO: optimize
61
	b.variants = b.variants[:0]
62
	if variants := t.Variants(); variants != "" {
63
		for _, vr := range strings.Split(variants[1:], "-") {
64
			b.variants = append(b.variants, vr)
65
		}
66
	}
67
	b.extensions, b.private = b.extensions[:0], ""
68
	for _, e := range t.Extensions() {
69
		b.AddExt(e)
70
	}
71
}
72
73
// AddExt adds extension e to the tag. e must be a valid extension as returned
74
// by Tag.Extension. If the extension already exists, it will be discarded,
75
// except for a -u extension, where non-existing key-type pairs will added.
76
func (b *Builder) AddExt(e string) {
77
	if e[0] == 'x' {
78
		if b.private == "" {
79
			b.private = e
80
		}
81
		return
82
	}
83
	for i, s := range b.extensions {
84
		if s[0] == e[0] {
85
			if e[0] == 'u' {
86
				b.extensions[i] += e[1:]
87
			}
88
			return
89
		}
90
	}
91
	b.extensions = append(b.extensions, e)
92
}
93
94
// SetExt sets the extension e to the tag. e must be a valid extension as
95
// returned by Tag.Extension. If the extension already exists, it will be
96
// overwritten, except for a -u extension, where the individual key-type pairs
97
// will be set.
98
func (b *Builder) SetExt(e string) {
99
	if e[0] == 'x' {
100
		b.private = e
101
		return
102
	}
103
	for i, s := range b.extensions {
104
		if s[0] == e[0] {
105
			if e[0] == 'u' {
106
				b.extensions[i] = e + s[1:]
107
			} else {
108
				b.extensions[i] = e
109
			}
110
			return
111
		}
112
	}
113
	b.extensions = append(b.extensions, e)
114
}
115
116
// AddVariant adds any number of variants.
117
func (b *Builder) AddVariant(v ...string) {
118
	for _, v := range v {
119
		if v != "" {
120
			b.variants = append(b.variants, v)
121
		}
122
	}
123
}
124
125
// ClearVariants removes any variants previously added, including those
126
// copied from a Tag in SetTag.
127
func (b *Builder) ClearVariants() {
128
	b.variants = b.variants[:0]
129
}
130
131
// ClearExtensions removes any extensions previously added, including those
132
// copied from a Tag in SetTag.
133
func (b *Builder) ClearExtensions() {
134
	b.private = ""
135
	b.extensions = b.extensions[:0]
136
}
137
138
func tokenLen(token ...string) (n int) {
139
	for _, t := range token {
140
		n += len(t) + 1
141
	}
142
	return
143
}
144
145
func appendTokens(b []byte, token ...string) int {
146
	p := 0
147
	for _, t := range token {
148
		b[p] = '-'
149
		copy(b[p+1:], t)
150
		p += 1 + len(t)
151
	}
152
	return p
153
}
154
155
type sortVariants []string
156
157
func (s sortVariants) Len() int {
158
	return len(s)
159
}
160
161
func (s sortVariants) Swap(i, j int) {
162
	s[j], s[i] = s[i], s[j]
163
}
164
165
func (s sortVariants) Less(i, j int) bool {
166
	return variantIndex[s[i]] < variantIndex[s[j]]
167
}