├── README.md
├── aes
├── aes.go
└── aes_test.go
├── client
├── client_msgsub_test.go
├── client_test.go
└── cmd_test.go
├── client_main.go
├── dns
├── .gitignore
├── LICENSE
├── README.markdown
├── TODO.markdown
├── client.go
├── client_test.go
├── clientconfig.go
├── contrib
│ └── check-soa
│ │ └── check-soa.go
├── debian
│ ├── changelog
│ ├── compat
│ ├── control
│ ├── copyright
│ ├── docs
│ ├── patches
│ │ ├── series
│ │ └── zscan-typo
│ ├── rules
│ └── source
│ │ └── format
├── defaults.go
├── dns.go
├── dns_test.go
├── dnssec.go
├── dnssec_test.go
├── dyn_test.go
├── edns.go
├── ex
│ ├── as112
│ │ └── as112.go
│ ├── chaos
│ │ └── chaos.go
│ ├── q
│ │ └── q.go
│ └── reflect
│ │ └── reflect.go
├── example_test.go
├── keygen.go
├── kscan.go
├── labels.go
├── labels_test.go
├── msg.go
├── nsecx.go
├── nsecx_test.go
├── parse_test.go
├── rawmsg.go
├── scanner.go
├── server.go
├── server_test.go
├── singleinflight.go
├── tlsa.go
├── tsig.go
├── types.go
├── update.go
├── xfr.go
├── zgenerate.go
├── zscan.go
└── zscan_rr.go
├── dns_server_mx.json
├── dns_server_text.json
├── dnstunnel_client.linux64
├── dnstunnel_client.win64
├── dnstunnel_server.linux64
├── dnstunnel_server.win64
├── generator
├── generator.bak
└── generator.e
├── http_test.go
├── logger
├── logger.go
└── logw.go
├── server_main.go.b
└── vendor
├── golang.org
└── x
│ └── text
│ ├── LICENSE
│ ├── PATENTS
│ ├── cases
│ ├── cases.go
│ ├── context.go
│ ├── context_test.go
│ ├── example_test.go
│ ├── fold.go
│ ├── fold_test.go
│ ├── gen.go
│ ├── gen_trieval.go
│ ├── icu.go
│ ├── icu_test.go
│ ├── info.go
│ ├── map.go
│ ├── map_test.go
│ ├── tables10.0.0.go
│ ├── tables10.0.0_test.go
│ ├── tables9.0.0.go
│ ├── tables9.0.0_test.go
│ └── trieval.go
│ ├── encoding
│ ├── charmap
│ │ ├── charmap.go
│ │ ├── charmap_test.go
│ │ ├── maketables.go
│ │ └── tables.go
│ ├── encoding.go
│ ├── encoding_test.go
│ ├── example_test.go
│ ├── internal
│ │ ├── enctest
│ │ │ └── enctest.go
│ │ ├── identifier
│ │ │ ├── gen.go
│ │ │ ├── identifier.go
│ │ │ └── mib.go
│ │ └── internal.go
│ ├── simplifiedchinese
│ │ ├── all.go
│ │ ├── all_test.go
│ │ ├── gbk.go
│ │ ├── hzgb2312.go
│ │ ├── maketables.go
│ │ └── tables.go
│ ├── testdata
│ │ ├── candide-gb18030.txt
│ │ ├── candide-utf-16le.txt
│ │ ├── candide-utf-32be.txt
│ │ ├── candide-utf-8.txt
│ │ ├── candide-windows-1252.txt
│ │ ├── rashomon-euc-jp.txt
│ │ ├── rashomon-iso-2022-jp.txt
│ │ ├── rashomon-shift-jis.txt
│ │ ├── rashomon-utf-8.txt
│ │ ├── sunzi-bingfa-gb-levels-1-and-2-hz-gb2312.txt
│ │ ├── sunzi-bingfa-gb-levels-1-and-2-utf-8.txt
│ │ ├── sunzi-bingfa-simplified-gbk.txt
│ │ ├── sunzi-bingfa-simplified-utf-8.txt
│ │ ├── sunzi-bingfa-traditional-big5.txt
│ │ ├── sunzi-bingfa-traditional-utf-8.txt
│ │ ├── unsu-joh-eun-nal-euc-kr.txt
│ │ └── unsu-joh-eun-nal-utf-8.txt
│ └── unicode
│ │ ├── override.go
│ │ ├── unicode.go
│ │ └── unicode_test.go
│ ├── internal
│ ├── gen
│ │ ├── code.go
│ │ └── gen.go
│ ├── internal.go
│ ├── internal_test.go
│ ├── language
│ │ ├── common.go
│ │ ├── compact.go
│ │ ├── compact
│ │ │ ├── compact.go
│ │ │ ├── gen.go
│ │ │ ├── gen_index.go
│ │ │ ├── gen_parents.go
│ │ │ ├── gen_test.go
│ │ │ ├── language.go
│ │ │ ├── language_test.go
│ │ │ ├── parents.go
│ │ │ ├── parse_test.go
│ │ │ ├── tables.go
│ │ │ └── tags.go
│ │ ├── compose.go
│ │ ├── compose_test.go
│ │ ├── coverage.go
│ │ ├── gen.go
│ │ ├── gen_common.go
│ │ ├── language.go
│ │ ├── language_test.go
│ │ ├── lookup.go
│ │ ├── lookup_test.go
│ │ ├── match.go
│ │ ├── match_test.go
│ │ ├── parse.go
│ │ ├── parse_test.go
│ │ ├── tables.go
│ │ └── tags.go
│ ├── match.go
│ ├── match_test.go
│ ├── tag
│ │ ├── tag.go
│ │ └── tag_test.go
│ ├── testtext
│ │ ├── codesize.go
│ │ ├── flag.go
│ │ ├── gc.go
│ │ ├── gccgo.go
│ │ ├── go1_6.go
│ │ ├── go1_7.go
│ │ └── text.go
│ ├── ucd
│ │ ├── example_test.go
│ │ ├── ucd.go
│ │ └── ucd_test.go
│ └── utf8internal
│ │ └── utf8internal.go
│ ├── language
│ ├── coverage.go
│ ├── coverage_test.go
│ ├── doc.go
│ ├── examples_test.go
│ ├── gen.go
│ ├── go1_1.go
│ ├── go1_2.go
│ ├── httpexample_test.go
│ ├── language.go
│ ├── language_test.go
│ ├── lookup_test.go
│ ├── match.go
│ ├── match_test.go
│ ├── parse.go
│ ├── parse_test.go
│ ├── tables.go
│ ├── tags.go
│ └── testdata
│ │ ├── CLDRLocaleMatcherTest.txt
│ │ └── GoLocaleMatcherTest.txt
│ ├── runes
│ ├── cond.go
│ ├── cond_test.go
│ ├── example_test.go
│ ├── runes.go
│ └── runes_test.go
│ ├── transform
│ ├── examples_test.go
│ ├── transform.go
│ └── transform_test.go
│ ├── unicode
│ ├── cldr
│ │ ├── base.go
│ │ ├── cldr.go
│ │ ├── cldr_test.go
│ │ ├── collate.go
│ │ ├── collate_test.go
│ │ ├── data_test.go
│ │ ├── decode.go
│ │ ├── examples_test.go
│ │ ├── makexml.go
│ │ ├── resolve.go
│ │ ├── resolve_test.go
│ │ ├── slice.go
│ │ ├── slice_test.go
│ │ └── xml.go
│ ├── norm
│ │ ├── composition.go
│ │ ├── composition_test.go
│ │ ├── data10.0.0_test.go
│ │ ├── data9.0.0_test.go
│ │ ├── example_iter_test.go
│ │ ├── example_test.go
│ │ ├── forminfo.go
│ │ ├── forminfo_test.go
│ │ ├── input.go
│ │ ├── iter.go
│ │ ├── iter_test.go
│ │ ├── maketables.go
│ │ ├── normalize.go
│ │ ├── normalize_test.go
│ │ ├── readwriter.go
│ │ ├── readwriter_test.go
│ │ ├── tables10.0.0.go
│ │ ├── tables9.0.0.go
│ │ ├── transform.go
│ │ ├── transform_test.go
│ │ ├── trie.go
│ │ ├── triegen.go
│ │ └── ucd_test.go
│ └── rangetable
│ │ ├── gen.go
│ │ ├── merge.go
│ │ ├── merge_test.go
│ │ ├── rangetable.go
│ │ ├── rangetable_test.go
│ │ ├── tables10.0.0.go
│ │ └── tables9.0.0.go
│ └── width
│ ├── common_test.go
│ ├── example_test.go
│ ├── gen.go
│ ├── gen_common.go
│ ├── gen_trieval.go
│ ├── kind_string.go
│ ├── runes_test.go
│ ├── tables10.0.0.go
│ ├── tables9.0.0.go
│ ├── tables_test.go
│ ├── transform.go
│ ├── transform_test.go
│ ├── trieval.go
│ └── width.go
└── vendor.json
/README.md:
--------------------------------------------------------------------------------
1 | # Ice Dns Tunnel Backdoor (DNS 隧道 渗透&后门)
2 | 本作品使用了DNS隧道技术,且是跨平台的(go语言),生成器使用了易语言,做界面简单粗暴。目前编译成了 windows 64位 和 linux64位的两个版本。功能和操作相同
3 |
4 | 本作品是我花费了2天半的时间写的,遵循了标准的DNS MX协议,在极端网络屏蔽情况下,内网渗透变得复杂,我们只能把通信包装成dns协议才能继续内网渗透。本作品利用了超长域名分段传输数据
5 |
6 | **优势:**
7 | 1】使用了aes对称加密算法,传输过程即使人工手动检测到DNS异常传输也难以解码
8 | 2】传输协议稳定,客户端&服务端严格遵循DNS MX协议,且传输过程分段打包传输
9 | 3】使用了http扩展协议,可以通过http post的方式优雅关停服务。避免手动hook隐藏以后 找不到进程无法结束(例如linux上使用 curl 即可优雅关停,下文有使用说明)
10 | 4】跨平台,多平台
11 |
12 |
13 | **劣势:**
14 | 1】没有做相关的rookit hook 进程可见。在此推荐1个linux效果不错 兼容性很强的hook。可以自己手动hook。已经测试了可用。
15 | 另一方面考虑是系统兼容性问题所以没有整合到代码中,还是自己make自己手动hook稳定性比较好。
16 | https://github.com/gianlucaborello/libprocesshider (使用了 ld preloader 技术)
17 |
18 | 2】体积略大,因为是使用golang写的,在没压缩的情况下已经比较大了,可以自行加壳压缩。目前渗透工作,文件体积大小不是瓶颈
19 | 3】只使用了dns隧道,其他隧道没有做,因为目前做工具只想做专精,不想整合太多隧道,恶意行为太多容易被一些极端防火墙告警。
20 | 后续其他隧道预计独立项目开发。尽量不做整合
21 | 4】传输略慢,因为dns隧道对数据包的大小有严格要求,所以只能分段传输,最后还要合包。效率不及普通TCP。
22 | 命令回显需要等待一些时间。命令发送禁止超长命令。
23 |
24 | **使用场景:**
25 | 内网极端环境下的渗透(防火墙只允许dns协议),以及拿到root权限后,配合hook隐藏技术,下后门。
26 |
27 | **用途:**
28 | 可以使用此工具 远程执行shell命令
29 |
30 |
31 | ## 目录结构
32 | client 目录 -> 目录里的_test文件是一些很重要的测试
33 | server_main.go.b -> 是服务端的main文件
34 | client.main.go -> 是客户端的main文件
35 | generator 目录 -> 是使用易语言写的生成器,只是生成方便一些,给菜鸟使用。大牛可以自行改代码编译
36 | generator.exe -> 是易语言编译好的生成器
37 |
38 |
39 | ## 使用说明
40 | 1、使用生成器generator.exe 配置服务端端口 和 客户端连接的地址 设置aes密钥(16位)
41 | 2、服务端启动、客户端启动。在服务端控制台上发送shell命令。稍作等待即可回显
42 | 3、优雅关停: 配置http服务端口,, 向指定地址 /off 发送http post请求,即可关闭程序
43 | 例如linux : curl "http://127.0.0.1:8080/off" -X POST -d "aes密钥"
44 | 密钥必须记好 否则不能优雅关停。
45 | 优雅关停场景:在hook进程或者内核hook的情况下,很难找到这个进程,销毁变得麻烦。使用优雅关停 http请求后自动销毁关闭,省心省力。
46 | 4、在服务端使用过程中, /e 可以直接退出程序 /up 可以返回上层菜单
47 | 5、该工具灵活运用,做好hook的情况下,可以在内网畅通无阻。
48 |
49 | ## 更新计划
50 | 1、添加win平台的自动 hook(感谢提建议),linux平台依然建议使用上面的工具手动hook。
51 | 2、添加端口复用
52 |
53 | ## 回答疑问
54 | 1、服务器只有web对外,无法通过转发等手段连接桌面3389,regeorg又被阻断(疑似检测到来了socket代理的缘故吧),这样的网络结构还有什么办法把3389转发出来么。
55 |
56 | 答:可以通过端口复用拦截,走web服务,思路和隧道一样,也可以叫https http隧道,将3389的数据包转发出来。等上面2个功能更新好后,后续我这边会研究一下。类似于国外软件 reduh
57 |
58 |
59 | ## 写给使用者
60 | 【免责声明:无恶意代码,仅作隧道技术研究,用于非法用途自负】
61 |
62 | 写的比较仓促,基础测试已经做过,基本命令可以执行,在windows环境上测试成功,linux还没来得及测试。有BUG可以提出。另外重申,不考虑整合入太多功能,而尽量是分散开。
63 |
64 | 如果有急迫需要什么工具的可以提issues 或者 联系我 。可以给我提供一些新思路。谢谢
65 |
66 |
67 | ## 写给golang爱好者
68 |
69 | 该程序大量使用了chan管道,编程难点在利用dns协议,数据大小有限,格式固定的情况下进行分包,组包。
70 |
71 | ### End
72 |
--------------------------------------------------------------------------------
/aes/aes.go:
--------------------------------------------------------------------------------
1 | package aes
2 |
3 | import (
4 | "bytes"
5 | "crypto/aes"
6 | "crypto/cipher"
7 | "encoding/base64"
8 | )
9 |
10 | // 明文加密aes编码base64
11 | func AesEncrypt(origData, key []byte) (string, error) {
12 | block, err := aes.NewCipher(key)
13 | if err != nil {
14 | return "", err
15 | }
16 |
17 | blockSize := block.BlockSize()
18 | origData = PKCS5Padding(origData, blockSize)
19 | blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
20 | crypted := make([]byte, len(origData))
21 | blockMode.CryptBlocks(crypted, origData)
22 | pass64 := base64.StdEncoding.EncodeToString(crypted)
23 | return pass64, nil
24 | }
25 |
26 | //base64 + aes解密
27 | func AesDecrypt(crypted string, key []byte) ([]byte, error) {
28 | bytesPass, err := base64.StdEncoding.DecodeString(crypted)
29 | if err != nil {
30 | return nil, err
31 | }
32 |
33 | block, err := aes.NewCipher(key)
34 | if err != nil {
35 | return nil, err
36 | }
37 |
38 | blockSize := block.BlockSize()
39 | blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
40 | origData := make([]byte, len(bytesPass))
41 | blockMode.CryptBlocks(origData, bytesPass)
42 | origData = PKCS5UnPadding(origData)
43 | return origData, nil
44 | }
45 |
46 | func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
47 | padding := blockSize - len(ciphertext)%blockSize
48 | padtext := bytes.Repeat([]byte{byte(padding)}, padding)
49 | return append(ciphertext, padtext...)
50 | }
51 |
52 | func PKCS5UnPadding(origData []byte) []byte {
53 | length := len(origData)
54 | unpadding := int(origData[length-1])
55 | return origData[:(length - unpadding)]
56 | }
57 |
--------------------------------------------------------------------------------
/aes/aes_test.go:
--------------------------------------------------------------------------------
1 | package aes
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func TestAes(t *testing.T) {
9 | //务必16位
10 | AesKey = "321423u9y8d2fwfl"
11 | enStr, err := AesEncrypt([]byte("guigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9k"), []byte(AesKey))
12 | fmt.Println(err)
13 | fmt.Println(enStr)
14 |
15 | deStr, err := AesDecrypt(enStr, []byte(AesKey))
16 | fmt.Println(err)
17 | fmt.Println(string(deStr))
18 | }
19 |
--------------------------------------------------------------------------------
/client/client_msgsub_test.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "math"
7 | "strconv"
8 | "testing"
9 | )
10 |
11 | //测试分割回传消息 是否完整
12 | func TestSubMsg(t *testing.T) {
13 | rootHost := "baidu.com"
14 | body := "guigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9k"
15 | shengyuLen := 63 - len(rootHost) - 1 - 1 //减去两个点的长度 和 根域名的长度
16 | bodyLen := len(body)
17 | //消息分段回传
18 | msgArray := make([]string, 0)
19 | if bodyLen > shengyuLen {
20 | f := float64(bodyLen) / float64(shengyuLen)
21 | //需要分多少段 向上取整
22 | duanCeilInt := int(math.Ceil(f))
23 | rs := []rune(body)
24 | for i := 0; i < duanCeilInt; i++ {
25 | var meiduan string
26 | if (i + 1) == duanCeilInt {
27 | //最后一段了
28 | //最后一段直接不用分割 直接放入
29 | meiduan = string(rs[(shengyuLen-1)*i:])
30 | } else {
31 | //每段分割长度为dns name的剩余长度 shengyuLen
32 | //分割好后存入切片
33 | meiduan = string(rs[(shengyuLen-1)*i : (shengyuLen-1)*(i+1)])
34 | }
35 | msgArray = append(msgArray, meiduan)
36 | }
37 |
38 | } else {
39 | //无需分段
40 | msgArray = append(msgArray, body)
41 | }
42 | b, _ := json.Marshal(msgArray)
43 | fmt.Println("msgArray len=" + strconv.Itoa(len(msgArray)))
44 | fmt.Println(string(b))
45 | }
46 |
--------------------------------------------------------------------------------
/client/cmd_test.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import (
4 | "golang.org/x/text/encoding/simplifiedchinese"
5 | "io/ioutil"
6 | "log"
7 | "os/exec"
8 | "strconv"
9 | "testing"
10 | )
11 |
12 | func TestCmd(t *testing.T) {
13 | str := "abcd"
14 | log.Println(str[1:])
15 |
16 | msgIdStr := "1" + strconv.Itoa(int(123))
17 | msgId, _ := strconv.Atoi(msgIdStr)
18 | uint := uint16(msgId)
19 | log.Println(uint)
20 | log.Println(exe("whoami"))
21 | }
22 |
23 | func exe(commond string) string {
24 | cmd := exec.Command(commond)
25 | //创建获取命令输出管道
26 | stdout, err := cmd.StdoutPipe()
27 | if err != nil {
28 | return "Error:can not obtain stdout pipe for command:" + err.Error()
29 | }
30 | //执行命令
31 | if err := cmd.Start(); err != nil {
32 | return "Error:The command is err," + err.Error()
33 | }
34 | //读取所有输出
35 | bytes, err := ioutil.ReadAll(stdout)
36 | if err != nil {
37 | return "ReadAll Stdout:" + err.Error()
38 | }
39 | if err := cmd.Wait(); err != nil {
40 | return "wait:" + err.Error()
41 | }
42 | var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(bytes)
43 | return string(decodeBytes)
44 | }
45 |
--------------------------------------------------------------------------------
/dns/.gitignore:
--------------------------------------------------------------------------------
1 | *.6
2 | test.out
3 | a.out
4 |
--------------------------------------------------------------------------------
/dns/LICENSE:
--------------------------------------------------------------------------------
1 | Extensions of the original work are copyright (c) 2011 Miek Gieben
2 |
3 | As this is fork of the official Go code the same license applies:
4 |
5 | Copyright (c) 2009 The Go Authors. All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are
9 | met:
10 |
11 | * Redistributions of source code must retain the above copyright
12 | notice, this list of conditions and the following disclaimer.
13 | * Redistributions in binary form must reproduce the above
14 | copyright notice, this list of conditions and the following disclaimer
15 | in the documentation and/or other materials provided with the
16 | distribution.
17 | * Neither the name of Google Inc. nor the names of its
18 | contributors may be used to endorse or promote products derived from
19 | this software without specific prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
33 |
--------------------------------------------------------------------------------
/dns/README.markdown:
--------------------------------------------------------------------------------
1 | # Alternative (more granular) approach to a DNS library.
2 |
3 | > Less is more.
4 |
5 | Complete and usable DNS library. All widely used Resource Records are
6 | supported, including the DNSSEC types. It follows a lean and mean philosophy.
7 | If there is stuff you should know as a DNS programmer there isn't a convenience
8 | function for it. Server side and client side programming is supported, i.e. you
9 | can build servers and resolvers with it.
10 |
11 | If you like this, you may also be interested in:
12 |
13 | * https://github.com/miekg/fks -- a (in)complete nameserver written in Go;
14 | * https://github.com/miekg/unbound -- Go wrapper for the Unbound resolver.
15 |
16 | # Goals
17 |
18 | * KISS;
19 | * Fast
20 | * Small API, if its easy to code in Go, don't make a function for it.
21 |
22 | # Users
23 |
24 | A not-so-up-to-date-list-that-may-be-actually-current:
25 |
26 | * https://github.com/abh/geodns
27 | * http://www.statdns.com/
28 | * http://www.dnsinspect.com/
29 | * https://github.com/chuangbo/jianbing-dictionary-dns
30 | * http://www.dns-lg.com/
31 | * https://github.com/fcambus/rrda
32 | * https://github.com/kenshinx/godns
33 | * more? (send pull request if you want to be listed here)
34 |
35 | # Features
36 |
37 | * UDP/TCP queries, IPv4 and IPv6;
38 | * RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported;
39 | * Fast:
40 | * Reply speed around ~ 80K qps (faster hardware results in more qps);
41 | * Parsing RRs with ~ 100K RR/s, that's 5M records in about 50 seconds;
42 | * Server side programming (mimicking the net/http package);
43 | * Client side programming;
44 | * DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA;
45 | * EDNS0, NSID;
46 | * AXFR/IXFR;
47 | * TSIG;
48 | * DNS name compression.
49 |
50 | Have fun!
51 |
52 | Miek Gieben - 2010-2012 - miek@miek.nl
53 |
54 | # Building
55 |
56 | Building is done with the `go` tool. If you have setup your GOPATH
57 | correctly, the following should work:
58 |
59 | go get github.com/miekg/dns
60 | go build github/com/miekg/dns
61 |
62 | A short "how to use the API" is at the beginning of dns.go (this also will show
63 | when you call `go doc github.com/miekg/dns`. Sample
64 | programs can be found in the `ex` directory. They can also be build
65 | with: `go build`.
66 |
67 | ## Supported RFCs
68 |
69 | *all of them*
70 |
71 | * 103{4,5} - DNS standard
72 | * 1982 - Serial Arithmetic
73 | * 1876 - LOC record
74 | * 1995 - IXFR
75 | * 1996 - DNS notify
76 | * 2136 - DNS Update (dynamic updates)
77 | * 2181 - RRset definition
78 | * 2537 - RSAMD5 DNS keys
79 | * 2065 - DNSSEC (updated in later RFCs)
80 | * 2671 - EDNS record
81 | * 2782 - SRV record
82 | * 2845 - TSIG record
83 | * 2915 - NAPTR record
84 | * 2929 - DNS IANA Considerations
85 | * 3110 - RSASHA1 DNS keys
86 | * 3225 - DO bit (DNSSEC OK)
87 | * 340{1,2,3} - NAPTR record
88 | * 3445 - Limiting the scope of (DNS)KEY
89 | * 3597 - Unkown RRs
90 | * 403{3,4,5} - DNSSEC + validation functions
91 | * 4255 - SSHFP record
92 | * 4343 - Case insensitivity
93 | * 4408 - SPF record
94 | * 4509 - SHA256 Hash in DS
95 | * 4592 - Wildcards in the DNS
96 | * 4635 - HMAC SHA TSIG
97 | * 4701 - DHCID
98 | * 4892 - id.server
99 | * 5001 - NSID
100 | * 5155 - NSEC3 record
101 | * 5205 - HIP record
102 | * 5702 - SHA2 in the DNS
103 | * 5936 - AXFR
104 | * 6605 - ECDSA
105 | * 6742 - ILNP DNS
106 | * 6891 - EDNS0 update
107 | * xxxx - URI record (draft)
108 | * xxxx - EDNS0 DNS Update Lease (draft)
109 | * xxxx - IEU48/IEU64 records (draft)
110 | * xxxx - Algorithm-Signal (draft)
111 |
112 | ## Loosely based upon
113 |
114 | * `ldns`
115 | * `NSD`
116 | * `Net::DNS`
117 | * `GRONG`
118 |
--------------------------------------------------------------------------------
/dns/TODO.markdown:
--------------------------------------------------------------------------------
1 | # TODO
2 |
3 | * Support for on-the-fly-signing or check how to do it
4 | * Ratelimiting? server side (rrl)
5 | * Ratelimiting? client side
6 |
7 | ## Nice to have
8 |
9 | * Speed, we can always go faster. A simple reflect server now hits 75/80K qps on
10 | moderate hardware
11 | * go test; only works correct on my machine
12 | * privatekey.Precompute() when signing?
13 |
14 | ## RRs not implemented
15 |
16 | These are deprecated, or rarely used (or just a bitch to implement).
17 |
18 | NSAP
19 | NSAP-PTR
20 | PX
21 | GPOS
22 | NIMLOC
23 | ATMA
24 | A6
25 | KEY
26 | SIG
27 | NXT
28 |
--------------------------------------------------------------------------------
/dns/client_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "testing"
9 | "time"
10 | )
11 |
12 | func TestClientSync(t *testing.T) {
13 | m := new(Msg)
14 | m.SetQuestion("miek.nl.", TypeSOA)
15 |
16 | c := new(Client)
17 | r, _, _ := c.Exchange(m, "37.251.95.53:53")
18 |
19 | if r != nil && r.Rcode != RcodeSuccess {
20 | t.Log("Failed to get an valid answer")
21 | t.Fail()
22 | t.Logf("%v\n", r)
23 | }
24 | }
25 |
26 | func TestClientEDNS0(t *testing.T) {
27 | m := new(Msg)
28 | m.SetQuestion("miek.nl.", TypeDNSKEY)
29 |
30 | m.SetEdns0(2048, true)
31 | //edns.Option = make([]Option, 1)
32 | //edns.SetNsid("") // Empty to request it
33 |
34 | c := new(Client)
35 | r, _, _ := c.Exchange(m, "37.251.95.53:53")
36 |
37 | if r != nil && r.Rcode != RcodeSuccess {
38 | t.Log("Failed to get an valid answer")
39 | t.Fail()
40 | t.Logf("%v\n", r)
41 | }
42 | }
43 |
44 | func TestSingleSingleInflight(t *testing.T) {
45 | m := new(Msg)
46 | m.SetQuestion("miek.nl.", TypeDNSKEY)
47 |
48 | c := new(Client)
49 | c.SingleInflight = true
50 | nr := 10
51 | ch := make(chan time.Duration)
52 | for i := 0; i < nr; i++ {
53 | go func() {
54 | _, rtt, _ := c.Exchange(m, "37.251.95.53:53")
55 | ch <- rtt
56 | }()
57 | }
58 | i := 0
59 | var first time.Duration
60 | // With inflight *all* rtt are identical, and by doing actual lookups
61 | // the changes that this is a coincidence is small.
62 | Loop:
63 | for {
64 | select {
65 | case rtt := <-ch:
66 | if i == 0 {
67 | first = rtt
68 | } else {
69 | if first != rtt {
70 | t.Log("All rtt should be equal")
71 | t.Fail()
72 | }
73 | }
74 | i++
75 | if i == 10 {
76 | break Loop
77 | }
78 | }
79 | }
80 | }
81 |
82 | func TestClientTsigAXFR(t *testing.T) {
83 | m := new(Msg)
84 | m.SetAxfr("miek.nl.")
85 | m.SetTsig("axfr.", HmacMD5, 300, time.Now().Unix())
86 |
87 | c := new(Client)
88 | c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
89 | c.Net = "tcp"
90 |
91 | if a, err := c.TransferIn(m, "37.251.95.53:53"); err != nil {
92 | t.Log("Failed to setup axfr: " + err.Error())
93 | t.Fatal()
94 | } else {
95 | for ex := range a {
96 | if ex.Error != nil {
97 | t.Logf("Error %s\n", ex.Error.Error())
98 | t.Fail()
99 | break
100 | }
101 | for _, rr := range ex.RR {
102 | t.Logf("%s\n", rr.String())
103 | }
104 | }
105 | }
106 | }
107 |
108 | func TestClientAXFRMultipleMessages(t *testing.T) {
109 | m := new(Msg)
110 | m.SetAxfr("dnsex.nl.")
111 |
112 | c := new(Client)
113 | c.Net = "tcp"
114 |
115 | if a, err := c.TransferIn(m, "37.251.95.53:53"); err != nil {
116 | t.Log("Failed to setup axfr" + err.Error())
117 | t.Fail()
118 | return
119 | } else {
120 | for ex := range a {
121 | if ex.Error != nil {
122 | t.Logf("Error %s\n", ex.Error.Error())
123 | t.Fail()
124 | break
125 | }
126 | }
127 | }
128 | }
129 |
130 | // not really a test, but shows how to use update leases
131 | func TestUpdateLeaseTSIG(t *testing.T) {
132 | m := new(Msg)
133 | m.SetUpdate("t.local.ip6.io.")
134 | rr, _ := NewRR("t.local.ip6.io. 30 A 127.0.0.1")
135 | rrs := make([]RR, 1)
136 | rrs[0] = rr
137 | m.Insert(rrs)
138 |
139 | lease_rr := new(OPT)
140 | lease_rr.Hdr.Name = "."
141 | lease_rr.Hdr.Rrtype = TypeOPT
142 | e := new(EDNS0_UL)
143 | e.Code = EDNS0UL
144 | e.Lease = 120
145 | lease_rr.Option = append(lease_rr.Option, e)
146 | m.Extra = append(m.Extra, lease_rr)
147 |
148 | c := new(Client)
149 | m.SetTsig("polvi.", HmacMD5, 300, time.Now().Unix())
150 | c.TsigSecret = map[string]string{"polvi.": "pRZgBrBvI4NAHZYhxmhs/Q=="}
151 |
152 | w := new(reply)
153 | w.client = c
154 | w.addr = "127.0.0.1:53"
155 | w.req = m
156 |
157 | if err := w.dial(); err != nil {
158 | t.Fail()
159 | }
160 | if err := w.send(m); err != nil {
161 | t.Fail()
162 | }
163 |
164 | }
165 |
--------------------------------------------------------------------------------
/dns/clientconfig.go:
--------------------------------------------------------------------------------
1 | // Copyright 2009 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 | // Extensions of the original work are copyright (c) 2011 Miek Gieben
5 |
6 | package dns
7 |
8 | import (
9 | "bufio"
10 | "os"
11 | "strconv"
12 | "strings"
13 | )
14 |
15 | // Wraps the contents of the /etc/resolv.conf.
16 | type ClientConfig struct {
17 | Servers []string // servers to use
18 | Search []string // suffixes to append to local name
19 | Port string // what port to use
20 | Ndots int // number of dots in name to trigger absolute lookup
21 | Timeout int // seconds before giving up on packet
22 | Attempts int // lost packets before giving up on server, not used in the package dns
23 | }
24 |
25 | // ClientConfigFromFile parses a resolv.conf(5) like file and returns
26 | // a *ClientConfig.
27 | func ClientConfigFromFile(conf string) (*ClientConfig, error) {
28 | file, err := os.Open(conf)
29 | if err != nil {
30 | return nil, err
31 | }
32 | defer file.Close()
33 | c := new(ClientConfig)
34 | b := bufio.NewReader(file)
35 | c.Servers = make([]string, 0)
36 | c.Search = make([]string, 0)
37 | c.Port = "53"
38 | c.Ndots = 1
39 | c.Timeout = 5
40 | c.Attempts = 2
41 | for line, ok := b.ReadString('\n'); ok == nil; line, ok = b.ReadString('\n') {
42 | f := strings.Fields(line)
43 | if len(f) < 1 {
44 | continue
45 | }
46 | switch f[0] {
47 | case "nameserver": // add one name server
48 | if len(f) > 1 {
49 | // One more check: make sure server name is
50 | // just an IP address. Otherwise we need DNS
51 | // to look it up.
52 | name := f[1]
53 | // Don't use this. net.JoinHostPort will fix this for you
54 | // switch x := net.ParseIP(name); true {
55 | // case x.To4() != nil:
56 | // c.Servers = append(c.Servers, name)
57 | // case x.To16() != nil:
58 | // name = "[" + name + "]"
59 | c.Servers = append(c.Servers, name)
60 | // }
61 | }
62 |
63 | case "domain": // set search path to just this domain
64 | if len(f) > 1 {
65 | c.Search = make([]string, 1)
66 | c.Search[0] = f[1]
67 | } else {
68 | c.Search = make([]string, 0)
69 | }
70 |
71 | case "search": // set search path to given servers
72 | c.Search = make([]string, len(f)-1)
73 | for i := 0; i < len(c.Search); i++ {
74 | c.Search[i] = f[i+1]
75 | }
76 |
77 | case "options": // magic options
78 | for i := 1; i < len(f); i++ {
79 | s := f[i]
80 | switch {
81 | case len(s) >= 6 && s[:6] == "ndots:":
82 | n, _ := strconv.Atoi(s[6:])
83 | if n < 1 {
84 | n = 1
85 | }
86 | c.Ndots = n
87 | case len(s) >= 8 && s[:8] == "timeout:":
88 | n, _ := strconv.Atoi(s[8:])
89 | if n < 1 {
90 | n = 1
91 | }
92 | c.Timeout = n
93 | case len(s) >= 8 && s[:9] == "attempts:":
94 | n, _ := strconv.Atoi(s[9:])
95 | if n < 1 {
96 | n = 1
97 | }
98 | c.Attempts = n
99 | case s == "rotate":
100 | /* not imp */
101 | }
102 | }
103 | }
104 | }
105 | return c, nil
106 | }
107 |
--------------------------------------------------------------------------------
/dns/debian/changelog:
--------------------------------------------------------------------------------
1 | golang-dns (0.0~git20130912-1) unstable; urgency=low
2 |
3 | * Initial release. Closes: 722973
4 |
5 | -- Tonnerre LOMBARD Sun, 15 Sep 2013 01:08:44 +0200
6 |
--------------------------------------------------------------------------------
/dns/debian/compat:
--------------------------------------------------------------------------------
1 | 9
2 |
--------------------------------------------------------------------------------
/dns/debian/control:
--------------------------------------------------------------------------------
1 | Source: golang-dns
2 | Section: devel
3 | Priority: extra
4 | Maintainer: Tonnerre LOMBARD
5 | Build-Depends: debhelper (>= 9), dh-golang, golang-go
6 | Standards-Version: 3.9.4
7 | Homepage: http://miek.nl/projects/godns/
8 | Vcs-Git: git://anonscm.debian.org/pkg-go/packages/golang-dns.git
9 | Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-go/packages/golang-dns.git;a=summary
10 |
11 | Package: golang-dns-dev
12 | Architecture: all
13 | Depends: ${shlibs:Depends}, ${misc:Depends}, golang-go
14 | Description: DNS protocol library for Go
15 | Complete and usable DNS library. All widely used Resource Records
16 | are supported, including the DNSSEC types. It follows a lean and
17 | mean philosophy. If there is stuff you should know as a DNS
18 | programmer there isn't a convenience function for it. Server side
19 | and client side programming is supported, i.e. you can build
20 | servers and resolvers with it.
21 |
--------------------------------------------------------------------------------
/dns/debian/copyright:
--------------------------------------------------------------------------------
1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: golang-dns
3 | Source: https://github.com/miekg/dns/
4 |
5 | Files: *
6 | Copyright: 2009-2013 Miek Gieben
7 | License: BSD-3-Clause
8 |
9 | Files: debian/*
10 | Copyright: 2013 Tonnerre Lombard
11 | License: BSD-3-Clause
12 |
13 | License: BSD-3-Clause
14 | Redistribution and use in source and binary forms, with or without
15 | modification, are permitted provided that the following conditions
16 | are met:
17 | .
18 | 1. Redistributions of source code must retain the above copyright
19 | notice, this list of conditions and the following disclaimer.
20 | 2. Redistributions in binary form must reproduce the above copyright
21 | notice, this list of conditions and the following disclaimer in the
22 | documentation and/or other materials provided with the distribution.
23 | 3. Neither the name of the University nor the names of its contributors
24 | may be used to endorse or promote products derived from this software
25 | without specific prior written permission.
26 | .
27 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 | SUCH DAMAGE.
38 |
--------------------------------------------------------------------------------
/dns/debian/docs:
--------------------------------------------------------------------------------
1 | README.markdown
2 | TODO.markdown
3 |
--------------------------------------------------------------------------------
/dns/debian/patches/series:
--------------------------------------------------------------------------------
1 | zscan-typo
2 |
--------------------------------------------------------------------------------
/dns/debian/patches/zscan-typo:
--------------------------------------------------------------------------------
1 | Description: Fix for typo in message in zscan_rr.
2 | Adress is spelled with an insufficient number of ds.
3 | Author: Tonnerre LOMBARD
4 | Forwarded: yes, https://github.com/miekg/dns/pull/54
5 | Last-Update: 2013-09-15
6 |
7 | --- golang-dns-0.0~git20130912.orig/zscan_rr.go
8 | +++ golang-dns-0.0~git20130912/zscan_rr.go
9 | @@ -1360,7 +1360,7 @@ func setWKS(h RR_Header, c chan lex, f s
10 | l := <-c
11 | rr.Address = net.ParseIP(l.token)
12 | if rr.Address == nil {
13 | - return nil, &ParseError{f, "bad WKS Adress", l}, ""
14 | + return nil, &ParseError{f, "bad WKS Address", l}, ""
15 | }
16 |
17 | <-c // _BLANK
18 |
--------------------------------------------------------------------------------
/dns/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 |
3 | # Uncomment this to turn on verbose mode.
4 | export DH_VERBOSE=1
5 |
6 | # DH_GOPKG is the upstream path which you would normally “go get”.
7 | # Using it allows us to build applications without patching locations.
8 | export DH_GOPKG := github.com/miekg/dns
9 |
10 | # Currently, tests can't win.
11 | override_dh_auto_test:
12 |
13 | %:
14 | dh $@ --buildsystem=golang --with=golang
15 |
16 | override_dh_auto_install:
17 | dh_auto_install -O--buildsystem=golang
18 | rm -rf ${CURDIR}/debian/golang-dns-dev/usr/bin
19 |
--------------------------------------------------------------------------------
/dns/debian/source/format:
--------------------------------------------------------------------------------
1 | 3.0 (quilt)
2 |
--------------------------------------------------------------------------------
/dns/dyn_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | // Find better solution
8 |
--------------------------------------------------------------------------------
/dns/ex/as112/as112.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 | // An AS112 blackhole DNS server. Similar to the one found in evldns.
6 | // Also see https://www.as112.net/
7 |
8 | package main
9 |
10 | import (
11 | "github.com/miekg/dns"
12 | "log"
13 | "os"
14 | "os/signal"
15 | "runtime"
16 | "syscall"
17 | )
18 |
19 | const SOA string = "@ SOA prisoner.iana.org. hostmaster.root-servers.org. 2002040800 1800 900 0604800 604800"
20 |
21 | func NewRR(s string) dns.RR { r, _ := dns.NewRR(s); return r }
22 |
23 | var zones = map[string]dns.RR{
24 | "10.in-addr.arpa.": NewRR("$ORIGIN 10.in-addr.arpa.\n" + SOA),
25 | "254.169.in-addr.arpa.": NewRR("$ORIGIN 254.169.in-addr.arpa.\n" + SOA),
26 | "168.192.in-addr.arpa.": NewRR("$ORIGIN 168.192.in-addr.arpa.\n" + SOA),
27 | "16.172.in-addr.arpa.": NewRR("$ORIGIN 16.172.in-addr.arpa.\n" + SOA),
28 | "17.172.in-addr.arpa.": NewRR("$ORIGIN 17.172.in-addr.arpa.\n" + SOA),
29 | "18.172.in-addr.arpa.": NewRR("$ORIGIN 18.172.in-addr.arpa.\n" + SOA),
30 | "19.172.in-addr.arpa.": NewRR("$ORIGIN 19.172.in-addr.arpa.\n" + SOA),
31 | "20.172.in-addr.arpa.": NewRR("$ORIGIN 20.172.in-addr.arpa.\n" + SOA),
32 | "21.172.in-addr.arpa.": NewRR("$ORIGIN 21.172.in-addr.arpa.\n" + SOA),
33 | "22.172.in-addr.arpa.": NewRR("$ORIGIN 22.172.in-addr.arpa.\n" + SOA),
34 | "23.172.in-addr.arpa.": NewRR("$ORIGIN 23.172.in-addr.arpa.\n" + SOA),
35 | "24.172.in-addr.arpa.": NewRR("$ORIGIN 24.172.in-addr.arpa.\n" + SOA),
36 | "25.172.in-addr.arpa.": NewRR("$ORIGIN 25.172.in-addr.arpa.\n" + SOA),
37 | "26.172.in-addr.arpa.": NewRR("$ORIGIN 26.172.in-addr.arpa.\n" + SOA),
38 | "27.172.in-addr.arpa.": NewRR("$ORIGIN 27.172.in-addr.arpa.\n" + SOA),
39 | "28.172.in-addr.arpa.": NewRR("$ORIGIN 28.172.in-addr.arpa.\n" + SOA),
40 | "29.172.in-addr.arpa.": NewRR("$ORIGIN 29.172.in-addr.arpa.\n" + SOA),
41 | "30.172.in-addr.arpa.": NewRR("$ORIGIN 30.172.in-addr.arpa.\n" + SOA),
42 | "31.172.in-addr.arpa.": NewRR("$ORIGIN 31.172.in-addr.arpa.\n" + SOA),
43 | }
44 |
45 | func main() {
46 | runtime.GOMAXPROCS(runtime.NumCPU() * 4)
47 | for z, rr := range zones {
48 | rrx := rr.(*dns.SOA) // Needed to create the actual RR, and not an reference.
49 | dns.HandleFunc(z, func(w dns.ResponseWriter, r *dns.Msg) {
50 | m := new(dns.Msg)
51 | m.SetReply(r)
52 | m.Authoritative = true
53 | m.Ns = []dns.RR{rrx}
54 | w.WriteMsg(m)
55 | })
56 | }
57 | go func() {
58 | err := dns.ListenAndServe(":8053", "tcp", nil)
59 | if err != nil {
60 | log.Fatal("Failed to set tcp listener %s\n", err.Error())
61 | }
62 | }()
63 | go func() {
64 | err := dns.ListenAndServe(":8053", "udp", nil)
65 | if err != nil {
66 | log.Fatal("Failed to set udp listener %s\n", err.Error())
67 | }
68 | }()
69 | sig := make(chan os.Signal)
70 | signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
71 | for {
72 | select {
73 | case s := <-sig:
74 | log.Fatalf("Signal (%d) received, stopping\n", s)
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/dns/ex/chaos/chaos.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 | // Chaos is a small program that prints the version.bind and hostname.bind
6 | // for each address of the nameserver given as argument.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | "github.com/miekg/dns"
12 | "net"
13 | "os"
14 | )
15 |
16 | func main() {
17 | if len(os.Args) != 2 {
18 | fmt.Printf("%s NAMESERVER\n", os.Args[0])
19 | os.Exit(1)
20 | }
21 | conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
22 |
23 | m := new(dns.Msg)
24 | m.Question = make([]dns.Question, 1)
25 | c := new(dns.Client)
26 |
27 | addr := addresses(conf, c, os.Args[1])
28 | if len(addr) == 0 {
29 | fmt.Printf("No address found for %s\n", os.Args[1])
30 | os.Exit(1)
31 | }
32 | for _, a := range addr {
33 | m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
34 | in, rtt, _ := c.Exchange(m, a)
35 | if in != nil && len(in.Answer) > 0 {
36 | fmt.Printf("(time %.3d µs) %v\n", rtt/1e3, in.Answer[0])
37 | }
38 | m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
39 | in, rtt, _ = c.Exchange(m, a)
40 | if in != nil && len(in.Answer) > 0 {
41 | fmt.Printf("(time %.3d µs) %v\n", rtt/1e3, in.Answer[0])
42 | }
43 | }
44 | }
45 |
46 | func do(t chan *dns.Msg, c *dns.Client, m *dns.Msg, addr string) {
47 | go func() {
48 | r, _, err := c.Exchange(m, addr)
49 | if err != nil {
50 | //print error stuff
51 | t <- nil
52 | }
53 | t <- r
54 | }()
55 | }
56 |
57 | func addresses(conf *dns.ClientConfig, c *dns.Client, name string) (ips []string) {
58 | m4 := new(dns.Msg)
59 | m4.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeA)
60 | m6 := new(dns.Msg)
61 | m6.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeAAAA)
62 | t := make(chan *dns.Msg)
63 | defer close(t)
64 | do(t, c, m4, net.JoinHostPort(conf.Servers[0], conf.Port))
65 | do(t, c, m6, net.JoinHostPort(conf.Servers[0], conf.Port))
66 |
67 | i := 2 // two outstanding queries
68 | forever:
69 | for {
70 | select {
71 | case d := <-t:
72 | i--
73 | if d == nil {
74 | continue
75 | }
76 | if i == 0 {
77 | break forever
78 | }
79 | if d.Rcode == dns.RcodeSuccess {
80 | for _, a := range d.Answer {
81 | switch a.(type) {
82 | case *dns.A:
83 | ips = append(ips,
84 | net.JoinHostPort(a.(*dns.A).A.String(), "53"))
85 | case *dns.AAAA:
86 | ips = append(ips,
87 | net.JoinHostPort(a.(*dns.AAAA).AAAA.String(), "53"))
88 |
89 | }
90 | }
91 | }
92 | }
93 | }
94 | return ips
95 | }
96 |
--------------------------------------------------------------------------------
/dns/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "fmt"
9 | )
10 |
11 | // Retrieve the MX records for miek.nl.
12 | func ExampleMX() {
13 | config, _ := ClientConfigFromFile("/etc/resolv.conf")
14 | c := new(Client)
15 | m := new(Msg)
16 | m.SetQuestion("miek.nl.", TypeMX)
17 | m.RecursionDesired = true
18 | r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
19 | if err != nil {
20 | return
21 | }
22 | if r.Rcode != RcodeSuccess {
23 | return
24 | }
25 | for _, a := range r.Answer {
26 | if mx, ok := a.(*MX); ok {
27 | fmt.Printf("%s\n", mx.String())
28 | }
29 | }
30 | }
31 |
32 | // Retrieve the DNSKEY records of a zone and convert them
33 | // to DS records for SHA1, SHA256 and SHA384.
34 | func ExampleDS(zone string) {
35 | config, _ := ClientConfigFromFile("/etc/resolv.conf")
36 | c := new(Client)
37 | m := new(Msg)
38 | if zone == "" {
39 | zone = "miek.nl"
40 | }
41 | m.SetQuestion(Fqdn(zone), TypeDNSKEY)
42 | m.SetEdns0(4096, true)
43 | r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
44 | if err != nil {
45 | return
46 | }
47 | if r.Rcode != RcodeSuccess {
48 | return
49 | }
50 | for _, k := range r.Answer {
51 | if key, ok := k.(*DNSKEY); ok {
52 | for _, alg := range []int{SHA1, SHA256, SHA384} {
53 | fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags)
54 | }
55 | }
56 | }
57 | }
58 |
59 | // Show how to setup the authors for 'authors.bind. CH TXT' or 'authors.server. CH TXT'
60 | // queries.
61 | func ExampleAuthors() {
62 | // ... server setup is out of scope ...
63 |
64 | // Register the handle funcs.
65 | HandleFunc("authors.bind.", HandleAuthors)
66 | HandleFunc("authors.server.", HandleAuthors)
67 |
68 | // To extend the authors list, just append to dns.Authors (a []string)
69 | Authors = append(Authors, "G. I. Joe")
70 |
71 | // Or ...
72 | Authors = []string{"Just Me"}
73 | }
74 |
--------------------------------------------------------------------------------
/dns/labels.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | // Holds a bunch of helper functions for dealing with labels.
8 |
9 | // SplitDomainName splits a name string into it's labels.
10 | // www.miek.nl. returns []string{"www", "miek", "nl"}
11 | // The root label (.) returns nil.
12 | func SplitDomainName(s string) (labels []string) {
13 | fqdnEnd := 0 // offset of the final '.' or the length of the name
14 | idx := Split(s)
15 | begin := 0
16 |
17 | if s[len(s)-1] == '.' {
18 | fqdnEnd = len(s) - 1
19 | } else {
20 | fqdnEnd = len(s)
21 | }
22 |
23 | switch len(idx) {
24 | case 0:
25 | return nil
26 | case 1:
27 | // no-op
28 | default:
29 | end := 0
30 | for i := 1; i < len(idx); i++ {
31 | end = idx[i]
32 | labels = append(labels, s[begin:end-1])
33 | begin = end
34 | }
35 | }
36 |
37 | labels = append(labels, s[begin:fqdnEnd])
38 | return labels
39 | }
40 |
41 | // CompareDomainName compares the names s1 and s2 and
42 | // returns how many labels they have in common starting from the *right*.
43 | // The comparison stops at the first inequality. The names are not downcased
44 | // before the comparison.
45 | //
46 | // www.miek.nl. and miek.nl. have two labels in common: miek and nl
47 | // www.miek.nl. and www.bla.nl. have one label in common: nl
48 | func CompareDomainName(s1, s2 string) (n int) {
49 | s1 = Fqdn(s1)
50 | s2 = Fqdn(s2)
51 | l1 := Split(s1)
52 | l2 := Split(s2)
53 |
54 | // the first check: root label
55 | if l1 == nil || l2 == nil {
56 | return
57 | }
58 |
59 | j1 := len(l1) - 1 // end
60 | i1 := len(l1) - 2 // start
61 | j2 := len(l2) - 1
62 | i2 := len(l2) - 2
63 | // the second check can be done here: last/only label
64 | // before we fall through into the for-loop below
65 | if s1[l1[j1]:] == s2[l2[j2]:] {
66 | n++
67 | } else {
68 | return
69 | }
70 | for {
71 | if i1 < 0 || i2 < 0 {
72 | break
73 | }
74 | if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
75 | n++
76 | } else {
77 | break
78 | }
79 | j1--
80 | i1--
81 | j2--
82 | i2--
83 | }
84 | return
85 | }
86 |
87 | // CountLabel counts the the number of labels in the string s.
88 | func CountLabel(s string) (labels int) {
89 | if s == "." {
90 | return
91 | }
92 | off := 0
93 | end := false
94 | for {
95 | off, end = NextLabel(s, off)
96 | labels++
97 | if end {
98 | return
99 | }
100 | }
101 | panic("dns: not reached")
102 | }
103 |
104 | // Split splits a name s into its label indexes.
105 | // www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
106 | // The root name (.) returns nil.
107 | func Split(s string) []int {
108 | if s == "." {
109 | return nil
110 | }
111 | idx := []int{0}
112 | off := 0
113 | end := false
114 |
115 | for {
116 | off, end = NextLabel(s, off)
117 | if end {
118 | return idx
119 | }
120 | idx = append(idx, off)
121 | }
122 | panic("dns: not reached")
123 | }
124 |
125 | // NextLabel returns the index of the start of the next label in the
126 | // string s starting at offset.
127 | // The bool end is true when the end of the string has been reached.
128 | func NextLabel(s string, offset int) (i int, end bool) {
129 | quote := false
130 | for i = offset; i < len(s)-1; i++ {
131 | switch s[i] {
132 | case '\\':
133 | quote = !quote
134 | default:
135 | quote = false
136 | case '.':
137 | if quote {
138 | quote = !quote
139 | continue
140 | }
141 | return i + 1, false
142 | }
143 | }
144 | return i + 1, true
145 | }
146 |
147 | // PrevLabel returns the index of the label when starting from the right and
148 | // jumping n labels to the left.
149 | // The bool start is true when the start of the string has been overshot.
150 | func PrevLabel(s string, n int) (i int, start bool) {
151 | if n == 0 {
152 | return len(s), false
153 | }
154 | lab := Split(s)
155 | if lab == nil {
156 | return 0, true
157 | }
158 | if n > len(lab) {
159 | return 0, true
160 | }
161 | return lab[len(lab)-n], false
162 | }
163 |
164 | func LenLabels(s string) int {
165 | println("LenLabels is to be removed in future versions, for the better named CountLabel")
166 | return CountLabel(s)
167 | }
168 | func SplitLabels(s string) []string {
169 | println("SplitLabels is to be removed in future versions, for the better named SplitDomainName")
170 | return SplitDomainName(s)
171 | }
172 |
173 | func CompareLabels(s1, s2 string) (n int) {
174 | println("CompareLabels is to be removed in future versions, for better named CompareDomainName")
175 | return CompareDomainName(s1, s2)
176 | }
177 |
--------------------------------------------------------------------------------
/dns/nsecx.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "crypto/sha1"
9 | "hash"
10 | "io"
11 | "strings"
12 | )
13 |
14 | type saltWireFmt struct {
15 | Salt string `dns:"size-hex"`
16 | }
17 |
18 | // HashName hashes a string (label) according to RFC 5155. It returns the hashed string.
19 | func HashName(label string, ha uint8, iter uint16, salt string) string {
20 | saltwire := new(saltWireFmt)
21 | saltwire.Salt = salt
22 | wire := make([]byte, DefaultMsgSize)
23 | n, err := PackStruct(saltwire, wire, 0)
24 | if err != nil {
25 | return ""
26 | }
27 | wire = wire[:n]
28 | name := make([]byte, 255)
29 | off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
30 | if err != nil {
31 | return ""
32 | }
33 | name = name[:off]
34 | var s hash.Hash
35 | switch ha {
36 | case SHA1:
37 | s = sha1.New()
38 | default:
39 | return ""
40 | }
41 |
42 | // k = 0
43 | name = append(name, wire...)
44 | io.WriteString(s, string(name))
45 | nsec3 := s.Sum(nil)
46 | // k > 0
47 | for k := uint16(0); k < iter; k++ {
48 | s.Reset()
49 | nsec3 = append(nsec3, wire...)
50 | io.WriteString(s, string(nsec3))
51 | nsec3 = s.Sum(nil)
52 | }
53 | return unpackBase32(nsec3)
54 | }
55 |
--------------------------------------------------------------------------------
/dns/nsecx_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "testing"
9 | )
10 |
11 | func TestPackNsec3(t *testing.T) {
12 | nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD")
13 | if nsec3 != "ROCCJAE8BJJU7HN6T7NG3TNM8ACRS87J" {
14 | t.Logf("%v\n", nsec3)
15 | t.Fail()
16 | }
17 |
18 | nsec3 = HashName("a.b.c.example.org.", SHA1, 2, "DEAD")
19 | if nsec3 != "6LQ07OAHBTOOEU2R9ANI2AT70K5O0RCG" {
20 | t.Logf("%v\n", nsec3)
21 | t.Fail()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dns/rawmsg.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | // These raw* functions do not use reflection, they directly set the values
8 | // in the buffer. There are faster than their reflection counterparts.
9 |
10 | // RawSetId sets the message id in buf.
11 | func rawSetId(msg []byte, i uint16) bool {
12 | if len(msg) < 2 {
13 | return false
14 | }
15 | msg[0], msg[1] = packUint16(i)
16 | return true
17 | }
18 |
19 | // rawSetQuestionLen sets the length of the question section.
20 | func rawSetQuestionLen(msg []byte, i uint16) bool {
21 | if len(msg) < 6 {
22 | return false
23 | }
24 | msg[4], msg[5] = packUint16(i)
25 | return true
26 | }
27 |
28 | // rawSetAnswerLen sets the lenght of the answer section.
29 | func rawSetAnswerLen(msg []byte, i uint16) bool {
30 | if len(msg) < 8 {
31 | return false
32 | }
33 | msg[6], msg[7] = packUint16(i)
34 | return true
35 | }
36 |
37 | // rawSetsNsLen sets the lenght of the authority section.
38 | func rawSetNsLen(msg []byte, i uint16) bool {
39 | if len(msg) < 10 {
40 | return false
41 | }
42 | msg[8], msg[9] = packUint16(i)
43 | return true
44 | }
45 |
46 | // rawSetExtraLen sets the lenght of the additional section.
47 | func rawSetExtraLen(msg []byte, i uint16) bool {
48 | if len(msg) < 12 {
49 | return false
50 | }
51 | msg[10], msg[11] = packUint16(i)
52 | return true
53 | }
54 |
55 | // rawSetRdlength sets the rdlength in the header of
56 | // the RR. The offset 'off' must be positioned at the
57 | // start of the header of the RR, 'end' must be the
58 | // end of the RR.
59 | func rawSetRdlength(msg []byte, off, end int) bool {
60 | l := len(msg)
61 | Loop:
62 | for {
63 | if off+1 > l {
64 | return false
65 | }
66 | c := int(msg[off])
67 | off++
68 | switch c & 0xC0 {
69 | case 0x00:
70 | if c == 0x00 {
71 | // End of the domainname
72 | break Loop
73 | }
74 | if off+c > l {
75 | return false
76 | }
77 | off += c
78 |
79 | case 0xC0:
80 | // pointer, next byte included, ends domainname
81 | off++
82 | break Loop
83 | }
84 | }
85 | // The domainname has been seen, we at the start of the fixed part in the header.
86 | // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
87 | off += 2 + 2 + 4
88 | if off+2 > l {
89 | return false
90 | }
91 | //off+1 is the end of the header, 'end' is the end of the rr
92 | //so 'end' - 'off+2' is the lenght of the rdata
93 | msg[off], msg[off+1] = packUint16(uint16(end - (off + 2)))
94 | return true
95 | }
96 |
--------------------------------------------------------------------------------
/dns/scanner.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | // Implement a simple scanner, return a byte stream from an io reader.
8 |
9 | import (
10 | "bufio"
11 | "io"
12 | "text/scanner"
13 | )
14 |
15 | type scan struct {
16 | src *bufio.Reader
17 | position scanner.Position
18 | eof bool // Have we just seen a eof
19 | }
20 |
21 | func scanInit(r io.Reader) *scan {
22 | s := new(scan)
23 | s.src = bufio.NewReader(r)
24 | s.position.Line = 1
25 | return s
26 | }
27 |
28 | // tokenText returns the next byte from the input
29 | func (s *scan) tokenText() (byte, error) {
30 | c, err := s.src.ReadByte()
31 | if err != nil {
32 | return c, err
33 | }
34 | // delay the newline handling until the next token is delivered,
35 | // fixes off-by-one errors when reporting a parse error.
36 | if s.eof == true {
37 | s.position.Line++
38 | s.position.Column = 0
39 | s.eof = false
40 | }
41 | if c == '\n' {
42 | s.eof = true
43 | return c, nil
44 | }
45 | s.position.Column++
46 | return c, nil
47 | }
48 |
--------------------------------------------------------------------------------
/dns/server_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "runtime"
9 | "testing"
10 | "time"
11 | )
12 |
13 | func HelloServer(w ResponseWriter, req *Msg) {
14 | m := new(Msg)
15 | m.SetReply(req)
16 |
17 | m.Extra = make([]RR, 1)
18 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
19 | w.WriteMsg(m)
20 | }
21 |
22 | func AnotherHelloServer(w ResponseWriter, req *Msg) {
23 | m := new(Msg)
24 | m.SetReply(req)
25 |
26 | m.Extra = make([]RR, 1)
27 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello example"}}
28 | w.WriteMsg(m)
29 | }
30 |
31 | func TestServing(t *testing.T) {
32 | HandleFunc("miek.nl.", HelloServer)
33 | HandleFunc("example.com.", AnotherHelloServer)
34 | go func() {
35 | err := ListenAndServe(":8053", "udp", nil)
36 | if err != nil {
37 | t.Log("ListenAndServe: ", err.Error())
38 | t.Fail()
39 | }
40 | }()
41 | time.Sleep(4e8)
42 | c := new(Client)
43 | m := new(Msg)
44 | m.SetQuestion("miek.nl.", TypeTXT)
45 | r, _, _ := c.Exchange(m, "127.0.0.1:8053")
46 | txt := r.Extra[0].(*TXT).Txt[0]
47 | if txt != "Hello world" {
48 | t.Log("Unexpected result for miek.nl", txt, "!= Hello world")
49 | t.Fail()
50 | }
51 | m.SetQuestion("example.com.", TypeTXT)
52 | r, _, _ = c.Exchange(m, "127.0.0.1:8053")
53 | txt = r.Extra[0].(*TXT).Txt[0]
54 | if txt != "Hello example" {
55 | t.Log("Unexpected result for example.com", txt, "!= Hello example")
56 | t.Fail()
57 | }
58 | // Test Mixes cased as notices by Ask.
59 | m.SetQuestion("eXaMplE.cOm.", TypeTXT)
60 | r, _, _ = c.Exchange(m, "127.0.0.1:8053")
61 | txt = r.Extra[0].(*TXT).Txt[0]
62 | if txt != "Hello example" {
63 | t.Log("Unexpected result for example.com", txt, "!= Hello example")
64 | t.Fail()
65 | }
66 | }
67 |
68 | func BenchmarkServing(b *testing.B) {
69 | b.StopTimer()
70 | HandleFunc("miek.nl.", HelloServer)
71 | a := runtime.GOMAXPROCS(4)
72 | go func() {
73 | ListenAndServe("127.0.0.1:8053", "udp", nil)
74 | }()
75 | c := new(Client)
76 | m := new(Msg)
77 | m.SetQuestion("miek.nl", TypeSOA)
78 |
79 | b.StartTimer()
80 | for i := 0; i < b.N; i++ {
81 | c.Exchange(m, "127.0.0.1:8053")
82 | }
83 | runtime.GOMAXPROCS(a)
84 | }
85 |
86 | func HelloServerCompress(w ResponseWriter, req *Msg) {
87 | m := new(Msg)
88 | m.SetReply(req)
89 | m.Extra = make([]RR, 1)
90 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
91 | m.Compress = true
92 | w.WriteMsg(m)
93 | }
94 |
95 | func BenchmarkServingCompress(b *testing.B) {
96 | b.StopTimer()
97 | HandleFunc("miek.nl.", HelloServerCompress)
98 | a := runtime.GOMAXPROCS(4)
99 | go func() {
100 | ListenAndServe("127.0.0.1:8053", "udp", nil)
101 | }()
102 |
103 | c := new(Client)
104 | m := new(Msg)
105 | m.SetQuestion("miek.nl", TypeSOA)
106 | b.StartTimer()
107 | for i := 0; i < b.N; i++ {
108 | c.Exchange(m, "127.0.0.1:8053")
109 | }
110 | runtime.GOMAXPROCS(a)
111 | }
112 |
113 | func TestDotAsCatchAllWildcard(t *testing.T) {
114 | mux := NewServeMux()
115 | mux.Handle(".", HandlerFunc(HelloServer))
116 | mux.Handle("example.com.", HandlerFunc(AnotherHelloServer))
117 |
118 | handler := mux.match("www.miek.nl.", TypeTXT)
119 | if handler == nil {
120 | t.Error("wildcard match failed")
121 | }
122 |
123 | handler = mux.match("www.example.com.", TypeTXT)
124 | if handler == nil {
125 | t.Error("example.com match failed")
126 | }
127 |
128 | handler = mux.match("a.www.example.com.", TypeTXT)
129 | if handler == nil {
130 | t.Error("a.www.example.com match failed")
131 | }
132 |
133 | handler = mux.match("boe.", TypeTXT)
134 | if handler == nil {
135 | t.Error("boe. match failed")
136 | }
137 | }
138 |
139 | func TestRootServer(t *testing.T) {
140 | mux := NewServeMux()
141 | mux.Handle(".", HandlerFunc(HelloServer))
142 |
143 | handler := mux.match(".", TypeNS)
144 | if handler == nil {
145 | t.Error("root match failed")
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/dns/singleinflight.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // Adapted for dns package usage by Miek Gieben.
6 |
7 | package dns
8 |
9 | import "sync"
10 | import "time"
11 |
12 | // call is an in-flight or completed singleflight.Do call
13 | type call struct {
14 | wg sync.WaitGroup
15 | val *Msg
16 | rtt time.Duration
17 | err error
18 | dups int
19 | }
20 |
21 | // singleflight represents a class of work and forms a namespace in
22 | // which units of work can be executed with duplicate suppression.
23 | type singleflight struct {
24 | sync.Mutex // protects m
25 | m map[string]*call // lazily initialized
26 | }
27 |
28 | // Do executes and returns the results of the given function, making
29 | // sure that only one execution is in-flight for a given key at a
30 | // time. If a duplicate comes in, the duplicate caller waits for the
31 | // original to complete and receives the same results.
32 | // The return value shared indicates whether v was given to multiple callers.
33 | func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) {
34 | g.Lock()
35 | if g.m == nil {
36 | g.m = make(map[string]*call)
37 | }
38 | if c, ok := g.m[key]; ok {
39 | c.dups++
40 | g.Unlock()
41 | c.wg.Wait()
42 | return c.val, c.rtt, c.err, true
43 | }
44 | c := new(call)
45 | c.wg.Add(1)
46 | g.m[key] = c
47 | g.Unlock()
48 |
49 | c.val, c.rtt, c.err = fn()
50 | c.wg.Done()
51 |
52 | g.Lock()
53 | delete(g.m, key)
54 | g.Unlock()
55 |
56 | return c.val, c.rtt, c.err, c.dups > 0
57 | }
58 |
--------------------------------------------------------------------------------
/dns/tlsa.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "crypto/sha256"
9 | "crypto/sha512"
10 | "crypto/x509"
11 | "encoding/hex"
12 | "errors"
13 | "io"
14 | "net"
15 | "strconv"
16 | )
17 |
18 | // CertificateToDANE converts a certificate to a hex string as used in the TLSA record.
19 | func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
20 | switch matchingType {
21 | case 0:
22 | switch selector {
23 | case 0:
24 | return hex.EncodeToString(cert.Raw), nil
25 | case 1:
26 | return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
27 | }
28 | case 1:
29 | h := sha256.New()
30 | switch selector {
31 | case 0:
32 | return hex.EncodeToString(cert.Raw), nil
33 | case 1:
34 | io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
35 | return hex.EncodeToString(h.Sum(nil)), nil
36 | }
37 | case 2:
38 | h := sha512.New()
39 | switch selector {
40 | case 0:
41 | return hex.EncodeToString(cert.Raw), nil
42 | case 1:
43 | io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
44 | return hex.EncodeToString(h.Sum(nil)), nil
45 | }
46 | }
47 | return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector")
48 | }
49 |
50 | // Sign creates a TLSA record from an SSL certificate.
51 | func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
52 | r.Hdr.Rrtype = TypeTLSA
53 | r.Usage = uint8(usage)
54 | r.Selector = uint8(selector)
55 | r.MatchingType = uint8(matchingType)
56 |
57 | r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
58 | if err != nil {
59 | return err
60 | }
61 | return nil
62 | }
63 |
64 | // Verify verifies a TLSA record against an SSL certificate. If it is OK
65 | // a nil error is returned.
66 | func (r *TLSA) Verify(cert *x509.Certificate) error {
67 | c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
68 | if err != nil {
69 | return err // Not also ErrSig?
70 | }
71 | if r.Certificate == c {
72 | return nil
73 | }
74 | return ErrSig // ErrSig, really?
75 | }
76 |
77 | // TLSAName returns the ownername of a TLSA resource record as per the
78 | // rules specified in RFC 6698, Section 3.
79 | func TLSAName(name, service, network string) (string, error) {
80 | if !IsFqdn(name) {
81 | return "", ErrFqdn
82 | }
83 | p, e := net.LookupPort(network, service)
84 | if e != nil {
85 | return "", e
86 | }
87 | return "_" + strconv.Itoa(p) + "_" + network + "." + name, nil
88 | }
89 |
--------------------------------------------------------------------------------
/dns/zgenerate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Miek Gieben. 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 dns
6 |
7 | import (
8 | "fmt"
9 | "strconv"
10 | "strings"
11 | )
12 |
13 | // Parse the $GENERATE statement as used in BIND9 zones.
14 | // See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
15 | // We are called after '$GENERATE '. After which we expect:
16 | // * the range (12-24/2)
17 | // * lhs (ownername)
18 | // * [[ttl][class]]
19 | // * type
20 | // * rhs (rdata)
21 | // But we are lazy here, only the range is parsed *all* occurences
22 | // of $ after that are interpreted.
23 | // Any error are returned as a string value, the empty string signals
24 | // "no error".
25 | func generate(l lex, c chan lex, t chan Token, o string) string {
26 | step := 1
27 | if i := strings.IndexAny(l.token, "/"); i != -1 {
28 | if i+1 == len(l.token) {
29 | return "bad step in $GENERATE range"
30 | }
31 | if s, e := strconv.Atoi(l.token[i+1:]); e != nil {
32 | return "bad step in $GENERATE range"
33 | } else {
34 | if s < 0 {
35 | return "bad step in $GENERATE range"
36 | }
37 | step = s
38 | }
39 | l.token = l.token[:i]
40 | }
41 | sx := strings.SplitN(l.token, "-", 2)
42 | if len(sx) != 2 {
43 | return "bad start-stop in $GENERATE range"
44 | }
45 | start, err := strconv.Atoi(sx[0])
46 | if err != nil {
47 | return "bad start in $GENERATE range"
48 | }
49 | end, err := strconv.Atoi(sx[1])
50 | if err != nil {
51 | return "bad stop in $GENERATE range"
52 | }
53 | if end < 0 || start < 0 || end <= start {
54 | return "bad range in $GENERATE range"
55 | }
56 |
57 | <-c // _BLANK
58 | // Create a complete new string, which we then parse again.
59 | s := ""
60 | BuildRR:
61 | l = <-c
62 | if l.value != _NEWLINE && l.value != _EOF {
63 | s += l.token
64 | goto BuildRR
65 | }
66 | for i := start; i <= end; i += step {
67 | var (
68 | escape bool
69 | dom string
70 | mod string
71 | err string
72 | offset int
73 | )
74 |
75 | for j := 0; j < len(s); j++ { // No 'range' because we need to jump around
76 | switch s[j] {
77 | case '\\':
78 | if escape {
79 | dom += "\\"
80 | escape = false
81 | continue
82 | }
83 | escape = true
84 | case '$':
85 | mod = "%d"
86 | offset = 0
87 | if escape {
88 | dom += "$"
89 | escape = false
90 | continue
91 | }
92 | escape = false
93 | if j+1 >= len(s) { // End of the string
94 | dom += fmt.Sprintf(mod, i+offset)
95 | continue
96 | } else {
97 | if s[j+1] == '$' {
98 | dom += "$"
99 | j++
100 | continue
101 | }
102 | }
103 | // Search for { and }
104 | if s[j+1] == '{' { // Modifier block
105 | sep := strings.Index(s[j+2:], "}")
106 | if sep == -1 {
107 | return "bad modifier in $GENERATE"
108 | }
109 | mod, offset, err = modToPrintf(s[j+2 : j+2+sep])
110 | if err != "" {
111 | return err
112 | }
113 | j += 2 + sep // Jump to it
114 | }
115 | dom += fmt.Sprintf(mod, i+offset)
116 | default:
117 | if escape { // Pretty useless here
118 | escape = false
119 | continue
120 | }
121 | dom += string(s[j])
122 | }
123 | }
124 | // Re-parse the RR and send it on the current channel t
125 | rx, e := NewRR("$ORIGIN " + o + "\n" + dom)
126 | if e != nil {
127 | return e.(*ParseError).err
128 | }
129 | t <- Token{RR: rx}
130 | // Its more efficient to first built the rrlist and then parse it in
131 | // one go! But is this a problem?
132 | }
133 | return ""
134 | }
135 |
136 | // Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
137 | func modToPrintf(s string) (string, int, string) {
138 | xs := strings.SplitN(s, ",", 3)
139 | if len(xs) != 3 {
140 | return "", 0, "bad modifier in $GENERATE"
141 | }
142 | // xs[0] is offset, xs[1] is width, xs[2] is base
143 | if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
144 | return "", 0, "bad base in $GENERATE"
145 | }
146 | offset, err := strconv.Atoi(xs[0])
147 | if err != nil {
148 | return "", 0, "bad offset in $GENERATE"
149 | }
150 | width, err := strconv.Atoi(xs[1])
151 | if err != nil {
152 | return "", offset, "bad width in $GENERATE"
153 | }
154 | switch {
155 | case width < 0:
156 | return "", offset, "bad width in $GENERATE"
157 | case width == 0:
158 | return "%" + xs[1] + xs[2], offset, ""
159 | default:
160 | return "%0" + xs[1] + xs[2], offset, ""
161 | }
162 | panic("dns: not reached")
163 | }
164 |
--------------------------------------------------------------------------------
/dns_server_mx.json:
--------------------------------------------------------------------------------
1 | {
2 | "Id": 5102,
3 | "Response": true,
4 | "Opcode": 0,
5 | "Authoritative": false,
6 | "Truncated": false,
7 | "RecursionDesired": true,
8 | "RecursionAvailable": true,
9 | "Zero": false,
10 | "AuthenticatedData": false,
11 | "CheckingDisabled": false,
12 | "Rcode": 0,
13 | "Question": [
14 | {
15 | "Name": "baidu.com.",
16 | "Qtype": 15,
17 | "Qclass": 1
18 | }
19 | ],
20 | "Answer": [
21 | {
22 | "Hdr": {
23 | "Name": "baidu.com.",
24 | "Rrtype": 15,
25 | "Class": 1,
26 | "Ttl": 5019,
27 | "Rdlength": 8
28 | },
29 | "Preference": 20,
30 | "Mx": "mx1.baidu.com."
31 | },
32 | {
33 | "Hdr": {
34 | "Name": "baidu.com.",
35 | "Rrtype": 15,
36 | "Class": 1,
37 | "Ttl": 5019,
38 | "Rdlength": 9
39 | },
40 | "Preference": 20,
41 | "Mx": "jpmx.baidu.com."
42 | },
43 | {
44 | "Hdr": {
45 | "Name": "baidu.com.",
46 | "Rrtype": 15,
47 | "Class": 1,
48 | "Ttl": 5019,
49 | "Rdlength": 16
50 | },
51 | "Preference": 15,
52 | "Mx": "mx.n.shifen.com."
53 | },
54 | {
55 | "Hdr": {
56 | "Name": "baidu.com.",
57 | "Rrtype": 15,
58 | "Class": 1,
59 | "Ttl": 5019,
60 | "Rdlength": 14
61 | },
62 | "Preference": 10,
63 | "Mx": "mx.maillb.baidu.com."
64 | },
65 | {
66 | "Hdr": {
67 | "Name": "baidu.com.",
68 | "Rrtype": 15,
69 | "Class": 1,
70 | "Ttl": 5019,
71 | "Rdlength": 9
72 | },
73 | "Preference": 20,
74 | "Mx": "mx50.baidu.com."
75 | }
76 | ],
77 | "Ns": [],
78 | "Extra": []
79 | }
--------------------------------------------------------------------------------
/dns_server_text.json:
--------------------------------------------------------------------------------
1 | {
2 | "Id": 50334,
3 | "Response": true,
4 | "Opcode": 0,
5 | "Authoritative": false,
6 | "Truncated": false,
7 | "RecursionDesired": true,
8 | "RecursionAvailable": false,
9 | "Zero": false,
10 | "AuthenticatedData": false,
11 | "CheckingDisabled": false,
12 | "Rcode": 0,
13 | "Question": [
14 | {
15 | "Name": "baidu.com.",
16 | "Qtype": 16,
17 | "Qclass": 1
18 | }
19 | ],
20 | "Answer": [],
21 | "Ns": [],
22 | "Extra": [
23 | {
24 | "Hdr": {
25 | "Name": "baidu.com.",
26 | "Rrtype": 16,
27 | "Class": 1,
28 | "Ttl": 0,
29 | "Rdlength": 12
30 | },
31 | "Txt": [
32 | "Hello world"
33 | ]
34 | }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/dnstunnel_client.linux64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_client.linux64
--------------------------------------------------------------------------------
/dnstunnel_client.win64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_client.win64
--------------------------------------------------------------------------------
/dnstunnel_server.linux64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_server.linux64
--------------------------------------------------------------------------------
/dnstunnel_server.win64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_server.win64
--------------------------------------------------------------------------------
/generator/generator.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/generator/generator.bak
--------------------------------------------------------------------------------
/generator/generator.e:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/generator/generator.e
--------------------------------------------------------------------------------
/http_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "io/ioutil"
6 | "net/http"
7 | "strings"
8 | "testing"
9 | )
10 |
11 | func TestHttpOff(t *testing.T) {
12 | fmt.Println(strings.Trim(" abc ", " "))
13 | resp, err := http.Post("http://127.0.0.1:8081/off",
14 | "text/plain",
15 | strings.NewReader("1111111111111111"))
16 | if err != nil {
17 | fmt.Println(err)
18 | return
19 | }
20 |
21 | defer resp.Body.Close()
22 | body, err := ioutil.ReadAll(resp.Body)
23 | if err != nil {
24 | fmt.Println(err)
25 | return
26 | }
27 |
28 | fmt.Println(string(body))
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009 The Go Authors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/cases/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 cases_test
6 |
7 | import (
8 | "fmt"
9 |
10 | "golang.org/x/text/cases"
11 | "golang.org/x/text/language"
12 | )
13 |
14 | func Example() {
15 | src := []string{
16 | "hello world!",
17 | "i with dot",
18 | "'n ijsberg",
19 | "here comes O'Brian",
20 | }
21 | for _, c := range []cases.Caser{
22 | cases.Lower(language.Und),
23 | cases.Upper(language.Turkish),
24 | cases.Title(language.Dutch),
25 | cases.Title(language.Und, cases.NoLower),
26 | } {
27 | fmt.Println()
28 | for _, s := range src {
29 | fmt.Println(c.String(s))
30 | }
31 | }
32 |
33 | // Output:
34 | // hello world!
35 | // i with dot
36 | // 'n ijsberg
37 | // here comes o'brian
38 | //
39 | // HELLO WORLD!
40 | // İ WİTH DOT
41 | // 'N İJSBERG
42 | // HERE COMES O'BRİAN
43 | //
44 | // Hello World!
45 | // I With Dot
46 | // 'n IJsberg
47 | // Here Comes O'brian
48 | //
49 | // Hello World!
50 | // I With Dot
51 | // 'N Ijsberg
52 | // Here Comes O'Brian
53 | }
54 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/cases/fold.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 cases
6 |
7 | import "golang.org/x/text/transform"
8 |
9 | type caseFolder struct{ transform.NopResetter }
10 |
11 | // caseFolder implements the Transformer interface for doing case folding.
12 | func (t *caseFolder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
13 | c := context{dst: dst, src: src, atEOF: atEOF}
14 | for c.next() {
15 | foldFull(&c)
16 | c.checkpoint()
17 | }
18 | return c.ret()
19 | }
20 |
21 | func (t *caseFolder) Span(src []byte, atEOF bool) (n int, err error) {
22 | c := context{src: src, atEOF: atEOF}
23 | for c.next() && isFoldFull(&c) {
24 | c.checkpoint()
25 | }
26 | return c.retSpan()
27 | }
28 |
29 | func makeFold(o options) transform.SpanningTransformer {
30 | // TODO: Special case folding, through option Language, Special/Turkic, or
31 | // both.
32 | // TODO: Implement Compact options.
33 | return &caseFolder{}
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/cases/fold_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 cases
6 |
7 | import (
8 | "testing"
9 |
10 | "golang.org/x/text/internal/testtext"
11 | )
12 |
13 | var foldTestCases = []string{
14 | "βß\u13f8", // "βssᏰ"
15 | "ab\u13fc\uab7aꭰ", // abᏴᎪᎠ
16 | "affifflast", // affifflast
17 | "Iİiı\u0345", // ii̇iıι
18 | "µµΜΜςσΣΣ", // μμμμσσσσ
19 | }
20 |
21 | func TestFold(t *testing.T) {
22 | for _, tc := range foldTestCases {
23 | testEntry := func(name string, c Caser, m func(r rune) string) {
24 | want := ""
25 | for _, r := range tc {
26 | want += m(r)
27 | }
28 | if got := c.String(tc); got != want {
29 | t.Errorf("%s(%s) = %+q; want %+q", name, tc, got, want)
30 | }
31 | dst := make([]byte, 256) // big enough to hold any result
32 | src := []byte(tc)
33 | v := testtext.AllocsPerRun(20, func() {
34 | c.Transform(dst, src, true)
35 | })
36 | if v > 0 {
37 | t.Errorf("%s(%s): number of allocs was %f; want 0", name, tc, v)
38 | }
39 | }
40 | testEntry("FullFold", Fold(), func(r rune) string {
41 | return runeFoldData(r).full
42 | })
43 | // TODO:
44 | // testEntry("SimpleFold", Fold(Compact), func(r rune) string {
45 | // return runeFoldData(r).simple
46 | // })
47 | // testEntry("SpecialFold", Fold(Turkic), func(r rune) string {
48 | // return runeFoldData(r).special
49 | // })
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/cases/icu.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 | // +build icu
6 |
7 | package cases
8 |
9 | // Ideally these functions would be defined in a test file, but go test doesn't
10 | // allow CGO in tests. The build tag should ensure either way that these
11 | // functions will not end up in the package.
12 |
13 | // TODO: Ensure that the correct ICU version is set.
14 |
15 | /*
16 | #cgo LDFLAGS: -licui18n.57 -licuuc.57
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | */
23 | import "C"
24 |
25 | import "unsafe"
26 |
27 | func doICU(tag, caser, input string) string {
28 | err := C.UErrorCode(0)
29 | loc := C.CString(tag)
30 | cm := C.ucasemap_open(loc, C.uint32_t(0), &err)
31 |
32 | buf := make([]byte, len(input)*4)
33 | dst := (*C.char)(unsafe.Pointer(&buf[0]))
34 | src := C.CString(input)
35 |
36 | cn := C.int32_t(0)
37 |
38 | switch caser {
39 | case "fold":
40 | cn = C.ucasemap_utf8FoldCase(cm,
41 | dst, C.int32_t(len(buf)),
42 | src, C.int32_t(len(input)),
43 | &err)
44 | case "lower":
45 | cn = C.ucasemap_utf8ToLower(cm,
46 | dst, C.int32_t(len(buf)),
47 | src, C.int32_t(len(input)),
48 | &err)
49 | case "upper":
50 | cn = C.ucasemap_utf8ToUpper(cm,
51 | dst, C.int32_t(len(buf)),
52 | src, C.int32_t(len(input)),
53 | &err)
54 | case "title":
55 | cn = C.ucasemap_utf8ToTitle(cm,
56 | dst, C.int32_t(len(buf)),
57 | src, C.int32_t(len(input)),
58 | &err)
59 | }
60 | return string(buf[:cn])
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/cases/info.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 cases
6 |
7 | func (c info) cccVal() info {
8 | if c&exceptionBit != 0 {
9 | return info(exceptions[c>>exceptionShift]) & cccMask
10 | }
11 | return c & cccMask
12 | }
13 |
14 | func (c info) cccType() info {
15 | ccc := c.cccVal()
16 | if ccc <= cccZero {
17 | return cccZero
18 | }
19 | return ccc
20 | }
21 |
22 | // TODO: Implement full Unicode breaking algorithm:
23 | // 1) Implement breaking in separate package.
24 | // 2) Use the breaker here.
25 | // 3) Compare table size and performance of using the more generic breaker.
26 | //
27 | // Note that we can extend the current algorithm to be much more accurate. This
28 | // only makes sense, though, if the performance and/or space penalty of using
29 | // the generic breaker is big. Extra data will only be needed for non-cased
30 | // runes, which means there are sufficient bits left in the caseType.
31 | // ICU prohibits breaking in such cases as well.
32 |
33 | // For the purpose of title casing we use an approximation of the Unicode Word
34 | // Breaking algorithm defined in Annex #29:
35 | // https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table.
36 | //
37 | // For our approximation, we group the Word Break types into the following
38 | // categories, with associated rules:
39 | //
40 | // 1) Letter:
41 | // ALetter, Hebrew_Letter, Numeric, ExtendNumLet, Extend, Format_FE, ZWJ.
42 | // Rule: Never break between consecutive runes of this category.
43 | //
44 | // 2) Mid:
45 | // MidLetter, MidNumLet, Single_Quote.
46 | // (Cf. case-ignorable: MidLetter, MidNumLet, Single_Quote or cat is Mn,
47 | // Me, Cf, Lm or Sk).
48 | // Rule: Don't break between Letter and Mid, but break between two Mids.
49 | //
50 | // 3) Break:
51 | // Any other category: NewLine, MidNum, CR, LF, Double_Quote, Katakana, and
52 | // Other.
53 | // These categories should always result in a break between two cased letters.
54 | // Rule: Always break.
55 | //
56 | // Note 1: the Katakana and MidNum categories can, in esoteric cases, result in
57 | // preventing a break between two cased letters. For now we will ignore this
58 | // (e.g. [ALetter] [ExtendNumLet] [Katakana] [ExtendNumLet] [ALetter] and
59 | // [ALetter] [Numeric] [MidNum] [Numeric] [ALetter].)
60 | //
61 | // Note 2: the rule for Mid is very approximate, but works in most cases. To
62 | // improve, we could store the categories in the trie value and use a FA to
63 | // manage breaks. See TODO comment above.
64 | //
65 | // Note 3: according to the spec, it is possible for the Extend category to
66 | // introduce breaks between other categories grouped in Letter. However, this
67 | // is undesirable for our purposes. ICU prevents breaks in such cases as well.
68 |
69 | // isBreak returns whether this rune should introduce a break.
70 | func (c info) isBreak() bool {
71 | return c.cccVal() == cccBreak
72 | }
73 |
74 | // isLetter returns whether the rune is of break type ALetter, Hebrew_Letter,
75 | // Numeric, ExtendNumLet, or Extend.
76 | func (c info) isLetter() bool {
77 | ccc := c.cccVal()
78 | if ccc == cccZero {
79 | return !c.isCaseIgnorable()
80 | }
81 | return ccc != cccBreak
82 | }
83 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 encoding_test
6 |
7 | import (
8 | "fmt"
9 | "io"
10 | "os"
11 | "strings"
12 |
13 | "golang.org/x/text/encoding"
14 | "golang.org/x/text/encoding/charmap"
15 | "golang.org/x/text/encoding/unicode"
16 | "golang.org/x/text/transform"
17 | )
18 |
19 | func ExampleDecodeWindows1252() {
20 | sr := strings.NewReader("Gar\xe7on !")
21 | tr := charmap.Windows1252.NewDecoder().Reader(sr)
22 | io.Copy(os.Stdout, tr)
23 | // Output: Garçon !
24 | }
25 |
26 | func ExampleUTF8Validator() {
27 | for i := 0; i < 2; i++ {
28 | var transformer transform.Transformer
29 | transformer = unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM).NewEncoder()
30 | if i == 1 {
31 | transformer = transform.Chain(encoding.UTF8Validator, transformer)
32 | }
33 | dst := make([]byte, 256)
34 | src := []byte("abc\xffxyz") // src is invalid UTF-8.
35 | nDst, nSrc, err := transformer.Transform(dst, src, true)
36 | fmt.Printf("i=%d: produced %q, consumed %q, error %v\n",
37 | i, dst[:nDst], src[:nSrc], err)
38 | }
39 | // Output:
40 | // i=0: produced "\x00a\x00b\x00c\xff\xfd\x00x\x00y\x00z", consumed "abc\xffxyz", error
41 | // i=1: produced "\x00a\x00b\x00c", consumed "abc", error encoding: invalid UTF-8
42 | }
43 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/internal/identifier/gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | package identifier
8 |
9 | import (
10 | "bytes"
11 | "encoding/xml"
12 | "fmt"
13 | "io"
14 | "log"
15 | "strings"
16 |
17 | "golang.org/x/text/internal/gen"
18 | )
19 |
20 | type registry struct {
21 | XMLName xml.Name `xml:"registry"`
22 | Updated string `xml:"updated"`
23 | Registry []struct {
24 | ID string `xml:"id,attr"`
25 | Record []struct {
26 | Name string `xml:"name"`
27 | Xref []struct {
28 | Type string `xml:"type,attr"`
29 | Data string `xml:"data,attr"`
30 | } `xml:"xref"`
31 | Desc struct {
32 | Data string `xml:",innerxml"`
33 | // Any []struct {
34 | // Data string `xml:",chardata"`
35 | // } `xml:",any"`
36 | // Data string `xml:",chardata"`
37 | } `xml:"description,"`
38 | MIB string `xml:"value"`
39 | Alias []string `xml:"alias"`
40 | MIME string `xml:"preferred_alias"`
41 | } `xml:"record"`
42 | } `xml:"registry"`
43 | }
44 |
45 | func main() {
46 | r := gen.OpenIANAFile("assignments/character-sets/character-sets.xml")
47 | reg := ®istry{}
48 | if err := xml.NewDecoder(r).Decode(®); err != nil && err != io.EOF {
49 | log.Fatalf("Error decoding charset registry: %v", err)
50 | }
51 | if len(reg.Registry) == 0 || reg.Registry[0].ID != "character-sets-1" {
52 | log.Fatalf("Unexpected ID %s", reg.Registry[0].ID)
53 | }
54 |
55 | w := &bytes.Buffer{}
56 | fmt.Fprintf(w, "const (\n")
57 | for _, rec := range reg.Registry[0].Record {
58 | constName := ""
59 | for _, a := range rec.Alias {
60 | if strings.HasPrefix(a, "cs") && strings.IndexByte(a, '-') == -1 {
61 | // Some of the constant definitions have comments in them. Strip those.
62 | constName = strings.Title(strings.SplitN(a[2:], "\n", 2)[0])
63 | }
64 | }
65 | if constName == "" {
66 | switch rec.MIB {
67 | case "2085":
68 | constName = "HZGB2312" // Not listed as alias for some reason.
69 | default:
70 | log.Fatalf("No cs alias defined for %s.", rec.MIB)
71 | }
72 | }
73 | if rec.MIME != "" {
74 | rec.MIME = fmt.Sprintf(" (MIME: %s)", rec.MIME)
75 | }
76 | fmt.Fprintf(w, "// %s is the MIB identifier with IANA name %s%s.\n//\n", constName, rec.Name, rec.MIME)
77 | if len(rec.Desc.Data) > 0 {
78 | fmt.Fprint(w, "// ")
79 | d := xml.NewDecoder(strings.NewReader(rec.Desc.Data))
80 | inElem := true
81 | attr := ""
82 | for {
83 | t, err := d.Token()
84 | if err != nil {
85 | if err != io.EOF {
86 | log.Fatal(err)
87 | }
88 | break
89 | }
90 | switch x := t.(type) {
91 | case xml.CharData:
92 | attr = "" // Don't need attribute info.
93 | a := bytes.Split([]byte(x), []byte("\n"))
94 | for i, b := range a {
95 | if b = bytes.TrimSpace(b); len(b) != 0 {
96 | if !inElem && i > 0 {
97 | fmt.Fprint(w, "\n// ")
98 | }
99 | inElem = false
100 | fmt.Fprintf(w, "%s ", string(b))
101 | }
102 | }
103 | case xml.StartElement:
104 | if x.Name.Local == "xref" {
105 | inElem = true
106 | use := false
107 | for _, a := range x.Attr {
108 | if a.Name.Local == "type" {
109 | use = use || a.Value != "person"
110 | }
111 | if a.Name.Local == "data" && use {
112 | attr = a.Value + " "
113 | }
114 | }
115 | }
116 | case xml.EndElement:
117 | inElem = false
118 | fmt.Fprint(w, attr)
119 | }
120 | }
121 | fmt.Fprint(w, "\n")
122 | }
123 | for _, x := range rec.Xref {
124 | switch x.Type {
125 | case "rfc":
126 | fmt.Fprintf(w, "// Reference: %s\n", strings.ToUpper(x.Data))
127 | case "uri":
128 | fmt.Fprintf(w, "// Reference: %s\n", x.Data)
129 | }
130 | }
131 | fmt.Fprintf(w, "%s MIB = %s\n", constName, rec.MIB)
132 | fmt.Fprintln(w)
133 | }
134 | fmt.Fprintln(w, ")")
135 |
136 | gen.WriteGoFile("mib.go", "identifier", w.Bytes())
137 | }
138 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | //go:generate go run gen.go
6 |
7 | // Package identifier defines the contract between implementations of Encoding
8 | // and Index by defining identifiers that uniquely identify standardized coded
9 | // character sets (CCS) and character encoding schemes (CES), which we will
10 | // together refer to as encodings, for which Encoding implementations provide
11 | // converters to and from UTF-8. This package is typically only of concern to
12 | // implementers of Indexes and Encodings.
13 | //
14 | // One part of the identifier is the MIB code, which is defined by IANA and
15 | // uniquely identifies a CCS or CES. Each code is associated with data that
16 | // references authorities, official documentation as well as aliases and MIME
17 | // names.
18 | //
19 | // Not all CESs are covered by the IANA registry. The "other" string that is
20 | // returned by ID can be used to identify other character sets or versions of
21 | // existing ones.
22 | //
23 | // It is recommended that each package that provides a set of Encodings provide
24 | // the All and Common variables to reference all supported encodings and
25 | // commonly used subset. This allows Index implementations to include all
26 | // available encodings without explicitly referencing or knowing about them.
27 | package identifier
28 |
29 | // Note: this package is internal, but could be made public if there is a need
30 | // for writing third-party Indexes and Encodings.
31 |
32 | // References:
33 | // - http://source.icu-project.org/repos/icu/icu/trunk/source/data/mappings/convrtrs.txt
34 | // - http://www.iana.org/assignments/character-sets/character-sets.xhtml
35 | // - http://www.iana.org/assignments/ianacharset-mib/ianacharset-mib
36 | // - http://www.ietf.org/rfc/rfc2978.txt
37 | // - https://www.unicode.org/reports/tr22/
38 | // - http://www.w3.org/TR/encoding/
39 | // - https://encoding.spec.whatwg.org/
40 | // - https://encoding.spec.whatwg.org/encodings.json
41 | // - https://tools.ietf.org/html/rfc6657#section-5
42 |
43 | // Interface can be implemented by Encodings to define the CCS or CES for which
44 | // it implements conversions.
45 | type Interface interface {
46 | // ID returns an encoding identifier. Exactly one of the mib and other
47 | // values should be non-zero.
48 | //
49 | // In the usual case it is only necessary to indicate the MIB code. The
50 | // other string can be used to specify encodings for which there is no MIB,
51 | // such as "x-mac-dingbat".
52 | //
53 | // The other string may only contain the characters a-z, A-Z, 0-9, - and _.
54 | ID() (mib MIB, other string)
55 |
56 | // NOTE: the restrictions on the encoding are to allow extending the syntax
57 | // with additional information such as versions, vendors and other variants.
58 | }
59 |
60 | // A MIB identifies an encoding. It is derived from the IANA MIB codes and adds
61 | // some identifiers for some encodings that are not covered by the IANA
62 | // standard.
63 | //
64 | // See http://www.iana.org/assignments/ianacharset-mib.
65 | type MIB uint16
66 |
67 | // These additional MIB types are not defined in IANA. They are added because
68 | // they are common and defined within the text repo.
69 | const (
70 | // Unofficial marks the start of encodings not registered by IANA.
71 | Unofficial MIB = 10000 + iota
72 |
73 | // Replacement is the WhatWG replacement encoding.
74 | Replacement
75 |
76 | // XUserDefined is the code for x-user-defined.
77 | XUserDefined
78 |
79 | // MacintoshCyrillic is the code for x-mac-cyrillic.
80 | MacintoshCyrillic
81 | )
82 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/internal/internal.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 internal contains code that is shared among encoding implementations.
6 | package internal
7 |
8 | import (
9 | "golang.org/x/text/encoding"
10 | "golang.org/x/text/encoding/internal/identifier"
11 | "golang.org/x/text/transform"
12 | )
13 |
14 | // Encoding is an implementation of the Encoding interface that adds the String
15 | // and ID methods to an existing encoding.
16 | type Encoding struct {
17 | encoding.Encoding
18 | Name string
19 | MIB identifier.MIB
20 | }
21 |
22 | // _ verifies that Encoding implements identifier.Interface.
23 | var _ identifier.Interface = (*Encoding)(nil)
24 |
25 | func (e *Encoding) String() string {
26 | return e.Name
27 | }
28 |
29 | func (e *Encoding) ID() (mib identifier.MIB, other string) {
30 | return e.MIB, ""
31 | }
32 |
33 | // SimpleEncoding is an Encoding that combines two Transformers.
34 | type SimpleEncoding struct {
35 | Decoder transform.Transformer
36 | Encoder transform.Transformer
37 | }
38 |
39 | func (e *SimpleEncoding) NewDecoder() *encoding.Decoder {
40 | return &encoding.Decoder{Transformer: e.Decoder}
41 | }
42 |
43 | func (e *SimpleEncoding) NewEncoder() *encoding.Encoder {
44 | return &encoding.Encoder{Transformer: e.Encoder}
45 | }
46 |
47 | // FuncEncoding is an Encoding that combines two functions returning a new
48 | // Transformer.
49 | type FuncEncoding struct {
50 | Decoder func() transform.Transformer
51 | Encoder func() transform.Transformer
52 | }
53 |
54 | func (e FuncEncoding) NewDecoder() *encoding.Decoder {
55 | return &encoding.Decoder{Transformer: e.Decoder()}
56 | }
57 |
58 | func (e FuncEncoding) NewEncoder() *encoding.Encoder {
59 | return &encoding.Encoder{Transformer: e.Encoder()}
60 | }
61 |
62 | // A RepertoireError indicates a rune is not in the repertoire of a destination
63 | // encoding. It is associated with an encoding-specific suggested replacement
64 | // byte.
65 | type RepertoireError byte
66 |
67 | // Error implements the error interrface.
68 | func (r RepertoireError) Error() string {
69 | return "encoding: rune not supported by encoding."
70 | }
71 |
72 | // Replacement returns the replacement string associated with this error.
73 | func (r RepertoireError) Replacement() byte { return byte(r) }
74 |
75 | var ErrASCIIReplacement = RepertoireError(encoding.ASCIISub)
76 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/simplifiedchinese/all.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 simplifiedchinese
6 |
7 | import (
8 | "golang.org/x/text/encoding"
9 | )
10 |
11 | // All is a list of all defined encodings in this package.
12 | var All = []encoding.Encoding{GB18030, GBK, HZGB2312}
13 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/candide-gb18030.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-gb18030.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/candide-utf-16le.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-utf-16le.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/candide-utf-32be.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-utf-32be.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/candide-windows-1252.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-windows-1252.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/rashomon-euc-jp.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/rashomon-euc-jp.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/rashomon-shift-jis.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/rashomon-shift-jis.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-simplified-gbk.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-simplified-gbk.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-traditional-big5.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-traditional-big5.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/testdata/unsu-joh-eun-nal-euc-kr.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/unsu-joh-eun-nal-euc-kr.txt
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/encoding/unicode/override.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 unicode
6 |
7 | import (
8 | "golang.org/x/text/transform"
9 | )
10 |
11 | // BOMOverride returns a new decoder transformer that is identical to fallback,
12 | // except that the presence of a Byte Order Mark at the start of the input
13 | // causes it to switch to the corresponding Unicode decoding. It will only
14 | // consider BOMs for UTF-8, UTF-16BE, and UTF-16LE.
15 | //
16 | // This differs from using ExpectBOM by allowing a BOM to switch to UTF-8, not
17 | // just UTF-16 variants, and allowing falling back to any encoding scheme.
18 | //
19 | // This technique is recommended by the W3C for use in HTML 5: "For
20 | // compatibility with deployed content, the byte order mark (also known as BOM)
21 | // is considered more authoritative than anything else."
22 | // http://www.w3.org/TR/encoding/#specification-hooks
23 | //
24 | // Using BOMOverride is mostly intended for use cases where the first characters
25 | // of a fallback encoding are known to not be a BOM, for example, for valid HTML
26 | // and most encodings.
27 | func BOMOverride(fallback transform.Transformer) transform.Transformer {
28 | // TODO: possibly allow a variadic argument of unicode encodings to allow
29 | // specifying details of which fallbacks are supported as well as
30 | // specifying the details of the implementations. This would also allow for
31 | // support for UTF-32, which should not be supported by default.
32 | return &bomOverride{fallback: fallback}
33 | }
34 |
35 | type bomOverride struct {
36 | fallback transform.Transformer
37 | current transform.Transformer
38 | }
39 |
40 | func (d *bomOverride) Reset() {
41 | d.current = nil
42 | d.fallback.Reset()
43 | }
44 |
45 | var (
46 | // TODO: we could use decode functions here, instead of allocating a new
47 | // decoder on every NewDecoder as IgnoreBOM decoders can be stateless.
48 | utf16le = UTF16(LittleEndian, IgnoreBOM)
49 | utf16be = UTF16(BigEndian, IgnoreBOM)
50 | )
51 |
52 | const utf8BOM = "\ufeff"
53 |
54 | func (d *bomOverride) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
55 | if d.current != nil {
56 | return d.current.Transform(dst, src, atEOF)
57 | }
58 | if len(src) < 3 && !atEOF {
59 | return 0, 0, transform.ErrShortSrc
60 | }
61 | d.current = d.fallback
62 | bomSize := 0
63 | if len(src) >= 2 {
64 | if src[0] == 0xFF && src[1] == 0xFE {
65 | d.current = utf16le.NewDecoder()
66 | bomSize = 2
67 | } else if src[0] == 0xFE && src[1] == 0xFF {
68 | d.current = utf16be.NewDecoder()
69 | bomSize = 2
70 | } else if len(src) >= 3 &&
71 | src[0] == utf8BOM[0] &&
72 | src[1] == utf8BOM[1] &&
73 | src[2] == utf8BOM[2] {
74 | d.current = transform.Nop
75 | bomSize = 3
76 | }
77 | }
78 | if bomSize < len(src) {
79 | nDst, nSrc, err = d.current.Transform(dst, src[bomSize:], atEOF)
80 | }
81 | return nDst, nSrc + bomSize, err
82 | }
83 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/internal.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 internal contains non-exported functionality that are used by
6 | // packages in the text repository.
7 | package internal // import "golang.org/x/text/internal"
8 |
9 | import (
10 | "sort"
11 |
12 | "golang.org/x/text/language"
13 | )
14 |
15 | // SortTags sorts tags in place.
16 | func SortTags(tags []language.Tag) {
17 | sort.Sort(sorter(tags))
18 | }
19 |
20 | type sorter []language.Tag
21 |
22 | func (s sorter) Len() int {
23 | return len(s)
24 | }
25 |
26 | func (s sorter) Swap(i, j int) {
27 | s[i], s[j] = s[j], s[i]
28 | }
29 |
30 | func (s sorter) Less(i, j int) bool {
31 | return s[i].String() < s[j].String()
32 | }
33 |
34 | // UniqueTags sorts and filters duplicate tags in place and returns a slice with
35 | // only unique tags.
36 | func UniqueTags(tags []language.Tag) []language.Tag {
37 | if len(tags) <= 1 {
38 | return tags
39 | }
40 | SortTags(tags)
41 | k := 0
42 | for i := 1; i < len(tags); i++ {
43 | if tags[k].String() < tags[i].String() {
44 | k++
45 | tags[k] = tags[i]
46 | }
47 | }
48 | return tags[:k+1]
49 | }
50 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/internal_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 internal
6 |
7 | import (
8 | "fmt"
9 | "strings"
10 | "testing"
11 |
12 | "golang.org/x/text/language"
13 | )
14 |
15 | func TestUnique(t *testing.T) {
16 | testCases := []struct {
17 | in, want string
18 | }{
19 | {"", "[]"},
20 | {"en", "[en]"},
21 | {"en en", "[en]"},
22 | {"en en en", "[en]"},
23 | {"en-u-cu-eur en", "[en en-u-cu-eur]"},
24 | {"nl en", "[en nl]"},
25 | {"pt-Pt pt", "[pt pt-PT]"},
26 | }
27 | for _, tc := range testCases {
28 | tags := []language.Tag{}
29 | for _, s := range strings.Split(tc.in, " ") {
30 | if s != "" {
31 | tags = append(tags, language.MustParse(s))
32 | }
33 | }
34 | if got := fmt.Sprint(UniqueTags(tags)); got != tc.want {
35 | t.Errorf("Unique(%s) = %s; want %s", tc.in, got, tc.want)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/common.go:
--------------------------------------------------------------------------------
1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2 |
3 | package language
4 |
5 | // This file contains code common to the maketables.go and the package code.
6 |
7 | // AliasType is the type of an alias in AliasMap.
8 | type AliasType int8
9 |
10 | const (
11 | Deprecated AliasType = iota
12 | Macro
13 | Legacy
14 |
15 | AliasTypeUnknown AliasType = -1
16 | )
17 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact.go:
--------------------------------------------------------------------------------
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 | // CompactCoreInfo is a compact integer with the three core tags encoded.
8 | type CompactCoreInfo uint32
9 |
10 | // GetCompactCore generates a uint32 value that is guaranteed to be unique for
11 | // different language, region, and script values.
12 | func GetCompactCore(t Tag) (cci CompactCoreInfo, ok bool) {
13 | if t.LangID > langNoIndexOffset {
14 | return 0, false
15 | }
16 | cci |= CompactCoreInfo(t.LangID) << (8 + 12)
17 | cci |= CompactCoreInfo(t.ScriptID) << 12
18 | cci |= CompactCoreInfo(t.RegionID)
19 | return cci, true
20 | }
21 |
22 | // Tag generates a tag from c.
23 | func (c CompactCoreInfo) Tag() Tag {
24 | return Tag{
25 | LangID: Language(c >> 20),
26 | RegionID: Region(c & 0x3ff),
27 | ScriptID: Script(c>>12) & 0xff,
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact/compact.go:
--------------------------------------------------------------------------------
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 compact defines a compact representation of language tags.
6 | //
7 | // Common language tags (at least all for which locale information is defined
8 | // in CLDR) are assigned a unique index. Each Tag is associated with such an
9 | // ID for selecting language-related resources (such as translations) as well
10 | // as one for selecting regional defaults (currency, number formatting, etc.)
11 | //
12 | // It may want to export this functionality at some point, but at this point
13 | // this is only available for use within x/text.
14 | package compact // import "golang.org/x/text/internal/language/compact"
15 |
16 | import (
17 | "sort"
18 | "strings"
19 |
20 | "golang.org/x/text/internal/language"
21 | )
22 |
23 | // ID is an integer identifying a single tag.
24 | type ID uint16
25 |
26 | func getCoreIndex(t language.Tag) (id ID, ok bool) {
27 | cci, ok := language.GetCompactCore(t)
28 | if !ok {
29 | return 0, false
30 | }
31 | i := sort.Search(len(coreTags), func(i int) bool {
32 | return cci <= coreTags[i]
33 | })
34 | if i == len(coreTags) || coreTags[i] != cci {
35 | return 0, false
36 | }
37 | return ID(i), true
38 | }
39 |
40 | // Parent returns the ID of the parent or the root ID if id is already the root.
41 | func (id ID) Parent() ID {
42 | return parents[id]
43 | }
44 |
45 | // Tag converts id to an internal language Tag.
46 | func (id ID) Tag() language.Tag {
47 | if int(id) >= len(coreTags) {
48 | return specialTags[int(id)-len(coreTags)]
49 | }
50 | return coreTags[id].Tag()
51 | }
52 |
53 | var specialTags []language.Tag
54 |
55 | func init() {
56 | tags := strings.Split(specialTagsStr, " ")
57 | specialTags = make([]language.Tag, len(tags))
58 | for i, t := range tags {
59 | specialTags[i] = language.MustParse(t)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact/gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // +build ignore
6 |
7 | // Language tag table generator.
8 | // Data read from the web.
9 |
10 | package compact
11 |
12 | import (
13 | "flag"
14 | "fmt"
15 | "log"
16 |
17 | "golang.org/x/text/internal/gen"
18 | "golang.org/x/text/unicode/cldr"
19 | )
20 |
21 | var (
22 | test = flag.Bool("test",
23 | false,
24 | "test existing tables; can be used to compare web data with package data.")
25 | outputFile = flag.String("output",
26 | "tables.go",
27 | "output file for generated tables")
28 | )
29 |
30 | func main() {
31 | gen.Init()
32 |
33 | w := gen.NewCodeWriter()
34 | defer w.WriteGoFile("tables.go", "compact")
35 |
36 | fmt.Fprintln(w, `import "golang.org/x/text/internal/language"`)
37 |
38 | b := newBuilder(w)
39 | gen.WriteCLDRVersion(w)
40 |
41 | b.writeCompactIndex()
42 | }
43 |
44 | type builder struct {
45 | w *gen.CodeWriter
46 | data *cldr.CLDR
47 | supp *cldr.SupplementalData
48 | }
49 |
50 | func newBuilder(w *gen.CodeWriter) *builder {
51 | r := gen.OpenCLDRCoreZip()
52 | defer r.Close()
53 | d := &cldr.Decoder{}
54 | data, err := d.DecodeZip(r)
55 | if err != nil {
56 | log.Fatal(err)
57 | }
58 | b := builder{
59 | w: w,
60 | data: data,
61 | supp: data.Supplemental(),
62 | }
63 | return &b
64 | }
65 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact/gen_index.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | package compact
8 |
9 | // This file generates derivative tables based on the language package itself.
10 |
11 | import (
12 | "fmt"
13 | "log"
14 | "sort"
15 | "strings"
16 |
17 | "golang.org/x/text/internal/language"
18 | )
19 |
20 | // Compact indices:
21 | // Note -va-X variants only apply to localization variants.
22 | // BCP variants only ever apply to language.
23 | // The only ambiguity between tags is with regions.
24 |
25 | func (b *builder) writeCompactIndex() {
26 | // Collect all language tags for which we have any data in CLDR.
27 | m := map[language.Tag]bool{}
28 | for _, lang := range b.data.Locales() {
29 | // We include all locales unconditionally to be consistent with en_US.
30 | // We want en_US, even though it has no data associated with it.
31 |
32 | // TODO: put any of the languages for which no data exists at the end
33 | // of the index. This allows all components based on ICU to use that
34 | // as the cutoff point.
35 | // if x := data.RawLDML(lang); false ||
36 | // x.LocaleDisplayNames != nil ||
37 | // x.Characters != nil ||
38 | // x.Delimiters != nil ||
39 | // x.Measurement != nil ||
40 | // x.Dates != nil ||
41 | // x.Numbers != nil ||
42 | // x.Units != nil ||
43 | // x.ListPatterns != nil ||
44 | // x.Collations != nil ||
45 | // x.Segmentations != nil ||
46 | // x.Rbnf != nil ||
47 | // x.Annotations != nil ||
48 | // x.Metadata != nil {
49 |
50 | // TODO: support POSIX natively, albeit non-standard.
51 | tag := language.Make(strings.Replace(lang, "_POSIX", "-u-va-posix", 1))
52 | m[tag] = true
53 | // }
54 | }
55 |
56 | // TODO: plural rules are also defined for the deprecated tags:
57 | // iw mo sh tl
58 | // Consider removing these as compact tags.
59 |
60 | // Include locales for plural rules, which uses a different structure.
61 | for _, plurals := range b.supp.Plurals {
62 | for _, rules := range plurals.PluralRules {
63 | for _, lang := range strings.Split(rules.Locales, " ") {
64 | m[language.Make(lang)] = true
65 | }
66 | }
67 | }
68 |
69 | var coreTags []language.CompactCoreInfo
70 | var special []string
71 |
72 | for t := range m {
73 | if x := t.Extensions(); len(x) != 0 && fmt.Sprint(x) != "[u-va-posix]" {
74 | log.Fatalf("Unexpected extension %v in %v", x, t)
75 | }
76 | if len(t.Variants()) == 0 && len(t.Extensions()) == 0 {
77 | cci, ok := language.GetCompactCore(t)
78 | if !ok {
79 | log.Fatalf("Locale for non-basic language %q", t)
80 | }
81 | coreTags = append(coreTags, cci)
82 | } else {
83 | special = append(special, t.String())
84 | }
85 | }
86 |
87 | w := b.w
88 |
89 | sort.Slice(coreTags, func(i, j int) bool { return coreTags[i] < coreTags[j] })
90 | sort.Strings(special)
91 |
92 | w.WriteComment(`
93 | NumCompactTags is the number of common tags. The maximum tag is
94 | NumCompactTags-1.`)
95 | w.WriteConst("NumCompactTags", len(m))
96 |
97 | fmt.Fprintln(w, "const (")
98 | for i, t := range coreTags {
99 | fmt.Fprintf(w, "%s ID = %d\n", ident(t.Tag().String()), i)
100 | }
101 | for i, t := range special {
102 | fmt.Fprintf(w, "%s ID = %d\n", ident(t), i+len(coreTags))
103 | }
104 | fmt.Fprintln(w, ")")
105 |
106 | w.WriteVar("coreTags", coreTags)
107 |
108 | w.WriteConst("specialTagsStr", strings.Join(special, " "))
109 | }
110 |
111 | func ident(s string) string {
112 | return strings.Replace(s, "-", "", -1) + "Index"
113 | }
114 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact/gen_parents.go:
--------------------------------------------------------------------------------
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 | // +build ignore
6 |
7 | package compact
8 |
9 | import (
10 | "log"
11 |
12 | "golang.org/x/text/internal/gen"
13 | "golang.org/x/text/internal/language"
14 | "golang.org/x/text/internal/language/compact"
15 | "golang.org/x/text/unicode/cldr"
16 | )
17 |
18 | func main() {
19 | r := gen.OpenCLDRCoreZip()
20 | defer r.Close()
21 |
22 | d := &cldr.Decoder{}
23 | data, err := d.DecodeZip(r)
24 | if err != nil {
25 | log.Fatalf("DecodeZip: %v", err)
26 | }
27 |
28 | w := gen.NewCodeWriter()
29 | defer w.WriteGoFile("parents.go", "compact")
30 |
31 | // Create parents table.
32 | type ID uint16
33 | parents := make([]ID, compact.NumCompactTags)
34 | for _, loc := range data.Locales() {
35 | tag := language.MustParse(loc)
36 | index, ok := compact.FromTag(tag)
37 | if !ok {
38 | continue
39 | }
40 | parentIndex := compact.ID(0) // und
41 | for p := tag.Parent(); p != language.Und; p = p.Parent() {
42 | if x, ok := compact.FromTag(p); ok {
43 | parentIndex = x
44 | break
45 | }
46 | }
47 | parents[index] = ID(parentIndex)
48 | }
49 |
50 | w.WriteComment(`
51 | parents maps a compact index of a tag to the compact index of the parent of
52 | this tag.`)
53 | w.WriteVar("parents", parents)
54 | }
55 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compact/gen_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 compact
6 |
7 | import (
8 | "testing"
9 |
10 | "golang.org/x/text/internal/language"
11 | )
12 |
13 | func TestParents(t *testing.T) {
14 | testCases := []struct {
15 | tag, parent string
16 | }{
17 | {"af", "und"},
18 | {"en", "und"},
19 | {"en-001", "en"},
20 | {"en-AU", "en-001"},
21 | {"en-US", "en"},
22 | {"en-US-u-va-posix", "en-US"},
23 | {"ca-ES-valencia", "ca-ES"},
24 | }
25 | for _, tc := range testCases {
26 | tag, ok := LanguageID(Make(language.MustParse(tc.tag)))
27 | if !ok {
28 | t.Fatalf("Could not get index of flag %s", tc.tag)
29 | }
30 | want, ok := LanguageID(Make(language.MustParse(tc.parent)))
31 | if !ok {
32 | t.Fatalf("Could not get index of parent %s of tag %s", tc.parent, tc.tag)
33 | }
34 | if got := parents[tag]; got != want {
35 | t.Errorf("Parent[%s] = %d; want %d (%s)", tc.tag, got, want, tc.parent)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compose.go:
--------------------------------------------------------------------------------
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 | }
168 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/compose_test.go:
--------------------------------------------------------------------------------
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 | "strings"
9 | "testing"
10 | )
11 |
12 | func parseBase(s string) Language {
13 | if s == "" {
14 | return 0
15 | }
16 | return MustParseBase(s)
17 | }
18 |
19 | func parseScript(s string) Script {
20 | if s == "" {
21 | return 0
22 | }
23 | return MustParseScript(s)
24 | }
25 |
26 | func parseRegion(s string) Region {
27 | if s == "" {
28 | return 0
29 | }
30 | return MustParseRegion(s)
31 | }
32 |
33 | func TestBuilder(t *testing.T) {
34 | partChecks(t, func(t *testing.T, tt *parseTest) (id Tag, skip bool) {
35 | tag := Make(tt.in)
36 | b := Builder{}
37 | b.SetTag(Tag{
38 | LangID: parseBase(tt.lang),
39 | ScriptID: parseScript(tt.script),
40 | RegionID: parseRegion(tt.region),
41 | })
42 | if tt.variants != "" {
43 | b.AddVariant(strings.Split(tt.variants, "-")...)
44 | }
45 | for _, e := range tag.Extensions() {
46 | b.AddExt(e)
47 | }
48 | got := b.Make()
49 | if got != tag {
50 | t.Errorf("%s: got %v; want %v", tt.in, got, tag)
51 | }
52 | return got, false
53 | })
54 | }
55 |
56 | func TestSetTag(t *testing.T) {
57 | partChecks(t, func(t *testing.T, tt *parseTest) (id Tag, skip bool) {
58 | tag := Make(tt.in)
59 | b := Builder{}
60 | b.SetTag(tag)
61 | got := b.Make()
62 | if got != tag {
63 | t.Errorf("%s: got %v; want %v", tt.in, got, tag)
64 | }
65 | return got, false
66 | })
67 | }
68 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/coverage.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 | // BaseLanguages returns the list of all supported base languages. It generates
8 | // the list by traversing the internal structures.
9 | func BaseLanguages() []Language {
10 | base := make([]Language, 0, NumLanguages)
11 | for i := 0; i < langNoIndexOffset; i++ {
12 | // We included "und" already for the value 0.
13 | if i != nonCanonicalUnd {
14 | base = append(base, Language(i))
15 | }
16 | }
17 | i := langNoIndexOffset
18 | for _, v := range langNoIndex {
19 | for k := 0; k < 8; k++ {
20 | if v&1 == 1 {
21 | base = append(base, Language(i))
22 | }
23 | v >>= 1
24 | i++
25 | }
26 | }
27 | return base
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/gen_common.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 | // +build ignore
6 |
7 | package language
8 |
9 | // This file contains code common to the maketables.go and the package code.
10 |
11 | // AliasType is the type of an alias in AliasMap.
12 | type AliasType int8
13 |
14 | const (
15 | Deprecated AliasType = iota
16 | Macro
17 | Legacy
18 |
19 | AliasTypeUnknown AliasType = -1
20 | )
21 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/language/tags.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
8 | // It simplifies safe initialization of Tag values.
9 | func MustParse(s string) Tag {
10 | t, err := Parse(s)
11 | if err != nil {
12 | panic(err)
13 | }
14 | return t
15 | }
16 |
17 | // MustParseBase is like ParseBase, but panics if the given base cannot be parsed.
18 | // It simplifies safe initialization of Base values.
19 | func MustParseBase(s string) Language {
20 | b, err := ParseBase(s)
21 | if err != nil {
22 | panic(err)
23 | }
24 | return b
25 | }
26 |
27 | // MustParseScript is like ParseScript, but panics if the given script cannot be
28 | // parsed. It simplifies safe initialization of Script values.
29 | func MustParseScript(s string) Script {
30 | scr, err := ParseScript(s)
31 | if err != nil {
32 | panic(err)
33 | }
34 | return scr
35 | }
36 |
37 | // MustParseRegion is like ParseRegion, but panics if the given region cannot be
38 | // parsed. It simplifies safe initialization of Region values.
39 | func MustParseRegion(s string) Region {
40 | r, err := ParseRegion(s)
41 | if err != nil {
42 | panic(err)
43 | }
44 | return r
45 | }
46 |
47 | // Und is the root language.
48 | var Und Tag
49 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/match.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 internal
6 |
7 | // This file contains matchers that implement CLDR inheritance.
8 | //
9 | // See https://unicode.org/reports/tr35/#Locale_Inheritance.
10 | //
11 | // Some of the inheritance described in this document is already handled by
12 | // the cldr package.
13 |
14 | import (
15 | "golang.org/x/text/language"
16 | )
17 |
18 | // TODO: consider if (some of the) matching algorithm needs to be public after
19 | // getting some feel about what is generic and what is specific.
20 |
21 | // NewInheritanceMatcher returns a matcher that matches based on the inheritance
22 | // chain.
23 | //
24 | // The matcher uses canonicalization and the parent relationship to find a
25 | // match. The resulting match will always be either Und or a language with the
26 | // same language and script as the requested language. It will not match
27 | // languages for which there is understood to be mutual or one-directional
28 | // intelligibility.
29 | //
30 | // A Match will indicate an Exact match if the language matches after
31 | // canonicalization and High if the matched tag is a parent.
32 | func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher {
33 | tags := &InheritanceMatcher{make(map[language.Tag]int)}
34 | for i, tag := range t {
35 | ct, err := language.All.Canonicalize(tag)
36 | if err != nil {
37 | ct = tag
38 | }
39 | tags.index[ct] = i
40 | }
41 | return tags
42 | }
43 |
44 | type InheritanceMatcher struct {
45 | index map[language.Tag]int
46 | }
47 |
48 | func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) {
49 | for _, t := range want {
50 | ct, err := language.All.Canonicalize(t)
51 | if err != nil {
52 | ct = t
53 | }
54 | conf := language.Exact
55 | for {
56 | if index, ok := m.index[ct]; ok {
57 | return ct, index, conf
58 | }
59 | if ct == language.Und {
60 | break
61 | }
62 | ct = ct.Parent()
63 | conf = language.High
64 | }
65 | }
66 | return language.Und, 0, language.No
67 | }
68 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/match_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 internal
6 |
7 | import (
8 | "strings"
9 | "testing"
10 |
11 | "golang.org/x/text/language"
12 | )
13 |
14 | func TestInheritanceMatcher(t *testing.T) {
15 | for i, tt := range []struct {
16 | haveTags string
17 | wantTags string
18 | match string
19 | conf language.Confidence
20 | }{
21 | {"und,en,en-US", "en-US", "en-US", language.Exact}, // most specific match
22 | {"zh-Hant,zh", "zh-TW", "zh-Hant", language.High}, // zh-TW implies Hant.
23 | {"und,zh", "zh-TW", "und", language.High}, // zh-TW does not match zh.
24 | {"zh", "zh-TW", "und", language.No}, // zh-TW does not match zh.
25 | {"iw,en,nl", "he", "he", language.Exact}, // matches after canonicalization
26 | {"he,en,nl", "iw", "he", language.Exact}, // matches after canonicalization
27 | // Prefer first match over more specific match for various reasons:
28 | // a) consistency of user interface is more important than an exact match,
29 | // b) _if_ und is specified, it should be considered a correct and useful match,
30 | // Note that a call to this Match will almost always be with a single tag.
31 | {"und,en,en-US", "he,en-US", "und", language.High},
32 | } {
33 | have := parseTags(tt.haveTags)
34 | m := NewInheritanceMatcher(have)
35 | tag, index, conf := m.Match(parseTags(tt.wantTags)...)
36 | want := language.Raw.Make(tt.match)
37 | if tag != want {
38 | t.Errorf("%d:tag: got %q; want %q", i, tag, want)
39 | }
40 | if conf != language.No {
41 | if got, _ := language.All.Canonicalize(have[index]); got != want {
42 | t.Errorf("%d:index: got %q; want %q ", i, got, want)
43 | }
44 | }
45 | if conf != tt.conf {
46 | t.Errorf("%d:conf: got %v; want %v", i, conf, tt.conf)
47 | }
48 | }
49 | }
50 |
51 | func parseTags(list string) (out []language.Tag) {
52 | for _, s := range strings.Split(list, ",") {
53 | out = append(out, language.Raw.Make(strings.TrimSpace(s)))
54 | }
55 | return out
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/tag/tag.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 tag contains functionality handling tags and related data.
6 | package tag // import "golang.org/x/text/internal/tag"
7 |
8 | import "sort"
9 |
10 | // An Index converts tags to a compact numeric value.
11 | //
12 | // All elements are of size 4. Tags may be up to 4 bytes long. Excess bytes can
13 | // be used to store additional information about the tag.
14 | type Index string
15 |
16 | // Elem returns the element data at the given index.
17 | func (s Index) Elem(x int) string {
18 | return string(s[x*4 : x*4+4])
19 | }
20 |
21 | // Index reports the index of the given key or -1 if it could not be found.
22 | // Only the first len(key) bytes from the start of the 4-byte entries will be
23 | // considered for the search and the first match in Index will be returned.
24 | func (s Index) Index(key []byte) int {
25 | n := len(key)
26 | // search the index of the first entry with an equal or higher value than
27 | // key in s.
28 | index := sort.Search(len(s)/4, func(i int) bool {
29 | return cmp(s[i*4:i*4+n], key) != -1
30 | })
31 | i := index * 4
32 | if cmp(s[i:i+len(key)], key) != 0 {
33 | return -1
34 | }
35 | return index
36 | }
37 |
38 | // Next finds the next occurrence of key after index x, which must have been
39 | // obtained from a call to Index using the same key. It returns x+1 or -1.
40 | func (s Index) Next(key []byte, x int) int {
41 | if x++; x*4 < len(s) && cmp(s[x*4:x*4+len(key)], key) == 0 {
42 | return x
43 | }
44 | return -1
45 | }
46 |
47 | // cmp returns an integer comparing a and b lexicographically.
48 | func cmp(a Index, b []byte) int {
49 | n := len(a)
50 | if len(b) < n {
51 | n = len(b)
52 | }
53 | for i, c := range b[:n] {
54 | switch {
55 | case a[i] > c:
56 | return 1
57 | case a[i] < c:
58 | return -1
59 | }
60 | }
61 | switch {
62 | case len(a) < len(b):
63 | return -1
64 | case len(a) > len(b):
65 | return 1
66 | }
67 | return 0
68 | }
69 |
70 | // Compare returns an integer comparing a and b lexicographically.
71 | func Compare(a string, b []byte) int {
72 | return cmp(Index(a), b)
73 | }
74 |
75 | // FixCase reformats b to the same pattern of cases as form.
76 | // If returns false if string b is malformed.
77 | func FixCase(form string, b []byte) bool {
78 | if len(form) != len(b) {
79 | return false
80 | }
81 | for i, c := range b {
82 | if form[i] <= 'Z' {
83 | if c >= 'a' {
84 | c -= 'z' - 'Z'
85 | }
86 | if c < 'A' || 'Z' < c {
87 | return false
88 | }
89 | } else {
90 | if c <= 'Z' {
91 | c += 'z' - 'Z'
92 | }
93 | if c < 'a' || 'z' < c {
94 | return false
95 | }
96 | }
97 | b[i] = c
98 | }
99 | return true
100 | }
101 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/tag/tag_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 tag
6 |
7 | import (
8 | "strings"
9 | "testing"
10 | )
11 |
12 | var strdata = []string{
13 | "aa ",
14 | "aaa ",
15 | "aaaa",
16 | "aaab",
17 | "aab ",
18 | "ab ",
19 | "ba ",
20 | "xxxx",
21 | "\xff\xff\xff\xff",
22 | }
23 |
24 | var testCases = map[string]int{
25 | "a": 0,
26 | "aa": 0,
27 | "aaa": 1,
28 | "aa ": 0,
29 | "aaaa": 2,
30 | "aaab": 3,
31 | "b": 6,
32 | "ba": 6,
33 | " ": -1,
34 | "aaax": -1,
35 | "bbbb": -1,
36 | "zzzz": -1,
37 | }
38 |
39 | func TestIndex(t *testing.T) {
40 | index := Index(strings.Join(strdata, ""))
41 | for k, v := range testCases {
42 | if i := index.Index([]byte(k)); i != v {
43 | t.Errorf("%s: got %d; want %d", k, i, v)
44 | }
45 | }
46 | }
47 |
48 | func TestFixCase(t *testing.T) {
49 | tests := []string{
50 | "aaaa", "AbCD", "abcd",
51 | "Zzzz", "AbCD", "Abcd",
52 | "Zzzz", "AbC", "",
53 | "XXX", "ab ", "",
54 | "XXX", "usd", "USD",
55 | "cmn", "AB ", "",
56 | "gsw", "CMN", "cmn",
57 | }
58 | for tc := tests; len(tc) > 0; tc = tc[3:] {
59 | b := []byte(tc[1])
60 | if !FixCase(tc[0], b) {
61 | b = nil
62 | }
63 | if string(b) != tc[2] {
64 | t.Errorf("FixCase(%q, %q) = %q; want %q", tc[0], tc[1], b, tc[2])
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/codesize.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 testtext
6 |
7 | import (
8 | "bytes"
9 | "fmt"
10 | "io/ioutil"
11 | "os"
12 | "os/exec"
13 | "path/filepath"
14 | "runtime"
15 | )
16 |
17 | // CodeSize builds the given code sample and returns the binary size or en error
18 | // if an error occurred. The code sample typically will look like this:
19 | // package main
20 | // import "golang.org/x/text/somepackage"
21 | // func main() {
22 | // somepackage.Func() // reference Func to cause it to be linked in.
23 | // }
24 | // See dict_test.go in the display package for an example.
25 | func CodeSize(s string) (int, error) {
26 | // Write the file.
27 | tmpdir, err := ioutil.TempDir(os.TempDir(), "testtext")
28 | if err != nil {
29 | return 0, fmt.Errorf("testtext: failed to create tmpdir: %v", err)
30 | }
31 | defer os.RemoveAll(tmpdir)
32 | filename := filepath.Join(tmpdir, "main.go")
33 | if err := ioutil.WriteFile(filename, []byte(s), 0644); err != nil {
34 | return 0, fmt.Errorf("testtext: failed to write main.go: %v", err)
35 | }
36 |
37 | // Build the binary.
38 | w := &bytes.Buffer{}
39 | cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "build", "-o", "main")
40 | cmd.Dir = tmpdir
41 | cmd.Stderr = w
42 | cmd.Stdout = w
43 | if err := cmd.Run(); err != nil {
44 | return 0, fmt.Errorf("testtext: failed to execute command: %v\nmain.go:\n%vErrors:%s", err, s, w)
45 | }
46 |
47 | // Determine the size.
48 | fi, err := os.Stat(filepath.Join(tmpdir, "main"))
49 | if err != nil {
50 | return 0, fmt.Errorf("testtext: failed to get file info: %v", err)
51 | }
52 | return int(fi.Size()), nil
53 | }
54 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/flag.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 testtext
6 |
7 | import (
8 | "flag"
9 | "testing"
10 |
11 | "golang.org/x/text/internal/gen"
12 | )
13 |
14 | var long = flag.Bool("long", false,
15 | "run tests that require fetching data online")
16 |
17 | // SkipIfNotLong returns whether long tests should be performed.
18 | func SkipIfNotLong(t *testing.T) {
19 | if testing.Short() || !(gen.IsLocal() || *long) {
20 | t.Skip("skipping test to prevent downloading; to run use -long or use -local or UNICODE_DIR to specify a local source")
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/gc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 | // +build !gccgo
6 |
7 | package testtext
8 |
9 | import "testing"
10 |
11 | // AllocsPerRun wraps testing.AllocsPerRun.
12 | func AllocsPerRun(runs int, f func()) (avg float64) {
13 | return testing.AllocsPerRun(runs, f)
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/gccgo.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 | // +build gccgo
6 |
7 | package testtext
8 |
9 | // AllocsPerRun always returns 0 for gccgo until gccgo implements escape
10 | // analysis equal or better to that of gc.
11 | func AllocsPerRun(runs int, f func()) (avg float64) { return 0 }
12 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/go1_6.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 | // +build !go1.7
6 |
7 | package testtext
8 |
9 | import "testing"
10 |
11 | func Run(t *testing.T, name string, fn func(t *testing.T)) bool {
12 | t.Logf("Running %s...", name)
13 | fn(t)
14 | return t.Failed()
15 | }
16 |
17 | // Bench runs the given benchmark function. This pre-1.7 implementation renders
18 | // the measurement useless, but allows the code to be compiled at least.
19 | func Bench(b *testing.B, name string, fn func(b *testing.B)) bool {
20 | b.Logf("Running %s...", name)
21 | fn(b)
22 | return b.Failed()
23 | }
24 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/testtext/go1_7.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 | // +build go1.7
6 |
7 | package testtext
8 |
9 | import "testing"
10 |
11 | func Run(t *testing.T, name string, fn func(t *testing.T)) bool {
12 | return t.Run(name, fn)
13 | }
14 |
15 | func Bench(b *testing.B, name string, fn func(b *testing.B)) bool {
16 | return b.Run(name, fn)
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/ucd/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 ucd_test
6 |
7 | import (
8 | "fmt"
9 | "strings"
10 |
11 | "golang.org/x/text/internal/ucd"
12 | )
13 |
14 | func Example() {
15 | // Read rune-by-rune from UnicodeData.
16 | var count int
17 | p := ucd.New(strings.NewReader(unicodeData))
18 | for p.Next() {
19 | count++
20 | if lower := p.Runes(ucd.SimpleLowercaseMapping); lower != nil {
21 | fmt.Printf("lower(%U) -> %U\n", p.Rune(0), lower[0])
22 | }
23 | }
24 | if err := p.Err(); err != nil {
25 | fmt.Println(err)
26 | }
27 | fmt.Println("Number of runes visited:", count)
28 |
29 | // Read raw ranges from Scripts.
30 | p = ucd.New(strings.NewReader(scripts), ucd.KeepRanges)
31 | for p.Next() {
32 | start, end := p.Range(0)
33 | fmt.Printf("%04X..%04X: %s\n", start, end, p.String(1))
34 | }
35 | if err := p.Err(); err != nil {
36 | fmt.Println(err)
37 | }
38 |
39 | // Output:
40 | // lower(U+00C0) -> U+00E0
41 | // lower(U+00C1) -> U+00E1
42 | // lower(U+00C2) -> U+00E2
43 | // lower(U+00C3) -> U+00E3
44 | // lower(U+00C4) -> U+00E4
45 | // Number of runes visited: 6594
46 | // 0000..001F: Common
47 | // 0020..0020: Common
48 | // 0021..0023: Common
49 | // 0024..0024: Common
50 | }
51 |
52 | // Excerpt from UnicodeData.txt
53 | const unicodeData = `
54 | 00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
55 | 00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L; 006F;;;;N;;;;;
56 | 00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;
57 | 00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
58 | 00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
59 | 00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;
60 | 00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;
61 | 00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;
62 | 00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;
63 | 00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;
64 | 00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;
65 | 00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;
66 |
67 | # A legacy rune range.
68 | 3400;;Lo;0;L;;;;;N;;;;;
69 | 4DB5;;Lo;0;L;;;;;N;;;;;
70 | `
71 |
72 | // Excerpt from Scripts.txt
73 | const scripts = `
74 | # Property: Script
75 | # ================================================
76 |
77 | 0000..001F ; Common # Cc [32] ..
78 | 0020 ; Common # Zs SPACE
79 | 0021..0023 ; Common # Po [3] EXCLAMATION MARK..NUMBER SIGN
80 | 0024 ; Common # Sc DOLLAR SIGN
81 | `
82 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/ucd/ucd_test.go:
--------------------------------------------------------------------------------
1 | package ucd
2 |
3 | import (
4 | "strings"
5 | "testing"
6 | )
7 |
8 | const file = `
9 | # Comments should be skipped
10 | # rune; bool; uint; int; float; runes; # Y
11 | 0..0005; Y; 0; 2; -5.25 ; 0 1 2 3 4 5;
12 | 6..0007; Yes ; 6; 1; -4.25 ; 0006 0007;
13 | 8; T ; 8 ; 0 ;-3.25 ;;# T
14 | 9; True ;9 ; -1;-2.25 ; 0009;
15 |
16 | # more comments to be ignored
17 | @Part0
18 |
19 | A; N; 10 ; -2; -1.25; ;# N
20 | B; No; 11 ; -3; -0.25;
21 | C; False;12; -4; 0.75;
22 | D; ;13;-5;1.75;
23 |
24 | @Part1 # Another part.
25 | # We test part comments get removed by not commenting the next line.
26 | E..10FFFF; F; 14 ; -6; 2.75;
27 | `
28 |
29 | var want = []struct {
30 | start, end rune
31 | }{
32 | {0x00, 0x05},
33 | {0x06, 0x07},
34 | {0x08, 0x08},
35 | {0x09, 0x09},
36 | {0x0A, 0x0A},
37 | {0x0B, 0x0B},
38 | {0x0C, 0x0C},
39 | {0x0D, 0x0D},
40 | {0x0E, 0x10FFFF},
41 | }
42 |
43 | func TestGetters(t *testing.T) {
44 | parts := [][2]string{
45 | {"Part0", ""},
46 | {"Part1", "Another part."},
47 | }
48 | handler := func(p *Parser) {
49 | if len(parts) == 0 {
50 | t.Error("Part handler invoked too many times.")
51 | return
52 | }
53 | want := parts[0]
54 | parts = parts[1:]
55 | if got0, got1 := p.String(0), p.Comment(); got0 != want[0] || got1 != want[1] {
56 | t.Errorf(`part: got %q, %q; want %q"`, got0, got1, want)
57 | }
58 | }
59 |
60 | p := New(strings.NewReader(file), KeepRanges, Part(handler))
61 | for i := 0; p.Next(); i++ {
62 | start, end := p.Range(0)
63 | w := want[i]
64 | if start != w.start || end != w.end {
65 | t.Fatalf("%d:Range(0); got %#x..%#x; want %#x..%#x", i, start, end, w.start, w.end)
66 | }
67 | if w.start == w.end && p.Rune(0) != w.start {
68 | t.Errorf("%d:Range(0).start: got %U; want %U", i, p.Rune(0), w.start)
69 | }
70 | if got, want := p.Bool(1), w.start <= 9; got != want {
71 | t.Errorf("%d:Bool(1): got %v; want %v", i, got, want)
72 | }
73 | if got := p.Rune(4); got != 0 || p.Err() == nil {
74 | t.Errorf("%d:Rune(%q): got no error; want error", i, p.String(1))
75 | }
76 | p.err = nil
77 | if got := p.Uint(2); rune(got) != start {
78 | t.Errorf("%d:Uint(2): got %v; want %v", i, got, start)
79 | }
80 | if got, want := p.Int(3), 2-i; got != want {
81 | t.Errorf("%d:Int(3): got %v; want %v", i, got, want)
82 | }
83 | if got, want := p.Float(4), -5.25+float64(i); got != want {
84 | t.Errorf("%d:Int(3): got %v; want %v", i, got, want)
85 | }
86 | if got := p.Runes(5); got == nil {
87 | if p.String(5) != "" {
88 | t.Errorf("%d:Runes(5): expected non-empty list", i)
89 | }
90 | } else {
91 | if got[0] != start || got[len(got)-1] != end {
92 | t.Errorf("%d:Runes(5): got %#x; want %#x..%#x", i, got, start, end)
93 | }
94 | }
95 | if got := p.Comment(); got != "" && got != p.String(1) {
96 | t.Errorf("%d:Comment(): got %v; want %v", i, got, p.String(1))
97 | }
98 | }
99 | if err := p.Err(); err != nil {
100 | t.Errorf("Parser error: %v", err)
101 | }
102 | if len(parts) != 0 {
103 | t.Errorf("expected %d more invocations of part handler", len(parts))
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 utf8internal contains low-level utf8-related constants, tables, etc.
6 | // that are used internally by the text package.
7 | package utf8internal
8 |
9 | // The default lowest and highest continuation byte.
10 | const (
11 | LoCB = 0x80 // 1000 0000
12 | HiCB = 0xBF // 1011 1111
13 | )
14 |
15 | // Constants related to getting information of first bytes of UTF-8 sequences.
16 | const (
17 | // ASCII identifies a UTF-8 byte as ASCII.
18 | ASCII = as
19 |
20 | // FirstInvalid indicates a byte is invalid as a first byte of a UTF-8
21 | // sequence.
22 | FirstInvalid = xx
23 |
24 | // SizeMask is a mask for the size bits. Use use x&SizeMask to get the size.
25 | SizeMask = 7
26 |
27 | // AcceptShift is the right-shift count for the first byte info byte to get
28 | // the index into the AcceptRanges table. See AcceptRanges.
29 | AcceptShift = 4
30 |
31 | // The names of these constants are chosen to give nice alignment in the
32 | // table below. The first nibble is an index into acceptRanges or F for
33 | // special one-byte cases. The second nibble is the Rune length or the
34 | // Status for the special one-byte case.
35 | xx = 0xF1 // invalid: size 1
36 | as = 0xF0 // ASCII: size 1
37 | s1 = 0x02 // accept 0, size 2
38 | s2 = 0x13 // accept 1, size 3
39 | s3 = 0x03 // accept 0, size 3
40 | s4 = 0x23 // accept 2, size 3
41 | s5 = 0x34 // accept 3, size 4
42 | s6 = 0x04 // accept 0, size 4
43 | s7 = 0x44 // accept 4, size 4
44 | )
45 |
46 | // First is information about the first byte in a UTF-8 sequence.
47 | var First = [256]uint8{
48 | // 1 2 3 4 5 6 7 8 9 A B C D E F
49 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F
50 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F
51 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F
52 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F
53 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F
54 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F
55 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F
56 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F
57 | // 1 2 3 4 5 6 7 8 9 A B C D E F
58 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F
59 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F
60 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF
61 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF
62 | xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF
63 | s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF
64 | s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF
65 | s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF
66 | }
67 |
68 | // AcceptRange gives the range of valid values for the second byte in a UTF-8
69 | // sequence for any value for First that is not ASCII or FirstInvalid.
70 | type AcceptRange struct {
71 | Lo uint8 // lowest value for second byte.
72 | Hi uint8 // highest value for second byte.
73 | }
74 |
75 | // AcceptRanges is a slice of AcceptRange values. For a given byte sequence b
76 | //
77 | // AcceptRanges[First[b[0]]>>AcceptShift]
78 | //
79 | // will give the value of AcceptRange for the multi-byte UTF-8 sequence starting
80 | // at b[0].
81 | var AcceptRanges = [...]AcceptRange{
82 | 0: {LoCB, HiCB},
83 | 1: {0xA0, HiCB},
84 | 2: {LoCB, 0x9F},
85 | 3: {0x90, HiCB},
86 | 4: {LoCB, 0x8F},
87 | }
88 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/language/coverage_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 | "fmt"
9 | "reflect"
10 | "testing"
11 |
12 | "golang.org/x/text/internal/language"
13 | )
14 |
15 | func TestSupported(t *testing.T) {
16 | // To prove the results are correct for a type, we test that the number of
17 | // results is identical to the number of results on record, that all results
18 | // are distinct and that all results are valid.
19 | tests := map[string]int{
20 | "BaseLanguages": language.NumLanguages,
21 | "Scripts": language.NumScripts,
22 | "Regions": language.NumRegions,
23 | "Tags": 0,
24 | }
25 | sup := reflect.ValueOf(Supported)
26 | for name, num := range tests {
27 | v := sup.MethodByName(name).Call(nil)[0]
28 | if n := v.Len(); n != num {
29 | t.Errorf("len(%s()) was %d; want %d", name, n, num)
30 | }
31 | dup := make(map[string]bool)
32 | for i := 0; i < v.Len(); i++ {
33 | x := v.Index(i).Interface()
34 | // An invalid value will either cause a crash or result in a
35 | // duplicate when passed to Sprint.
36 | s := fmt.Sprint(x)
37 | if dup[s] {
38 | t.Errorf("%s: duplicate entry %q", name, s)
39 | }
40 | dup[s] = true
41 | }
42 | if len(dup) != v.Len() {
43 | t.Errorf("%s: # unique entries was %d; want %d", name, len(dup), v.Len())
44 | }
45 | }
46 | }
47 |
48 | func TestNewCoverage(t *testing.T) {
49 | bases := []Base{Base{0}, Base{3}, Base{7}}
50 | scripts := []Script{Script{11}, Script{17}, Script{23}}
51 | regions := []Region{Region{101}, Region{103}, Region{107}}
52 | tags := []Tag{Make("pt"), Make("en"), Make("en-GB"), Make("en-US"), Make("pt-PT")}
53 | fbases := func() []Base { return bases }
54 | fscripts := func() []Script { return scripts }
55 | fregions := func() []Region { return regions }
56 | ftags := func() []Tag { return tags }
57 |
58 | tests := []struct {
59 | desc string
60 | list []interface{}
61 | bases []Base
62 | scripts []Script
63 | regions []Region
64 | tags []Tag
65 | }{
66 | {
67 | desc: "empty",
68 | },
69 | {
70 | desc: "bases",
71 | list: []interface{}{bases},
72 | bases: bases,
73 | },
74 | {
75 | desc: "scripts",
76 | list: []interface{}{scripts},
77 | scripts: scripts,
78 | },
79 | {
80 | desc: "regions",
81 | list: []interface{}{regions},
82 | regions: regions,
83 | },
84 | {
85 | desc: "bases derives from tags",
86 | list: []interface{}{tags},
87 | bases: []Base{Base{_en}, Base{_pt}},
88 | tags: tags,
89 | },
90 | {
91 | desc: "tags and bases",
92 | list: []interface{}{tags, bases},
93 | bases: bases,
94 | tags: tags,
95 | },
96 | {
97 | desc: "fully specified",
98 | list: []interface{}{tags, bases, scripts, regions},
99 | bases: bases,
100 | scripts: scripts,
101 | regions: regions,
102 | tags: tags,
103 | },
104 | {
105 | desc: "bases func",
106 | list: []interface{}{fbases},
107 | bases: bases,
108 | },
109 | {
110 | desc: "scripts func",
111 | list: []interface{}{fscripts},
112 | scripts: scripts,
113 | },
114 | {
115 | desc: "regions func",
116 | list: []interface{}{fregions},
117 | regions: regions,
118 | },
119 | {
120 | desc: "tags func",
121 | list: []interface{}{ftags},
122 | bases: []Base{Base{_en}, Base{_pt}},
123 | tags: tags,
124 | },
125 | {
126 | desc: "tags and bases",
127 | list: []interface{}{ftags, fbases},
128 | bases: bases,
129 | tags: tags,
130 | },
131 | {
132 | desc: "fully specified",
133 | list: []interface{}{ftags, fbases, fscripts, fregions},
134 | bases: bases,
135 | scripts: scripts,
136 | regions: regions,
137 | tags: tags,
138 | },
139 | }
140 |
141 | for i, tt := range tests {
142 | l := NewCoverage(tt.list...)
143 | if a := l.BaseLanguages(); !reflect.DeepEqual(a, tt.bases) {
144 | t.Errorf("%d:%s: BaseLanguages was %v; want %v", i, tt.desc, a, tt.bases)
145 | }
146 | if a := l.Scripts(); !reflect.DeepEqual(a, tt.scripts) {
147 | t.Errorf("%d:%s: Scripts was %v; want %v", i, tt.desc, a, tt.scripts)
148 | }
149 | if a := l.Regions(); !reflect.DeepEqual(a, tt.regions) {
150 | t.Errorf("%d:%s: Regions was %v; want %v", i, tt.desc, a, tt.regions)
151 | }
152 | if a := l.Tags(); !reflect.DeepEqual(a, tt.tags) {
153 | t.Errorf("%d:%s: Tags was %v; want %v", i, tt.desc, a, tt.tags)
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/language/go1_1.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // +build !go1.2
6 |
7 | package language
8 |
9 | import "sort"
10 |
11 | func sortStable(s sort.Interface) {
12 | ss := stableSort{
13 | s: s,
14 | pos: make([]int, s.Len()),
15 | }
16 | for i := range ss.pos {
17 | ss.pos[i] = i
18 | }
19 | sort.Sort(&ss)
20 | }
21 |
22 | type stableSort struct {
23 | s sort.Interface
24 | pos []int
25 | }
26 |
27 | func (s *stableSort) Len() int {
28 | return len(s.pos)
29 | }
30 |
31 | func (s *stableSort) Less(i, j int) bool {
32 | return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j]
33 | }
34 |
35 | func (s *stableSort) Swap(i, j int) {
36 | s.s.Swap(i, j)
37 | s.pos[i], s.pos[j] = s.pos[j], s.pos[i]
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/language/go1_2.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // +build go1.2
6 |
7 | package language
8 |
9 | import "sort"
10 |
11 | var sortStable = sort.Stable
12 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/language/httpexample_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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_test
6 |
7 | import (
8 | "fmt"
9 | "net/http"
10 | "strings"
11 |
12 | "golang.org/x/text/language"
13 | )
14 |
15 | // matcher is a language.Matcher configured for all supported languages.
16 | var matcher = language.NewMatcher([]language.Tag{
17 | language.BritishEnglish,
18 | language.Norwegian,
19 | language.German,
20 | })
21 |
22 | // handler is a http.HandlerFunc.
23 | func handler(w http.ResponseWriter, r *http.Request) {
24 | t, q, err := language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
25 | // We ignore the error: the default language will be selected for t == nil.
26 | tag, _, _ := matcher.Match(t...)
27 | fmt.Printf("%17v (t: %6v; q: %3v; err: %v)\n", tag, t, q, err)
28 | }
29 |
30 | func ExampleParseAcceptLanguage() {
31 | for _, al := range []string{
32 | "nn;q=0.3, en-us;q=0.8, en,",
33 | "gsw, en;q=0.7, en-US;q=0.8",
34 | "gsw, nl, da",
35 | "invalid",
36 | } {
37 | // Create dummy request with Accept-Language set and pass it to handler.
38 | r, _ := http.NewRequest("GET", "example.com", strings.NewReader("Hello"))
39 | r.Header.Set("Accept-Language", al)
40 | handler(nil, r)
41 | }
42 |
43 | // Output:
44 | // en-GB (t: [ en en-US nn]; q: [ 1 0.8 0.3]; err: )
45 | // en-GB-u-rg-uszzzz (t: [ gsw en-US en]; q: [ 1 0.8 0.7]; err: )
46 | // de (t: [ gsw nl da]; q: [ 1 1 1]; err: )
47 | // en-GB (t: []; q: []; err: language: tag is not well-formed)
48 | }
49 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/runes/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 runes_test
6 |
7 | import (
8 | "fmt"
9 | "unicode"
10 |
11 | "golang.org/x/text/runes"
12 | "golang.org/x/text/transform"
13 | "golang.org/x/text/unicode/norm"
14 | "golang.org/x/text/width"
15 | )
16 |
17 | func ExampleRemove() {
18 | t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
19 | s, _, _ := transform.String(t, "résumé")
20 | fmt.Println(s)
21 |
22 | // Output:
23 | // resume
24 | }
25 |
26 | func ExampleMap() {
27 | replaceHyphens := runes.Map(func(r rune) rune {
28 | if unicode.Is(unicode.Hyphen, r) {
29 | return '|'
30 | }
31 | return r
32 | })
33 | s, _, _ := transform.String(replaceHyphens, "a-b‐c⸗d﹣e")
34 | fmt.Println(s)
35 |
36 | // Output:
37 | // a|b|c|d|e
38 | }
39 |
40 | func ExampleIn() {
41 | // Convert Latin characters to their canonical form, while keeping other
42 | // width distinctions.
43 | t := runes.If(runes.In(unicode.Latin), width.Fold, nil)
44 | s, _, _ := transform.String(t, "アルアノリウ tech / アルアノリウ tech")
45 | fmt.Println(s)
46 |
47 | // Output:
48 | // アルアノリウ tech / アルアノリウ tech
49 | }
50 |
51 | func ExampleIf() {
52 | // Widen everything but ASCII.
53 | isASCII := func(r rune) bool { return r <= unicode.MaxASCII }
54 | t := runes.If(runes.Predicate(isASCII), nil, width.Widen)
55 | s, _, _ := transform.String(t, "アルアノリウ tech / 中國 / 5₩")
56 | fmt.Println(s)
57 |
58 | // Output:
59 | // アルアノリウ tech / 中國 / 5₩
60 | }
61 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/transform/examples_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 transform_test
6 |
7 | import (
8 | "fmt"
9 | "unicode"
10 |
11 | "golang.org/x/text/transform"
12 | "golang.org/x/text/unicode/norm"
13 | )
14 |
15 | func ExampleRemoveFunc() {
16 | input := []byte(`tschüß; до свидания`)
17 |
18 | b := make([]byte, len(input))
19 |
20 | t := transform.RemoveFunc(unicode.IsSpace)
21 | n, _, _ := t.Transform(b, input, true)
22 | fmt.Println(string(b[:n]))
23 |
24 | t = transform.RemoveFunc(func(r rune) bool {
25 | return !unicode.Is(unicode.Latin, r)
26 | })
27 | n, _, _ = t.Transform(b, input, true)
28 | fmt.Println(string(b[:n]))
29 |
30 | n, _, _ = t.Transform(b, norm.NFD.Bytes(input), true)
31 | fmt.Println(string(b[:n]))
32 |
33 | // Output:
34 | // tschüß;досвидания
35 | // tschüß
36 | // tschuß
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/cldr/base.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 cldr
6 |
7 | import (
8 | "encoding/xml"
9 | "regexp"
10 | "strconv"
11 | )
12 |
13 | // Elem is implemented by every XML element.
14 | type Elem interface {
15 | setEnclosing(Elem)
16 | setName(string)
17 | enclosing() Elem
18 |
19 | GetCommon() *Common
20 | }
21 |
22 | type hidden struct {
23 | CharData string `xml:",chardata"`
24 | Alias *struct {
25 | Common
26 | Source string `xml:"source,attr"`
27 | Path string `xml:"path,attr"`
28 | } `xml:"alias"`
29 | Def *struct {
30 | Common
31 | Choice string `xml:"choice,attr,omitempty"`
32 | Type string `xml:"type,attr,omitempty"`
33 | } `xml:"default"`
34 | }
35 |
36 | // Common holds several of the most common attributes and sub elements
37 | // of an XML element.
38 | type Common struct {
39 | XMLName xml.Name
40 | name string
41 | enclElem Elem
42 | Type string `xml:"type,attr,omitempty"`
43 | Reference string `xml:"reference,attr,omitempty"`
44 | Alt string `xml:"alt,attr,omitempty"`
45 | ValidSubLocales string `xml:"validSubLocales,attr,omitempty"`
46 | Draft string `xml:"draft,attr,omitempty"`
47 | hidden
48 | }
49 |
50 | // Default returns the default type to select from the enclosed list
51 | // or "" if no default value is specified.
52 | func (e *Common) Default() string {
53 | if e.Def == nil {
54 | return ""
55 | }
56 | if e.Def.Choice != "" {
57 | return e.Def.Choice
58 | } else if e.Def.Type != "" {
59 | // Type is still used by the default element in collation.
60 | return e.Def.Type
61 | }
62 | return ""
63 | }
64 |
65 | // Element returns the XML element name.
66 | func (e *Common) Element() string {
67 | return e.name
68 | }
69 |
70 | // GetCommon returns e. It is provided such that Common implements Elem.
71 | func (e *Common) GetCommon() *Common {
72 | return e
73 | }
74 |
75 | // Data returns the character data accumulated for this element.
76 | func (e *Common) Data() string {
77 | e.CharData = charRe.ReplaceAllStringFunc(e.CharData, replaceUnicode)
78 | return e.CharData
79 | }
80 |
81 | func (e *Common) setName(s string) {
82 | e.name = s
83 | }
84 |
85 | func (e *Common) enclosing() Elem {
86 | return e.enclElem
87 | }
88 |
89 | func (e *Common) setEnclosing(en Elem) {
90 | e.enclElem = en
91 | }
92 |
93 | // Escape characters that can be escaped without further escaping the string.
94 | var charRe = regexp.MustCompile(`[0-9a-fA-F]*;|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\[abtnvfr]`)
95 |
96 | // replaceUnicode converts hexadecimal Unicode codepoint notations to a one-rune string.
97 | // It assumes the input string is correctly formatted.
98 | func replaceUnicode(s string) string {
99 | if s[1] == '#' {
100 | r, _ := strconv.ParseInt(s[3:len(s)-1], 16, 32)
101 | return string(r)
102 | }
103 | r, _, _, _ := strconv.UnquoteChar(s, 0)
104 | return string(r)
105 | }
106 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/cldr/cldr_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 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 cldr
6 |
7 | import "testing"
8 |
9 | func TestParseDraft(t *testing.T) {
10 | tests := []struct {
11 | in string
12 | draft Draft
13 | err bool
14 | }{
15 | {"unconfirmed", Unconfirmed, false},
16 | {"provisional", Provisional, false},
17 | {"contributed", Contributed, false},
18 | {"approved", Approved, false},
19 | {"", Approved, false},
20 | {"foo", Approved, true},
21 | }
22 | for _, tt := range tests {
23 | if d, err := ParseDraft(tt.in); d != tt.draft || (err != nil) != tt.err {
24 | t.Errorf("%q: was %v, %v; want %v, %v", tt.in, d, err != nil, tt.draft, tt.err)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/cldr/examples_test.go:
--------------------------------------------------------------------------------
1 | package cldr_test
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "path/filepath"
7 |
8 | "golang.org/x/text/internal/gen"
9 | "golang.org/x/text/unicode/cldr"
10 | )
11 |
12 | func ExampleDecoder() {
13 | // Obtain the default CLDR reader (only for x/text packages).
14 |
15 | var d cldr.Decoder
16 |
17 | // Speed up decoding by setting filters for only what you need.
18 | d.SetDirFilter("main", "supplemental")
19 | d.SetSectionFilter("numbers", "plurals")
20 |
21 | cldr, err := d.DecodeZip(gen.OpenCLDRCoreZip())
22 | if err != nil {
23 | fmt.Println("ERROR", err)
24 | return
25 | }
26 | supplemental := cldr.Supplemental()
27 |
28 | fmt.Println(supplemental.MeasurementData.MeasurementSystem[0].Type)
29 | for _, lang := range cldr.Locales() {
30 | data := cldr.RawLDML(lang)
31 | fmt.Println(lang, data.Identity.Version.Number)
32 | }
33 | }
34 |
35 | func ExampleDecoder_DecodePath() {
36 | // This directory will exist if a go generate has been run in any of the
37 | // packages in x/text using the cldr package.
38 | path := filepath.FromSlash("../../DATA/cldr/" + cldr.Version)
39 |
40 | var d cldr.Decoder
41 |
42 | // Speed up decoding by setting filters for only what you need.
43 | d.SetDirFilter("main")
44 | d.SetSectionFilter("numbers")
45 |
46 | cldr, err := d.DecodePath(path)
47 | if err != nil {
48 | // handle error
49 | fmt.Println("ERROR", err)
50 | return
51 | }
52 | for _, lang := range cldr.Locales() {
53 | if numbers := cldr.RawLDML(lang).Numbers; numbers != nil {
54 | fmt.Println(lang, len(numbers.Symbols))
55 | }
56 | }
57 | }
58 |
59 | func ExampleDecoder_DecodeZip() {
60 | // This directory will exist if a go generate has been run in any of the
61 | // packages in x/text using the cldr package.
62 | path := filepath.FromSlash("../../DATA/cldr/" + cldr.Version)
63 |
64 | var d cldr.Decoder
65 |
66 | r, err := os.Open(filepath.Join(path, "core.zip"))
67 | if err != nil {
68 | fmt.Println("error:", err)
69 | return
70 | }
71 |
72 | // Only loading supplemental data can be done much faster using a dir
73 | // filter.
74 | d.SetDirFilter("supplemental")
75 | cldr, err := d.DecodeZip(r)
76 | if err != nil {
77 | fmt.Println("error:", err)
78 | return
79 | }
80 |
81 | fmt.Println(cldr.Supplemental().MeasurementData.MeasurementSystem[0].Type)
82 | }
83 |
84 | func ExampleSlice() {
85 | var dr *cldr.CLDR // assume this is initialized
86 |
87 | x, _ := dr.LDML("en")
88 | cs := x.Collations.Collation
89 | // remove all but the default
90 | cldr.MakeSlice(&cs).Filter(func(e cldr.Elem) bool {
91 | return e.GetCommon().Type != x.Collations.Default()
92 | })
93 | for i, c := range cs {
94 | fmt.Println(i, c.Type)
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/cldr/slice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 cldr
6 |
7 | import (
8 | "fmt"
9 | "reflect"
10 | "sort"
11 | )
12 |
13 | // Slice provides utilities for modifying slices of elements.
14 | // It can be wrapped around any slice of which the element type implements
15 | // interface Elem.
16 | type Slice struct {
17 | ptr reflect.Value
18 | typ reflect.Type
19 | }
20 |
21 | // Value returns the reflect.Value of the underlying slice.
22 | func (s *Slice) Value() reflect.Value {
23 | return s.ptr.Elem()
24 | }
25 |
26 | // MakeSlice wraps a pointer to a slice of Elems.
27 | // It replaces the array pointed to by the slice so that subsequent modifications
28 | // do not alter the data in a CLDR type.
29 | // It panics if an incorrect type is passed.
30 | func MakeSlice(slicePtr interface{}) Slice {
31 | ptr := reflect.ValueOf(slicePtr)
32 | if ptr.Kind() != reflect.Ptr {
33 | panic(fmt.Sprintf("MakeSlice: argument must be pointer to slice, found %v", ptr.Type()))
34 | }
35 | sl := ptr.Elem()
36 | if sl.Kind() != reflect.Slice {
37 | panic(fmt.Sprintf("MakeSlice: argument must point to a slice, found %v", sl.Type()))
38 | }
39 | intf := reflect.TypeOf((*Elem)(nil)).Elem()
40 | if !sl.Type().Elem().Implements(intf) {
41 | panic(fmt.Sprintf("MakeSlice: element type of slice (%v) does not implement Elem", sl.Type().Elem()))
42 | }
43 | nsl := reflect.MakeSlice(sl.Type(), sl.Len(), sl.Len())
44 | reflect.Copy(nsl, sl)
45 | sl.Set(nsl)
46 | return Slice{
47 | ptr: ptr,
48 | typ: sl.Type().Elem().Elem(),
49 | }
50 | }
51 |
52 | func (s Slice) indexForAttr(a string) []int {
53 | for i := iter(reflect.Zero(s.typ)); !i.done(); i.next() {
54 | if n, _ := xmlName(i.field()); n == a {
55 | return i.index
56 | }
57 | }
58 | panic(fmt.Sprintf("MakeSlice: no attribute %q for type %v", a, s.typ))
59 | }
60 |
61 | // Filter filters s to only include elements for which fn returns true.
62 | func (s Slice) Filter(fn func(e Elem) bool) {
63 | k := 0
64 | sl := s.Value()
65 | for i := 0; i < sl.Len(); i++ {
66 | vi := sl.Index(i)
67 | if fn(vi.Interface().(Elem)) {
68 | sl.Index(k).Set(vi)
69 | k++
70 | }
71 | }
72 | sl.Set(sl.Slice(0, k))
73 | }
74 |
75 | // Group finds elements in s for which fn returns the same value and groups
76 | // them in a new Slice.
77 | func (s Slice) Group(fn func(e Elem) string) []Slice {
78 | m := make(map[string][]reflect.Value)
79 | sl := s.Value()
80 | for i := 0; i < sl.Len(); i++ {
81 | vi := sl.Index(i)
82 | key := fn(vi.Interface().(Elem))
83 | m[key] = append(m[key], vi)
84 | }
85 | keys := []string{}
86 | for k, _ := range m {
87 | keys = append(keys, k)
88 | }
89 | sort.Strings(keys)
90 | res := []Slice{}
91 | for _, k := range keys {
92 | nsl := reflect.New(sl.Type())
93 | nsl.Elem().Set(reflect.Append(nsl.Elem(), m[k]...))
94 | res = append(res, MakeSlice(nsl.Interface()))
95 | }
96 | return res
97 | }
98 |
99 | // SelectAnyOf filters s to contain only elements for which attr matches
100 | // any of the values.
101 | func (s Slice) SelectAnyOf(attr string, values ...string) {
102 | index := s.indexForAttr(attr)
103 | s.Filter(func(e Elem) bool {
104 | vf := reflect.ValueOf(e).Elem().FieldByIndex(index)
105 | return in(values, vf.String())
106 | })
107 | }
108 |
109 | // SelectOnePerGroup filters s to include at most one element e per group of
110 | // elements matching Key(attr), where e has an attribute a that matches any
111 | // the values in v.
112 | // If more than one element in a group matches a value in v preference
113 | // is given to the element that matches the first value in v.
114 | func (s Slice) SelectOnePerGroup(a string, v []string) {
115 | index := s.indexForAttr(a)
116 | grouped := s.Group(func(e Elem) string { return Key(e, a) })
117 | sl := s.Value()
118 | sl.Set(sl.Slice(0, 0))
119 | for _, g := range grouped {
120 | e := reflect.Value{}
121 | found := len(v)
122 | gsl := g.Value()
123 | for i := 0; i < gsl.Len(); i++ {
124 | vi := gsl.Index(i).Elem().FieldByIndex(index)
125 | j := 0
126 | for ; j < len(v) && v[j] != vi.String(); j++ {
127 | }
128 | if j < found {
129 | found = j
130 | e = gsl.Index(i)
131 | }
132 | }
133 | if found < len(v) {
134 | sl.Set(reflect.Append(sl, e))
135 | }
136 | }
137 | }
138 |
139 | // SelectDraft drops all elements from the list with a draft level smaller than d
140 | // and selects the highest draft level of the remaining.
141 | // This method assumes that the input CLDR is canonicalized.
142 | func (s Slice) SelectDraft(d Draft) {
143 | s.SelectOnePerGroup("draft", drafts[len(drafts)-2-int(d):])
144 | }
145 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/composition_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import "testing"
8 |
9 | // TestCase is used for most tests.
10 | type TestCase struct {
11 | in []rune
12 | out []rune
13 | }
14 |
15 | func runTests(t *testing.T, name string, fm Form, tests []TestCase) {
16 | rb := reorderBuffer{}
17 | rb.init(fm, nil)
18 | for i, test := range tests {
19 | rb.setFlusher(nil, appendFlush)
20 | for j, rune := range test.in {
21 | b := []byte(string(rune))
22 | src := inputBytes(b)
23 | info := rb.f.info(src, 0)
24 | if j == 0 {
25 | rb.ss.first(info)
26 | } else {
27 | rb.ss.next(info)
28 | }
29 | if rb.insertFlush(src, 0, info) < 0 {
30 | t.Errorf("%s:%d: insert failed for rune %d", name, i, j)
31 | }
32 | }
33 | rb.doFlush()
34 | was := string(rb.out)
35 | want := string(test.out)
36 | if len(was) != len(want) {
37 | t.Errorf("%s:%d: length = %d; want %d", name, i, len(was), len(want))
38 | }
39 | if was != want {
40 | k, pfx := pidx(was, want)
41 | t.Errorf("%s:%d: \nwas %s%+q; \nwant %s%+q", name, i, pfx, was[k:], pfx, want[k:])
42 | }
43 | }
44 | }
45 |
46 | func TestFlush(t *testing.T) {
47 | const (
48 | hello = "Hello "
49 | world = "world!"
50 | )
51 | buf := make([]byte, maxByteBufferSize)
52 | p := copy(buf, hello)
53 | out := buf[p:]
54 | rb := reorderBuffer{}
55 | rb.initString(NFC, world)
56 | if i := rb.flushCopy(out); i != 0 {
57 | t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", i)
58 | }
59 |
60 | for i := range world {
61 | // No need to set streamSafe values for this test.
62 | rb.insertFlush(rb.src, i, rb.f.info(rb.src, i))
63 | n := rb.flushCopy(out)
64 | out = out[n:]
65 | p += n
66 | }
67 |
68 | was := buf[:p]
69 | want := hello + world
70 | if string(was) != want {
71 | t.Errorf(`output after flush was "%s"; want "%s"`, string(was), want)
72 | }
73 | if rb.nrune != 0 {
74 | t.Errorf("non-null size of info buffer (rb.nrune == %d)", rb.nrune)
75 | }
76 | if rb.nbyte != 0 {
77 | t.Errorf("non-null size of byte buffer (rb.nbyte == %d)", rb.nbyte)
78 | }
79 | }
80 |
81 | var insertTests = []TestCase{
82 | {[]rune{'a'}, []rune{'a'}},
83 | {[]rune{0x300}, []rune{0x300}},
84 | {[]rune{0x300, 0x316}, []rune{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220
85 | {[]rune{0x316, 0x300}, []rune{0x316, 0x300}},
86 | {[]rune{0x41, 0x316, 0x300}, []rune{0x41, 0x316, 0x300}},
87 | {[]rune{0x41, 0x300, 0x316}, []rune{0x41, 0x316, 0x300}},
88 | {[]rune{0x300, 0x316, 0x41}, []rune{0x316, 0x300, 0x41}},
89 | {[]rune{0x41, 0x300, 0x40, 0x316}, []rune{0x41, 0x300, 0x40, 0x316}},
90 | }
91 |
92 | func TestInsert(t *testing.T) {
93 | runTests(t, "TestInsert", NFD, insertTests)
94 | }
95 |
96 | var decompositionNFDTest = []TestCase{
97 | {[]rune{0xC0}, []rune{0x41, 0x300}},
98 | {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
99 | {[]rune{0x01C4}, []rune{0x01C4}},
100 | {[]rune{0x320E}, []rune{0x320E}},
101 | {[]rune("음ẻ과"), []rune{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}},
102 | }
103 |
104 | var decompositionNFKDTest = []TestCase{
105 | {[]rune{0xC0}, []rune{0x41, 0x300}},
106 | {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
107 | {[]rune{0x01C4}, []rune{0x44, 0x5A, 0x030C}},
108 | {[]rune{0x320E}, []rune{0x28, 0x1100, 0x1161, 0x29}},
109 | }
110 |
111 | func TestDecomposition(t *testing.T) {
112 | runTests(t, "TestDecompositionNFD", NFD, decompositionNFDTest)
113 | runTests(t, "TestDecompositionNFKD", NFKD, decompositionNFKDTest)
114 | }
115 |
116 | var compositionTest = []TestCase{
117 | {[]rune{0x41, 0x300}, []rune{0xC0}},
118 | {[]rune{0x41, 0x316}, []rune{0x41, 0x316}},
119 | {[]rune{0x41, 0x300, 0x35D}, []rune{0xC0, 0x35D}},
120 | {[]rune{0x41, 0x316, 0x300}, []rune{0xC0, 0x316}},
121 | // blocking starter
122 | {[]rune{0x41, 0x316, 0x40, 0x300}, []rune{0x41, 0x316, 0x40, 0x300}},
123 | {[]rune{0x1100, 0x1161}, []rune{0xAC00}},
124 | // parenthesized Hangul, alternate between ASCII and Hangul.
125 | {[]rune{0x28, 0x1100, 0x1161, 0x29}, []rune{0x28, 0xAC00, 0x29}},
126 | }
127 |
128 | func TestComposition(t *testing.T) {
129 | runTests(t, "TestComposition", NFC, compositionTest)
130 | }
131 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/example_iter_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2012 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 norm_test
6 |
7 | import (
8 | "bytes"
9 | "fmt"
10 | "io"
11 | "unicode/utf8"
12 |
13 | "golang.org/x/text/unicode/norm"
14 | )
15 |
16 | // EqualSimple uses a norm.Iter to compare two non-normalized
17 | // strings for equivalence.
18 | func EqualSimple(a, b string) bool {
19 | var ia, ib norm.Iter
20 | ia.InitString(norm.NFKD, a)
21 | ib.InitString(norm.NFKD, b)
22 | for !ia.Done() && !ib.Done() {
23 | if !bytes.Equal(ia.Next(), ib.Next()) {
24 | return false
25 | }
26 | }
27 | return ia.Done() && ib.Done()
28 | }
29 |
30 | // FindPrefix finds the longest common prefix of ASCII characters
31 | // of a and b.
32 | func FindPrefix(a, b string) int {
33 | i := 0
34 | for ; i < len(a) && i < len(b) && a[i] < utf8.RuneSelf && a[i] == b[i]; i++ {
35 | }
36 | return i
37 | }
38 |
39 | // EqualOpt is like EqualSimple, but optimizes the special
40 | // case for ASCII characters.
41 | func EqualOpt(a, b string) bool {
42 | n := FindPrefix(a, b)
43 | a, b = a[n:], b[n:]
44 | var ia, ib norm.Iter
45 | ia.InitString(norm.NFKD, a)
46 | ib.InitString(norm.NFKD, b)
47 | for !ia.Done() && !ib.Done() {
48 | if !bytes.Equal(ia.Next(), ib.Next()) {
49 | return false
50 | }
51 | if n := int64(FindPrefix(a[ia.Pos():], b[ib.Pos():])); n != 0 {
52 | ia.Seek(n, io.SeekCurrent)
53 | ib.Seek(n, io.SeekCurrent)
54 | }
55 | }
56 | return ia.Done() && ib.Done()
57 | }
58 |
59 | var compareTests = []struct{ a, b string }{
60 | {"aaa", "aaa"},
61 | {"aaa", "aab"},
62 | {"a\u0300a", "\u00E0a"},
63 | {"a\u0300\u0320b", "a\u0320\u0300b"},
64 | {"\u1E0A\u0323", "\x44\u0323\u0307"},
65 | // A character that decomposes into multiple segments
66 | // spans several iterations.
67 | {"\u3304", "\u30A4\u30CB\u30F3\u30AF\u3099"},
68 | }
69 |
70 | func ExampleIter() {
71 | for i, t := range compareTests {
72 | r0 := EqualSimple(t.a, t.b)
73 | r1 := EqualOpt(t.a, t.b)
74 | fmt.Printf("%d: %v %v\n", i, r0, r1)
75 | }
76 | // Output:
77 | // 0: true true
78 | // 1: false false
79 | // 2: true true
80 | // 3: true true
81 | // 4: true true
82 | // 5: true true
83 | }
84 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 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 norm_test
6 |
7 | import (
8 | "fmt"
9 |
10 | "golang.org/x/text/unicode/norm"
11 | )
12 |
13 | func ExampleForm_NextBoundary() {
14 | s := norm.NFD.String("Mêlée")
15 |
16 | for i := 0; i < len(s); {
17 | d := norm.NFC.NextBoundaryInString(s[i:], true)
18 | fmt.Printf("%[1]s: %+[1]q\n", s[i:i+d])
19 | i += d
20 | }
21 | // Output:
22 | // M: "M"
23 | // ê: "e\u0302"
24 | // l: "l"
25 | // é: "e\u0301"
26 | // e: "e"
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/forminfo_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 | // +build test
6 |
7 | package norm
8 |
9 | import "testing"
10 |
11 | func TestProperties(t *testing.T) {
12 | var d runeData
13 | CK := [2]string{"C", "K"}
14 | for k, r := 1, rune(0); r < 0x2ffff; r++ {
15 | if k < len(testData) && r == testData[k].r {
16 | d = testData[k]
17 | k++
18 | }
19 | s := string(r)
20 | for j, p := range []Properties{NFC.PropertiesString(s), NFKC.PropertiesString(s)} {
21 | f := d.f[j]
22 | if p.CCC() != d.ccc {
23 | t.Errorf("%U: ccc(%s): was %d; want %d %X", r, CK[j], p.CCC(), d.ccc, p.index)
24 | }
25 | if p.isYesC() != (f.qc == Yes) {
26 | t.Errorf("%U: YesC(%s): was %v; want %v", r, CK[j], p.isYesC(), f.qc == Yes)
27 | }
28 | if p.combinesBackward() != (f.qc == Maybe) {
29 | t.Errorf("%U: combines backwards(%s): was %v; want %v", r, CK[j], p.combinesBackward(), f.qc == Maybe)
30 | }
31 | if p.nLeadingNonStarters() != d.nLead {
32 | t.Errorf("%U: nLead(%s): was %d; want %d %#v %#v", r, CK[j], p.nLeadingNonStarters(), d.nLead, p, d)
33 | }
34 | if p.nTrailingNonStarters() != d.nTrail {
35 | t.Errorf("%U: nTrail(%s): was %d; want %d %#v %#v", r, CK[j], p.nTrailingNonStarters(), d.nTrail, p, d)
36 | }
37 | if p.combinesForward() != f.combinesForward {
38 | t.Errorf("%U: combines forward(%s): was %v; want %v %#v", r, CK[j], p.combinesForward(), f.combinesForward, p)
39 | }
40 | // Skip Hangul as it is algorithmically computed.
41 | if r >= hangulBase && r < hangulEnd {
42 | continue
43 | }
44 | if p.hasDecomposition() {
45 | if has := f.decomposition != ""; !has {
46 | t.Errorf("%U: hasDecomposition(%s): was %v; want %v", r, CK[j], p.hasDecomposition(), has)
47 | }
48 | if string(p.Decomposition()) != f.decomposition {
49 | t.Errorf("%U: decomp(%s): was %+q; want %+q", r, CK[j], p.Decomposition(), f.decomposition)
50 | }
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/input.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import "unicode/utf8"
8 |
9 | type input struct {
10 | str string
11 | bytes []byte
12 | }
13 |
14 | func inputBytes(str []byte) input {
15 | return input{bytes: str}
16 | }
17 |
18 | func inputString(str string) input {
19 | return input{str: str}
20 | }
21 |
22 | func (in *input) setBytes(str []byte) {
23 | in.str = ""
24 | in.bytes = str
25 | }
26 |
27 | func (in *input) setString(str string) {
28 | in.str = str
29 | in.bytes = nil
30 | }
31 |
32 | func (in *input) _byte(p int) byte {
33 | if in.bytes == nil {
34 | return in.str[p]
35 | }
36 | return in.bytes[p]
37 | }
38 |
39 | func (in *input) skipASCII(p, max int) int {
40 | if in.bytes == nil {
41 | for ; p < max && in.str[p] < utf8.RuneSelf; p++ {
42 | }
43 | } else {
44 | for ; p < max && in.bytes[p] < utf8.RuneSelf; p++ {
45 | }
46 | }
47 | return p
48 | }
49 |
50 | func (in *input) skipContinuationBytes(p int) int {
51 | if in.bytes == nil {
52 | for ; p < len(in.str) && !utf8.RuneStart(in.str[p]); p++ {
53 | }
54 | } else {
55 | for ; p < len(in.bytes) && !utf8.RuneStart(in.bytes[p]); p++ {
56 | }
57 | }
58 | return p
59 | }
60 |
61 | func (in *input) appendSlice(buf []byte, b, e int) []byte {
62 | if in.bytes != nil {
63 | return append(buf, in.bytes[b:e]...)
64 | }
65 | for i := b; i < e; i++ {
66 | buf = append(buf, in.str[i])
67 | }
68 | return buf
69 | }
70 |
71 | func (in *input) copySlice(buf []byte, b, e int) int {
72 | if in.bytes == nil {
73 | return copy(buf, in.str[b:e])
74 | }
75 | return copy(buf, in.bytes[b:e])
76 | }
77 |
78 | func (in *input) charinfoNFC(p int) (uint16, int) {
79 | if in.bytes == nil {
80 | return nfcData.lookupString(in.str[p:])
81 | }
82 | return nfcData.lookup(in.bytes[p:])
83 | }
84 |
85 | func (in *input) charinfoNFKC(p int) (uint16, int) {
86 | if in.bytes == nil {
87 | return nfkcData.lookupString(in.str[p:])
88 | }
89 | return nfkcData.lookup(in.bytes[p:])
90 | }
91 |
92 | func (in *input) hangul(p int) (r rune) {
93 | var size int
94 | if in.bytes == nil {
95 | if !isHangulString(in.str[p:]) {
96 | return 0
97 | }
98 | r, size = utf8.DecodeRuneInString(in.str[p:])
99 | } else {
100 | if !isHangul(in.bytes[p:]) {
101 | return 0
102 | }
103 | r, size = utf8.DecodeRune(in.bytes[p:])
104 | }
105 | if size != hangulUTF8Size {
106 | return 0
107 | }
108 | return r
109 | }
110 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/iter_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import (
8 | "strings"
9 | "testing"
10 | )
11 |
12 | func doIterNormString(f Form, s string) []byte {
13 | acc := []byte{}
14 | i := Iter{}
15 | i.InitString(f, s)
16 | for !i.Done() {
17 | acc = append(acc, i.Next()...)
18 | }
19 | return acc
20 | }
21 |
22 | func doIterNorm(f Form, s string) []byte {
23 | acc := []byte{}
24 | i := Iter{}
25 | i.Init(f, []byte(s))
26 | for !i.Done() {
27 | acc = append(acc, i.Next()...)
28 | }
29 | return acc
30 | }
31 |
32 | func TestIterNext(t *testing.T) {
33 | runNormTests(t, "IterNext", func(f Form, out []byte, s string) []byte {
34 | return doIterNormString(f, string(append(out, s...)))
35 | })
36 | runNormTests(t, "IterNext", func(f Form, out []byte, s string) []byte {
37 | return doIterNorm(f, string(append(out, s...)))
38 | })
39 | }
40 |
41 | type SegmentTest struct {
42 | in string
43 | out []string
44 | }
45 |
46 | var segmentTests = []SegmentTest{
47 | {"\u1E0A\u0323a", []string{"\x44\u0323\u0307", "a", ""}},
48 | {rep('a', segSize), append(strings.Split(rep('a', segSize), ""), "")},
49 | {rep('a', segSize+2), append(strings.Split(rep('a', segSize+2), ""), "")},
50 | {rep('a', segSize) + "\u0300aa",
51 | append(strings.Split(rep('a', segSize-1), ""), "a\u0300", "a", "a", "")},
52 |
53 | // U+0f73 is NOT treated as a starter as it is a modifier
54 | {"a" + grave(29) + "\u0f73", []string{"a" + grave(29), cgj + "\u0f73"}},
55 | {"a\u0f73", []string{"a\u0f73"}},
56 |
57 | // U+ff9e is treated as a non-starter.
58 | // TODO: should we? Note that this will only affect iteration, as whether
59 | // or not we do so does not affect the normalization output and will either
60 | // way result in consistent iteration output.
61 | {"a" + grave(30) + "\uff9e", []string{"a" + grave(30), cgj + "\uff9e"}},
62 | {"a\uff9e", []string{"a\uff9e"}},
63 | }
64 |
65 | var segmentTestsK = []SegmentTest{
66 | {"\u3332", []string{"\u30D5", "\u30A1", "\u30E9", "\u30C3", "\u30C8\u3099", ""}},
67 | // last segment of multi-segment decomposition needs normalization
68 | {"\u3332\u093C", []string{"\u30D5", "\u30A1", "\u30E9", "\u30C3", "\u30C8\u093C\u3099", ""}},
69 | {"\u320E", []string{"\x28", "\uAC00", "\x29"}},
70 |
71 | // last segment should be copied to start of buffer.
72 | {"\ufdfa", []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645", ""}},
73 | {"\ufdfa" + grave(30), []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645" + grave(30), ""}},
74 | {"\uFDFA" + grave(64), []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645" + grave(30), cgj + grave(30), cgj + grave(4), ""}},
75 |
76 | // Hangul and Jamo are grouped together.
77 | {"\uAC00", []string{"\u1100\u1161", ""}},
78 | {"\uAC01", []string{"\u1100\u1161\u11A8", ""}},
79 | {"\u1100\u1161", []string{"\u1100\u1161", ""}},
80 | }
81 |
82 | // Note that, by design, segmentation is equal for composing and decomposing forms.
83 | func TestIterSegmentation(t *testing.T) {
84 | segmentTest(t, "SegmentTestD", NFD, segmentTests)
85 | segmentTest(t, "SegmentTestC", NFC, segmentTests)
86 | segmentTest(t, "SegmentTestKD", NFKD, segmentTestsK)
87 | segmentTest(t, "SegmentTestKC", NFKC, segmentTestsK)
88 | }
89 |
90 | func segmentTest(t *testing.T, name string, f Form, tests []SegmentTest) {
91 | iter := Iter{}
92 | for i, tt := range tests {
93 | iter.InitString(f, tt.in)
94 | for j, seg := range tt.out {
95 | if seg == "" {
96 | if !iter.Done() {
97 | res := string(iter.Next())
98 | t.Errorf(`%s:%d:%d: expected Done()==true, found segment %+q`, name, i, j, res)
99 | }
100 | continue
101 | }
102 | if iter.Done() {
103 | t.Errorf("%s:%d:%d: Done()==true, want false", name, i, j)
104 | }
105 | seg = f.String(seg)
106 | if res := string(iter.Next()); res != seg {
107 | t.Errorf(`%s:%d:%d" segment was %+q (%d); want %+q (%d)`, name, i, j, pc(res), len(res), pc(seg), len(seg))
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/readwriter.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import "io"
8 |
9 | type normWriter struct {
10 | rb reorderBuffer
11 | w io.Writer
12 | buf []byte
13 | }
14 |
15 | // Write implements the standard write interface. If the last characters are
16 | // not at a normalization boundary, the bytes will be buffered for the next
17 | // write. The remaining bytes will be written on close.
18 | func (w *normWriter) Write(data []byte) (n int, err error) {
19 | // Process data in pieces to keep w.buf size bounded.
20 | const chunk = 4000
21 |
22 | for len(data) > 0 {
23 | // Normalize into w.buf.
24 | m := len(data)
25 | if m > chunk {
26 | m = chunk
27 | }
28 | w.rb.src = inputBytes(data[:m])
29 | w.rb.nsrc = m
30 | w.buf = doAppend(&w.rb, w.buf, 0)
31 | data = data[m:]
32 | n += m
33 |
34 | // Write out complete prefix, save remainder.
35 | // Note that lastBoundary looks back at most 31 runes.
36 | i := lastBoundary(&w.rb.f, w.buf)
37 | if i == -1 {
38 | i = 0
39 | }
40 | if i > 0 {
41 | if _, err = w.w.Write(w.buf[:i]); err != nil {
42 | break
43 | }
44 | bn := copy(w.buf, w.buf[i:])
45 | w.buf = w.buf[:bn]
46 | }
47 | }
48 | return n, err
49 | }
50 |
51 | // Close forces data that remains in the buffer to be written.
52 | func (w *normWriter) Close() error {
53 | if len(w.buf) > 0 {
54 | _, err := w.w.Write(w.buf)
55 | if err != nil {
56 | return err
57 | }
58 | }
59 | return nil
60 | }
61 |
62 | // Writer returns a new writer that implements Write(b)
63 | // by writing f(b) to w. The returned writer may use an
64 | // internal buffer to maintain state across Write calls.
65 | // Calling its Close method writes any buffered data to w.
66 | func (f Form) Writer(w io.Writer) io.WriteCloser {
67 | wr := &normWriter{rb: reorderBuffer{}, w: w}
68 | wr.rb.init(f, nil)
69 | return wr
70 | }
71 |
72 | type normReader struct {
73 | rb reorderBuffer
74 | r io.Reader
75 | inbuf []byte
76 | outbuf []byte
77 | bufStart int
78 | lastBoundary int
79 | err error
80 | }
81 |
82 | // Read implements the standard read interface.
83 | func (r *normReader) Read(p []byte) (int, error) {
84 | for {
85 | if r.lastBoundary-r.bufStart > 0 {
86 | n := copy(p, r.outbuf[r.bufStart:r.lastBoundary])
87 | r.bufStart += n
88 | if r.lastBoundary-r.bufStart > 0 {
89 | return n, nil
90 | }
91 | return n, r.err
92 | }
93 | if r.err != nil {
94 | return 0, r.err
95 | }
96 | outn := copy(r.outbuf, r.outbuf[r.lastBoundary:])
97 | r.outbuf = r.outbuf[0:outn]
98 | r.bufStart = 0
99 |
100 | n, err := r.r.Read(r.inbuf)
101 | r.rb.src = inputBytes(r.inbuf[0:n])
102 | r.rb.nsrc, r.err = n, err
103 | if n > 0 {
104 | r.outbuf = doAppend(&r.rb, r.outbuf, 0)
105 | }
106 | if err == io.EOF {
107 | r.lastBoundary = len(r.outbuf)
108 | } else {
109 | r.lastBoundary = lastBoundary(&r.rb.f, r.outbuf)
110 | if r.lastBoundary == -1 {
111 | r.lastBoundary = 0
112 | }
113 | }
114 | }
115 | }
116 |
117 | // Reader returns a new reader that implements Read
118 | // by reading data from r and returning f(data).
119 | func (f Form) Reader(r io.Reader) io.Reader {
120 | const chunk = 4000
121 | buf := make([]byte, chunk)
122 | rr := &normReader{rb: reorderBuffer{}, r: r, inbuf: buf}
123 | rr.rb.init(f, buf)
124 | return rr
125 | }
126 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/readwriter_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import (
8 | "bytes"
9 | "fmt"
10 | "testing"
11 | )
12 |
13 | var bufSizes = []int{1, 2, 3, 4, 5, 6, 7, 8, 100, 101, 102, 103, 4000, 4001, 4002, 4003}
14 |
15 | func readFunc(size int) appendFunc {
16 | return func(f Form, out []byte, s string) []byte {
17 | out = append(out, s...)
18 | r := f.Reader(bytes.NewBuffer(out))
19 | buf := make([]byte, size)
20 | result := []byte{}
21 | for n, err := 0, error(nil); err == nil; {
22 | n, err = r.Read(buf)
23 | result = append(result, buf[:n]...)
24 | }
25 | return result
26 | }
27 | }
28 |
29 | func TestReader(t *testing.T) {
30 | for _, s := range bufSizes {
31 | name := fmt.Sprintf("TestReader%d", s)
32 | runNormTests(t, name, readFunc(s))
33 | }
34 | }
35 |
36 | func writeFunc(size int) appendFunc {
37 | return func(f Form, out []byte, s string) []byte {
38 | in := append(out, s...)
39 | result := new(bytes.Buffer)
40 | w := f.Writer(result)
41 | buf := make([]byte, size)
42 | for n := 0; len(in) > 0; in = in[n:] {
43 | n = copy(buf, in)
44 | _, _ = w.Write(buf[:n])
45 | }
46 | w.Close()
47 | return result.Bytes()
48 | }
49 | }
50 |
51 | func TestWriter(t *testing.T) {
52 | for _, s := range bufSizes {
53 | name := fmt.Sprintf("TestWriter%d", s)
54 | runNormTests(t, name, writeFunc(s))
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/transform.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 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 norm
6 |
7 | import (
8 | "unicode/utf8"
9 |
10 | "golang.org/x/text/transform"
11 | )
12 |
13 | // Reset implements the Reset method of the transform.Transformer interface.
14 | func (Form) Reset() {}
15 |
16 | // Transform implements the Transform method of the transform.Transformer
17 | // interface. It may need to write segments of up to MaxSegmentSize at once.
18 | // Users should either catch ErrShortDst and allow dst to grow or have dst be at
19 | // least of size MaxTransformChunkSize to be guaranteed of progress.
20 | func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
21 | // Cap the maximum number of src bytes to check.
22 | b := src
23 | eof := atEOF
24 | if ns := len(dst); ns < len(b) {
25 | err = transform.ErrShortDst
26 | eof = false
27 | b = b[:ns]
28 | }
29 | i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof)
30 | n := copy(dst, b[:i])
31 | if !ok {
32 | nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF)
33 | return nDst + n, nSrc + n, err
34 | }
35 |
36 | if err == nil && n < len(src) && !atEOF {
37 | err = transform.ErrShortSrc
38 | }
39 | return n, n, err
40 | }
41 |
42 | func flushTransform(rb *reorderBuffer) bool {
43 | // Write out (must fully fit in dst, or else it is an ErrShortDst).
44 | if len(rb.out) < rb.nrune*utf8.UTFMax {
45 | return false
46 | }
47 | rb.out = rb.out[rb.flushCopy(rb.out):]
48 | return true
49 | }
50 |
51 | var errs = []error{nil, transform.ErrShortDst, transform.ErrShortSrc}
52 |
53 | // transform implements the transform.Transformer interface. It is only called
54 | // when quickSpan does not pass for a given string.
55 | func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
56 | // TODO: get rid of reorderBuffer. See CL 23460044.
57 | rb := reorderBuffer{}
58 | rb.init(f, src)
59 | for {
60 | // Load segment into reorder buffer.
61 | rb.setFlusher(dst[nDst:], flushTransform)
62 | end := decomposeSegment(&rb, nSrc, atEOF)
63 | if end < 0 {
64 | return nDst, nSrc, errs[-end]
65 | }
66 | nDst = len(dst) - len(rb.out)
67 | nSrc = end
68 |
69 | // Next quickSpan.
70 | end = rb.nsrc
71 | eof := atEOF
72 | if n := nSrc + len(dst) - nDst; n < end {
73 | err = transform.ErrShortDst
74 | end = n
75 | eof = false
76 | }
77 | end, ok := rb.f.quickSpan(rb.src, nSrc, end, eof)
78 | n := copy(dst[nDst:], rb.src.bytes[nSrc:end])
79 | nSrc += n
80 | nDst += n
81 | if ok {
82 | if err == nil && n < rb.nsrc && !atEOF {
83 | err = transform.ErrShortSrc
84 | }
85 | return nDst, nSrc, err
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/transform_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | import (
8 | "fmt"
9 | "testing"
10 |
11 | "golang.org/x/text/transform"
12 | )
13 |
14 | func TestTransform(t *testing.T) {
15 | tests := []struct {
16 | f Form
17 | in, out string
18 | eof bool
19 | dstSize int
20 | err error
21 | }{
22 | {NFC, "ab", "ab", true, 2, nil},
23 | {NFC, "qx", "qx", true, 2, nil},
24 | {NFD, "qx", "qx", true, 2, nil},
25 | {NFC, "", "", true, 1, nil},
26 | {NFD, "", "", true, 1, nil},
27 | {NFC, "", "", false, 1, nil},
28 | {NFD, "", "", false, 1, nil},
29 |
30 | // Normalized segment does not fit in destination.
31 | {NFD, "ö", "", true, 1, transform.ErrShortDst},
32 | {NFD, "ö", "", true, 2, transform.ErrShortDst},
33 |
34 | // As an artifact of the algorithm, only full segments are written.
35 | // This is not strictly required, and some bytes could be written.
36 | // In practice, for Transform to not block, the destination buffer
37 | // should be at least MaxSegmentSize to work anyway and these edge
38 | // conditions will be relatively rare.
39 | {NFC, "ab", "", true, 1, transform.ErrShortDst},
40 | // This is even true for inert runes.
41 | {NFC, "qx", "", true, 1, transform.ErrShortDst},
42 | {NFC, "a\u0300abc", "\u00e0a", true, 4, transform.ErrShortDst},
43 |
44 | // We cannot write a segment if successive runes could still change the result.
45 | {NFD, "ö", "", false, 3, transform.ErrShortSrc},
46 | {NFC, "a\u0300", "", false, 4, transform.ErrShortSrc},
47 | {NFD, "a\u0300", "", false, 4, transform.ErrShortSrc},
48 | {NFC, "ö", "", false, 3, transform.ErrShortSrc},
49 |
50 | {NFD, "abc", "", false, 1, transform.ErrShortDst},
51 | {NFC, "abc", "", false, 1, transform.ErrShortDst},
52 | {NFC, "abc", "a", false, 2, transform.ErrShortDst},
53 | {NFD, "éfff", "", false, 2, transform.ErrShortDst},
54 | {NFC, "e\u0301fffff", "\u00e9fff", false, 6, transform.ErrShortDst},
55 | {NFD, "ééééé", "e\u0301e\u0301e\u0301", false, 15, transform.ErrShortDst},
56 |
57 | {NFC, "a\u0300", "", true, 1, transform.ErrShortDst},
58 | // Theoretically could fit, but won't due to simplified checks.
59 | {NFC, "a\u0300", "", true, 2, transform.ErrShortDst},
60 | {NFC, "a\u0300", "", true, 3, transform.ErrShortDst},
61 | {NFC, "a\u0300", "\u00e0", true, 4, nil},
62 |
63 | {NFD, "öa\u0300", "o\u0308", false, 8, transform.ErrShortSrc},
64 | {NFD, "öa\u0300ö", "o\u0308a\u0300", true, 8, transform.ErrShortDst},
65 | {NFD, "öa\u0300ö", "o\u0308a\u0300", false, 12, transform.ErrShortSrc},
66 |
67 | // Illegal input is copied verbatim.
68 | {NFD, "\xbd\xb2=\xbc ", "\xbd\xb2=\xbc ", true, 8, nil},
69 | }
70 | b := make([]byte, 100)
71 | for i, tt := range tests {
72 | t.Run(fmt.Sprintf("%d:%s", i, tt.in), func(t *testing.T) {
73 | nDst, _, err := tt.f.Transform(b[:tt.dstSize], []byte(tt.in), tt.eof)
74 | out := string(b[:nDst])
75 | if out != tt.out || err != tt.err {
76 | t.Errorf("was %+q (%v); want %+q (%v)", out, err, tt.out, tt.err)
77 | }
78 | if want := tt.f.String(tt.in)[:nDst]; want != out {
79 | t.Errorf("incorrect normalization: was %+q; want %+q", out, want)
80 | }
81 | })
82 | }
83 | }
84 |
85 | var transBufSizes = []int{
86 | MaxTransformChunkSize,
87 | 3 * MaxTransformChunkSize / 2,
88 | 2 * MaxTransformChunkSize,
89 | 3 * MaxTransformChunkSize,
90 | 100 * MaxTransformChunkSize,
91 | }
92 |
93 | func doTransNorm(f Form, buf []byte, b []byte) []byte {
94 | acc := []byte{}
95 | for p := 0; p < len(b); {
96 | nd, ns, _ := f.Transform(buf[:], b[p:], true)
97 | p += ns
98 | acc = append(acc, buf[:nd]...)
99 | }
100 | return acc
101 | }
102 |
103 | func TestTransformNorm(t *testing.T) {
104 | for _, sz := range transBufSizes {
105 | buf := make([]byte, sz)
106 | runNormTests(t, fmt.Sprintf("Transform:%d", sz), func(f Form, out []byte, s string) []byte {
107 | return doTransNorm(f, buf, append(out, s...))
108 | })
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/trie.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 norm
6 |
7 | type valueRange struct {
8 | value uint16 // header: value:stride
9 | lo, hi byte // header: lo:n
10 | }
11 |
12 | type sparseBlocks struct {
13 | values []valueRange
14 | offset []uint16
15 | }
16 |
17 | var nfcSparse = sparseBlocks{
18 | values: nfcSparseValues[:],
19 | offset: nfcSparseOffset[:],
20 | }
21 |
22 | var nfkcSparse = sparseBlocks{
23 | values: nfkcSparseValues[:],
24 | offset: nfkcSparseOffset[:],
25 | }
26 |
27 | var (
28 | nfcData = newNfcTrie(0)
29 | nfkcData = newNfkcTrie(0)
30 | )
31 |
32 | // lookupValue determines the type of block n and looks up the value for b.
33 | // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
34 | // is a list of ranges with an accompanying value. Given a matching range r,
35 | // the value for b is by r.value + (b - r.lo) * stride.
36 | func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
37 | offset := t.offset[n]
38 | header := t.values[offset]
39 | lo := offset + 1
40 | hi := lo + uint16(header.lo)
41 | for lo < hi {
42 | m := lo + (hi-lo)/2
43 | r := t.values[m]
44 | if r.lo <= b && b <= r.hi {
45 | return r.value + uint16(b-r.lo)*header.value
46 | }
47 | if b < r.lo {
48 | hi = m
49 | } else {
50 | lo = m + 1
51 | }
52 | }
53 | return 0
54 | }
55 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/norm/triegen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 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 | // +build ignore
6 |
7 | // Trie table generator.
8 | // Used by make*tables tools to generate a go file with trie data structures
9 | // for mapping UTF-8 to a 16-bit value. All but the last byte in a UTF-8 byte
10 | // sequence are used to lookup offsets in the index table to be used for the
11 | // next byte. The last byte is used to index into a table with 16-bit values.
12 |
13 | package norm
14 |
15 | import (
16 | "fmt"
17 | "io"
18 | )
19 |
20 | const maxSparseEntries = 16
21 |
22 | type normCompacter struct {
23 | sparseBlocks [][]uint64
24 | sparseOffset []uint16
25 | sparseCount int
26 | name string
27 | }
28 |
29 | func mostFrequentStride(a []uint64) int {
30 | counts := make(map[int]int)
31 | var v int
32 | for _, x := range a {
33 | if stride := int(x) - v; v != 0 && stride >= 0 {
34 | counts[stride]++
35 | }
36 | v = int(x)
37 | }
38 | var maxs, maxc int
39 | for stride, cnt := range counts {
40 | if cnt > maxc || (cnt == maxc && stride < maxs) {
41 | maxs, maxc = stride, cnt
42 | }
43 | }
44 | return maxs
45 | }
46 |
47 | func countSparseEntries(a []uint64) int {
48 | stride := mostFrequentStride(a)
49 | var v, count int
50 | for _, tv := range a {
51 | if int(tv)-v != stride {
52 | if tv != 0 {
53 | count++
54 | }
55 | }
56 | v = int(tv)
57 | }
58 | return count
59 | }
60 |
61 | func (c *normCompacter) Size(v []uint64) (sz int, ok bool) {
62 | if n := countSparseEntries(v); n <= maxSparseEntries {
63 | return (n+1)*4 + 2, true
64 | }
65 | return 0, false
66 | }
67 |
68 | func (c *normCompacter) Store(v []uint64) uint32 {
69 | h := uint32(len(c.sparseOffset))
70 | c.sparseBlocks = append(c.sparseBlocks, v)
71 | c.sparseOffset = append(c.sparseOffset, uint16(c.sparseCount))
72 | c.sparseCount += countSparseEntries(v) + 1
73 | return h
74 | }
75 |
76 | func (c *normCompacter) Handler() string {
77 | return c.name + "Sparse.lookup"
78 | }
79 |
80 | func (c *normCompacter) Print(w io.Writer) (retErr error) {
81 | p := func(f string, x ...interface{}) {
82 | if _, err := fmt.Fprintf(w, f, x...); retErr == nil && err != nil {
83 | retErr = err
84 | }
85 | }
86 |
87 | ls := len(c.sparseBlocks)
88 | p("// %sSparseOffset: %d entries, %d bytes\n", c.name, ls, ls*2)
89 | p("var %sSparseOffset = %#v\n\n", c.name, c.sparseOffset)
90 |
91 | ns := c.sparseCount
92 | p("// %sSparseValues: %d entries, %d bytes\n", c.name, ns, ns*4)
93 | p("var %sSparseValues = [%d]valueRange {", c.name, ns)
94 | for i, b := range c.sparseBlocks {
95 | p("\n// Block %#x, offset %#x", i, c.sparseOffset[i])
96 | var v int
97 | stride := mostFrequentStride(b)
98 | n := countSparseEntries(b)
99 | p("\n{value:%#04x,lo:%#02x},", stride, uint8(n))
100 | for i, nv := range b {
101 | if int(nv)-v != stride {
102 | if v != 0 {
103 | p(",hi:%#02x},", 0x80+i-1)
104 | }
105 | if nv != 0 {
106 | p("\n{value:%#04x,lo:%#02x", nv, 0x80+i)
107 | }
108 | }
109 | v = int(nv)
110 | }
111 | if v != 0 {
112 | p(",hi:%#02x},", 0x80+len(b)-1)
113 | }
114 | }
115 | p("\n}\n\n")
116 | return
117 | }
118 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/rangetable/gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | package rangetable
8 |
9 | import (
10 | "bytes"
11 | "flag"
12 | "fmt"
13 | "io"
14 | "log"
15 | "reflect"
16 | "strings"
17 | "unicode"
18 |
19 | "golang.org/x/text/collate"
20 | "golang.org/x/text/internal/gen"
21 | "golang.org/x/text/internal/ucd"
22 | "golang.org/x/text/language"
23 | "golang.org/x/text/unicode/rangetable"
24 | )
25 |
26 | var versionList = flag.String("versions", "",
27 | "list of versions for which to generate RangeTables")
28 |
29 | const bootstrapMessage = `No versions specified.
30 | To bootstrap the code generation, run:
31 | go run gen.go --versions=4.1.0,5.0.0,6.0.0,6.1.0,6.2.0,6.3.0,7.0.0
32 |
33 | and ensure that the latest versions are included by checking:
34 | https://www.unicode.org/Public/`
35 |
36 | func getVersions() []string {
37 | if *versionList == "" {
38 | log.Fatal(bootstrapMessage)
39 | }
40 |
41 | c := collate.New(language.Und, collate.Numeric)
42 | versions := strings.Split(*versionList, ",")
43 | c.SortStrings(versions)
44 |
45 | // Ensure that at least the current version is included.
46 | for _, v := range versions {
47 | if v == gen.UnicodeVersion() {
48 | return versions
49 | }
50 | }
51 |
52 | versions = append(versions, gen.UnicodeVersion())
53 | c.SortStrings(versions)
54 | return versions
55 | }
56 |
57 | func main() {
58 | gen.Init()
59 |
60 | versions := getVersions()
61 |
62 | w := &bytes.Buffer{}
63 |
64 | fmt.Fprintf(w, "//go:generate go run gen.go --versions=%s\n\n", strings.Join(versions, ","))
65 | fmt.Fprintf(w, "import \"unicode\"\n\n")
66 |
67 | vstr := func(s string) string { return strings.Replace(s, ".", "_", -1) }
68 |
69 | fmt.Fprintf(w, "var assigned = map[string]*unicode.RangeTable{\n")
70 | for _, v := range versions {
71 | fmt.Fprintf(w, "\t%q: assigned%s,\n", v, vstr(v))
72 | }
73 | fmt.Fprintf(w, "}\n\n")
74 |
75 | var size int
76 | for _, v := range versions {
77 | assigned := []rune{}
78 |
79 | r := gen.Open("https://www.unicode.org/Public/", "", v+"/ucd/UnicodeData.txt")
80 | ucd.Parse(r, func(p *ucd.Parser) {
81 | assigned = append(assigned, p.Rune(0))
82 | })
83 |
84 | rt := rangetable.New(assigned...)
85 | sz := int(reflect.TypeOf(unicode.RangeTable{}).Size())
86 | sz += int(reflect.TypeOf(unicode.Range16{}).Size()) * len(rt.R16)
87 | sz += int(reflect.TypeOf(unicode.Range32{}).Size()) * len(rt.R32)
88 |
89 | fmt.Fprintf(w, "// size %d bytes (%d KiB)\n", sz, sz/1024)
90 | fmt.Fprintf(w, "var assigned%s = ", vstr(v))
91 | print(w, rt)
92 |
93 | size += sz
94 | }
95 |
96 | fmt.Fprintf(w, "// Total size %d bytes (%d KiB)\n", size, size/1024)
97 |
98 | gen.WriteVersionedGoFile("tables.go", "rangetable", w.Bytes())
99 | }
100 |
101 | func print(w io.Writer, rt *unicode.RangeTable) {
102 | fmt.Fprintln(w, "&unicode.RangeTable{")
103 | fmt.Fprintln(w, "\tR16: []unicode.Range16{")
104 | for _, r := range rt.R16 {
105 | fmt.Fprintf(w, "\t\t{%#04x, %#04x, %d},\n", r.Lo, r.Hi, r.Stride)
106 | }
107 | fmt.Fprintln(w, "\t},")
108 | fmt.Fprintln(w, "\tR32: []unicode.Range32{")
109 | for _, r := range rt.R32 {
110 | fmt.Fprintf(w, "\t\t{%#08x, %#08x, %d},\n", r.Lo, r.Hi, r.Stride)
111 | }
112 | fmt.Fprintln(w, "\t},")
113 | fmt.Fprintf(w, "\tLatinOffset: %d,\n", rt.LatinOffset)
114 | fmt.Fprintf(w, "}\n\n")
115 | }
116 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/rangetable/rangetable.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 rangetable provides utilities for creating and inspecting
6 | // unicode.RangeTables.
7 | package rangetable
8 |
9 | import (
10 | "sort"
11 | "unicode"
12 | )
13 |
14 | // New creates a RangeTable from the given runes, which may contain duplicates.
15 | func New(r ...rune) *unicode.RangeTable {
16 | if len(r) == 0 {
17 | return &unicode.RangeTable{}
18 | }
19 |
20 | sort.Sort(byRune(r))
21 |
22 | // Remove duplicates.
23 | k := 1
24 | for i := 1; i < len(r); i++ {
25 | if r[k-1] != r[i] {
26 | r[k] = r[i]
27 | k++
28 | }
29 | }
30 |
31 | var rt unicode.RangeTable
32 | for _, r := range r[:k] {
33 | if r <= 0xFFFF {
34 | rt.R16 = append(rt.R16, unicode.Range16{Lo: uint16(r), Hi: uint16(r), Stride: 1})
35 | } else {
36 | rt.R32 = append(rt.R32, unicode.Range32{Lo: uint32(r), Hi: uint32(r), Stride: 1})
37 | }
38 | }
39 |
40 | // Optimize RangeTable.
41 | return Merge(&rt)
42 | }
43 |
44 | type byRune []rune
45 |
46 | func (r byRune) Len() int { return len(r) }
47 | func (r byRune) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
48 | func (r byRune) Less(i, j int) bool { return r[i] < r[j] }
49 |
50 | // Visit visits all runes in the given RangeTable in order, calling fn for each.
51 | func Visit(rt *unicode.RangeTable, fn func(rune)) {
52 | for _, r16 := range rt.R16 {
53 | for r := rune(r16.Lo); r <= rune(r16.Hi); r += rune(r16.Stride) {
54 | fn(r)
55 | }
56 | }
57 | for _, r32 := range rt.R32 {
58 | for r := rune(r32.Lo); r <= rune(r32.Hi); r += rune(r32.Stride) {
59 | fn(r)
60 | }
61 | }
62 | }
63 |
64 | // Assigned returns a RangeTable with all assigned code points for a given
65 | // Unicode version. This includes graphic, format, control, and private-use
66 | // characters. It returns nil if the data for the given version is not
67 | // available.
68 | func Assigned(version string) *unicode.RangeTable {
69 | return assigned[version]
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/unicode/rangetable/rangetable_test.go:
--------------------------------------------------------------------------------
1 | package rangetable
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 | "unicode"
7 | )
8 |
9 | var (
10 | empty = &unicode.RangeTable{}
11 | many = &unicode.RangeTable{
12 | R16: []unicode.Range16{{0, 0xffff, 5}},
13 | R32: []unicode.Range32{{0x10004, 0x10009, 5}},
14 | LatinOffset: 0,
15 | }
16 | )
17 |
18 | func TestVisit(t *testing.T) {
19 | Visit(empty, func(got rune) {
20 | t.Error("call from empty RangeTable")
21 | })
22 |
23 | var want rune
24 | Visit(many, func(got rune) {
25 | if got != want {
26 | t.Errorf("got %U; want %U", got, want)
27 | }
28 | want += 5
29 | })
30 | if want -= 5; want != 0x10009 {
31 | t.Errorf("last run was %U; want U+10009", want)
32 | }
33 | }
34 |
35 | func TestNew(t *testing.T) {
36 | for i, rt := range []*unicode.RangeTable{
37 | empty,
38 | unicode.Co,
39 | unicode.Letter,
40 | unicode.ASCII_Hex_Digit,
41 | many,
42 | maxRuneTable,
43 | } {
44 | var got, want []rune
45 | Visit(rt, func(r rune) {
46 | want = append(want, r)
47 | })
48 | Visit(New(want...), func(r rune) {
49 | got = append(got, r)
50 | })
51 | if !reflect.DeepEqual(got, want) {
52 | t.Errorf("%d:\ngot %v;\nwant %v", i, got, want)
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/common_test.go:
--------------------------------------------------------------------------------
1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2 |
3 | package width
4 |
5 | // This code is shared between the main code generator and the test code.
6 |
7 | import (
8 | "flag"
9 | "log"
10 | "strconv"
11 | "strings"
12 |
13 | "golang.org/x/text/internal/gen"
14 | "golang.org/x/text/internal/ucd"
15 | )
16 |
17 | var (
18 | outputFile = flag.String("out", "tables.go", "output file")
19 | )
20 |
21 | var typeMap = map[string]elem{
22 | "A": tagAmbiguous,
23 | "N": tagNeutral,
24 | "Na": tagNarrow,
25 | "W": tagWide,
26 | "F": tagFullwidth,
27 | "H": tagHalfwidth,
28 | }
29 |
30 | // getWidthData calls f for every entry for which it is defined.
31 | //
32 | // f may be called multiple times for the same rune. The last call to f is the
33 | // correct value. f is not called for all runes. The default tag type is
34 | // Neutral.
35 | func getWidthData(f func(r rune, tag elem, alt rune)) {
36 | // Set the default values for Unified Ideographs. In line with Annex 11,
37 | // we encode full ranges instead of the defined runes in Unified_Ideograph.
38 | for _, b := range []struct{ lo, hi rune }{
39 | {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block,
40 | {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block,
41 | {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block,
42 | {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane,
43 | {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane,
44 | } {
45 | for r := b.lo; r <= b.hi; r++ {
46 | f(r, tagWide, 0)
47 | }
48 | }
49 |
50 | inverse := map[rune]rune{}
51 | maps := map[string]bool{
52 | "": true,
53 | "": true,
54 | }
55 |
56 | // We cannot reuse package norm's decomposition, as we need an unexpanded
57 | // decomposition. We make use of the opportunity to verify that the
58 | // decomposition type is as expected.
59 | ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) {
60 | r := p.Rune(0)
61 | s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2)
62 | if !maps[s[0]] {
63 | return
64 | }
65 | x, err := strconv.ParseUint(s[1], 16, 32)
66 | if err != nil {
67 | log.Fatalf("Error parsing rune %q", s[1])
68 | }
69 | if inverse[r] != 0 || inverse[rune(x)] != 0 {
70 | log.Fatalf("Circular dependency in mapping between %U and %U", r, x)
71 | }
72 | inverse[r] = rune(x)
73 | inverse[rune(x)] = r
74 | })
75 |
76 | // ;
77 | ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) {
78 | tag, ok := typeMap[p.String(1)]
79 | if !ok {
80 | log.Fatalf("Unknown width type %q", p.String(1))
81 | }
82 | r := p.Rune(0)
83 | alt, ok := inverse[r]
84 | if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign {
85 | tag |= tagNeedsFold
86 | if !ok {
87 | log.Fatalf("Narrow or wide rune %U has no decomposition", r)
88 | }
89 | }
90 | f(r, tag, alt)
91 | })
92 | }
93 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/example_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 width_test
6 |
7 | import (
8 | "fmt"
9 |
10 | "golang.org/x/text/width"
11 | )
12 |
13 | func ExampleTransformer_fold() {
14 | s := "abヲ₩○¥A"
15 | f := width.Fold.String(s)
16 | fmt.Printf("%U: %s\n", []rune(s), s)
17 | fmt.Printf("%U: %s\n", []rune(f), f)
18 |
19 | // Output:
20 | // [U+0061 U+0062 U+FF66 U+FFE6 U+FFEE U+FFE5 U+FF21]: abヲ₩○¥A
21 | // [U+0061 U+0062 U+30F2 U+20A9 U+25CB U+00A5 U+0041]: abヲ₩○¥A
22 | }
23 |
24 | func ExampleTransformer_widen() {
25 | s := "ab¥ヲ₩○"
26 | w := width.Widen.String(s)
27 | fmt.Printf("%U: %s\n", []rune(s), s)
28 | fmt.Printf("%U: %s\n", []rune(w), w)
29 |
30 | // Output:
31 | // [U+0061 U+0062 U+00A5 U+FF66 U+20A9 U+FFEE]: ab¥ヲ₩○
32 | // [U+FF41 U+FF42 U+FFE5 U+30F2 U+FFE6 U+25CB]: ab¥ヲ₩○
33 | }
34 |
35 | func ExampleTransformer_narrow() {
36 | s := "abヲ₩○¥A"
37 | n := width.Narrow.String(s)
38 | fmt.Printf("%U: %s\n", []rune(s), s)
39 | fmt.Printf("%U: %s\n", []rune(n), n)
40 |
41 | // Ambiguous characters with a halfwidth equivalent get mapped as well.
42 | s = "←"
43 | n = width.Narrow.String(s)
44 | fmt.Printf("%U: %s\n", []rune(s), s)
45 | fmt.Printf("%U: %s\n", []rune(n), n)
46 |
47 | // Output:
48 | // [U+0061 U+0062 U+30F2 U+FFE6 U+25CB U+FFE5 U+FF21]: abヲ₩○¥A
49 | // [U+0061 U+0062 U+FF66 U+20A9 U+FFEE U+00A5 U+0041]: abヲ₩○¥A
50 | // [U+2190]: ←
51 | // [U+FFE9]: ←
52 | }
53 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | // This program generates the trie for width operations. The generated table
8 | // includes width category information as well as the normalization mappings.
9 | package width
10 |
11 | import (
12 | "bytes"
13 | "fmt"
14 | "io"
15 | "log"
16 | "math"
17 | "unicode/utf8"
18 |
19 | "golang.org/x/text/internal/gen"
20 | "golang.org/x/text/internal/triegen"
21 | )
22 |
23 | // See gen_common.go for flags.
24 |
25 | func main() {
26 | gen.Init()
27 | genTables()
28 | genTests()
29 | gen.Repackage("gen_trieval.go", "trieval.go", "width")
30 | gen.Repackage("gen_common.go", "common_test.go", "width")
31 | }
32 |
33 | func genTables() {
34 | t := triegen.NewTrie("width")
35 | // fold and inverse mappings. See mapComment for a description of the format
36 | // of each entry. Add dummy value to make an index of 0 mean no mapping.
37 | inverse := [][4]byte{{}}
38 | mapping := map[[4]byte]int{[4]byte{}: 0}
39 |
40 | getWidthData(func(r rune, tag elem, alt rune) {
41 | idx := 0
42 | if alt != 0 {
43 | var buf [4]byte
44 | buf[0] = byte(utf8.EncodeRune(buf[1:], alt))
45 | s := string(r)
46 | buf[buf[0]] ^= s[len(s)-1]
47 | var ok bool
48 | if idx, ok = mapping[buf]; !ok {
49 | idx = len(mapping)
50 | if idx > math.MaxUint8 {
51 | log.Fatalf("Index %d does not fit in a byte.", idx)
52 | }
53 | mapping[buf] = idx
54 | inverse = append(inverse, buf)
55 | }
56 | }
57 | t.Insert(r, uint64(tag|elem(idx)))
58 | })
59 |
60 | w := &bytes.Buffer{}
61 | gen.WriteUnicodeVersion(w)
62 |
63 | sz, err := t.Gen(w)
64 | if err != nil {
65 | log.Fatal(err)
66 | }
67 |
68 | sz += writeMappings(w, inverse)
69 |
70 | fmt.Fprintf(w, "// Total table size %d bytes (%dKiB)\n", sz, sz/1024)
71 |
72 | gen.WriteVersionedGoFile(*outputFile, "width", w.Bytes())
73 | }
74 |
75 | const inverseDataComment = `
76 | // inverseData contains 4-byte entries of the following format:
77 | // <0 padding>
78 | // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the
79 | // UTF-8 encoding of the original rune. Mappings often have the following
80 | // pattern:
81 | // A -> A (U+FF21 -> U+0041)
82 | // B -> B (U+FF22 -> U+0042)
83 | // ...
84 | // By xor-ing the last byte the same entry can be shared by many mappings. This
85 | // reduces the total number of distinct entries by about two thirds.
86 | // The resulting entry for the aforementioned mappings is
87 | // { 0x01, 0xE0, 0x00, 0x00 }
88 | // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get
89 | // E0 ^ A1 = 41.
90 | // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get
91 | // E0 ^ A2 = 42.
92 | // Note that because of the xor-ing, the byte sequence stored in the entry is
93 | // not valid UTF-8.`
94 |
95 | func writeMappings(w io.Writer, data [][4]byte) int {
96 | fmt.Fprintln(w, inverseDataComment)
97 | fmt.Fprintf(w, "var inverseData = [%d][4]byte{\n", len(data))
98 | for _, x := range data {
99 | fmt.Fprintf(w, "{ 0x%02x, 0x%02x, 0x%02x, 0x%02x },\n", x[0], x[1], x[2], x[3])
100 | }
101 | fmt.Fprintln(w, "}")
102 | return len(data) * 4
103 | }
104 |
105 | func genTests() {
106 | w := &bytes.Buffer{}
107 | fmt.Fprintf(w, "\nvar mapRunes = map[rune]struct{r rune; e elem}{\n")
108 | getWidthData(func(r rune, tag elem, alt rune) {
109 | if alt != 0 {
110 | fmt.Fprintf(w, "\t0x%X: {0x%X, 0x%X},\n", r, alt, tag)
111 | }
112 | })
113 | fmt.Fprintln(w, "}")
114 | gen.WriteGoFile("runes_test.go", "width", w.Bytes())
115 | }
116 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/gen_common.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | package width
8 |
9 | // This code is shared between the main code generator and the test code.
10 |
11 | import (
12 | "flag"
13 | "log"
14 | "strconv"
15 | "strings"
16 |
17 | "golang.org/x/text/internal/gen"
18 | "golang.org/x/text/internal/ucd"
19 | )
20 |
21 | var (
22 | outputFile = flag.String("out", "tables.go", "output file")
23 | )
24 |
25 | var typeMap = map[string]elem{
26 | "A": tagAmbiguous,
27 | "N": tagNeutral,
28 | "Na": tagNarrow,
29 | "W": tagWide,
30 | "F": tagFullwidth,
31 | "H": tagHalfwidth,
32 | }
33 |
34 | // getWidthData calls f for every entry for which it is defined.
35 | //
36 | // f may be called multiple times for the same rune. The last call to f is the
37 | // correct value. f is not called for all runes. The default tag type is
38 | // Neutral.
39 | func getWidthData(f func(r rune, tag elem, alt rune)) {
40 | // Set the default values for Unified Ideographs. In line with Annex 11,
41 | // we encode full ranges instead of the defined runes in Unified_Ideograph.
42 | for _, b := range []struct{ lo, hi rune }{
43 | {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block,
44 | {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block,
45 | {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block,
46 | {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane,
47 | {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane,
48 | } {
49 | for r := b.lo; r <= b.hi; r++ {
50 | f(r, tagWide, 0)
51 | }
52 | }
53 |
54 | inverse := map[rune]rune{}
55 | maps := map[string]bool{
56 | "": true,
57 | "": true,
58 | }
59 |
60 | // We cannot reuse package norm's decomposition, as we need an unexpanded
61 | // decomposition. We make use of the opportunity to verify that the
62 | // decomposition type is as expected.
63 | ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) {
64 | r := p.Rune(0)
65 | s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2)
66 | if !maps[s[0]] {
67 | return
68 | }
69 | x, err := strconv.ParseUint(s[1], 16, 32)
70 | if err != nil {
71 | log.Fatalf("Error parsing rune %q", s[1])
72 | }
73 | if inverse[r] != 0 || inverse[rune(x)] != 0 {
74 | log.Fatalf("Circular dependency in mapping between %U and %U", r, x)
75 | }
76 | inverse[r] = rune(x)
77 | inverse[rune(x)] = r
78 | })
79 |
80 | // ;
81 | ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) {
82 | tag, ok := typeMap[p.String(1)]
83 | if !ok {
84 | log.Fatalf("Unknown width type %q", p.String(1))
85 | }
86 | r := p.Rune(0)
87 | alt, ok := inverse[r]
88 | if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign {
89 | tag |= tagNeedsFold
90 | if !ok {
91 | log.Fatalf("Narrow or wide rune %U has no decomposition", r)
92 | }
93 | }
94 | f(r, tag, alt)
95 | })
96 | }
97 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/gen_trieval.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 | // +build ignore
6 |
7 | package width
8 |
9 | // elem is an entry of the width trie. The high byte is used to encode the type
10 | // of the rune. The low byte is used to store the index to a mapping entry in
11 | // the inverseData array.
12 | type elem uint16
13 |
14 | const (
15 | tagNeutral elem = iota << typeShift
16 | tagAmbiguous
17 | tagWide
18 | tagNarrow
19 | tagFullwidth
20 | tagHalfwidth
21 | )
22 |
23 | const (
24 | numTypeBits = 3
25 | typeShift = 16 - numTypeBits
26 |
27 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for
28 | // the Won sign U+20A9.
29 | tagNeedsFold = 0x1000
30 |
31 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide
32 | // variant.
33 | wonSign rune = 0x20A9
34 | )
35 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/kind_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Kind"; DO NOT EDIT.
2 |
3 | package width
4 |
5 | import "strconv"
6 |
7 | const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth"
8 |
9 | var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89}
10 |
11 | func (i Kind) String() string {
12 | if i < 0 || i >= Kind(len(_Kind_index)-1) {
13 | return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
14 | }
15 | return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
16 | }
17 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/tables_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 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 width
6 |
7 | import (
8 | "testing"
9 |
10 | "golang.org/x/text/internal/testtext"
11 | )
12 |
13 | const (
14 | loSurrogate = 0xD800
15 | hiSurrogate = 0xDFFF
16 | )
17 |
18 | func TestTables(t *testing.T) {
19 | testtext.SkipIfNotLong(t)
20 |
21 | runes := map[rune]Kind{}
22 | getWidthData(func(r rune, tag elem, _ rune) {
23 | runes[r] = tag.kind()
24 | })
25 | for r := rune(0); r < 0x10FFFF; r++ {
26 | if loSurrogate <= r && r <= hiSurrogate {
27 | continue
28 | }
29 | p := LookupRune(r)
30 | if got, want := p.Kind(), runes[r]; got != want {
31 | t.Errorf("Kind of %U was %s; want %s.", r, got, want)
32 | }
33 | want, mapped := foldRune(r)
34 | if got := p.Folded(); (got == 0) == mapped || got != 0 && got != want {
35 | t.Errorf("Folded(%U) = %U; want %U", r, got, want)
36 | }
37 | want, mapped = widenRune(r)
38 | if got := p.Wide(); (got == 0) == mapped || got != 0 && got != want {
39 | t.Errorf("Wide(%U) = %U; want %U", r, got, want)
40 | }
41 | want, mapped = narrowRune(r)
42 | if got := p.Narrow(); (got == 0) == mapped || got != 0 && got != want {
43 | t.Errorf("Narrow(%U) = %U; want %U", r, got, want)
44 | }
45 | }
46 | }
47 |
48 | // TestAmbiguous verifies that ambiguous runes with a mapping always map to
49 | // a halfwidth rune.
50 | func TestAmbiguous(t *testing.T) {
51 | for r, m := range mapRunes {
52 | if m.e != tagAmbiguous {
53 | continue
54 | }
55 | if k := mapRunes[m.r].e.kind(); k != EastAsianHalfwidth {
56 | t.Errorf("Rune %U is ambiguous and maps to a rune of type %v", r, k)
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/text/width/trieval.go:
--------------------------------------------------------------------------------
1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
2 |
3 | package width
4 |
5 | // elem is an entry of the width trie. The high byte is used to encode the type
6 | // of the rune. The low byte is used to store the index to a mapping entry in
7 | // the inverseData array.
8 | type elem uint16
9 |
10 | const (
11 | tagNeutral elem = iota << typeShift
12 | tagAmbiguous
13 | tagWide
14 | tagNarrow
15 | tagFullwidth
16 | tagHalfwidth
17 | )
18 |
19 | const (
20 | numTypeBits = 3
21 | typeShift = 16 - numTypeBits
22 |
23 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for
24 | // the Won sign U+20A9.
25 | tagNeedsFold = 0x1000
26 |
27 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide
28 | // variant.
29 | wonSign rune = 0x20A9
30 | )
31 |
--------------------------------------------------------------------------------