blob: 772c3d4702e20266a417604ea75433381efd466f [file] [log] [blame]
// Copyright 2018 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 language
import (
"sort"
"strings"
)
type Builder struct {
Tag Tag
Private string // the x extension
Ext []string
Variant []string
Err error
}
func (b *Builder) Make() Tag {
t := b.Tag
if len(b.Ext) > 0 || len(b.Variant) > 0 {
sort.Sort(sortVariants(b.Variant))
sort.Strings(b.Ext)
if b.Private != "" {
b.Ext = append(b.Ext, b.Private)
}
n := maxCoreSize + tokenLen(b.Variant...) + tokenLen(b.Ext...)
buf := make([]byte, n)
p := t.genCoreBytes(buf)
t.pVariant = byte(p)
p += appendTokens(buf[p:], b.Variant...)
t.pExt = uint16(p)
p += appendTokens(buf[p:], b.Ext...)
t.str = string(buf[:p])
} else if b.Private != "" {
t.str = b.Private
t.RemakeString()
}
return t
}
func (b *Builder) SetTag(t Tag) {
b.Tag.LangID = t.LangID
b.Tag.RegionID = t.RegionID
b.Tag.ScriptID = t.ScriptID
// TODO: optimize
b.Variant = b.Variant[:0]
if variants := t.Variants(); variants != "" {
for _, vr := range strings.Split(variants[1:], "-") {
b.Variant = append(b.Variant, vr)
}
}
b.Ext, b.Private = b.Ext[:0], ""
for _, e := range t.Extensions() {
b.AddExt(e)
}
}
func (b *Builder) AddExt(e string) {
if e == "" {
} else if e[0] == 'x' {
b.Private = e
} else {
b.Ext = append(b.Ext, e)
}
}
func tokenLen(token ...string) (n int) {
for _, t := range token {
n += len(t) + 1
}
return
}
func appendTokens(b []byte, token ...string) int {
p := 0
for _, t := range token {
b[p] = '-'
copy(b[p+1:], t)
p += 1 + len(t)
}
return p
}
type sortVariants []string
func (s sortVariants) Len() int {
return len(s)
}
func (s sortVariants) Swap(i, j int) {
s[j], s[i] = s[i], s[j]
}
func (s sortVariants) Less(i, j int) bool {
return variantIndex[s[i]] < variantIndex[s[j]]
}