Update dependencies. (#10136)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8af05aa43a
Коммит
9168482623
6
vendor/github.com/avct/uasurfer/README.md
сгенерированный
поставляемый
6
vendor/github.com/avct/uasurfer/README.md
сгенерированный
поставляемый
@@ -72,6 +72,10 @@ where example UserAgent is:
|
||||
* `BrowserSilk` - Amazon [Silk](https://en.wikipedia.org/wiki/Amazon_Silk)
|
||||
* `BrowserSpotify` - [Spotify](https://en.wikipedia.org/wiki/Spotify#Clients) desktop client
|
||||
* `BrowserBlackberry` - RIM [BlackBerry](https://en.wikipedia.org/wiki/BlackBerry)
|
||||
* `BrowserYandex` - [Yandex](https://en.wikipedia.org/wiki/Yandex_Browser)
|
||||
* `BrowserNintendo` - [Nintendo DS(i) Browser](https://en.wikipedia.org/wiki/Nintendo_DS_%26_DSi_Browser)
|
||||
* `BrowserSamsung` - [Samsung Internet](https://en.wikipedia.org/wiki/Samsung_Internet_for_Android)
|
||||
* `BrowserCocCoc`- [Cốc Cốc](https://en.wikipedia.org/wiki/C%E1%BB%91c_C%E1%BB%91c)
|
||||
* `BrowserUnknown` - Unknown
|
||||
|
||||
#### Browser Version
|
||||
@@ -90,7 +94,7 @@ Unknown version is returned as `0`.
|
||||
* `PlatformWindowsPhone` Microsoft Windows Phone & Mobile
|
||||
* `PlatformKindle` - Amazon Kindle & Kindle Fire
|
||||
* `PlatformPlaystation` - Sony Playstation, Vita, PSP
|
||||
* `PlatformXbox` - Microsoft Xbox - `PlatformXbox`
|
||||
* `PlatformXbox` - Microsoft Xbox
|
||||
* `PlatformNintendo` - Nintendo DS, Wii, etc.
|
||||
* `PlatformUnknown` - Unknown
|
||||
|
||||
|
||||
25
vendor/github.com/avct/uasurfer/browser.go
сгенерированный
поставляемый
25
vendor/github.com/avct/uasurfer/browser.go
сгенерированный
поставляемый
@@ -43,6 +43,18 @@ func (u *UserAgent) evalBrowserName(ua string) bool {
|
||||
case strings.Contains(ua, "ucbrowser/") || strings.Contains(ua, "ucweb/"):
|
||||
u.Browser.Name = BrowserUCBrowser
|
||||
|
||||
case strings.Contains(ua, "nintendobrowser/"):
|
||||
u.Browser.Name = BrowserNintendo
|
||||
|
||||
case strings.Contains(ua, "samsungbrowser/"):
|
||||
u.Browser.Name = BrowserSamsung
|
||||
|
||||
case strings.Contains(ua, "coc_coc_browser/"):
|
||||
u.Browser.Name = BrowserCocCoc
|
||||
|
||||
case strings.Contains(ua, "yabrowser/"):
|
||||
u.Browser.Name = BrowserYandex
|
||||
|
||||
// Edge, Silk and other chrome-identifying browsers must evaluate before chrome, unless we want to add more overhead
|
||||
case strings.Contains(ua, "chrome/") || strings.Contains(ua, "crios/") || strings.Contains(ua, "chromium/") || strings.Contains(ua, "crmo/"):
|
||||
u.Browser.Name = BrowserChrome
|
||||
@@ -62,7 +74,7 @@ func (u *UserAgent) evalBrowserName(ua string) bool {
|
||||
u.Browser.Name = BrowserAppleBot
|
||||
|
||||
// presume it's safari unless an esoteric browser is being specified (webOSBrowser, SamsungBrowser, etc.)
|
||||
case strings.Contains(ua, "like gecko") && strings.Contains(ua, "mozilla/") && strings.Contains(ua, "safari/") && !strings.Contains(ua, "linux") && !strings.Contains(ua, "android") && !strings.Contains(ua, "browser/") && !strings.Contains(ua, "os/"):
|
||||
case strings.Contains(ua, "like gecko") && strings.Contains(ua, "mozilla/") && strings.Contains(ua, "safari/") && !strings.Contains(ua, "linux") && !strings.Contains(ua, "android") && !strings.Contains(ua, "browser/") && !strings.Contains(ua, "os/") && !strings.Contains(ua, "yabrowser/"):
|
||||
u.Browser.Name = BrowserSafari
|
||||
|
||||
// if we got this far and the device is iPhone or iPad, assume safari. Some agents don't actually contain the word "safari"
|
||||
@@ -130,6 +142,9 @@ notwebkit:
|
||||
case strings.Contains(ua, "yahoo"):
|
||||
u.Browser.Name = BrowserYahooBot
|
||||
|
||||
case strings.Contains(ua, "coccocbot"):
|
||||
u.Browser.Name = BrowserCocCocBot
|
||||
|
||||
case strings.Contains(ua, "phantomjs"):
|
||||
u.Browser.Name = BrowserBot
|
||||
|
||||
@@ -156,7 +171,8 @@ func (u *UserAgent) evalBrowserVersion(ua string) {
|
||||
case BrowserChrome:
|
||||
// match both chrome and crios
|
||||
_ = u.Browser.Version.findVersionNumber(ua, "chrome/") || u.Browser.Version.findVersionNumber(ua, "crios/") || u.Browser.Version.findVersionNumber(ua, "crmo/")
|
||||
|
||||
case BrowserYandex:
|
||||
_ = u.Browser.Version.findVersionNumber(ua, "yabrowser/")
|
||||
case BrowserIE:
|
||||
if u.Browser.Version.findVersionNumber(ua, "msie ") || u.Browser.Version.findVersionNumber(ua, "edge/") {
|
||||
return
|
||||
@@ -191,5 +207,8 @@ func (u *UserAgent) evalBrowserVersion(ua string) {
|
||||
|
||||
case BrowserSpotify:
|
||||
_ = u.Browser.Version.findVersionNumber(ua, "spotify/")
|
||||
|
||||
case BrowserCocCoc:
|
||||
_ = u.Browser.Version.findVersionNumber(ua, "coc_coc_browser/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/github.com/avct/uasurfer/const_string.go
сгенерированный
поставляемый
4
vendor/github.com/avct/uasurfer/const_string.go
сгенерированный
поставляемый
@@ -15,9 +15,9 @@ func (i DeviceType) String() string {
|
||||
return _DeviceType_name[_DeviceType_index[i]:_DeviceType_index[i+1]]
|
||||
}
|
||||
|
||||
const _BrowserName_name = "BrowserUnknownBrowserChromeBrowserIEBrowserSafariBrowserFirefoxBrowserAndroidBrowserOperaBrowserBlackberryBrowserUCBrowserBrowserSilkBrowserNokiaBrowserNetFrontBrowserQQBrowserMaxthonBrowserSogouExplorerBrowserSpotifyBrowserBotBrowserAppleBotBrowserBaiduBotBrowserBingBotBrowserDuckDuckGoBotBrowserFacebookBotBrowserGoogleBotBrowserLinkedInBotBrowserMsnBotBrowserPingdomBotBrowserTwitterBotBrowserYandexBotBrowserYahooBot"
|
||||
const _BrowserName_name = "BrowserUnknownBrowserChromeBrowserIEBrowserSafariBrowserFirefoxBrowserAndroidBrowserOperaBrowserBlackberryBrowserUCBrowserBrowserSilkBrowserNokiaBrowserNetFrontBrowserQQBrowserMaxthonBrowserSogouExplorerBrowserSpotifyBrowserNintendoBrowserSamsungBrowserYandexBrowserCocCocBrowserBotBrowserAppleBotBrowserBaiduBotBrowserBingBotBrowserDuckDuckGoBotBrowserFacebookBotBrowserGoogleBotBrowserLinkedInBotBrowserMsnBotBrowserPingdomBotBrowserTwitterBotBrowserYandexBotBrowserCocCocBotBrowserYahooBot"
|
||||
|
||||
var _BrowserName_index = [...]uint16{0, 14, 27, 36, 49, 63, 77, 89, 106, 122, 133, 145, 160, 169, 183, 203, 217, 227, 242, 257, 271, 291, 309, 325, 343, 356, 373, 390, 406, 421}
|
||||
var _BrowserName_index = [...]uint16{0, 14, 27, 36, 49, 63, 77, 89, 106, 122, 133, 145, 160, 169, 183, 203, 217, 232, 246, 259, 272, 282, 297, 312, 326, 346, 364, 380, 398, 411, 428, 445, 461, 477, 492}
|
||||
|
||||
func (i BrowserName) String() string {
|
||||
if i < 0 || i >= BrowserName(len(_BrowserName_index)-1) {
|
||||
|
||||
5
vendor/github.com/avct/uasurfer/uasurfer.go
сгенерированный
поставляемый
5
vendor/github.com/avct/uasurfer/uasurfer.go
сгенерированный
поставляемый
@@ -46,6 +46,10 @@ const (
|
||||
BrowserMaxthon
|
||||
BrowserSogouExplorer
|
||||
BrowserSpotify
|
||||
BrowserNintendo
|
||||
BrowserSamsung
|
||||
BrowserYandex
|
||||
BrowserCocCoc
|
||||
BrowserBot // Bot list begins here
|
||||
BrowserAppleBot
|
||||
BrowserBaiduBot
|
||||
@@ -58,6 +62,7 @@ const (
|
||||
BrowserPingdomBot
|
||||
BrowserTwitterBot
|
||||
BrowserYandexBot
|
||||
BrowserCocCocBot
|
||||
BrowserYahooBot // Bot list ends here
|
||||
)
|
||||
|
||||
|
||||
2
vendor/github.com/go-ini/ini/file.go
сгенерированный
поставляемый
2
vendor/github.com/go-ini/ini/file.go
сгенерированный
поставляемый
@@ -314,7 +314,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
|
||||
lines := strings.Split(key.Comment, LineBreak)
|
||||
for i := range lines {
|
||||
if lines[i][0] != '#' && lines[i][0] != ';' {
|
||||
lines[i] = "; " + lines[i]
|
||||
lines[i] = "; " + strings.TrimSpace(lines[i])
|
||||
} else {
|
||||
lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-ini/ini/ini.go
сгенерированный
поставляемый
2
vendor/github.com/go-ini/ini/ini.go
сгенерированный
поставляемый
@@ -34,7 +34,7 @@ const (
|
||||
|
||||
// Maximum allowed depth when recursively substituing variable names.
|
||||
_DEPTH_VALUES = 99
|
||||
_VERSION = "1.39.1"
|
||||
_VERSION = "1.41.0"
|
||||
)
|
||||
|
||||
// Version returns current package version literal.
|
||||
|
||||
21
vendor/github.com/go-ini/ini/key.go
сгенерированный
поставляемый
21
vendor/github.com/go-ini/ini/key.go
сгенерированный
поставляемый
@@ -133,8 +133,7 @@ func (k *Key) transformValue(val string) string {
|
||||
}
|
||||
|
||||
// Take off leading '%(' and trailing ')s'.
|
||||
noption := strings.TrimLeft(vr, "%(")
|
||||
noption = strings.TrimRight(noption, ")s")
|
||||
noption := vr[2 : len(vr)-2]
|
||||
|
||||
// Search in the same section.
|
||||
nk, err := k.s.GetKey(noption)
|
||||
@@ -187,23 +186,24 @@ func (k *Key) Float64() (float64, error) {
|
||||
|
||||
// Int returns int type value.
|
||||
func (k *Key) Int() (int, error) {
|
||||
return strconv.Atoi(k.String())
|
||||
v, err := strconv.ParseInt(k.String(), 0, 64)
|
||||
return int(v), err
|
||||
}
|
||||
|
||||
// Int64 returns int64 type value.
|
||||
func (k *Key) Int64() (int64, error) {
|
||||
return strconv.ParseInt(k.String(), 10, 64)
|
||||
return strconv.ParseInt(k.String(), 0, 64)
|
||||
}
|
||||
|
||||
// Uint returns uint type valued.
|
||||
func (k *Key) Uint() (uint, error) {
|
||||
u, e := strconv.ParseUint(k.String(), 10, 64)
|
||||
u, e := strconv.ParseUint(k.String(), 0, 64)
|
||||
return uint(u), e
|
||||
}
|
||||
|
||||
// Uint64 returns uint64 type value.
|
||||
func (k *Key) Uint64() (uint64, error) {
|
||||
return strconv.ParseUint(k.String(), 10, 64)
|
||||
return strconv.ParseUint(k.String(), 0, 64)
|
||||
}
|
||||
|
||||
// Duration returns time.Duration type value.
|
||||
@@ -668,7 +668,8 @@ func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]
|
||||
func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) {
|
||||
vals := make([]int, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.Atoi(str)
|
||||
valInt64, err := strconv.ParseInt(str, 0, 64)
|
||||
val := int(valInt64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
@@ -683,7 +684,7 @@ func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int,
|
||||
func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) {
|
||||
vals := make([]int64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseInt(str, 10, 64)
|
||||
val, err := strconv.ParseInt(str, 0, 64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
@@ -698,7 +699,7 @@ func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]in
|
||||
func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) {
|
||||
vals := make([]uint, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseUint(str, 10, 0)
|
||||
val, err := strconv.ParseUint(str, 0, 0)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
@@ -713,7 +714,7 @@ func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uin
|
||||
func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) {
|
||||
vals := make([]uint64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseUint(str, 10, 64)
|
||||
val, err := strconv.ParseUint(str, 0, 64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
1
vendor/github.com/go-ini/ini/section.go
сгенерированный
поставляемый
1
vendor/github.com/go-ini/ini/section.go
сгенерированный
поставляемый
@@ -238,6 +238,7 @@ func (s *Section) DeleteKey(name string) {
|
||||
if k == name {
|
||||
s.keyList = append(s.keyList[:i], s.keyList[i+1:]...)
|
||||
delete(s.keys, name)
|
||||
delete(s.keysHash, name)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-ini/ini/struct.go
сгенерированный
поставляемый
2
vendor/github.com/go-ini/ini/struct.go
сгенерированный
поставляемый
@@ -180,7 +180,7 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri
|
||||
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
durationVal, err := key.Duration()
|
||||
// Skip zero value
|
||||
if err == nil && int(durationVal) > 0 {
|
||||
if err == nil && uint64(durationVal) > 0 {
|
||||
field.Set(reflect.ValueOf(durationVal))
|
||||
return nil
|
||||
}
|
||||
|
||||
4
vendor/github.com/go-ldap/ldap/conn.go
сгенерированный
поставляемый
4
vendor/github.com/go-ldap/ldap/conn.go
сгенерированный
поставляемый
@@ -85,6 +85,9 @@ const (
|
||||
|
||||
// Conn represents an LDAP Connection
|
||||
type Conn struct {
|
||||
// requestTimeout is loaded atomically
|
||||
// so we need to ensure 64-bit alignment on 32-bit platforms.
|
||||
requestTimeout int64
|
||||
conn net.Conn
|
||||
isTLS bool
|
||||
closing uint32
|
||||
@@ -98,7 +101,6 @@ type Conn struct {
|
||||
wgClose sync.WaitGroup
|
||||
outstandingRequests uint
|
||||
messageMutex sync.Mutex
|
||||
requestTimeout int64
|
||||
}
|
||||
|
||||
var _ Client = &Conn{}
|
||||
|
||||
2
vendor/github.com/go-redis/redis/.travis.yml
сгенерированный
поставляемый
2
vendor/github.com/go-redis/redis/.travis.yml
сгенерированный
поставляемый
@@ -5,8 +5,6 @@ services:
|
||||
- redis-server
|
||||
|
||||
go:
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
|
||||
2
vendor/github.com/go-redis/redis/Makefile
сгенерированный
поставляемый
2
vendor/github.com/go-redis/redis/Makefile
сгенерированный
поставляемый
@@ -3,6 +3,8 @@ all: testdeps
|
||||
go test ./... -short -race
|
||||
env GOOS=linux GOARCH=386 go test ./...
|
||||
go vet
|
||||
go get github.com/gordonklaus/ineffassign
|
||||
ineffassign .
|
||||
|
||||
testdeps: testdata/redis/src/redis-server
|
||||
|
||||
|
||||
113
vendor/github.com/go-redis/redis/cluster.go
сгенерированный
поставляемый
113
vendor/github.com/go-redis/redis/cluster.go
сгенерированный
поставляемый
@@ -3,7 +3,6 @@ package redis
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
@@ -18,7 +17,6 @@ import (
|
||||
"github.com/go-redis/redis/internal/hashtag"
|
||||
"github.com/go-redis/redis/internal/pool"
|
||||
"github.com/go-redis/redis/internal/proto"
|
||||
"github.com/go-redis/redis/internal/singleflight"
|
||||
)
|
||||
|
||||
var errClusterNoNodes = fmt.Errorf("redis: cluster has no nodes")
|
||||
@@ -50,6 +48,9 @@ type ClusterOptions struct {
|
||||
// and Cluster.ReloadState to manually trigger state reloading.
|
||||
ClusterSlots func() ([]ClusterSlot, error)
|
||||
|
||||
// Optional hook that is called when a new node is created.
|
||||
OnNewNode func(*Client)
|
||||
|
||||
// Following options are copied from Options struct.
|
||||
|
||||
OnConnect func(*Conn) error
|
||||
@@ -166,6 +167,10 @@ func newClusterNode(clOpt *ClusterOptions, addr string) *clusterNode {
|
||||
go node.updateLatency()
|
||||
}
|
||||
|
||||
if clOpt.OnNewNode != nil {
|
||||
clOpt.OnNewNode(node.Client)
|
||||
}
|
||||
|
||||
return &node
|
||||
}
|
||||
|
||||
@@ -237,8 +242,6 @@ type clusterNodes struct {
|
||||
clusterAddrs []string
|
||||
closed bool
|
||||
|
||||
nodeCreateGroup singleflight.Group
|
||||
|
||||
_generation uint32 // atomic
|
||||
}
|
||||
|
||||
@@ -341,11 +344,6 @@ func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
|
||||
return node, nil
|
||||
}
|
||||
|
||||
v, err := c.nodeCreateGroup.Do(addr, func() (interface{}, error) {
|
||||
node := newClusterNode(c.opt, addr)
|
||||
return node, nil
|
||||
})
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
@@ -355,15 +353,13 @@ func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
|
||||
|
||||
node, ok := c.allNodes[addr]
|
||||
if ok {
|
||||
_ = v.(*clusterNode).Close()
|
||||
return node, err
|
||||
}
|
||||
node = v.(*clusterNode)
|
||||
|
||||
node = newClusterNode(c.opt, addr)
|
||||
|
||||
c.allAddrs = appendIfNotExists(c.allAddrs, addr)
|
||||
if err == nil {
|
||||
c.clusterAddrs = append(c.clusterAddrs, addr)
|
||||
}
|
||||
c.clusterAddrs = append(c.clusterAddrs, addr)
|
||||
c.allNodes[addr] = node
|
||||
|
||||
return node, err
|
||||
@@ -533,10 +529,12 @@ func (c *clusterState) slotSlaveNode(slot int) (*clusterNode, error) {
|
||||
n := rand.Intn(len(nodes)-1) + 1
|
||||
slave = nodes[n]
|
||||
if !slave.Loading() {
|
||||
break
|
||||
return slave, nil
|
||||
}
|
||||
}
|
||||
return slave, nil
|
||||
|
||||
// All slaves are loading - use master.
|
||||
return nodes[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,23 +578,12 @@ func (c *clusterState) slotNodes(slot int) []*clusterNode {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *clusterState) IsConsistent() bool {
|
||||
if c.nodes.opt.ClusterSlots != nil {
|
||||
return true
|
||||
}
|
||||
return len(c.Masters) <= len(c.Slaves)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
type clusterStateHolder struct {
|
||||
load func() (*clusterState, error)
|
||||
|
||||
state atomic.Value
|
||||
|
||||
firstErrMu sync.RWMutex
|
||||
firstErr error
|
||||
|
||||
state atomic.Value
|
||||
reloading uint32 // atomic
|
||||
}
|
||||
|
||||
@@ -607,24 +594,8 @@ func newClusterStateHolder(fn func() (*clusterState, error)) *clusterStateHolder
|
||||
}
|
||||
|
||||
func (c *clusterStateHolder) Reload() (*clusterState, error) {
|
||||
state, err := c.reload()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !state.IsConsistent() {
|
||||
time.AfterFunc(time.Second, c.LazyReload)
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (c *clusterStateHolder) reload() (*clusterState, error) {
|
||||
state, err := c.load()
|
||||
if err != nil {
|
||||
c.firstErrMu.Lock()
|
||||
if c.firstErr == nil {
|
||||
c.firstErr = err
|
||||
}
|
||||
c.firstErrMu.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
c.state.Store(state)
|
||||
@@ -638,16 +609,11 @@ func (c *clusterStateHolder) LazyReload() {
|
||||
go func() {
|
||||
defer atomic.StoreUint32(&c.reloading, 0)
|
||||
|
||||
for {
|
||||
state, err := c.reload()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if state.IsConsistent() {
|
||||
return
|
||||
}
|
||||
_, err := c.Reload()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -660,15 +626,7 @@ func (c *clusterStateHolder) Get() (*clusterState, error) {
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
c.firstErrMu.RLock()
|
||||
err := c.firstErr
|
||||
c.firstErrMu.RUnlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.New("redis: cluster has no state")
|
||||
return c.Reload()
|
||||
}
|
||||
|
||||
func (c *clusterStateHolder) ReloadOrGet() (*clusterState, error) {
|
||||
@@ -716,10 +674,6 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
|
||||
c.processTxPipeline = c.defaultProcessTxPipeline
|
||||
|
||||
c.init()
|
||||
|
||||
_, _ = c.state.Reload()
|
||||
_, _ = c.cmdsInfoCache.Get()
|
||||
|
||||
if opt.IdleCheckFrequency > 0 {
|
||||
go c.reaper(opt.IdleCheckFrequency)
|
||||
}
|
||||
@@ -727,17 +681,17 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
|
||||
return c
|
||||
}
|
||||
|
||||
// ReloadState reloads cluster state. It calls ClusterSlots func
|
||||
func (c *ClusterClient) init() {
|
||||
c.cmdable.setProcessor(c.Process)
|
||||
}
|
||||
|
||||
// ReloadState reloads cluster state. If available it calls ClusterSlots func
|
||||
// to get cluster slots information.
|
||||
func (c *ClusterClient) ReloadState() error {
|
||||
_, err := c.state.Reload()
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ClusterClient) init() {
|
||||
c.cmdable.setProcessor(c.Process)
|
||||
}
|
||||
|
||||
func (c *ClusterClient) Context() context.Context {
|
||||
if c.ctx != nil {
|
||||
return c.ctx
|
||||
@@ -979,9 +933,10 @@ func (c *ClusterClient) defaultProcess(cmd Cmder) error {
|
||||
break
|
||||
}
|
||||
|
||||
// If slave is loading - read from master.
|
||||
// If slave is loading - pick another node.
|
||||
if c.opt.ReadOnly && internal.IsLoadingError(err) {
|
||||
node.MarkAsLoading()
|
||||
node = nil
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1349,14 +1304,15 @@ func (c *ClusterClient) pipelineProcessCmds(
|
||||
}
|
||||
|
||||
err = cn.WithReader(c.opt.ReadTimeout, func(rd *proto.Reader) error {
|
||||
return c.pipelineReadCmds(rd, cmds, failedCmds)
|
||||
return c.pipelineReadCmds(node, rd, cmds, failedCmds)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ClusterClient) pipelineReadCmds(
|
||||
rd *proto.Reader, cmds []Cmder, failedCmds *cmdsMap,
|
||||
node *clusterNode, rd *proto.Reader, cmds []Cmder, failedCmds *cmdsMap,
|
||||
) error {
|
||||
var firstErr error
|
||||
for _, cmd := range cmds {
|
||||
err := cmd.readReply(rd)
|
||||
if err == nil {
|
||||
@@ -1371,9 +1327,14 @@ func (c *ClusterClient) pipelineReadCmds(
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
failedCmds.mu.Lock()
|
||||
failedCmds.m[node] = append(failedCmds.m[node], cmd)
|
||||
failedCmds.mu.Unlock()
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return firstErr
|
||||
}
|
||||
|
||||
func (c *ClusterClient) checkMovedErr(
|
||||
|
||||
62
vendor/github.com/go-redis/redis/command.go
сгенерированный
поставляемый
62
vendor/github.com/go-redis/redis/command.go
сгенерированный
поставляемый
@@ -1337,6 +1337,68 @@ func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
type ZWithKeyCmd struct {
|
||||
baseCmd
|
||||
|
||||
val ZWithKey
|
||||
}
|
||||
|
||||
var _ Cmder = (*ZWithKeyCmd)(nil)
|
||||
|
||||
func NewZWithKeyCmd(args ...interface{}) *ZWithKeyCmd {
|
||||
return &ZWithKeyCmd{
|
||||
baseCmd: baseCmd{_args: args},
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *ZWithKeyCmd) Val() ZWithKey {
|
||||
return cmd.val
|
||||
}
|
||||
|
||||
func (cmd *ZWithKeyCmd) Result() (ZWithKey, error) {
|
||||
return cmd.Val(), cmd.Err()
|
||||
}
|
||||
|
||||
func (cmd *ZWithKeyCmd) String() string {
|
||||
return cmdString(cmd, cmd.val)
|
||||
}
|
||||
|
||||
func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) error {
|
||||
var v interface{}
|
||||
v, cmd.err = rd.ReadArrayReply(zWithKeyParser)
|
||||
if cmd.err != nil {
|
||||
return cmd.err
|
||||
}
|
||||
cmd.val = v.(ZWithKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Implements proto.MultiBulkParse
|
||||
func zWithKeyParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||
if n != 3 {
|
||||
return nil, fmt.Errorf("got %d elements, expected 3", n)
|
||||
}
|
||||
|
||||
var z ZWithKey
|
||||
var err error
|
||||
|
||||
z.Key, err = rd.ReadString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
z.Member, err = rd.ReadString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
z.Score, err = rd.ReadFloatReply()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return z, nil
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
type ScanCmd struct {
|
||||
baseCmd
|
||||
|
||||
|
||||
77
vendor/github.com/go-redis/redis/commands.go
сгенерированный
поставляемый
77
vendor/github.com/go-redis/redis/commands.go
сгенерированный
поставляемый
@@ -166,6 +166,7 @@ type Cmdable interface {
|
||||
SUnion(keys ...string) *StringSliceCmd
|
||||
SUnionStore(destination string, keys ...string) *IntCmd
|
||||
XAdd(a *XAddArgs) *StringCmd
|
||||
XDel(stream string, ids ...string) *IntCmd
|
||||
XLen(stream string) *IntCmd
|
||||
XRange(stream, start, stop string) *XMessageSliceCmd
|
||||
XRangeN(stream, start, stop string, count int64) *XMessageSliceCmd
|
||||
@@ -174,6 +175,7 @@ type Cmdable interface {
|
||||
XRead(a *XReadArgs) *XStreamSliceCmd
|
||||
XReadStreams(streams ...string) *XStreamSliceCmd
|
||||
XGroupCreate(stream, group, start string) *StatusCmd
|
||||
XGroupCreateMkStream(stream, group, start string) *StatusCmd
|
||||
XGroupSetID(stream, group, start string) *StatusCmd
|
||||
XGroupDestroy(stream, group string) *IntCmd
|
||||
XGroupDelConsumer(stream, group, consumer string) *IntCmd
|
||||
@@ -185,6 +187,8 @@ type Cmdable interface {
|
||||
XClaimJustID(a *XClaimArgs) *StringSliceCmd
|
||||
XTrim(key string, maxLen int64) *IntCmd
|
||||
XTrimApprox(key string, maxLen int64) *IntCmd
|
||||
BZPopMax(timeout time.Duration, keys ...string) *ZWithKeyCmd
|
||||
BZPopMin(timeout time.Duration, keys ...string) *ZWithKeyCmd
|
||||
ZAdd(key string, members ...Z) *IntCmd
|
||||
ZAddNX(key string, members ...Z) *IntCmd
|
||||
ZAddXX(key string, members ...Z) *IntCmd
|
||||
@@ -228,6 +232,7 @@ type Cmdable interface {
|
||||
ClientKillByFilter(keys ...string) *IntCmd
|
||||
ClientList() *StringCmd
|
||||
ClientPause(dur time.Duration) *BoolCmd
|
||||
ClientID() *IntCmd
|
||||
ConfigGet(parameter string) *SliceCmd
|
||||
ConfigResetStat() *StatusCmd
|
||||
ConfigSet(parameter, value string) *StatusCmd
|
||||
@@ -1337,6 +1342,16 @@ func (c *cmdable) XAdd(a *XAddArgs) *StringCmd {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) XDel(stream string, ids ...string) *IntCmd {
|
||||
args := []interface{}{"xdel", stream}
|
||||
for _, id := range ids {
|
||||
args = append(args, id)
|
||||
}
|
||||
cmd := NewIntCmd(args...)
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) XLen(stream string) *IntCmd {
|
||||
cmd := NewIntCmd("xlen", stream)
|
||||
c.process(cmd)
|
||||
@@ -1410,6 +1425,12 @@ func (c *cmdable) XGroupCreate(stream, group, start string) *StatusCmd {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) XGroupCreateMkStream(stream, group, start string) *StatusCmd {
|
||||
cmd := NewStatusCmd("xgroup", "create", stream, group, start, "mkstream")
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) XGroupSetID(stream, group, start string) *StatusCmd {
|
||||
cmd := NewStatusCmd("xgroup", "setid", stream, group, start)
|
||||
c.process(cmd)
|
||||
@@ -1434,6 +1455,7 @@ type XReadGroupArgs struct {
|
||||
Streams []string
|
||||
Count int64
|
||||
Block time.Duration
|
||||
NoAck bool
|
||||
}
|
||||
|
||||
func (c *cmdable) XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd {
|
||||
@@ -1445,6 +1467,9 @@ func (c *cmdable) XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd {
|
||||
if a.Block >= 0 {
|
||||
args = append(args, "block", int64(a.Block/time.Millisecond))
|
||||
}
|
||||
if a.NoAck {
|
||||
args = append(args, "noack")
|
||||
}
|
||||
args = append(args, "streams")
|
||||
for _, s := range a.Streams {
|
||||
args = append(args, s)
|
||||
@@ -1550,6 +1575,12 @@ type Z struct {
|
||||
Member interface{}
|
||||
}
|
||||
|
||||
// ZWithKey represents sorted set member including the name of the key where it was popped.
|
||||
type ZWithKey struct {
|
||||
Z
|
||||
Key string
|
||||
}
|
||||
|
||||
// ZStore is used as an arg to ZInterStore and ZUnionStore.
|
||||
type ZStore struct {
|
||||
Weights []float64
|
||||
@@ -1557,6 +1588,34 @@ type ZStore struct {
|
||||
Aggregate string
|
||||
}
|
||||
|
||||
// Redis `BZPOPMAX key [key ...] timeout` command.
|
||||
func (c *cmdable) BZPopMax(timeout time.Duration, keys ...string) *ZWithKeyCmd {
|
||||
args := make([]interface{}, 1+len(keys)+1)
|
||||
args[0] = "bzpopmax"
|
||||
for i, key := range keys {
|
||||
args[1+i] = key
|
||||
}
|
||||
args[len(args)-1] = formatSec(timeout)
|
||||
cmd := NewZWithKeyCmd(args...)
|
||||
cmd.setReadTimeout(timeout)
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Redis `BZPOPMIN key [key ...] timeout` command.
|
||||
func (c *cmdable) BZPopMin(timeout time.Duration, keys ...string) *ZWithKeyCmd {
|
||||
args := make([]interface{}, 1+len(keys)+1)
|
||||
args[0] = "bzpopmin"
|
||||
for i, key := range keys {
|
||||
args[1+i] = key
|
||||
}
|
||||
args[len(args)-1] = formatSec(timeout)
|
||||
cmd := NewZWithKeyCmd(args...)
|
||||
cmd.setReadTimeout(timeout)
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) zAdd(a []interface{}, n int, members ...Z) *IntCmd {
|
||||
for i, m := range members {
|
||||
a[n+2*i] = m.Score
|
||||
@@ -2010,6 +2069,24 @@ func (c *cmdable) ClientPause(dur time.Duration) *BoolCmd {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) ClientID() *IntCmd {
|
||||
cmd := NewIntCmd("client", "id")
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) ClientUnblock(id int64) *IntCmd {
|
||||
cmd := NewIntCmd("client", "unblock", id)
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmdable) ClientUnblockWithError(id int64) *IntCmd {
|
||||
cmd := NewIntCmd("client", "unblock", id, "error")
|
||||
c.process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// ClientSetName assigns a name to the connection.
|
||||
func (c *statefulCmdable) ClientSetName(name string) *BoolCmd {
|
||||
cmd := NewBoolCmd("client", "setname", name)
|
||||
|
||||
64
vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go
сгенерированный
поставляемый
64
vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go
сгенерированный
поставляемый
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package singleflight provides a duplicate function call suppression
|
||||
// mechanism.
|
||||
package singleflight
|
||||
|
||||
import "sync"
|
||||
|
||||
// call is an in-flight or completed Do call
|
||||
type call struct {
|
||||
wg sync.WaitGroup
|
||||
val interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
// Group represents a class of work and forms a namespace in which
|
||||
// units of work can be executed with duplicate suppression.
|
||||
type Group struct {
|
||||
mu sync.Mutex // protects m
|
||||
m map[string]*call // lazily initialized
|
||||
}
|
||||
|
||||
// Do executes and returns the results of the given function, making
|
||||
// sure that only one execution is in-flight for a given key at a
|
||||
// time. If a duplicate comes in, the duplicate caller waits for the
|
||||
// original to complete and receives the same results.
|
||||
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
|
||||
g.mu.Lock()
|
||||
if g.m == nil {
|
||||
g.m = make(map[string]*call)
|
||||
}
|
||||
if c, ok := g.m[key]; ok {
|
||||
g.mu.Unlock()
|
||||
c.wg.Wait()
|
||||
return c.val, c.err
|
||||
}
|
||||
c := new(call)
|
||||
c.wg.Add(1)
|
||||
g.m[key] = c
|
||||
g.mu.Unlock()
|
||||
|
||||
c.val, c.err = fn()
|
||||
c.wg.Done()
|
||||
|
||||
g.mu.Lock()
|
||||
delete(g.m, key)
|
||||
g.mu.Unlock()
|
||||
|
||||
return c.val, c.err
|
||||
}
|
||||
11
vendor/github.com/go-redis/redis/options.go
сгенерированный
поставляемый
11
vendor/github.com/go-redis/redis/options.go
сгенерированный
поставляемый
@@ -14,6 +14,17 @@ import (
|
||||
"github.com/go-redis/redis/internal/pool"
|
||||
)
|
||||
|
||||
// Limiter is the interface of a rate limiter or a circuit breaker.
|
||||
type Limiter interface {
|
||||
// Allow returns a nil if operation is allowed or an error otherwise.
|
||||
// If operation is allowed client must report the result of operation
|
||||
// whether is a success or a failure.
|
||||
Allow() error
|
||||
// ReportResult reports the result of previously allowed operation.
|
||||
// nil indicates a success, non-nil error indicates a failure.
|
||||
ReportResult(result error)
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
// The network type, either tcp or unix.
|
||||
// Default is tcp.
|
||||
|
||||
62
vendor/github.com/go-redis/redis/redis.go
сгенерированный
поставляемый
62
vendor/github.com/go-redis/redis/redis.go
сгенерированный
поставляемый
@@ -26,6 +26,7 @@ func SetLogger(logger *log.Logger) {
|
||||
type baseClient struct {
|
||||
opt *Options
|
||||
connPool pool.Pooler
|
||||
limiter Limiter
|
||||
|
||||
process func(Cmder) error
|
||||
processPipeline func([]Cmder) error
|
||||
@@ -61,6 +62,24 @@ func (c *baseClient) newConn() (*pool.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *baseClient) getConn() (*pool.Conn, error) {
|
||||
if c.limiter != nil {
|
||||
err := c.limiter.Allow()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
cn, err := c._getConn()
|
||||
if err != nil {
|
||||
if c.limiter != nil {
|
||||
c.limiter.ReportResult(err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return cn, nil
|
||||
}
|
||||
|
||||
func (c *baseClient) _getConn() (*pool.Conn, error) {
|
||||
cn, err := c.connPool.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,6 +97,10 @@ func (c *baseClient) getConn() (*pool.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *baseClient) releaseConn(cn *pool.Conn, err error) {
|
||||
if c.limiter != nil {
|
||||
c.limiter.ReportResult(err)
|
||||
}
|
||||
|
||||
if internal.IsBadConn(err, false) {
|
||||
c.connPool.Remove(cn)
|
||||
} else {
|
||||
@@ -86,6 +109,10 @@ func (c *baseClient) releaseConn(cn *pool.Conn, err error) {
|
||||
}
|
||||
|
||||
func (c *baseClient) releaseConnStrict(cn *pool.Conn, err error) {
|
||||
if c.limiter != nil {
|
||||
c.limiter.ReportResult(err)
|
||||
}
|
||||
|
||||
if err == nil || internal.IsRedisError(err) {
|
||||
c.connPool.Put(cn)
|
||||
} else {
|
||||
@@ -132,7 +159,7 @@ func (c *baseClient) initConn(cn *pool.Conn) error {
|
||||
// Do creates a Cmd from the args and processes the cmd.
|
||||
func (c *baseClient) Do(args ...interface{}) *Cmd {
|
||||
cmd := NewCmd(args...)
|
||||
c.Process(cmd)
|
||||
_ = c.Process(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -396,12 +423,12 @@ func (c *Client) WithContext(ctx context.Context) *Client {
|
||||
if ctx == nil {
|
||||
panic("nil context")
|
||||
}
|
||||
c2 := c.copy()
|
||||
c2 := c.clone()
|
||||
c2.ctx = ctx
|
||||
return c2
|
||||
}
|
||||
|
||||
func (c *Client) copy() *Client {
|
||||
func (c *Client) clone() *Client {
|
||||
cp := *c
|
||||
cp.init()
|
||||
return &cp
|
||||
@@ -412,6 +439,11 @@ func (c *Client) Options() *Options {
|
||||
return c.opt
|
||||
}
|
||||
|
||||
func (c *Client) SetLimiter(l Limiter) *Client {
|
||||
c.limiter = l
|
||||
return c
|
||||
}
|
||||
|
||||
type PoolStats pool.Stats
|
||||
|
||||
// PoolStats returns connection pool stats.
|
||||
@@ -460,6 +492,30 @@ func (c *Client) pubSub() *PubSub {
|
||||
|
||||
// Subscribe subscribes the client to the specified channels.
|
||||
// Channels can be omitted to create empty subscription.
|
||||
// Note that this method does not wait on a response from Redis, so the
|
||||
// subscription may not be active immediately. To force the connection to wait,
|
||||
// you may call the Receive() method on the returned *PubSub like so:
|
||||
//
|
||||
// sub := client.Subscribe(queryResp)
|
||||
// iface, err := sub.Receive()
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// // Should be *Subscription, but others are possible if other actions have been
|
||||
// // taken on sub since it was created.
|
||||
// switch iface.(type) {
|
||||
// case *Subscription:
|
||||
// // subscribe succeeded
|
||||
// case *Message:
|
||||
// // received first message
|
||||
// case *Pong:
|
||||
// // pong received
|
||||
// default:
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// ch := sub.Channel()
|
||||
func (c *Client) Subscribe(channels ...string) *PubSub {
|
||||
pubsub := c.pubSub()
|
||||
if len(channels) > 0 {
|
||||
|
||||
26
vendor/github.com/go-redis/redis/sentinel.go
сгенерированный
поставляемый
26
vendor/github.com/go-redis/redis/sentinel.go
сгенерированный
поставляемый
@@ -176,6 +176,7 @@ type sentinelFailover struct {
|
||||
masterName string
|
||||
_masterAddr string
|
||||
sentinel *SentinelClient
|
||||
pubsub *PubSub
|
||||
}
|
||||
|
||||
func (c *sentinelFailover) Close() error {
|
||||
@@ -304,13 +305,27 @@ func (c *sentinelFailover) switchMaster(addr string) {
|
||||
func (c *sentinelFailover) setSentinel(sentinel *SentinelClient) {
|
||||
c.discoverSentinels(sentinel)
|
||||
c.sentinel = sentinel
|
||||
go c.listen(sentinel)
|
||||
|
||||
c.pubsub = sentinel.Subscribe("+switch-master")
|
||||
go c.listen(c.pubsub)
|
||||
}
|
||||
|
||||
func (c *sentinelFailover) closeSentinel() error {
|
||||
err := c.sentinel.Close()
|
||||
var firstErr error
|
||||
|
||||
err := c.pubsub.Close()
|
||||
if err != nil && firstErr == err {
|
||||
firstErr = err
|
||||
}
|
||||
c.pubsub = nil
|
||||
|
||||
err = c.sentinel.Close()
|
||||
if err != nil && firstErr == err {
|
||||
firstErr = err
|
||||
}
|
||||
c.sentinel = nil
|
||||
return err
|
||||
|
||||
return firstErr
|
||||
}
|
||||
|
||||
func (c *sentinelFailover) discoverSentinels(sentinel *SentinelClient) {
|
||||
@@ -335,10 +350,7 @@ func (c *sentinelFailover) discoverSentinels(sentinel *SentinelClient) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *sentinelFailover) listen(sentinel *SentinelClient) {
|
||||
pubsub := sentinel.Subscribe("+switch-master")
|
||||
defer pubsub.Close()
|
||||
|
||||
func (c *sentinelFailover) listen(pubsub *PubSub) {
|
||||
ch := pubsub.Channel()
|
||||
for {
|
||||
msg, ok := <-ch
|
||||
|
||||
1
vendor/github.com/google/btree/.travis.yml
сгенерированный
поставляемый
Обычный файл
1
vendor/github.com/google/btree/.travis.yml
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1 @@
|
||||
language: go
|
||||
202
vendor/github.com/google/btree/LICENSE
сгенерированный
поставляемый
Обычный файл
202
vendor/github.com/google/btree/LICENSE
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
12
vendor/github.com/google/btree/README.md
сгенерированный
поставляемый
Обычный файл
12
vendor/github.com/google/btree/README.md
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,12 @@
|
||||
# BTree implementation for Go
|
||||
|
||||

|
||||
|
||||
This package provides an in-memory B-Tree implementation for Go, useful as
|
||||
an ordered, mutable data structure.
|
||||
|
||||
The API is based off of the wonderful
|
||||
http://godoc.org/github.com/petar/GoLLRB/llrb, and is meant to allow btree to
|
||||
act as a drop-in replacement for gollrb trees.
|
||||
|
||||
See http://godoc.org/github.com/google/btree for documentation.
|
||||
890
vendor/github.com/google/btree/btree.go
сгенерированный
поставляемый
Обычный файл
890
vendor/github.com/google/btree/btree.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,890 @@
|
||||
// Copyright 2014 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package btree implements in-memory B-Trees of arbitrary degree.
|
||||
//
|
||||
// btree implements an in-memory B-Tree for use as an ordered data structure.
|
||||
// It is not meant for persistent storage solutions.
|
||||
//
|
||||
// It has a flatter structure than an equivalent red-black or other binary tree,
|
||||
// which in some cases yields better memory usage and/or performance.
|
||||
// See some discussion on the matter here:
|
||||
// http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html
|
||||
// Note, though, that this project is in no way related to the C++ B-Tree
|
||||
// implementation written about there.
|
||||
//
|
||||
// Within this tree, each node contains a slice of items and a (possibly nil)
|
||||
// slice of children. For basic numeric values or raw structs, this can cause
|
||||
// efficiency differences when compared to equivalent C++ template code that
|
||||
// stores values in arrays within the node:
|
||||
// * Due to the overhead of storing values as interfaces (each
|
||||
// value needs to be stored as the value itself, then 2 words for the
|
||||
// interface pointing to that value and its type), resulting in higher
|
||||
// memory use.
|
||||
// * Since interfaces can point to values anywhere in memory, values are
|
||||
// most likely not stored in contiguous blocks, resulting in a higher
|
||||
// number of cache misses.
|
||||
// These issues don't tend to matter, though, when working with strings or other
|
||||
// heap-allocated structures, since C++-equivalent structures also must store
|
||||
// pointers and also distribute their values across the heap.
|
||||
//
|
||||
// This implementation is designed to be a drop-in replacement to gollrb.LLRB
|
||||
// trees, (http://github.com/petar/gollrb), an excellent and probably the most
|
||||
// widely used ordered tree implementation in the Go ecosystem currently.
|
||||
// Its functions, therefore, exactly mirror those of
|
||||
// llrb.LLRB where possible. Unlike gollrb, though, we currently don't
|
||||
// support storing multiple equivalent values.
|
||||
package btree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Item represents a single object in the tree.
|
||||
type Item interface {
|
||||
// Less tests whether the current item is less than the given argument.
|
||||
//
|
||||
// This must provide a strict weak ordering.
|
||||
// If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only
|
||||
// hold one of either a or b in the tree).
|
||||
Less(than Item) bool
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultFreeListSize = 32
|
||||
)
|
||||
|
||||
var (
|
||||
nilItems = make(items, 16)
|
||||
nilChildren = make(children, 16)
|
||||
)
|
||||
|
||||
// FreeList represents a free list of btree nodes. By default each
|
||||
// BTree has its own FreeList, but multiple BTrees can share the same
|
||||
// FreeList.
|
||||
// Two Btrees using the same freelist are safe for concurrent write access.
|
||||
type FreeList struct {
|
||||
mu sync.Mutex
|
||||
freelist []*node
|
||||
}
|
||||
|
||||
// NewFreeList creates a new free list.
|
||||
// size is the maximum size of the returned free list.
|
||||
func NewFreeList(size int) *FreeList {
|
||||
return &FreeList{freelist: make([]*node, 0, size)}
|
||||
}
|
||||
|
||||
func (f *FreeList) newNode() (n *node) {
|
||||
f.mu.Lock()
|
||||
index := len(f.freelist) - 1
|
||||
if index < 0 {
|
||||
f.mu.Unlock()
|
||||
return new(node)
|
||||
}
|
||||
n = f.freelist[index]
|
||||
f.freelist[index] = nil
|
||||
f.freelist = f.freelist[:index]
|
||||
f.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// freeNode adds the given node to the list, returning true if it was added
|
||||
// and false if it was discarded.
|
||||
func (f *FreeList) freeNode(n *node) (out bool) {
|
||||
f.mu.Lock()
|
||||
if len(f.freelist) < cap(f.freelist) {
|
||||
f.freelist = append(f.freelist, n)
|
||||
out = true
|
||||
}
|
||||
f.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// ItemIterator allows callers of Ascend* to iterate in-order over portions of
|
||||
// the tree. When this function returns false, iteration will stop and the
|
||||
// associated Ascend* function will immediately return.
|
||||
type ItemIterator func(i Item) bool
|
||||
|
||||
// New creates a new B-Tree with the given degree.
|
||||
//
|
||||
// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
|
||||
// and 2-4 children).
|
||||
func New(degree int) *BTree {
|
||||
return NewWithFreeList(degree, NewFreeList(DefaultFreeListSize))
|
||||
}
|
||||
|
||||
// NewWithFreeList creates a new B-Tree that uses the given node free list.
|
||||
func NewWithFreeList(degree int, f *FreeList) *BTree {
|
||||
if degree <= 1 {
|
||||
panic("bad degree")
|
||||
}
|
||||
return &BTree{
|
||||
degree: degree,
|
||||
cow: ©OnWriteContext{freelist: f},
|
||||
}
|
||||
}
|
||||
|
||||
// items stores items in a node.
|
||||
type items []Item
|
||||
|
||||
// insertAt inserts a value into the given index, pushing all subsequent values
|
||||
// forward.
|
||||
func (s *items) insertAt(index int, item Item) {
|
||||
*s = append(*s, nil)
|
||||
if index < len(*s) {
|
||||
copy((*s)[index+1:], (*s)[index:])
|
||||
}
|
||||
(*s)[index] = item
|
||||
}
|
||||
|
||||
// removeAt removes a value at a given index, pulling all subsequent values
|
||||
// back.
|
||||
func (s *items) removeAt(index int) Item {
|
||||
item := (*s)[index]
|
||||
copy((*s)[index:], (*s)[index+1:])
|
||||
(*s)[len(*s)-1] = nil
|
||||
*s = (*s)[:len(*s)-1]
|
||||
return item
|
||||
}
|
||||
|
||||
// pop removes and returns the last element in the list.
|
||||
func (s *items) pop() (out Item) {
|
||||
index := len(*s) - 1
|
||||
out = (*s)[index]
|
||||
(*s)[index] = nil
|
||||
*s = (*s)[:index]
|
||||
return
|
||||
}
|
||||
|
||||
// truncate truncates this instance at index so that it contains only the
|
||||
// first index items. index must be less than or equal to length.
|
||||
func (s *items) truncate(index int) {
|
||||
var toClear items
|
||||
*s, toClear = (*s)[:index], (*s)[index:]
|
||||
for len(toClear) > 0 {
|
||||
toClear = toClear[copy(toClear, nilItems):]
|
||||
}
|
||||
}
|
||||
|
||||
// find returns the index where the given item should be inserted into this
|
||||
// list. 'found' is true if the item already exists in the list at the given
|
||||
// index.
|
||||
func (s items) find(item Item) (index int, found bool) {
|
||||
i := sort.Search(len(s), func(i int) bool {
|
||||
return item.Less(s[i])
|
||||
})
|
||||
if i > 0 && !s[i-1].Less(item) {
|
||||
return i - 1, true
|
||||
}
|
||||
return i, false
|
||||
}
|
||||
|
||||
// children stores child nodes in a node.
|
||||
type children []*node
|
||||
|
||||
// insertAt inserts a value into the given index, pushing all subsequent values
|
||||
// forward.
|
||||
func (s *children) insertAt(index int, n *node) {
|
||||
*s = append(*s, nil)
|
||||
if index < len(*s) {
|
||||
copy((*s)[index+1:], (*s)[index:])
|
||||
}
|
||||
(*s)[index] = n
|
||||
}
|
||||
|
||||
// removeAt removes a value at a given index, pulling all subsequent values
|
||||
// back.
|
||||
func (s *children) removeAt(index int) *node {
|
||||
n := (*s)[index]
|
||||
copy((*s)[index:], (*s)[index+1:])
|
||||
(*s)[len(*s)-1] = nil
|
||||
*s = (*s)[:len(*s)-1]
|
||||
return n
|
||||
}
|
||||
|
||||
// pop removes and returns the last element in the list.
|
||||
func (s *children) pop() (out *node) {
|
||||
index := len(*s) - 1
|
||||
out = (*s)[index]
|
||||
(*s)[index] = nil
|
||||
*s = (*s)[:index]
|
||||
return
|
||||
}
|
||||
|
||||
// truncate truncates this instance at index so that it contains only the
|
||||
// first index children. index must be less than or equal to length.
|
||||
func (s *children) truncate(index int) {
|
||||
var toClear children
|
||||
*s, toClear = (*s)[:index], (*s)[index:]
|
||||
for len(toClear) > 0 {
|
||||
toClear = toClear[copy(toClear, nilChildren):]
|
||||
}
|
||||
}
|
||||
|
||||
// node is an internal node in a tree.
|
||||
//
|
||||
// It must at all times maintain the invariant that either
|
||||
// * len(children) == 0, len(items) unconstrained
|
||||
// * len(children) == len(items) + 1
|
||||
type node struct {
|
||||
items items
|
||||
children children
|
||||
cow *copyOnWriteContext
|
||||
}
|
||||
|
||||
func (n *node) mutableFor(cow *copyOnWriteContext) *node {
|
||||
if n.cow == cow {
|
||||
return n
|
||||
}
|
||||
out := cow.newNode()
|
||||
if cap(out.items) >= len(n.items) {
|
||||
out.items = out.items[:len(n.items)]
|
||||
} else {
|
||||
out.items = make(items, len(n.items), cap(n.items))
|
||||
}
|
||||
copy(out.items, n.items)
|
||||
// Copy children
|
||||
if cap(out.children) >= len(n.children) {
|
||||
out.children = out.children[:len(n.children)]
|
||||
} else {
|
||||
out.children = make(children, len(n.children), cap(n.children))
|
||||
}
|
||||
copy(out.children, n.children)
|
||||
return out
|
||||
}
|
||||
|
||||
func (n *node) mutableChild(i int) *node {
|
||||
c := n.children[i].mutableFor(n.cow)
|
||||
n.children[i] = c
|
||||
return c
|
||||
}
|
||||
|
||||
// split splits the given node at the given index. The current node shrinks,
|
||||
// and this function returns the item that existed at that index and a new node
|
||||
// containing all items/children after it.
|
||||
func (n *node) split(i int) (Item, *node) {
|
||||
item := n.items[i]
|
||||
next := n.cow.newNode()
|
||||
next.items = append(next.items, n.items[i+1:]...)
|
||||
n.items.truncate(i)
|
||||
if len(n.children) > 0 {
|
||||
next.children = append(next.children, n.children[i+1:]...)
|
||||
n.children.truncate(i + 1)
|
||||
}
|
||||
return item, next
|
||||
}
|
||||
|
||||
// maybeSplitChild checks if a child should be split, and if so splits it.
|
||||
// Returns whether or not a split occurred.
|
||||
func (n *node) maybeSplitChild(i, maxItems int) bool {
|
||||
if len(n.children[i].items) < maxItems {
|
||||
return false
|
||||
}
|
||||
first := n.mutableChild(i)
|
||||
item, second := first.split(maxItems / 2)
|
||||
n.items.insertAt(i, item)
|
||||
n.children.insertAt(i+1, second)
|
||||
return true
|
||||
}
|
||||
|
||||
// insert inserts an item into the subtree rooted at this node, making sure
|
||||
// no nodes in the subtree exceed maxItems items. Should an equivalent item be
|
||||
// be found/replaced by insert, it will be returned.
|
||||
func (n *node) insert(item Item, maxItems int) Item {
|
||||
i, found := n.items.find(item)
|
||||
if found {
|
||||
out := n.items[i]
|
||||
n.items[i] = item
|
||||
return out
|
||||
}
|
||||
if len(n.children) == 0 {
|
||||
n.items.insertAt(i, item)
|
||||
return nil
|
||||
}
|
||||
if n.maybeSplitChild(i, maxItems) {
|
||||
inTree := n.items[i]
|
||||
switch {
|
||||
case item.Less(inTree):
|
||||
// no change, we want first split node
|
||||
case inTree.Less(item):
|
||||
i++ // we want second split node
|
||||
default:
|
||||
out := n.items[i]
|
||||
n.items[i] = item
|
||||
return out
|
||||
}
|
||||
}
|
||||
return n.mutableChild(i).insert(item, maxItems)
|
||||
}
|
||||
|
||||
// get finds the given key in the subtree and returns it.
|
||||
func (n *node) get(key Item) Item {
|
||||
i, found := n.items.find(key)
|
||||
if found {
|
||||
return n.items[i]
|
||||
} else if len(n.children) > 0 {
|
||||
return n.children[i].get(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// min returns the first item in the subtree.
|
||||
func min(n *node) Item {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
for len(n.children) > 0 {
|
||||
n = n.children[0]
|
||||
}
|
||||
if len(n.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
return n.items[0]
|
||||
}
|
||||
|
||||
// max returns the last item in the subtree.
|
||||
func max(n *node) Item {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
for len(n.children) > 0 {
|
||||
n = n.children[len(n.children)-1]
|
||||
}
|
||||
if len(n.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
return n.items[len(n.items)-1]
|
||||
}
|
||||
|
||||
// toRemove details what item to remove in a node.remove call.
|
||||
type toRemove int
|
||||
|
||||
const (
|
||||
removeItem toRemove = iota // removes the given item
|
||||
removeMin // removes smallest item in the subtree
|
||||
removeMax // removes largest item in the subtree
|
||||
)
|
||||
|
||||
// remove removes an item from the subtree rooted at this node.
|
||||
func (n *node) remove(item Item, minItems int, typ toRemove) Item {
|
||||
var i int
|
||||
var found bool
|
||||
switch typ {
|
||||
case removeMax:
|
||||
if len(n.children) == 0 {
|
||||
return n.items.pop()
|
||||
}
|
||||
i = len(n.items)
|
||||
case removeMin:
|
||||
if len(n.children) == 0 {
|
||||
return n.items.removeAt(0)
|
||||
}
|
||||
i = 0
|
||||
case removeItem:
|
||||
i, found = n.items.find(item)
|
||||
if len(n.children) == 0 {
|
||||
if found {
|
||||
return n.items.removeAt(i)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
panic("invalid type")
|
||||
}
|
||||
// If we get to here, we have children.
|
||||
if len(n.children[i].items) <= minItems {
|
||||
return n.growChildAndRemove(i, item, minItems, typ)
|
||||
}
|
||||
child := n.mutableChild(i)
|
||||
// Either we had enough items to begin with, or we've done some
|
||||
// merging/stealing, because we've got enough now and we're ready to return
|
||||
// stuff.
|
||||
if found {
|
||||
// The item exists at index 'i', and the child we've selected can give us a
|
||||
// predecessor, since if we've gotten here it's got > minItems items in it.
|
||||
out := n.items[i]
|
||||
// We use our special-case 'remove' call with typ=maxItem to pull the
|
||||
// predecessor of item i (the rightmost leaf of our immediate left child)
|
||||
// and set it into where we pulled the item from.
|
||||
n.items[i] = child.remove(nil, minItems, removeMax)
|
||||
return out
|
||||
}
|
||||
// Final recursive call. Once we're here, we know that the item isn't in this
|
||||
// node and that the child is big enough to remove from.
|
||||
return child.remove(item, minItems, typ)
|
||||
}
|
||||
|
||||
// growChildAndRemove grows child 'i' to make sure it's possible to remove an
|
||||
// item from it while keeping it at minItems, then calls remove to actually
|
||||
// remove it.
|
||||
//
|
||||
// Most documentation says we have to do two sets of special casing:
|
||||
// 1) item is in this node
|
||||
// 2) item is in child
|
||||
// In both cases, we need to handle the two subcases:
|
||||
// A) node has enough values that it can spare one
|
||||
// B) node doesn't have enough values
|
||||
// For the latter, we have to check:
|
||||
// a) left sibling has node to spare
|
||||
// b) right sibling has node to spare
|
||||
// c) we must merge
|
||||
// To simplify our code here, we handle cases #1 and #2 the same:
|
||||
// If a node doesn't have enough items, we make sure it does (using a,b,c).
|
||||
// We then simply redo our remove call, and the second time (regardless of
|
||||
// whether we're in case 1 or 2), we'll have enough items and can guarantee
|
||||
// that we hit case A.
|
||||
func (n *node) growChildAndRemove(i int, item Item, minItems int, typ toRemove) Item {
|
||||
if i > 0 && len(n.children[i-1].items) > minItems {
|
||||
// Steal from left child
|
||||
child := n.mutableChild(i)
|
||||
stealFrom := n.mutableChild(i - 1)
|
||||
stolenItem := stealFrom.items.pop()
|
||||
child.items.insertAt(0, n.items[i-1])
|
||||
n.items[i-1] = stolenItem
|
||||
if len(stealFrom.children) > 0 {
|
||||
child.children.insertAt(0, stealFrom.children.pop())
|
||||
}
|
||||
} else if i < len(n.items) && len(n.children[i+1].items) > minItems {
|
||||
// steal from right child
|
||||
child := n.mutableChild(i)
|
||||
stealFrom := n.mutableChild(i + 1)
|
||||
stolenItem := stealFrom.items.removeAt(0)
|
||||
child.items = append(child.items, n.items[i])
|
||||
n.items[i] = stolenItem
|
||||
if len(stealFrom.children) > 0 {
|
||||
child.children = append(child.children, stealFrom.children.removeAt(0))
|
||||
}
|
||||
} else {
|
||||
if i >= len(n.items) {
|
||||
i--
|
||||
}
|
||||
child := n.mutableChild(i)
|
||||
// merge with right child
|
||||
mergeItem := n.items.removeAt(i)
|
||||
mergeChild := n.children.removeAt(i + 1)
|
||||
child.items = append(child.items, mergeItem)
|
||||
child.items = append(child.items, mergeChild.items...)
|
||||
child.children = append(child.children, mergeChild.children...)
|
||||
n.cow.freeNode(mergeChild)
|
||||
}
|
||||
return n.remove(item, minItems, typ)
|
||||
}
|
||||
|
||||
type direction int
|
||||
|
||||
const (
|
||||
descend = direction(-1)
|
||||
ascend = direction(+1)
|
||||
)
|
||||
|
||||
// iterate provides a simple method for iterating over elements in the tree.
|
||||
//
|
||||
// When ascending, the 'start' should be less than 'stop' and when descending,
|
||||
// the 'start' should be greater than 'stop'. Setting 'includeStart' to true
|
||||
// will force the iterator to include the first item when it equals 'start',
|
||||
// thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
|
||||
// "greaterThan" or "lessThan" queries.
|
||||
func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {
|
||||
var ok, found bool
|
||||
var index int
|
||||
switch dir {
|
||||
case ascend:
|
||||
if start != nil {
|
||||
index, _ = n.items.find(start)
|
||||
}
|
||||
for i := index; i < len(n.items); i++ {
|
||||
if len(n.children) > 0 {
|
||||
if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
if !includeStart && !hit && start != nil && !start.Less(n.items[i]) {
|
||||
hit = true
|
||||
continue
|
||||
}
|
||||
hit = true
|
||||
if stop != nil && !n.items[i].Less(stop) {
|
||||
return hit, false
|
||||
}
|
||||
if !iter(n.items[i]) {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
if len(n.children) > 0 {
|
||||
if hit, ok = n.children[len(n.children)-1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
case descend:
|
||||
if start != nil {
|
||||
index, found = n.items.find(start)
|
||||
if !found {
|
||||
index = index - 1
|
||||
}
|
||||
} else {
|
||||
index = len(n.items) - 1
|
||||
}
|
||||
for i := index; i >= 0; i-- {
|
||||
if start != nil && !n.items[i].Less(start) {
|
||||
if !includeStart || hit || start.Less(n.items[i]) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(n.children) > 0 {
|
||||
if hit, ok = n.children[i+1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
if stop != nil && !stop.Less(n.items[i]) {
|
||||
return hit, false // continue
|
||||
}
|
||||
hit = true
|
||||
if !iter(n.items[i]) {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
if len(n.children) > 0 {
|
||||
if hit, ok = n.children[0].iterate(dir, start, stop, includeStart, hit, iter); !ok {
|
||||
return hit, false
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit, true
|
||||
}
|
||||
|
||||
// Used for testing/debugging purposes.
|
||||
func (n *node) print(w io.Writer, level int) {
|
||||
fmt.Fprintf(w, "%sNODE:%v\n", strings.Repeat(" ", level), n.items)
|
||||
for _, c := range n.children {
|
||||
c.print(w, level+1)
|
||||
}
|
||||
}
|
||||
|
||||
// BTree is an implementation of a B-Tree.
|
||||
//
|
||||
// BTree stores Item instances in an ordered structure, allowing easy insertion,
|
||||
// removal, and iteration.
|
||||
//
|
||||
// Write operations are not safe for concurrent mutation by multiple
|
||||
// goroutines, but Read operations are.
|
||||
type BTree struct {
|
||||
degree int
|
||||
length int
|
||||
root *node
|
||||
cow *copyOnWriteContext
|
||||
}
|
||||
|
||||
// copyOnWriteContext pointers determine node ownership... a tree with a write
|
||||
// context equivalent to a node's write context is allowed to modify that node.
|
||||
// A tree whose write context does not match a node's is not allowed to modify
|
||||
// it, and must create a new, writable copy (IE: it's a Clone).
|
||||
//
|
||||
// When doing any write operation, we maintain the invariant that the current
|
||||
// node's context is equal to the context of the tree that requested the write.
|
||||
// We do this by, before we descend into any node, creating a copy with the
|
||||
// correct context if the contexts don't match.
|
||||
//
|
||||
// Since the node we're currently visiting on any write has the requesting
|
||||
// tree's context, that node is modifiable in place. Children of that node may
|
||||
// not share context, but before we descend into them, we'll make a mutable
|
||||
// copy.
|
||||
type copyOnWriteContext struct {
|
||||
freelist *FreeList
|
||||
}
|
||||
|
||||
// Clone clones the btree, lazily. Clone should not be called concurrently,
|
||||
// but the original tree (t) and the new tree (t2) can be used concurrently
|
||||
// once the Clone call completes.
|
||||
//
|
||||
// The internal tree structure of b is marked read-only and shared between t and
|
||||
// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes
|
||||
// whenever one of b's original nodes would have been modified. Read operations
|
||||
// should have no performance degredation. Write operations for both t and t2
|
||||
// will initially experience minor slow-downs caused by additional allocs and
|
||||
// copies due to the aforementioned copy-on-write logic, but should converge to
|
||||
// the original performance characteristics of the original tree.
|
||||
func (t *BTree) Clone() (t2 *BTree) {
|
||||
// Create two entirely new copy-on-write contexts.
|
||||
// This operation effectively creates three trees:
|
||||
// the original, shared nodes (old b.cow)
|
||||
// the new b.cow nodes
|
||||
// the new out.cow nodes
|
||||
cow1, cow2 := *t.cow, *t.cow
|
||||
out := *t
|
||||
t.cow = &cow1
|
||||
out.cow = &cow2
|
||||
return &out
|
||||
}
|
||||
|
||||
// maxItems returns the max number of items to allow per node.
|
||||
func (t *BTree) maxItems() int {
|
||||
return t.degree*2 - 1
|
||||
}
|
||||
|
||||
// minItems returns the min number of items to allow per node (ignored for the
|
||||
// root node).
|
||||
func (t *BTree) minItems() int {
|
||||
return t.degree - 1
|
||||
}
|
||||
|
||||
func (c *copyOnWriteContext) newNode() (n *node) {
|
||||
n = c.freelist.newNode()
|
||||
n.cow = c
|
||||
return
|
||||
}
|
||||
|
||||
type freeType int
|
||||
|
||||
const (
|
||||
ftFreelistFull freeType = iota // node was freed (available for GC, not stored in freelist)
|
||||
ftStored // node was stored in the freelist for later use
|
||||
ftNotOwned // node was ignored by COW, since it's owned by another one
|
||||
)
|
||||
|
||||
// freeNode frees a node within a given COW context, if it's owned by that
|
||||
// context. It returns what happened to the node (see freeType const
|
||||
// documentation).
|
||||
func (c *copyOnWriteContext) freeNode(n *node) freeType {
|
||||
if n.cow == c {
|
||||
// clear to allow GC
|
||||
n.items.truncate(0)
|
||||
n.children.truncate(0)
|
||||
n.cow = nil
|
||||
if c.freelist.freeNode(n) {
|
||||
return ftStored
|
||||
} else {
|
||||
return ftFreelistFull
|
||||
}
|
||||
} else {
|
||||
return ftNotOwned
|
||||
}
|
||||
}
|
||||
|
||||
// ReplaceOrInsert adds the given item to the tree. If an item in the tree
|
||||
// already equals the given one, it is removed from the tree and returned.
|
||||
// Otherwise, nil is returned.
|
||||
//
|
||||
// nil cannot be added to the tree (will panic).
|
||||
func (t *BTree) ReplaceOrInsert(item Item) Item {
|
||||
if item == nil {
|
||||
panic("nil item being added to BTree")
|
||||
}
|
||||
if t.root == nil {
|
||||
t.root = t.cow.newNode()
|
||||
t.root.items = append(t.root.items, item)
|
||||
t.length++
|
||||
return nil
|
||||
} else {
|
||||
t.root = t.root.mutableFor(t.cow)
|
||||
if len(t.root.items) >= t.maxItems() {
|
||||
item2, second := t.root.split(t.maxItems() / 2)
|
||||
oldroot := t.root
|
||||
t.root = t.cow.newNode()
|
||||
t.root.items = append(t.root.items, item2)
|
||||
t.root.children = append(t.root.children, oldroot, second)
|
||||
}
|
||||
}
|
||||
out := t.root.insert(item, t.maxItems())
|
||||
if out == nil {
|
||||
t.length++
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Delete removes an item equal to the passed in item from the tree, returning
|
||||
// it. If no such item exists, returns nil.
|
||||
func (t *BTree) Delete(item Item) Item {
|
||||
return t.deleteItem(item, removeItem)
|
||||
}
|
||||
|
||||
// DeleteMin removes the smallest item in the tree and returns it.
|
||||
// If no such item exists, returns nil.
|
||||
func (t *BTree) DeleteMin() Item {
|
||||
return t.deleteItem(nil, removeMin)
|
||||
}
|
||||
|
||||
// DeleteMax removes the largest item in the tree and returns it.
|
||||
// If no such item exists, returns nil.
|
||||
func (t *BTree) DeleteMax() Item {
|
||||
return t.deleteItem(nil, removeMax)
|
||||
}
|
||||
|
||||
func (t *BTree) deleteItem(item Item, typ toRemove) Item {
|
||||
if t.root == nil || len(t.root.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
t.root = t.root.mutableFor(t.cow)
|
||||
out := t.root.remove(item, t.minItems(), typ)
|
||||
if len(t.root.items) == 0 && len(t.root.children) > 0 {
|
||||
oldroot := t.root
|
||||
t.root = t.root.children[0]
|
||||
t.cow.freeNode(oldroot)
|
||||
}
|
||||
if out != nil {
|
||||
t.length--
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AscendRange calls the iterator for every value in the tree within the range
|
||||
// [greaterOrEqual, lessThan), until iterator returns false.
|
||||
func (t *BTree) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(ascend, greaterOrEqual, lessThan, true, false, iterator)
|
||||
}
|
||||
|
||||
// AscendLessThan calls the iterator for every value in the tree within the range
|
||||
// [first, pivot), until iterator returns false.
|
||||
func (t *BTree) AscendLessThan(pivot Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(ascend, nil, pivot, false, false, iterator)
|
||||
}
|
||||
|
||||
// AscendGreaterOrEqual calls the iterator for every value in the tree within
|
||||
// the range [pivot, last], until iterator returns false.
|
||||
func (t *BTree) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(ascend, pivot, nil, true, false, iterator)
|
||||
}
|
||||
|
||||
// Ascend calls the iterator for every value in the tree within the range
|
||||
// [first, last], until iterator returns false.
|
||||
func (t *BTree) Ascend(iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(ascend, nil, nil, false, false, iterator)
|
||||
}
|
||||
|
||||
// DescendRange calls the iterator for every value in the tree within the range
|
||||
// [lessOrEqual, greaterThan), until iterator returns false.
|
||||
func (t *BTree) DescendRange(lessOrEqual, greaterThan Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(descend, lessOrEqual, greaterThan, true, false, iterator)
|
||||
}
|
||||
|
||||
// DescendLessOrEqual calls the iterator for every value in the tree within the range
|
||||
// [pivot, first], until iterator returns false.
|
||||
func (t *BTree) DescendLessOrEqual(pivot Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(descend, pivot, nil, true, false, iterator)
|
||||
}
|
||||
|
||||
// DescendGreaterThan calls the iterator for every value in the tree within
|
||||
// the range (pivot, last], until iterator returns false.
|
||||
func (t *BTree) DescendGreaterThan(pivot Item, iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(descend, nil, pivot, false, false, iterator)
|
||||
}
|
||||
|
||||
// Descend calls the iterator for every value in the tree within the range
|
||||
// [last, first], until iterator returns false.
|
||||
func (t *BTree) Descend(iterator ItemIterator) {
|
||||
if t.root == nil {
|
||||
return
|
||||
}
|
||||
t.root.iterate(descend, nil, nil, false, false, iterator)
|
||||
}
|
||||
|
||||
// Get looks for the key item in the tree, returning it. It returns nil if
|
||||
// unable to find that item.
|
||||
func (t *BTree) Get(key Item) Item {
|
||||
if t.root == nil {
|
||||
return nil
|
||||
}
|
||||
return t.root.get(key)
|
||||
}
|
||||
|
||||
// Min returns the smallest item in the tree, or nil if the tree is empty.
|
||||
func (t *BTree) Min() Item {
|
||||
return min(t.root)
|
||||
}
|
||||
|
||||
// Max returns the largest item in the tree, or nil if the tree is empty.
|
||||
func (t *BTree) Max() Item {
|
||||
return max(t.root)
|
||||
}
|
||||
|
||||
// Has returns true if the given key is in the tree.
|
||||
func (t *BTree) Has(key Item) bool {
|
||||
return t.Get(key) != nil
|
||||
}
|
||||
|
||||
// Len returns the number of items currently in the tree.
|
||||
func (t *BTree) Len() int {
|
||||
return t.length
|
||||
}
|
||||
|
||||
// Clear removes all items from the btree. If addNodesToFreelist is true,
|
||||
// t's nodes are added to its freelist as part of this call, until the freelist
|
||||
// is full. Otherwise, the root node is simply dereferenced and the subtree
|
||||
// left to Go's normal GC processes.
|
||||
//
|
||||
// This can be much faster
|
||||
// than calling Delete on all elements, because that requires finding/removing
|
||||
// each element in the tree and updating the tree accordingly. It also is
|
||||
// somewhat faster than creating a new tree to replace the old one, because
|
||||
// nodes from the old tree are reclaimed into the freelist for use by the new
|
||||
// one, instead of being lost to the garbage collector.
|
||||
//
|
||||
// This call takes:
|
||||
// O(1): when addNodesToFreelist is false, this is a single operation.
|
||||
// O(1): when the freelist is already full, it breaks out immediately
|
||||
// O(freelist size): when the freelist is empty and the nodes are all owned
|
||||
// by this tree, nodes are added to the freelist until full.
|
||||
// O(tree size): when all nodes are owned by another tree, all nodes are
|
||||
// iterated over looking for nodes to add to the freelist, and due to
|
||||
// ownership, none are.
|
||||
func (t *BTree) Clear(addNodesToFreelist bool) {
|
||||
if t.root != nil && addNodesToFreelist {
|
||||
t.root.reset(t.cow)
|
||||
}
|
||||
t.root, t.length = nil, 0
|
||||
}
|
||||
|
||||
// reset returns a subtree to the freelist. It breaks out immediately if the
|
||||
// freelist is full, since the only benefit of iterating is to fill that
|
||||
// freelist up. Returns true if parent reset call should continue.
|
||||
func (n *node) reset(c *copyOnWriteContext) bool {
|
||||
for _, child := range n.children {
|
||||
if !child.reset(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return c.freeNode(n) != ftFreelistFull
|
||||
}
|
||||
|
||||
// Int implements the Item interface for integers.
|
||||
type Int int
|
||||
|
||||
// Less returns true if int(a) < int(b).
|
||||
func (a Int) Less(b Item) bool {
|
||||
return a < b.(Int)
|
||||
}
|
||||
76
vendor/github.com/google/btree/btree_mem.go
сгенерированный
поставляемый
Обычный файл
76
vendor/github.com/google/btree/btree_mem.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,76 @@
|
||||
// Copyright 2014 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// This binary compares memory usage between btree and gollrb.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/google/btree"
|
||||
"github.com/petar/GoLLRB/llrb"
|
||||
)
|
||||
|
||||
var (
|
||||
size = flag.Int("size", 1000000, "size of the tree to build")
|
||||
degree = flag.Int("degree", 8, "degree of btree")
|
||||
gollrb = flag.Bool("llrb", false, "use llrb instead of btree")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
vals := rand.Perm(*size)
|
||||
var t, v interface{}
|
||||
v = vals
|
||||
var stats runtime.MemStats
|
||||
for i := 0; i < 10; i++ {
|
||||
runtime.GC()
|
||||
}
|
||||
fmt.Println("-------- BEFORE ----------")
|
||||
runtime.ReadMemStats(&stats)
|
||||
fmt.Printf("%+v\n", stats)
|
||||
start := time.Now()
|
||||
if *gollrb {
|
||||
tr := llrb.New()
|
||||
for _, v := range vals {
|
||||
tr.ReplaceOrInsert(llrb.Int(v))
|
||||
}
|
||||
t = tr // keep it around
|
||||
} else {
|
||||
tr := btree.New(*degree)
|
||||
for _, v := range vals {
|
||||
tr.ReplaceOrInsert(btree.Int(v))
|
||||
}
|
||||
t = tr // keep it around
|
||||
}
|
||||
fmt.Printf("%v inserts in %v\n", *size, time.Since(start))
|
||||
fmt.Println("-------- AFTER ----------")
|
||||
runtime.ReadMemStats(&stats)
|
||||
fmt.Printf("%+v\n", stats)
|
||||
for i := 0; i < 10; i++ {
|
||||
runtime.GC()
|
||||
}
|
||||
fmt.Println("-------- AFTER GC ----------")
|
||||
runtime.ReadMemStats(&stats)
|
||||
fmt.Printf("%+v\n", stats)
|
||||
if t == v {
|
||||
fmt.Println("to make sure vals and tree aren't GC'd")
|
||||
}
|
||||
}
|
||||
8
vendor/github.com/hashicorp/go-sockaddr/go.mod
сгенерированный
поставляемый
Обычный файл
8
vendor/github.com/hashicorp/go-sockaddr/go.mod
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,8 @@
|
||||
module github.com/hashicorp/go-sockaddr
|
||||
|
||||
require (
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/mitchellh/cli v1.0.0
|
||||
github.com/mitchellh/go-wordwrap v1.0.0
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible
|
||||
)
|
||||
24
vendor/github.com/hashicorp/go-sockaddr/go.sum
сгенерированный
поставляемый
Обычный файл
24
vendor/github.com/hashicorp/go-sockaddr/go.sum
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,24 @@
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc h1:MeuS1UDyZyFH++6vVy44PuufTeFF0d0nfI6XB87YGSk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
6
vendor/github.com/hashicorp/memberlist/.travis.yml
сгенерированный
поставляемый
6
vendor/github.com/hashicorp/memberlist/.travis.yml
сгенерированный
поставляемый
@@ -9,5 +9,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
install:
|
||||
- make deps
|
||||
install: true
|
||||
|
||||
env:
|
||||
- GO111MODULE=on # Enable Go modules in 1.11
|
||||
|
||||
5
vendor/github.com/hashicorp/memberlist/broadcast.go
сгенерированный
поставляемый
5
vendor/github.com/hashicorp/memberlist/broadcast.go
сгенерированный
поставляемый
@@ -29,6 +29,11 @@ func (b *memberlistBroadcast) Invalidates(other Broadcast) bool {
|
||||
return b.node == mb.node
|
||||
}
|
||||
|
||||
// memberlist.NamedBroadcast optional interface
|
||||
func (b *memberlistBroadcast) Name() string {
|
||||
return b.node
|
||||
}
|
||||
|
||||
func (b *memberlistBroadcast) Message() []byte {
|
||||
return b.msg
|
||||
}
|
||||
|
||||
20
vendor/github.com/hashicorp/memberlist/go.mod
сгенерированный
поставляемый
Обычный файл
20
vendor/github.com/hashicorp/memberlist/go.mod
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,20 @@
|
||||
module github.com/hashicorp/memberlist
|
||||
|
||||
require (
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||
github.com/hashicorp/go-msgpack v0.5.3
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hashicorp/go-sockaddr v1.0.0
|
||||
github.com/miekg/dns v1.0.14
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3 // indirect
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 // indirect
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5 // indirect
|
||||
)
|
||||
38
vendor/github.com/hashicorp/memberlist/go.sum
сгенерированный
поставляемый
Обычный файл
38
vendor/github.com/hashicorp/memberlist/go.sum
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,38 @@
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3 h1:KYQXGkl6vs02hK7pK4eIbw0NpNPedieTSTEiJ//bwGs=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 h1:x6rhz8Y9CjbgQkccRGmELH6K+LJj7tOoh3XWeC1yaQM=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5 h1:x6r4Jo0KNzOOzYd8lbcRsqjuqEASK6ob3auvWYM4/8U=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
23
vendor/github.com/hashicorp/memberlist/net_transport.go
сгенерированный
поставляемый
23
vendor/github.com/hashicorp/memberlist/net_transport.go
сгенерированный
поставляемый
@@ -221,6 +221,16 @@ func (t *NetTransport) Shutdown() error {
|
||||
// and hands them off to the stream channel.
|
||||
func (t *NetTransport) tcpListen(tcpLn *net.TCPListener) {
|
||||
defer t.wg.Done()
|
||||
|
||||
// baseDelay is the initial delay after an AcceptTCP() error before attempting again
|
||||
const baseDelay = 5 * time.Millisecond
|
||||
|
||||
// maxDelay is the maximum delay after an AcceptTCP() error before attempting again.
|
||||
// In the case that tcpListen() is error-looping, it will delay the shutdown check.
|
||||
// Therefore, changes to maxDelay may have an effect on the latency of shutdown.
|
||||
const maxDelay = 1 * time.Second
|
||||
|
||||
var loopDelay time.Duration
|
||||
for {
|
||||
conn, err := tcpLn.AcceptTCP()
|
||||
if err != nil {
|
||||
@@ -228,9 +238,22 @@ func (t *NetTransport) tcpListen(tcpLn *net.TCPListener) {
|
||||
break
|
||||
}
|
||||
|
||||
if loopDelay == 0 {
|
||||
loopDelay = baseDelay
|
||||
} else {
|
||||
loopDelay *= 2
|
||||
}
|
||||
|
||||
if loopDelay > maxDelay {
|
||||
loopDelay = maxDelay
|
||||
}
|
||||
|
||||
t.logger.Printf("[ERR] memberlist: Error accepting TCP connection: %v", err)
|
||||
time.Sleep(loopDelay)
|
||||
continue
|
||||
}
|
||||
// No error, reset loop delay
|
||||
loopDelay = 0
|
||||
|
||||
t.streamCh <- conn
|
||||
}
|
||||
|
||||
415
vendor/github.com/hashicorp/memberlist/queue.go
сгенерированный
поставляемый
415
vendor/github.com/hashicorp/memberlist/queue.go
сгенерированный
поставляемый
@@ -1,8 +1,10 @@
|
||||
package memberlist
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"github.com/google/btree"
|
||||
)
|
||||
|
||||
// TransmitLimitedQueue is used to queue messages to broadcast to
|
||||
@@ -19,35 +21,93 @@ type TransmitLimitedQueue struct {
|
||||
// number of retransmissions attempted.
|
||||
RetransmitMult int
|
||||
|
||||
sync.Mutex
|
||||
bcQueue limitedBroadcasts
|
||||
mu sync.Mutex
|
||||
tq *btree.BTree // stores *limitedBroadcast as btree.Item
|
||||
tm map[string]*limitedBroadcast
|
||||
idGen int64
|
||||
}
|
||||
|
||||
type limitedBroadcast struct {
|
||||
transmits int // Number of transmissions attempted.
|
||||
transmits int // btree-key[0]: Number of transmissions attempted.
|
||||
msgLen int64 // btree-key[1]: copied from len(b.Message())
|
||||
id int64 // btree-key[2]: unique incrementing id stamped at submission time
|
||||
b Broadcast
|
||||
|
||||
name string // set if Broadcast is a NamedBroadcast
|
||||
}
|
||||
|
||||
// Less tests whether the current item is less than the given argument.
|
||||
//
|
||||
// This must provide a strict weak ordering.
|
||||
// If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only
|
||||
// hold one of either a or b in the tree).
|
||||
//
|
||||
// default ordering is
|
||||
// - [transmits=0, ..., transmits=inf]
|
||||
// - [transmits=0:len=999, ..., transmits=0:len=2, ...]
|
||||
// - [transmits=0:len=999,id=999, ..., transmits=0:len=999:id=1, ...]
|
||||
func (b *limitedBroadcast) Less(than btree.Item) bool {
|
||||
o := than.(*limitedBroadcast)
|
||||
if b.transmits < o.transmits {
|
||||
return true
|
||||
} else if b.transmits > o.transmits {
|
||||
return false
|
||||
}
|
||||
if b.msgLen > o.msgLen {
|
||||
return true
|
||||
} else if b.msgLen < o.msgLen {
|
||||
return false
|
||||
}
|
||||
return b.id > o.id
|
||||
}
|
||||
|
||||
// for testing; emits in transmit order if reverse=false
|
||||
func (q *TransmitLimitedQueue) orderedView(reverse bool) []*limitedBroadcast {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
out := make([]*limitedBroadcast, 0, len(q.bcQueue))
|
||||
if reverse {
|
||||
for i := 0; i < len(q.bcQueue); i++ {
|
||||
out = append(out, q.bcQueue[i])
|
||||
}
|
||||
} else {
|
||||
for i := len(q.bcQueue) - 1; i >= 0; i-- {
|
||||
out = append(out, q.bcQueue[i])
|
||||
}
|
||||
}
|
||||
out := make([]*limitedBroadcast, 0, q.lenLocked())
|
||||
q.walkReadOnlyLocked(reverse, func(cur *limitedBroadcast) bool {
|
||||
out = append(out, cur)
|
||||
return true
|
||||
})
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type limitedBroadcasts []*limitedBroadcast
|
||||
// walkReadOnlyLocked calls f for each item in the queue traversing it in
|
||||
// natural order (by Less) when reverse=false and the opposite when true. You
|
||||
// must hold the mutex.
|
||||
//
|
||||
// This method panics if you attempt to mutate the item during traversal. The
|
||||
// underlying btree should also not be mutated during traversal.
|
||||
func (q *TransmitLimitedQueue) walkReadOnlyLocked(reverse bool, f func(*limitedBroadcast) bool) {
|
||||
if q.lenLocked() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
iter := func(item btree.Item) bool {
|
||||
cur := item.(*limitedBroadcast)
|
||||
|
||||
prevTransmits := cur.transmits
|
||||
prevMsgLen := cur.msgLen
|
||||
prevID := cur.id
|
||||
|
||||
keepGoing := f(cur)
|
||||
|
||||
if prevTransmits != cur.transmits || prevMsgLen != cur.msgLen || prevID != cur.id {
|
||||
panic("edited queue while walking read only")
|
||||
}
|
||||
|
||||
return keepGoing
|
||||
}
|
||||
|
||||
if reverse {
|
||||
q.tq.Descend(iter) // end with transmit 0
|
||||
} else {
|
||||
q.tq.Ascend(iter) // start with transmit 0
|
||||
}
|
||||
}
|
||||
|
||||
// Broadcast is something that can be broadcasted via gossip to
|
||||
// the memberlist cluster.
|
||||
@@ -65,123 +125,298 @@ type Broadcast interface {
|
||||
Finished()
|
||||
}
|
||||
|
||||
// NamedBroadcast is an optional extension of the Broadcast interface that
|
||||
// gives each message a unique string name, and that is used to optimize
|
||||
//
|
||||
// You shoud ensure that Invalidates() checks the same uniqueness as the
|
||||
// example below:
|
||||
//
|
||||
// func (b *foo) Invalidates(other Broadcast) bool {
|
||||
// nb, ok := other.(NamedBroadcast)
|
||||
// if !ok {
|
||||
// return false
|
||||
// }
|
||||
// return b.Name() == nb.Name()
|
||||
// }
|
||||
//
|
||||
// Invalidates() isn't currently used for NamedBroadcasts, but that may change
|
||||
// in the future.
|
||||
type NamedBroadcast interface {
|
||||
Broadcast
|
||||
// The unique identity of this broadcast message.
|
||||
Name() string
|
||||
}
|
||||
|
||||
// UniqueBroadcast is an optional interface that indicates that each message is
|
||||
// intrinsically unique and there is no need to scan the broadcast queue for
|
||||
// duplicates.
|
||||
//
|
||||
// You should ensure that Invalidates() always returns false if implementing
|
||||
// this interface. Invalidates() isn't currently used for UniqueBroadcasts, but
|
||||
// that may change in the future.
|
||||
type UniqueBroadcast interface {
|
||||
Broadcast
|
||||
// UniqueBroadcast is just a marker method for this interface.
|
||||
UniqueBroadcast()
|
||||
}
|
||||
|
||||
// QueueBroadcast is used to enqueue a broadcast
|
||||
func (q *TransmitLimitedQueue) QueueBroadcast(b Broadcast) {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
q.queueBroadcast(b, 0)
|
||||
}
|
||||
|
||||
// Check if this message invalidates another
|
||||
n := len(q.bcQueue)
|
||||
for i := 0; i < n; i++ {
|
||||
if b.Invalidates(q.bcQueue[i].b) {
|
||||
q.bcQueue[i].b.Finished()
|
||||
copy(q.bcQueue[i:], q.bcQueue[i+1:])
|
||||
q.bcQueue[n-1] = nil
|
||||
q.bcQueue = q.bcQueue[:n-1]
|
||||
n--
|
||||
// lazyInit initializes internal data structures the first time they are
|
||||
// needed. You must already hold the mutex.
|
||||
func (q *TransmitLimitedQueue) lazyInit() {
|
||||
if q.tq == nil {
|
||||
q.tq = btree.New(32)
|
||||
}
|
||||
if q.tm == nil {
|
||||
q.tm = make(map[string]*limitedBroadcast)
|
||||
}
|
||||
}
|
||||
|
||||
// queueBroadcast is like QueueBroadcast but you can use a nonzero value for
|
||||
// the initial transmit tier assigned to the message. This is meant to be used
|
||||
// for unit testing.
|
||||
func (q *TransmitLimitedQueue) queueBroadcast(b Broadcast, initialTransmits int) {
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
q.lazyInit()
|
||||
|
||||
if q.idGen == math.MaxInt64 {
|
||||
// it's super duper unlikely to wrap around within the retransmit limit
|
||||
q.idGen = 1
|
||||
} else {
|
||||
q.idGen++
|
||||
}
|
||||
id := q.idGen
|
||||
|
||||
lb := &limitedBroadcast{
|
||||
transmits: initialTransmits,
|
||||
msgLen: int64(len(b.Message())),
|
||||
id: id,
|
||||
b: b,
|
||||
}
|
||||
unique := false
|
||||
if nb, ok := b.(NamedBroadcast); ok {
|
||||
lb.name = nb.Name()
|
||||
} else if _, ok := b.(UniqueBroadcast); ok {
|
||||
unique = true
|
||||
}
|
||||
|
||||
// Check if this message invalidates another.
|
||||
if lb.name != "" {
|
||||
if old, ok := q.tm[lb.name]; ok {
|
||||
old.b.Finished()
|
||||
q.deleteItem(old)
|
||||
}
|
||||
} else if !unique {
|
||||
// Slow path, hopefully nothing hot hits this.
|
||||
var remove []*limitedBroadcast
|
||||
q.tq.Ascend(func(item btree.Item) bool {
|
||||
cur := item.(*limitedBroadcast)
|
||||
|
||||
// Special Broadcasts can only invalidate each other.
|
||||
switch cur.b.(type) {
|
||||
case NamedBroadcast:
|
||||
// noop
|
||||
case UniqueBroadcast:
|
||||
// noop
|
||||
default:
|
||||
if b.Invalidates(cur.b) {
|
||||
cur.b.Finished()
|
||||
remove = append(remove, cur)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
for _, cur := range remove {
|
||||
q.deleteItem(cur)
|
||||
}
|
||||
}
|
||||
|
||||
// Append to the queue
|
||||
q.bcQueue = append(q.bcQueue, &limitedBroadcast{0, b})
|
||||
// Append to the relevant queue.
|
||||
q.addItem(lb)
|
||||
}
|
||||
|
||||
// deleteItem removes the given item from the overall datastructure. You
|
||||
// must already hold the mutex.
|
||||
func (q *TransmitLimitedQueue) deleteItem(cur *limitedBroadcast) {
|
||||
_ = q.tq.Delete(cur)
|
||||
if cur.name != "" {
|
||||
delete(q.tm, cur.name)
|
||||
}
|
||||
|
||||
if q.tq.Len() == 0 {
|
||||
// At idle there's no reason to let the id generator keep going
|
||||
// indefinitely.
|
||||
q.idGen = 0
|
||||
}
|
||||
}
|
||||
|
||||
// addItem adds the given item into the overall datastructure. You must already
|
||||
// hold the mutex.
|
||||
func (q *TransmitLimitedQueue) addItem(cur *limitedBroadcast) {
|
||||
_ = q.tq.ReplaceOrInsert(cur)
|
||||
if cur.name != "" {
|
||||
q.tm[cur.name] = cur
|
||||
}
|
||||
}
|
||||
|
||||
// getTransmitRange returns a pair of min/max values for transmit values
|
||||
// represented by the current queue contents. Both values represent actual
|
||||
// transmit values on the interval [0, len). You must already hold the mutex.
|
||||
func (q *TransmitLimitedQueue) getTransmitRange() (minTransmit, maxTransmit int) {
|
||||
if q.lenLocked() == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
minItem, maxItem := q.tq.Min(), q.tq.Max()
|
||||
if minItem == nil || maxItem == nil {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
min := minItem.(*limitedBroadcast).transmits
|
||||
max := maxItem.(*limitedBroadcast).transmits
|
||||
|
||||
return min, max
|
||||
}
|
||||
|
||||
// GetBroadcasts is used to get a number of broadcasts, up to a byte limit
|
||||
// and applying a per-message overhead as provided.
|
||||
func (q *TransmitLimitedQueue) GetBroadcasts(overhead, limit int) [][]byte {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
// Fast path the default case
|
||||
if len(q.bcQueue) == 0 {
|
||||
if q.lenLocked() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
transmitLimit := retransmitLimit(q.RetransmitMult, q.NumNodes())
|
||||
bytesUsed := 0
|
||||
var toSend [][]byte
|
||||
|
||||
for i := len(q.bcQueue) - 1; i >= 0; i-- {
|
||||
// Check if this is within our limits
|
||||
b := q.bcQueue[i]
|
||||
msg := b.b.Message()
|
||||
if bytesUsed+overhead+len(msg) > limit {
|
||||
var (
|
||||
bytesUsed int
|
||||
toSend [][]byte
|
||||
reinsert []*limitedBroadcast
|
||||
)
|
||||
|
||||
// Visit fresher items first, but only look at stuff that will fit.
|
||||
// We'll go tier by tier, grabbing the largest items first.
|
||||
minTr, maxTr := q.getTransmitRange()
|
||||
for transmits := minTr; transmits <= maxTr; /*do not advance automatically*/ {
|
||||
free := int64(limit - bytesUsed - overhead)
|
||||
if free <= 0 {
|
||||
break // bail out early
|
||||
}
|
||||
|
||||
// Search for the least element on a given tier (by transmit count) as
|
||||
// defined in the limitedBroadcast.Less function that will fit into our
|
||||
// remaining space.
|
||||
greaterOrEqual := &limitedBroadcast{
|
||||
transmits: transmits,
|
||||
msgLen: free,
|
||||
id: math.MaxInt64,
|
||||
}
|
||||
lessThan := &limitedBroadcast{
|
||||
transmits: transmits + 1,
|
||||
msgLen: math.MaxInt64,
|
||||
id: math.MaxInt64,
|
||||
}
|
||||
var keep *limitedBroadcast
|
||||
q.tq.AscendRange(greaterOrEqual, lessThan, func(item btree.Item) bool {
|
||||
cur := item.(*limitedBroadcast)
|
||||
// Check if this is within our limits
|
||||
if int64(len(cur.b.Message())) > free {
|
||||
// If this happens it's a bug in the datastructure or
|
||||
// surrounding use doing something like having len(Message())
|
||||
// change over time. There's enough going on here that it's
|
||||
// probably sane to just skip it and move on for now.
|
||||
return true
|
||||
}
|
||||
keep = cur
|
||||
return false
|
||||
})
|
||||
if keep == nil {
|
||||
// No more items of an appropriate size in the tier.
|
||||
transmits++
|
||||
continue
|
||||
}
|
||||
|
||||
msg := keep.b.Message()
|
||||
|
||||
// Add to slice to send
|
||||
bytesUsed += overhead + len(msg)
|
||||
toSend = append(toSend, msg)
|
||||
|
||||
// Check if we should stop transmission
|
||||
b.transmits++
|
||||
if b.transmits >= transmitLimit {
|
||||
b.b.Finished()
|
||||
n := len(q.bcQueue)
|
||||
q.bcQueue[i], q.bcQueue[n-1] = q.bcQueue[n-1], nil
|
||||
q.bcQueue = q.bcQueue[:n-1]
|
||||
q.deleteItem(keep)
|
||||
if keep.transmits+1 >= transmitLimit {
|
||||
keep.b.Finished()
|
||||
} else {
|
||||
// We need to bump this item down to another transmit tier, but
|
||||
// because it would be in the same direction that we're walking the
|
||||
// tiers, we will have to delay the reinsertion until we are
|
||||
// finished our search. Otherwise we'll possibly re-add the message
|
||||
// when we ascend to the next tier.
|
||||
keep.transmits++
|
||||
reinsert = append(reinsert, keep)
|
||||
}
|
||||
}
|
||||
|
||||
// If we are sending anything, we need to re-sort to deal
|
||||
// with adjusted transmit counts
|
||||
if len(toSend) > 0 {
|
||||
q.bcQueue.Sort()
|
||||
for _, cur := range reinsert {
|
||||
q.addItem(cur)
|
||||
}
|
||||
|
||||
return toSend
|
||||
}
|
||||
|
||||
// NumQueued returns the number of queued messages
|
||||
func (q *TransmitLimitedQueue) NumQueued() int {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
return len(q.bcQueue)
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
return q.lenLocked()
|
||||
}
|
||||
|
||||
// Reset clears all the queued messages
|
||||
func (q *TransmitLimitedQueue) Reset() {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
for _, b := range q.bcQueue {
|
||||
b.b.Finished()
|
||||
// lenLocked returns the length of the overall queue datastructure. You must
|
||||
// hold the mutex.
|
||||
func (q *TransmitLimitedQueue) lenLocked() int {
|
||||
if q.tq == nil {
|
||||
return 0
|
||||
}
|
||||
q.bcQueue = nil
|
||||
return q.tq.Len()
|
||||
}
|
||||
|
||||
// Reset clears all the queued messages. Should only be used for tests.
|
||||
func (q *TransmitLimitedQueue) Reset() {
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
q.walkReadOnlyLocked(false, func(cur *limitedBroadcast) bool {
|
||||
cur.b.Finished()
|
||||
return true
|
||||
})
|
||||
|
||||
q.tq = nil
|
||||
q.tm = nil
|
||||
q.idGen = 0
|
||||
}
|
||||
|
||||
// Prune will retain the maxRetain latest messages, and the rest
|
||||
// will be discarded. This can be used to prevent unbounded queue sizes
|
||||
func (q *TransmitLimitedQueue) Prune(maxRetain int) {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
// Do nothing if queue size is less than the limit
|
||||
n := len(q.bcQueue)
|
||||
if n < maxRetain {
|
||||
return
|
||||
for q.tq.Len() > maxRetain {
|
||||
item := q.tq.Max()
|
||||
if item == nil {
|
||||
break
|
||||
}
|
||||
cur := item.(*limitedBroadcast)
|
||||
cur.b.Finished()
|
||||
q.deleteItem(cur)
|
||||
}
|
||||
|
||||
// Invalidate the messages we will be removing
|
||||
for i := 0; i < n-maxRetain; i++ {
|
||||
q.bcQueue[i].b.Finished()
|
||||
}
|
||||
|
||||
// Move the messages, and retain only the last maxRetain
|
||||
copy(q.bcQueue[0:], q.bcQueue[n-maxRetain:])
|
||||
q.bcQueue = q.bcQueue[:maxRetain]
|
||||
}
|
||||
|
||||
func (b limitedBroadcasts) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
func (b limitedBroadcasts) Less(i, j int) bool {
|
||||
return b[i].transmits < b[j].transmits
|
||||
}
|
||||
|
||||
func (b limitedBroadcasts) Swap(i, j int) {
|
||||
b[i], b[j] = b[j], b[i]
|
||||
}
|
||||
|
||||
func (b limitedBroadcasts) Sort() {
|
||||
sort.Sort(sort.Reverse(b))
|
||||
}
|
||||
|
||||
838
vendor/github.com/mattn/go-runewidth/runewidth.go
сгенерированный
поставляемый
838
vendor/github.com/mattn/go-runewidth/runewidth.go
сгенерированный
поставляемый
@@ -1,22 +1,34 @@
|
||||
package runewidth
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
// EastAsianWidth will be set true if the current locale is CJK
|
||||
EastAsianWidth bool
|
||||
|
||||
// ZeroWidthJoiner is flag to set to use UTR#51 ZWJ
|
||||
ZeroWidthJoiner bool
|
||||
|
||||
// DefaultCondition is a condition in current locale
|
||||
DefaultCondition = &Condition{EastAsianWidth}
|
||||
DefaultCondition = &Condition{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
handleEnv()
|
||||
}
|
||||
|
||||
func handleEnv() {
|
||||
env := os.Getenv("RUNEWIDTH_EASTASIAN")
|
||||
if env == "" {
|
||||
EastAsianWidth = IsEastAsian()
|
||||
} else {
|
||||
EastAsianWidth = env == "1"
|
||||
}
|
||||
// update DefaultCondition
|
||||
DefaultCondition.EastAsianWidth = EastAsianWidth
|
||||
DefaultCondition.ZeroWidthJoiner = ZeroWidthJoiner
|
||||
}
|
||||
|
||||
type interval struct {
|
||||
@@ -44,7 +56,7 @@ func inTable(r rune, t table) bool {
|
||||
bot := 0
|
||||
top := len(t) - 1
|
||||
for top >= bot {
|
||||
mid := (bot + top) / 2
|
||||
mid := (bot + top) >> 1
|
||||
|
||||
switch {
|
||||
case t[mid].last < r:
|
||||
@@ -66,8 +78,7 @@ var private = table{
|
||||
var nonprint = table{
|
||||
{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
|
||||
{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
|
||||
{0x2028, 0x2029},
|
||||
{0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
|
||||
{0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
|
||||
}
|
||||
|
||||
@@ -261,19 +272,54 @@ var ambiguous = table{
|
||||
}
|
||||
|
||||
var emoji = table{
|
||||
{0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C},
|
||||
{0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397},
|
||||
{0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE},
|
||||
{0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7},
|
||||
{0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD},
|
||||
{0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579},
|
||||
{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
|
||||
{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
|
||||
{0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF},
|
||||
{0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2},
|
||||
{0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0},
|
||||
{0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E},
|
||||
{0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618},
|
||||
{0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623},
|
||||
{0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F},
|
||||
{0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642},
|
||||
{0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663},
|
||||
{0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B},
|
||||
{0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699},
|
||||
{0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26AA, 0x26AB},
|
||||
{0x26B0, 0x26B1}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
|
||||
{0x26C8, 0x26C8}, {0x26CE, 0x26CF}, {0x26D1, 0x26D1},
|
||||
{0x26D3, 0x26D4}, {0x26E9, 0x26EA}, {0x26F0, 0x26F5},
|
||||
{0x26F7, 0x26FA}, {0x26FD, 0x26FD}, {0x2702, 0x2702},
|
||||
{0x2705, 0x2705}, {0x2708, 0x270D}, {0x270F, 0x270F},
|
||||
{0x2712, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
|
||||
{0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
|
||||
{0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
|
||||
{0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
|
||||
{0x2757, 0x2757}, {0x2763, 0x2764}, {0x2795, 0x2797},
|
||||
{0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
|
||||
{0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
|
||||
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
|
||||
{0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
|
||||
{0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F170, 0x1F171},
|
||||
{0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
|
||||
{0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F202}, {0x1F21A, 0x1F21A},
|
||||
{0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F250, 0x1F251},
|
||||
{0x1F300, 0x1F321}, {0x1F324, 0x1F393}, {0x1F396, 0x1F397},
|
||||
{0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0}, {0x1F3F3, 0x1F3F5},
|
||||
{0x1F3F7, 0x1F4FD}, {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E},
|
||||
{0x1F550, 0x1F567}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A},
|
||||
{0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590},
|
||||
{0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2},
|
||||
{0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3},
|
||||
{0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3},
|
||||
{0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3},
|
||||
{0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5},
|
||||
{0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3},
|
||||
{0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8},
|
||||
{0x1F5B1, 0x1F5B2}, {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4},
|
||||
{0x1F5D1, 0x1F5D3}, {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1},
|
||||
{0x1F5E3, 0x1F5E3}, {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF},
|
||||
{0x1F5F3, 0x1F5F3}, {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5},
|
||||
{0x1F6CB, 0x1F6D2}, {0x1F6E0, 0x1F6E5}, {0x1F6E9, 0x1F6E9},
|
||||
{0x1F6EB, 0x1F6EC}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F9},
|
||||
{0x1F910, 0x1F93A}, {0x1F93C, 0x1F93E}, {0x1F940, 0x1F945},
|
||||
{0x1F947, 0x1F970}, {0x1F973, 0x1F976}, {0x1F97A, 0x1F97A},
|
||||
{0x1F97C, 0x1F9A2}, {0x1F9B0, 0x1F9B9}, {0x1F9C0, 0x1F9C2},
|
||||
{0x1F9D0, 0x1F9FF},
|
||||
}
|
||||
|
||||
var notassigned = table{
|
||||
@@ -493,314 +539,141 @@ var notassigned = table{
|
||||
}
|
||||
|
||||
var neutral = table{
|
||||
{0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F},
|
||||
{0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB},
|
||||
{0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5},
|
||||
{0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD},
|
||||
{0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB},
|
||||
{0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6},
|
||||
{0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF},
|
||||
{0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
|
||||
{0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},
|
||||
{0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},
|
||||
{0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},
|
||||
{0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},
|
||||
{0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},
|
||||
{0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},
|
||||
{0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
|
||||
{0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
|
||||
{0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
|
||||
{0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
|
||||
{0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
|
||||
{0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB},
|
||||
{0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD},
|
||||
{0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3},
|
||||
{0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9},
|
||||
{0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250},
|
||||
{0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294},
|
||||
{0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3},
|
||||
{0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8},
|
||||
{0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1},
|
||||
{0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
|
||||
{0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC},
|
||||
{0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF},
|
||||
{0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375},
|
||||
{0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D},
|
||||
{0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385},
|
||||
{0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A},
|
||||
{0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0},
|
||||
{0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6},
|
||||
{0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F},
|
||||
{0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482},
|
||||
{0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF},
|
||||
{0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559},
|
||||
{0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589},
|
||||
{0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F},
|
||||
{0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF},
|
||||
{0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3},
|
||||
{0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7},
|
||||
{0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4},
|
||||
{0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A},
|
||||
{0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F},
|
||||
{0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C},
|
||||
{0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640},
|
||||
{0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669},
|
||||
{0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670},
|
||||
{0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5},
|
||||
{0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE},
|
||||
{0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8},
|
||||
{0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF},
|
||||
{0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE},
|
||||
{0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F},
|
||||
{0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F},
|
||||
{0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F},
|
||||
{0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1},
|
||||
{0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3},
|
||||
{0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9},
|
||||
{0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819},
|
||||
{0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824},
|
||||
{0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D},
|
||||
{0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B},
|
||||
{0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD},
|
||||
{0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF},
|
||||
{0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939},
|
||||
{0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C},
|
||||
{0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948},
|
||||
{0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F},
|
||||
{0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961},
|
||||
{0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F},
|
||||
{0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F},
|
||||
{0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983},
|
||||
{0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
|
||||
{0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
|
||||
{0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0},
|
||||
{0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC},
|
||||
{0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7},
|
||||
{0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3},
|
||||
{0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3},
|
||||
{0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB},
|
||||
{0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A},
|
||||
{0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
|
||||
{0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39},
|
||||
{0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42},
|
||||
{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
|
||||
{0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F},
|
||||
{0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75},
|
||||
{0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D},
|
||||
{0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},
|
||||
{0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},
|
||||
{0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},
|
||||
{0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},
|
||||
{0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},
|
||||
{0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
|
||||
{0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},
|
||||
{0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},
|
||||
{0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},
|
||||
{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
|
||||
{0x0531, 0x0556}, {0x0559, 0x055F}, {0x0561, 0x0587},
|
||||
{0x0589, 0x058A}, {0x058D, 0x058F}, {0x0591, 0x05C7},
|
||||
{0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0600, 0x061C},
|
||||
{0x061E, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1},
|
||||
{0x07C0, 0x07FA}, {0x0800, 0x082D}, {0x0830, 0x083E},
|
||||
{0x0840, 0x085B}, {0x085E, 0x085E}, {0x08A0, 0x08B4},
|
||||
{0x08B6, 0x08BD}, {0x08D4, 0x0983}, {0x0985, 0x098C},
|
||||
{0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0},
|
||||
{0x09B2, 0x09B2}, {0x09B6, 0x09B9}, {0x09BC, 0x09C4},
|
||||
{0x09C7, 0x09C8}, {0x09CB, 0x09CE}, {0x09D7, 0x09D7},
|
||||
{0x09DC, 0x09DD}, {0x09DF, 0x09E3}, {0x09E6, 0x09FB},
|
||||
{0x0A01, 0x0A03}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10},
|
||||
{0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
|
||||
{0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C},
|
||||
{0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D},
|
||||
{0x0A51, 0x0A51}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E},
|
||||
{0x0A66, 0x0A75}, {0x0A81, 0x0A83}, {0x0A85, 0x0A8D},
|
||||
{0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0},
|
||||
{0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC},
|
||||
{0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5},
|
||||
{0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC},
|
||||
{0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1},
|
||||
{0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0},
|
||||
{0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01},
|
||||
{0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
|
||||
{0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5},
|
||||
{0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0},
|
||||
{0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AF9},
|
||||
{0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
|
||||
{0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33},
|
||||
{0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D},
|
||||
{0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40},
|
||||
{0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C},
|
||||
{0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57},
|
||||
{0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63},
|
||||
{0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71},
|
||||
{0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83},
|
||||
{0x0B35, 0x0B39}, {0x0B3C, 0x0B44}, {0x0B47, 0x0B48},
|
||||
{0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B5C, 0x0B5D},
|
||||
{0x0B5F, 0x0B63}, {0x0B66, 0x0B77}, {0x0B82, 0x0B83},
|
||||
{0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
|
||||
{0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F},
|
||||
{0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9},
|
||||
{0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2},
|
||||
{0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD},
|
||||
{0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF},
|
||||
{0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9},
|
||||
{0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03},
|
||||
{0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28},
|
||||
{0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40},
|
||||
{0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
|
||||
{0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61},
|
||||
{0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E},
|
||||
{0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81},
|
||||
{0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
|
||||
{0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD},
|
||||
{0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA},
|
||||
{0x0C00, 0x0C03}, {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10},
|
||||
{0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3D, 0x0C44},
|
||||
{0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
|
||||
{0x0C58, 0x0C5A}, {0x0C60, 0x0C63}, {0x0C66, 0x0C6F},
|
||||
{0x0C78, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
|
||||
{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
|
||||
{0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE},
|
||||
{0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6},
|
||||
{0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD},
|
||||
{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1},
|
||||
{0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2},
|
||||
{0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C},
|
||||
{0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D},
|
||||
{0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48},
|
||||
{0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E},
|
||||
{0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57},
|
||||
{0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63},
|
||||
{0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79},
|
||||
{0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96},
|
||||
{0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD},
|
||||
{0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1},
|
||||
{0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF},
|
||||
{0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4},
|
||||
{0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33},
|
||||
{0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45},
|
||||
{0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F},
|
||||
{0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82},
|
||||
{0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A},
|
||||
{0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F},
|
||||
{0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7},
|
||||
{0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1},
|
||||
{0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC},
|
||||
{0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6},
|
||||
{0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF},
|
||||
{0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12},
|
||||
{0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17},
|
||||
{0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29},
|
||||
{0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35},
|
||||
{0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38},
|
||||
{0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B},
|
||||
{0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F},
|
||||
{0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E},
|
||||
{0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85},
|
||||
{0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97},
|
||||
{0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6},
|
||||
{0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4},
|
||||
{0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A},
|
||||
{0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031},
|
||||
{0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A},
|
||||
{0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F},
|
||||
{0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055},
|
||||
{0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D},
|
||||
{0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064},
|
||||
{0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070},
|
||||
{0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082},
|
||||
{0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C},
|
||||
{0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F},
|
||||
{0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D},
|
||||
{0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7},
|
||||
{0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB},
|
||||
{0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF},
|
||||
{0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256},
|
||||
{0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288},
|
||||
{0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5},
|
||||
{0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5},
|
||||
{0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315},
|
||||
{0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368},
|
||||
{0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399},
|
||||
{0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400},
|
||||
{0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F},
|
||||
{0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B},
|
||||
{0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED},
|
||||
{0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C},
|
||||
{0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731},
|
||||
{0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751},
|
||||
{0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
|
||||
{0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5},
|
||||
{0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5},
|
||||
{0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3},
|
||||
{0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA},
|
||||
{0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD},
|
||||
{0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805},
|
||||
{0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D},
|
||||
{0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842},
|
||||
{0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884},
|
||||
{0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9},
|
||||
{0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E},
|
||||
{0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928},
|
||||
{0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932},
|
||||
{0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940},
|
||||
{0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D},
|
||||
{0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9},
|
||||
{0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF},
|
||||
{0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18},
|
||||
{0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F},
|
||||
{0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56},
|
||||
{0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60},
|
||||
{0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64},
|
||||
{0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C},
|
||||
{0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99},
|
||||
{0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD},
|
||||
{0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03},
|
||||
{0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34},
|
||||
{0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B},
|
||||
{0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42},
|
||||
{0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59},
|
||||
{0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73},
|
||||
{0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82},
|
||||
{0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5},
|
||||
{0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA},
|
||||
{0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9},
|
||||
{0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6},
|
||||
{0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC},
|
||||
{0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1},
|
||||
{0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23},
|
||||
{0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35},
|
||||
{0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49},
|
||||
{0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77},
|
||||
{0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88},
|
||||
{0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3},
|
||||
{0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8},
|
||||
{0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1},
|
||||
{0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6},
|
||||
{0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A},
|
||||
{0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F},
|
||||
{0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5},
|
||||
{0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15},
|
||||
{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
|
||||
{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},
|
||||
{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D01, 0x0D03},
|
||||
{0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A},
|
||||
{0x0D3D, 0x0D44}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4F},
|
||||
{0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, {0x0D82, 0x0D83},
|
||||
{0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB},
|
||||
{0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA},
|
||||
{0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF},
|
||||
{0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, {0x0E01, 0x0E3A},
|
||||
{0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, {0x0E84, 0x0E84},
|
||||
{0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, {0x0E8D, 0x0E8D},
|
||||
{0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3},
|
||||
{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, {0x0EAA, 0x0EAB},
|
||||
{0x0EAD, 0x0EB9}, {0x0EBB, 0x0EBD}, {0x0EC0, 0x0EC4},
|
||||
{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},
|
||||
{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
|
||||
{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
|
||||
{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
|
||||
{0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
|
||||
{0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
|
||||
{0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
|
||||
{0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
|
||||
{0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
|
||||
{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
|
||||
{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
|
||||
{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
|
||||
{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},
|
||||
{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
|
||||
{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},
|
||||
{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},
|
||||
{0x1820, 0x1877}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},
|
||||
{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},
|
||||
{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},
|
||||
{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},
|
||||
{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},
|
||||
{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},
|
||||
{0x1AB0, 0x1ABE}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},
|
||||
{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},
|
||||
{0x1C4D, 0x1C88}, {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CF6},
|
||||
{0x1CF8, 0x1CF9}, {0x1D00, 0x1DF5}, {0x1DFB, 0x1F15},
|
||||
{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
|
||||
{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
|
||||
{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
|
||||
{0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE},
|
||||
{0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC},
|
||||
{0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB},
|
||||
{0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF},
|
||||
{0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE},
|
||||
{0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012},
|
||||
{0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B},
|
||||
{0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023},
|
||||
{0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E},
|
||||
{0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
|
||||
{0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A},
|
||||
{0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043},
|
||||
{0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046},
|
||||
{0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053},
|
||||
{0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F},
|
||||
{0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070},
|
||||
{0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C},
|
||||
{0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080},
|
||||
{0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D},
|
||||
{0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
|
||||
{0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC},
|
||||
{0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4},
|
||||
{0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102},
|
||||
{0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107},
|
||||
{0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114},
|
||||
{0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118},
|
||||
{0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123},
|
||||
{0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127},
|
||||
{0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A},
|
||||
{0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134},
|
||||
{0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B},
|
||||
{0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149},
|
||||
{0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D},
|
||||
{0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152},
|
||||
{0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
|
||||
{0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
|
||||
{0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
|
||||
{0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
|
||||
{0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
|
||||
{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
|
||||
{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
|
||||
{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
|
||||
{0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20F0},
|
||||
{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
|
||||
{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
|
||||
{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
|
||||
{0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
|
||||
{0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188},
|
||||
{0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F},
|
||||
{0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3},
|
||||
{0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD},
|
||||
{0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD},
|
||||
{0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3},
|
||||
{0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF},
|
||||
{0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A},
|
||||
{0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214},
|
||||
{0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222},
|
||||
{0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D},
|
||||
{0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247},
|
||||
{0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F},
|
||||
{0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D},
|
||||
{0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294},
|
||||
{0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE},
|
||||
{0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308},
|
||||
{0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B},
|
||||
{0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F},
|
||||
{0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B},
|
||||
{0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3},
|
||||
{0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8},
|
||||
{0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE},
|
||||
{0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA},
|
||||
{0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591},
|
||||
{0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1},
|
||||
{0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF},
|
||||
{0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD},
|
||||
{0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7},
|
||||
{0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604},
|
||||
{0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
|
||||
{0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
|
||||
{0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
|
||||
{0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
|
||||
{0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
|
||||
{0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
|
||||
{0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
|
||||
{0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
|
||||
{0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
|
||||
{0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
|
||||
{0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
|
||||
{0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
|
||||
{0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
|
||||
{0x23F1, 0x23F2}, {0x23F4, 0x23FE}, {0x2400, 0x2426},
|
||||
{0x2440, 0x244A}, {0x24EA, 0x24EA}, {0x254C, 0x254F},
|
||||
{0x2574, 0x257F}, {0x2590, 0x2591}, {0x2596, 0x259F},
|
||||
{0x25A2, 0x25A2}, {0x25AA, 0x25B1}, {0x25B4, 0x25B5},
|
||||
{0x25B8, 0x25BB}, {0x25BE, 0x25BF}, {0x25C2, 0x25C5},
|
||||
{0x25C9, 0x25CA}, {0x25CC, 0x25CD}, {0x25D2, 0x25E1},
|
||||
{0x25E6, 0x25EE}, {0x25F0, 0x25FC}, {0x25FF, 0x2604},
|
||||
{0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613},
|
||||
{0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F},
|
||||
{0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F},
|
||||
@@ -811,256 +684,98 @@ var neutral = table{
|
||||
{0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709},
|
||||
{0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B},
|
||||
{0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756},
|
||||
{0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769},
|
||||
{0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C},
|
||||
{0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F},
|
||||
{0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772},
|
||||
{0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775},
|
||||
{0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF},
|
||||
{0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5},
|
||||
{0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE},
|
||||
{0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF},
|
||||
{0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983},
|
||||
{0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988},
|
||||
{0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B},
|
||||
{0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E},
|
||||
{0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991},
|
||||
{0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994},
|
||||
{0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997},
|
||||
{0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8},
|
||||
{0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB},
|
||||
{0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD},
|
||||
{0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A},
|
||||
{0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46},
|
||||
{0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54},
|
||||
{0x2758, 0x2775}, {0x2780, 0x2794}, {0x2798, 0x27AF},
|
||||
{0x27B1, 0x27BE}, {0x27C0, 0x27E5}, {0x27EE, 0x2984},
|
||||
{0x2987, 0x2B1A}, {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54},
|
||||
{0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9},
|
||||
{0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF},
|
||||
{0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B},
|
||||
{0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4},
|
||||
{0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1},
|
||||
{0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD},
|
||||
{0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27},
|
||||
{0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F},
|
||||
{0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96},
|
||||
{0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2CF3},
|
||||
{0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D},
|
||||
{0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96},
|
||||
{0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6},
|
||||
{0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE},
|
||||
{0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF},
|
||||
{0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03},
|
||||
{0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08},
|
||||
{0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B},
|
||||
{0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16},
|
||||
{0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A},
|
||||
{0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D},
|
||||
{0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21},
|
||||
{0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24},
|
||||
{0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27},
|
||||
{0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E},
|
||||
{0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B},
|
||||
{0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41},
|
||||
{0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F},
|
||||
{0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD},
|
||||
{0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C},
|
||||
{0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629},
|
||||
{0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E},
|
||||
{0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673},
|
||||
{0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F},
|
||||
{0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F},
|
||||
{0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1},
|
||||
{0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F},
|
||||
{0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770},
|
||||
{0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A},
|
||||
{0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE},
|
||||
{0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9},
|
||||
{0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801},
|
||||
{0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806},
|
||||
{0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822},
|
||||
{0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827},
|
||||
{0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837},
|
||||
{0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873},
|
||||
{0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3},
|
||||
{0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF},
|
||||
{0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7},
|
||||
{0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC},
|
||||
{0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925},
|
||||
{0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946},
|
||||
{0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F},
|
||||
{0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2},
|
||||
{0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9},
|
||||
{0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0},
|
||||
{0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9},
|
||||
{0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5},
|
||||
{0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9},
|
||||
{0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E},
|
||||
{0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34},
|
||||
{0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43},
|
||||
{0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D},
|
||||
{0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F},
|
||||
{0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79},
|
||||
{0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C},
|
||||
{0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF},
|
||||
{0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4},
|
||||
{0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD},
|
||||
{0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1},
|
||||
{0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD},
|
||||
{0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB},
|
||||
{0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1},
|
||||
{0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5},
|
||||
{0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
|
||||
{0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E44},
|
||||
{0x303F, 0x303F}, {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B},
|
||||
{0xA640, 0xA6F7}, {0xA700, 0xA7AE}, {0xA7B0, 0xA7B7},
|
||||
{0xA7F7, 0xA82B}, {0xA830, 0xA839}, {0xA840, 0xA877},
|
||||
{0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA8FD},
|
||||
{0xA900, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
|
||||
{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
|
||||
{0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
|
||||
{0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
|
||||
{0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
|
||||
{0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F},
|
||||
{0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2},
|
||||
{0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7},
|
||||
{0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB},
|
||||
{0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9},
|
||||
{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F},
|
||||
{0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06},
|
||||
{0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E},
|
||||
{0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36},
|
||||
{0xAB30, 0xAB65}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
|
||||
{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
|
||||
{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
|
||||
{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
|
||||
{0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1},
|
||||
{0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E},
|
||||
{0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7},
|
||||
{0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD},
|
||||
{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},
|
||||
{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},
|
||||
{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC},
|
||||
{0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A},
|
||||
{0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D},
|
||||
{0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
{0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178},
|
||||
{0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E},
|
||||
{0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC},
|
||||
{0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0},
|
||||
{0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F},
|
||||
{0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341},
|
||||
{0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375},
|
||||
{0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F},
|
||||
{0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0},
|
||||
{0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F},
|
||||
{0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
|
||||
{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
|
||||
{0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
|
||||
{0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
|
||||
{0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
|
||||
{0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
|
||||
{0x10300, 0x10323}, {0x10330, 0x1034A}, {0x10350, 0x1037A},
|
||||
{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
|
||||
{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
|
||||
{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
|
||||
{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
|
||||
{0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857},
|
||||
{0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878},
|
||||
{0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF},
|
||||
{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF},
|
||||
{0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F},
|
||||
{0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F},
|
||||
{0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF},
|
||||
{0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00},
|
||||
{0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F},
|
||||
{0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33},
|
||||
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47},
|
||||
{0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E},
|
||||
{0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F},
|
||||
{0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4},
|
||||
{0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6},
|
||||
{0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55},
|
||||
{0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F},
|
||||
{0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
|
||||
{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
|
||||
{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
|
||||
{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},
|
||||
{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
|
||||
{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33},
|
||||
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A47}, {0x10A50, 0x10A58},
|
||||
{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
|
||||
{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
|
||||
{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
|
||||
{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
|
||||
{0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000},
|
||||
{0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037},
|
||||
{0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065},
|
||||
{0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081},
|
||||
{0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2},
|
||||
{0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA},
|
||||
{0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1},
|
||||
{0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102},
|
||||
{0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C},
|
||||
{0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143},
|
||||
{0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175},
|
||||
{0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182},
|
||||
{0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE},
|
||||
{0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9},
|
||||
{0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9},
|
||||
{0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC},
|
||||
{0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
|
||||
{0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231},
|
||||
{0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235},
|
||||
{0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E},
|
||||
{0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x1104D},
|
||||
{0x11052, 0x1106F}, {0x1107F, 0x110C1}, {0x110D0, 0x110E8},
|
||||
{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11143},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111CD}, {0x111D0, 0x111DF},
|
||||
{0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x1123E},
|
||||
{0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D},
|
||||
{0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9},
|
||||
{0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2},
|
||||
{0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301},
|
||||
{0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
|
||||
{0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
|
||||
{0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D},
|
||||
{0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344},
|
||||
{0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA},
|
||||
{0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C},
|
||||
{0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330},
|
||||
{0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133C, 0x11344},
|
||||
{0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350},
|
||||
{0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363},
|
||||
{0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434},
|
||||
{0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441},
|
||||
{0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446},
|
||||
{0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459},
|
||||
{0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF},
|
||||
{0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9},
|
||||
{0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0},
|
||||
{0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5},
|
||||
{0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9},
|
||||
{0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5},
|
||||
{0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE},
|
||||
{0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB},
|
||||
{0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632},
|
||||
{0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D},
|
||||
{0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643},
|
||||
{0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
|
||||
{0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC},
|
||||
{0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5},
|
||||
{0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9},
|
||||
{0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721},
|
||||
{0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B},
|
||||
{0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E},
|
||||
{0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9},
|
||||
{0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8},
|
||||
{0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F},
|
||||
{0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E},
|
||||
{0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45},
|
||||
{0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71},
|
||||
{0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9},
|
||||
{0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3},
|
||||
{0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399},
|
||||
{0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C},
|
||||
{0x11370, 0x11374}, {0x11400, 0x11459}, {0x1145B, 0x1145B},
|
||||
{0x1145D, 0x1145D}, {0x11480, 0x114C7}, {0x114D0, 0x114D9},
|
||||
{0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644},
|
||||
{0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B7},
|
||||
{0x116C0, 0x116C9}, {0x11700, 0x11719}, {0x1171D, 0x1172B},
|
||||
{0x11730, 0x1173F}, {0x118A0, 0x118F2}, {0x118FF, 0x118FF},
|
||||
{0x11AC0, 0x11AF8}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36},
|
||||
{0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F},
|
||||
{0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x12000, 0x12399},
|
||||
{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38},
|
||||
{0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F},
|
||||
{0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5},
|
||||
{0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B},
|
||||
{0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44},
|
||||
{0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
|
||||
{0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44},
|
||||
{0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92},
|
||||
{0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
|
||||
{0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C},
|
||||
{0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3},
|
||||
{0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164},
|
||||
{0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C},
|
||||
{0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182},
|
||||
{0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9},
|
||||
{0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241},
|
||||
{0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356},
|
||||
{0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C},
|
||||
{0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6},
|
||||
{0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB},
|
||||
{0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A},
|
||||
{0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539},
|
||||
{0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546},
|
||||
{0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0},
|
||||
{0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB},
|
||||
{0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714},
|
||||
{0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735},
|
||||
{0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E},
|
||||
{0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789},
|
||||
{0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2},
|
||||
{0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF},
|
||||
{0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A},
|
||||
{0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75},
|
||||
{0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86},
|
||||
{0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF},
|
||||
{0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
|
||||
{0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4},
|
||||
{0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943},
|
||||
{0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
|
||||
{0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45},
|
||||
{0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77},
|
||||
{0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, {0x16F50, 0x16F7E},
|
||||
{0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
|
||||
{0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3},
|
||||
{0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1E8},
|
||||
{0x1D200, 0x1D245}, {0x1D300, 0x1D356}, {0x1D360, 0x1D371},
|
||||
{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},
|
||||
{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},
|
||||
{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},
|
||||
{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},
|
||||
{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},
|
||||
{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},
|
||||
{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},
|
||||
{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
|
||||
{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
|
||||
{0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
|
||||
{0x1E900, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
|
||||
{0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22},
|
||||
{0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32},
|
||||
{0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B},
|
||||
@@ -1091,12 +806,16 @@ var neutral = table{
|
||||
|
||||
// Condition have flag EastAsianWidth whether the current locale is CJK or not.
|
||||
type Condition struct {
|
||||
EastAsianWidth bool
|
||||
EastAsianWidth bool
|
||||
ZeroWidthJoiner bool
|
||||
}
|
||||
|
||||
// NewCondition return new instance of Condition which is current locale.
|
||||
func NewCondition() *Condition {
|
||||
return &Condition{EastAsianWidth}
|
||||
return &Condition{
|
||||
EastAsianWidth: EastAsianWidth,
|
||||
ZeroWidthJoiner: ZeroWidthJoiner,
|
||||
}
|
||||
}
|
||||
|
||||
// RuneWidth returns the number of cells in r.
|
||||
@@ -1114,14 +833,37 @@ func (c *Condition) RuneWidth(r rune) int {
|
||||
}
|
||||
}
|
||||
|
||||
// StringWidth return width as you can see
|
||||
func (c *Condition) StringWidth(s string) (width int) {
|
||||
func (c *Condition) stringWidth(s string) (width int) {
|
||||
for _, r := range []rune(s) {
|
||||
width += c.RuneWidth(r)
|
||||
}
|
||||
return width
|
||||
}
|
||||
|
||||
func (c *Condition) stringWidthZeroJoiner(s string) (width int) {
|
||||
r1, r2 := rune(0), rune(0)
|
||||
for _, r := range []rune(s) {
|
||||
if r == 0xFE0E || r == 0xFE0F {
|
||||
continue
|
||||
}
|
||||
w := c.RuneWidth(r)
|
||||
if r2 == 0x200D && inTables(r, emoji) && inTables(r1, emoji) {
|
||||
w = 0
|
||||
}
|
||||
width += w
|
||||
r1, r2 = r2, r
|
||||
}
|
||||
return width
|
||||
}
|
||||
|
||||
// StringWidth return width as you can see
|
||||
func (c *Condition) StringWidth(s string) (width int) {
|
||||
if c.ZeroWidthJoiner {
|
||||
return c.stringWidthZeroJoiner(s)
|
||||
}
|
||||
return c.stringWidth(s)
|
||||
}
|
||||
|
||||
// Truncate return string truncated with w cells
|
||||
func (c *Condition) Truncate(s string, w int, tail string) string {
|
||||
if c.StringWidth(s) <= w {
|
||||
|
||||
8
vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
сгенерированный
поставляемый
Обычный файл
8
vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,8 @@
|
||||
// +build appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
return false
|
||||
}
|
||||
1
vendor/github.com/mattn/go-runewidth/runewidth_js.go
сгенерированный
поставляемый
1
vendor/github.com/mattn/go-runewidth/runewidth_js.go
сгенерированный
поставляемый
@@ -1,4 +1,5 @@
|
||||
// +build js
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
|
||||
4
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
сгенерированный
поставляемый
4
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
сгенерированный
поставляемый
@@ -1,4 +1,6 @@
|
||||
// +build !windows,!js
|
||||
// +build !windows
|
||||
// +build !js
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
|
||||
3
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
сгенерированный
поставляемый
3
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
сгенерированный
поставляемый
@@ -1,3 +1,6 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
|
||||
7
vendor/github.com/miekg/dns/README.md
сгенерированный
поставляемый
7
vendor/github.com/miekg/dns/README.md
сгенерированный
поставляемый
@@ -99,8 +99,8 @@ work:
|
||||
|
||||
## Examples
|
||||
|
||||
A short "how to use the API" is at the beginning of doc.go (this also will show
|
||||
when you call `godoc github.com/miekg/dns`).
|
||||
A short "how to use the API" is at the beginning of doc.go (this also will show when you call `godoc
|
||||
github.com/miekg/dns`).
|
||||
|
||||
Example programs can be found in the `github.com/miekg/exdns` repository.
|
||||
|
||||
@@ -158,8 +158,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
|
||||
* 7553 - URI record
|
||||
* 7858 - DNS over TLS: Initiation and Performance Considerations
|
||||
* 7871 - EDNS0 Client Subnet
|
||||
* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)
|
||||
* 7873 - Domain Name System (DNS) Cookies
|
||||
* 8080 - EdDSA for DNSSEC
|
||||
* 8499 - DNS Terminology
|
||||
|
||||
## Loosely Based Upon
|
||||
|
||||
|
||||
10
vendor/github.com/miekg/dns/acceptfunc.go
сгенерированный
поставляемый
10
vendor/github.com/miekg/dns/acceptfunc.go
сгенерированный
поставляемый
@@ -10,7 +10,7 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
|
||||
// * opcode isn't OpcodeQuery or OpcodeNotify
|
||||
// * Zero bit isn't zero
|
||||
// * has more than 1 question in the question section
|
||||
// * has more than 0 RRs in the Answer section
|
||||
// * has more than 1 RR in the Answer section
|
||||
// * has more than 0 RRs in the Authority section
|
||||
// * has more than 2 RRs in the Additional section
|
||||
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
MsgIgnore // Ignore the error and send nothing back.
|
||||
)
|
||||
|
||||
var defaultMsgAcceptFunc = func(dh Header) MsgAcceptAction {
|
||||
func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {
|
||||
if isResponse := dh.Bits&_QR != 0; isResponse {
|
||||
return MsgIgnore
|
||||
}
|
||||
@@ -41,10 +41,12 @@ var defaultMsgAcceptFunc = func(dh Header) MsgAcceptAction {
|
||||
if dh.Qdcount != 1 {
|
||||
return MsgReject
|
||||
}
|
||||
if dh.Ancount != 0 {
|
||||
// NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11.
|
||||
if dh.Ancount > 1 {
|
||||
return MsgReject
|
||||
}
|
||||
if dh.Nscount != 0 {
|
||||
// IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3.
|
||||
if dh.Nscount > 1 {
|
||||
return MsgReject
|
||||
}
|
||||
if dh.Arcount > 2 {
|
||||
|
||||
36
vendor/github.com/miekg/dns/client.go
сгенерированный
поставляемый
36
vendor/github.com/miekg/dns/client.go
сгенерированный
поставляемый
@@ -320,16 +320,12 @@ func (co *Conn) Read(p []byte) (n int, err error) {
|
||||
return 0, err
|
||||
}
|
||||
if l > len(p) {
|
||||
return int(l), io.ErrShortBuffer
|
||||
return l, io.ErrShortBuffer
|
||||
}
|
||||
return tcpRead(r, p[:l])
|
||||
}
|
||||
// UDP connection
|
||||
n, err = co.Conn.Read(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
return n, err
|
||||
return co.Conn.Read(p)
|
||||
}
|
||||
|
||||
// WriteMsg sends a message through the connection co.
|
||||
@@ -351,10 +347,8 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = co.Write(out); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err = co.Write(out)
|
||||
return err
|
||||
}
|
||||
|
||||
// Write implements the net.Conn Write method.
|
||||
@@ -376,8 +370,7 @@ func (co *Conn) Write(p []byte) (n int, err error) {
|
||||
n, err := io.Copy(w, bytes.NewReader(p))
|
||||
return int(n), err
|
||||
}
|
||||
n, err = co.Conn.Write(p)
|
||||
return n, err
|
||||
return co.Conn.Write(p)
|
||||
}
|
||||
|
||||
// Return the appropriate timeout for a specific request
|
||||
@@ -444,11 +437,7 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||
// DialTimeout acts like Dial but takes a timeout.
|
||||
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
|
||||
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
return client.Dial(address)
|
||||
}
|
||||
|
||||
// DialWithTLS connects to the address on the named network with TLS.
|
||||
@@ -457,12 +446,7 @@ func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, er
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
return client.Dial(address)
|
||||
}
|
||||
|
||||
// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
|
||||
@@ -471,11 +455,7 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
return client.Dial(address)
|
||||
}
|
||||
|
||||
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||
|
||||
100
vendor/github.com/miekg/dns/defaults.go
сгенерированный
поставляемый
100
vendor/github.com/miekg/dns/defaults.go
сгенерированный
поставляемый
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const hexDigit = "0123456789abcdef"
|
||||
@@ -163,11 +164,72 @@ func (dns *Msg) IsEdns0() *OPT {
|
||||
// the number of labels. When false is returned the number of labels is not
|
||||
// defined. Also note that this function is extremely liberal; almost any
|
||||
// string is a valid domain name as the DNS is 8 bit protocol. It checks if each
|
||||
// label fits in 63 characters, but there is no length check for the entire
|
||||
// string s. I.e. a domain name longer than 255 characters is considered valid.
|
||||
// label fits in 63 characters and that the entire name will fit into the 255
|
||||
// octet wire format limit.
|
||||
func IsDomainName(s string) (labels int, ok bool) {
|
||||
_, labels, err := packDomainName(s, nil, 0, compressionMap{}, false)
|
||||
return labels, err == nil
|
||||
// XXX: The logic in this function was copied from packDomainName and
|
||||
// should be kept in sync with that function.
|
||||
|
||||
const lenmsg = 256
|
||||
|
||||
if len(s) == 0 { // Ok, for instance when dealing with update RR without any rdata.
|
||||
return 0, false
|
||||
}
|
||||
|
||||
s = Fqdn(s)
|
||||
|
||||
// Each dot ends a segment of the name. Except for escaped dots (\.), which
|
||||
// are normal dots.
|
||||
|
||||
var (
|
||||
off int
|
||||
begin int
|
||||
wasDot bool
|
||||
)
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '\\':
|
||||
if off+1 > lenmsg {
|
||||
return labels, false
|
||||
}
|
||||
|
||||
// check for \DDD
|
||||
if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) {
|
||||
i += 3
|
||||
begin += 3
|
||||
} else {
|
||||
i++
|
||||
begin++
|
||||
}
|
||||
|
||||
wasDot = false
|
||||
case '.':
|
||||
if wasDot {
|
||||
// two dots back to back is not legal
|
||||
return labels, false
|
||||
}
|
||||
wasDot = true
|
||||
|
||||
labelLen := i - begin
|
||||
if labelLen >= 1<<6 { // top two bits of length must be clear
|
||||
return labels, false
|
||||
}
|
||||
|
||||
// off can already (we're in a loop) be bigger than lenmsg
|
||||
// this happens when a name isn't fully qualified
|
||||
off += 1 + labelLen
|
||||
if off > lenmsg {
|
||||
return labels, false
|
||||
}
|
||||
|
||||
labels++
|
||||
begin = i + 1
|
||||
default:
|
||||
wasDot = false
|
||||
}
|
||||
}
|
||||
|
||||
return labels, true
|
||||
}
|
||||
|
||||
// IsSubDomain checks if child is indeed a child of the parent. If child and parent
|
||||
@@ -181,7 +243,7 @@ func IsSubDomain(parent, child string) bool {
|
||||
// The checking is performed on the binary payload.
|
||||
func IsMsg(buf []byte) error {
|
||||
// Header
|
||||
if len(buf) < 12 {
|
||||
if len(buf) < headerSize {
|
||||
return errors.New("dns: bad message header")
|
||||
}
|
||||
// Header: Opcode
|
||||
@@ -191,11 +253,18 @@ func IsMsg(buf []byte) error {
|
||||
|
||||
// IsFqdn checks if a domain name is fully qualified.
|
||||
func IsFqdn(s string) bool {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
s2 := strings.TrimSuffix(s, ".")
|
||||
if s == s2 {
|
||||
return false
|
||||
}
|
||||
return s[l-1] == '.'
|
||||
|
||||
i := strings.LastIndexFunc(s2, func(r rune) bool {
|
||||
return r != '\\'
|
||||
})
|
||||
|
||||
// Test whether we have an even number of escape sequences before
|
||||
// the dot or none.
|
||||
return (len(s2)-i)%2 != 0
|
||||
}
|
||||
|
||||
// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181.
|
||||
@@ -244,12 +313,19 @@ func ReverseAddr(addr string) (arpa string, err error) {
|
||||
if ip == nil {
|
||||
return "", &Error{err: "unrecognized address: " + addr}
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." +
|
||||
strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil
|
||||
if v4 := ip.To4(); v4 != nil {
|
||||
buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa."))
|
||||
// Add it, in reverse, to the buffer
|
||||
for i := len(v4) - 1; i >= 0; i-- {
|
||||
buf = strconv.AppendInt(buf, int64(v4[i]), 10)
|
||||
buf = append(buf, '.')
|
||||
}
|
||||
// Append "in-addr.arpa." and return (buf already has the final .)
|
||||
buf = append(buf, "in-addr.arpa."...)
|
||||
return string(buf), nil
|
||||
}
|
||||
// Must be IPv6
|
||||
buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
|
||||
buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa."))
|
||||
// Add it, in reverse, to the buffer
|
||||
for i := len(ip) - 1; i >= 0; i-- {
|
||||
v := ip[i]
|
||||
|
||||
43
vendor/github.com/miekg/dns/dns.go
сгенерированный
поставляемый
43
vendor/github.com/miekg/dns/dns.go
сгенерированный
поставляемый
@@ -41,8 +41,23 @@ type RR interface {
|
||||
// size will be returned and domain names will be added to the map for future compression.
|
||||
len(off int, compression map[string]struct{}) int
|
||||
|
||||
// pack packs an RR into wire format.
|
||||
pack(msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error)
|
||||
// pack packs the records RDATA into wire format. The header will
|
||||
// already have been packed into msg.
|
||||
pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error)
|
||||
|
||||
// unpack unpacks an RR from wire format.
|
||||
//
|
||||
// This will only be called on a new and empty RR type with only the header populated. It
|
||||
// will only be called if the record's RDATA is non-empty.
|
||||
unpack(msg []byte, off int) (off1 int, err error)
|
||||
|
||||
// parse parses an RR from zone file format.
|
||||
//
|
||||
// This will only be called on a new and empty RR type with only the header populated.
|
||||
parse(c *zlexer, origin, file string) *ParseError
|
||||
|
||||
// isDuplicate returns whether the two RRs are duplicates.
|
||||
isDuplicate(r2 RR) bool
|
||||
}
|
||||
|
||||
// RR_Header is the header all DNS resource records share.
|
||||
@@ -81,6 +96,19 @@ func (h *RR_Header) len(off int, compression map[string]struct{}) int {
|
||||
return l
|
||||
}
|
||||
|
||||
func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
// RR_Header has no RDATA to pack.
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (h *RR_Header) unpack(msg []byte, off int) (int, error) {
|
||||
panic("dns: internal error: unpack should never be called on RR_Header")
|
||||
}
|
||||
|
||||
func (h *RR_Header) parse(c *zlexer, origin, file string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on RR_Header")
|
||||
}
|
||||
|
||||
// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
|
||||
func (rr *RFC3597) ToRFC3597(r RR) error {
|
||||
buf := make([]byte, Len(r)*2)
|
||||
@@ -90,14 +118,17 @@ func (rr *RFC3597) ToRFC3597(r RR) error {
|
||||
}
|
||||
buf = buf[:off]
|
||||
|
||||
hdr := *r.Header()
|
||||
hdr.Rdlength = uint16(off - headerEnd)
|
||||
*rr = RFC3597{Hdr: *r.Header()}
|
||||
rr.Hdr.Rdlength = uint16(off - headerEnd)
|
||||
|
||||
rfc3597, _, err := unpackRFC3597(hdr, buf, headerEnd)
|
||||
if noRdata(rr.Hdr) {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = rr.unpack(buf, headerEnd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*rr = *rfc3597.(*RFC3597)
|
||||
return nil
|
||||
}
|
||||
|
||||
35
vendor/github.com/miekg/dns/dnssec.go
сгенерированный
поставляемый
35
vendor/github.com/miekg/dns/dnssec.go
сгенерированный
поставляемый
@@ -67,9 +67,6 @@ var AlgorithmToString = map[uint8]string{
|
||||
PRIVATEOID: "PRIVATEOID",
|
||||
}
|
||||
|
||||
// StringToAlgorithm is the reverse of AlgorithmToString.
|
||||
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
||||
|
||||
// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
|
||||
var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
||||
@@ -102,9 +99,6 @@ var HashToString = map[uint8]string{
|
||||
SHA512: "SHA512",
|
||||
}
|
||||
|
||||
// StringToHash is a map of names to hash IDs.
|
||||
var StringToHash = reverseInt8(HashToString)
|
||||
|
||||
// DNSKEY flag values.
|
||||
const (
|
||||
SEP = 1
|
||||
@@ -268,16 +262,17 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||
return ErrKey
|
||||
}
|
||||
|
||||
h0 := rrset[0].Header()
|
||||
rr.Hdr.Rrtype = TypeRRSIG
|
||||
rr.Hdr.Name = rrset[0].Header().Name
|
||||
rr.Hdr.Class = rrset[0].Header().Class
|
||||
rr.Hdr.Name = h0.Name
|
||||
rr.Hdr.Class = h0.Class
|
||||
if rr.OrigTtl == 0 { // If set don't override
|
||||
rr.OrigTtl = rrset[0].Header().Ttl
|
||||
rr.OrigTtl = h0.Ttl
|
||||
}
|
||||
rr.TypeCovered = rrset[0].Header().Rrtype
|
||||
rr.Labels = uint8(CountLabel(rrset[0].Header().Name))
|
||||
rr.TypeCovered = h0.Rrtype
|
||||
rr.Labels = uint8(CountLabel(h0.Name))
|
||||
|
||||
if strings.HasPrefix(rrset[0].Header().Name, "*") {
|
||||
if strings.HasPrefix(h0.Name, "*") {
|
||||
rr.Labels-- // wildcard, remove from label count
|
||||
}
|
||||
|
||||
@@ -411,10 +406,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||
// IsRRset checked that we have at least one RR and that the RRs in
|
||||
// the set have consistent type, class, and name. Also check that type and
|
||||
// class matches the RRSIG record.
|
||||
if rrset[0].Header().Class != rr.Hdr.Class {
|
||||
return ErrRRset
|
||||
}
|
||||
if rrset[0].Header().Rrtype != rr.TypeCovered {
|
||||
if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered {
|
||||
return ErrRRset
|
||||
}
|
||||
|
||||
@@ -563,7 +555,7 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
|
||||
|
||||
pubkey := new(rsa.PublicKey)
|
||||
|
||||
expo := uint64(0)
|
||||
var expo uint64
|
||||
for i := 0; i < int(explen); i++ {
|
||||
expo <<= 8
|
||||
expo |= uint64(keybuf[keyoff+i])
|
||||
@@ -658,15 +650,16 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
|
||||
wires := make(wireSlice, len(rrset))
|
||||
for i, r := range rrset {
|
||||
r1 := r.copy()
|
||||
r1.Header().Ttl = s.OrigTtl
|
||||
labels := SplitDomainName(r1.Header().Name)
|
||||
h := r1.Header()
|
||||
h.Ttl = s.OrigTtl
|
||||
labels := SplitDomainName(h.Name)
|
||||
// 6.2. Canonical RR Form. (4) - wildcards
|
||||
if len(labels) > int(s.Labels) {
|
||||
// Wildcard
|
||||
r1.Header().Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
|
||||
h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
|
||||
}
|
||||
// RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
|
||||
r1.Header().Name = strings.ToLower(r1.Header().Name)
|
||||
h.Name = strings.ToLower(h.Name)
|
||||
// 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
|
||||
// NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
|
||||
// HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
|
||||
|
||||
23
vendor/github.com/miekg/dns/duplicate.go
сгенерированный
поставляемый
23
vendor/github.com/miekg/dns/duplicate.go
сгенерированный
поставляемый
@@ -7,18 +7,31 @@ package dns
|
||||
// is so, otherwise false.
|
||||
// It's is a protocol violation to have identical RRs in a message.
|
||||
func IsDuplicate(r1, r2 RR) bool {
|
||||
if r1.Header().Class != r2.Header().Class {
|
||||
// Check whether the record header is identical.
|
||||
if !r1.Header().isDuplicate(r2.Header()) {
|
||||
return false
|
||||
}
|
||||
if r1.Header().Rrtype != r2.Header().Rrtype {
|
||||
|
||||
// Check whether the RDATA is identical.
|
||||
return r1.isDuplicate(r2)
|
||||
}
|
||||
|
||||
func (r1 *RR_Header) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RR_Header)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !isDulicateName(r1.Header().Name, r2.Header().Name) {
|
||||
if r1.Class != r2.Class {
|
||||
return false
|
||||
}
|
||||
if r1.Rrtype != r2.Rrtype {
|
||||
return false
|
||||
}
|
||||
if !isDulicateName(r1.Name, r2.Name) {
|
||||
return false
|
||||
}
|
||||
// ignore TTL
|
||||
|
||||
return isDuplicateRdata(r1, r2)
|
||||
return true
|
||||
}
|
||||
|
||||
// isDulicateName checks if the domain names s1 and s2 are equal.
|
||||
|
||||
30
vendor/github.com/miekg/dns/duplicate_generate.go
сгенерированный
поставляемый
30
vendor/github.com/miekg/dns/duplicate_generate.go
сгенерированный
поставляемый
@@ -57,10 +57,7 @@ func main() {
|
||||
continue
|
||||
}
|
||||
|
||||
if name == "PrivateRR" || name == "RFC3597" {
|
||||
continue
|
||||
}
|
||||
if name == "OPT" || name == "ANY" || name == "IXFR" || name == "AXFR" {
|
||||
if name == "PrivateRR" || name == "OPT" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -70,22 +67,6 @@ func main() {
|
||||
b := &bytes.Buffer{}
|
||||
b.WriteString(packageHdr)
|
||||
|
||||
// Generate the giant switch that calls the correct function for each type.
|
||||
fmt.Fprint(b, "// isDuplicateRdata calls the rdata specific functions\n")
|
||||
fmt.Fprint(b, "func isDuplicateRdata(r1, r2 RR) bool {\n")
|
||||
fmt.Fprint(b, "switch r1.Header().Rrtype {\n")
|
||||
|
||||
for _, name := range namedTypes {
|
||||
|
||||
o := scope.Lookup(name)
|
||||
_, isEmbedded := getTypeStruct(o.Type(), scope)
|
||||
if isEmbedded {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(b, "case Type%s:\nreturn isDuplicate%s(r1.(*%s), r2.(*%s))\n", name, name, name, name)
|
||||
}
|
||||
fmt.Fprintf(b, "}\nreturn false\n}\n")
|
||||
|
||||
// Generate the duplicate check for each type.
|
||||
fmt.Fprint(b, "// isDuplicate() functions\n\n")
|
||||
for _, name := range namedTypes {
|
||||
@@ -95,7 +76,10 @@ func main() {
|
||||
if isEmbedded {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(b, "func isDuplicate%s(r1, r2 *%s) bool {\n", name, name)
|
||||
fmt.Fprintf(b, "func (r1 *%s) isDuplicate(_r2 RR) bool {\n", name)
|
||||
fmt.Fprintf(b, "r2, ok := _r2.(*%s)\n", name)
|
||||
fmt.Fprint(b, "if !ok { return false }\n")
|
||||
fmt.Fprint(b, "_ = r2\n")
|
||||
for i := 1; i < st.NumFields(); i++ {
|
||||
field := st.Field(i).Name()
|
||||
o2 := func(s string) { fmt.Fprintf(b, s+"\n", field, field) }
|
||||
@@ -103,7 +87,7 @@ func main() {
|
||||
|
||||
// For some reason, a and aaaa don't pop up as *types.Slice here (mostly like because the are
|
||||
// *indirectly* defined as a slice in the net package).
|
||||
if _, ok := st.Field(i).Type().(*types.Slice); ok || st.Tag(i) == `dns:"a"` || st.Tag(i) == `dns:"aaaa"` {
|
||||
if _, ok := st.Field(i).Type().(*types.Slice); ok {
|
||||
o2("if len(r1.%s) != len(r2.%s) {\nreturn false\n}")
|
||||
|
||||
if st.Tag(i) == `dns:"cdomain-name"` || st.Tag(i) == `dns:"domain-name"` {
|
||||
@@ -128,6 +112,8 @@ func main() {
|
||||
switch st.Tag(i) {
|
||||
case `dns:"-"`:
|
||||
// ignored
|
||||
case `dns:"a"`, `dns:"aaaa"`:
|
||||
o2("if !r1.%s.Equal(r2.%s) {\nreturn false\n}")
|
||||
case `dns:"cdomain-name"`, `dns:"domain-name"`:
|
||||
o2("if !isDulicateName(r1.%s, r2.%s) {\nreturn false\n}")
|
||||
default:
|
||||
|
||||
15
vendor/github.com/miekg/dns/edns.go
сгенерированный
поставляемый
15
vendor/github.com/miekg/dns/edns.go
сгенерированный
поставляемый
@@ -88,6 +88,12 @@ func (rr *OPT) len(off int, compression map[string]struct{}) int {
|
||||
return l
|
||||
}
|
||||
|
||||
func (rr *OPT) parse(c *zlexer, origin, file string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on OPT")
|
||||
}
|
||||
|
||||
func (r1 *OPT) isDuplicate(r2 RR) bool { return false }
|
||||
|
||||
// return the old value -> delete SetVersion?
|
||||
|
||||
// Version returns the EDNS version used. Only zero is defined.
|
||||
@@ -183,7 +189,7 @@ func (e *EDNS0_NSID) pack() ([]byte, error) {
|
||||
// Option implements the EDNS0 interface.
|
||||
func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code.
|
||||
func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
|
||||
func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
|
||||
func (e *EDNS0_NSID) String() string { return e.Nsid }
|
||||
|
||||
// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
|
||||
// an idea of where the client lives. See RFC 7871. It can then give back a different
|
||||
@@ -411,7 +417,7 @@ func (e *EDNS0_LLQ) unpack(b []byte) error {
|
||||
|
||||
func (e *EDNS0_LLQ) String() string {
|
||||
s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
|
||||
" " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(uint64(e.Id), 10) +
|
||||
" " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) +
|
||||
" " + strconv.FormatUint(uint64(e.LeaseLife), 10)
|
||||
return s
|
||||
}
|
||||
@@ -498,10 +504,7 @@ func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expi
|
||||
|
||||
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||
b := make([]byte, 4)
|
||||
b[0] = byte(e.Expire >> 24)
|
||||
b[1] = byte(e.Expire >> 16)
|
||||
b[2] = byte(e.Expire >> 8)
|
||||
b[3] = byte(e.Expire)
|
||||
binary.BigEndian.PutUint32(b, e.Expire)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/miekg/dns/format.go
сгенерированный
поставляемый
2
vendor/github.com/miekg/dns/format.go
сгенерированный
поставляемый
@@ -20,7 +20,7 @@ func Field(r RR, i int) string {
|
||||
return ""
|
||||
}
|
||||
d := reflect.ValueOf(r).Elem().Field(i)
|
||||
switch k := d.Kind(); k {
|
||||
switch d.Kind() {
|
||||
case reflect.String:
|
||||
return d.String()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
|
||||
5
vendor/github.com/miekg/dns/labels.go
сгенерированный
поставляемый
5
vendor/github.com/miekg/dns/labels.go
сгенерированный
поставляемый
@@ -16,7 +16,7 @@ func SplitDomainName(s string) (labels []string) {
|
||||
fqdnEnd := 0 // offset of the final '.' or the length of the name
|
||||
idx := Split(s)
|
||||
begin := 0
|
||||
if s[len(s)-1] == '.' {
|
||||
if IsFqdn(s) {
|
||||
fqdnEnd = len(s) - 1
|
||||
} else {
|
||||
fqdnEnd = len(s)
|
||||
@@ -36,8 +36,7 @@ func SplitDomainName(s string) (labels []string) {
|
||||
}
|
||||
}
|
||||
|
||||
labels = append(labels, s[begin:fqdnEnd])
|
||||
return labels
|
||||
return append(labels, s[begin:fqdnEnd])
|
||||
}
|
||||
|
||||
// CompareDomainName compares the names s1 and s2 and
|
||||
|
||||
102
vendor/github.com/miekg/dns/msg.go
сгенерированный
поставляемый
102
vendor/github.com/miekg/dns/msg.go
сгенерированный
поставляемый
@@ -231,29 +231,21 @@ func (m compressionMap) find(s string) (int, bool) {
|
||||
// map needs to hold a mapping between domain names and offsets
|
||||
// pointing into msg.
|
||||
func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
|
||||
off1, _, err = packDomainName(s, msg, off, compressionMap{ext: compression}, compress)
|
||||
return
|
||||
return packDomainName(s, msg, off, compressionMap{ext: compression}, compress)
|
||||
}
|
||||
|
||||
func packDomainName(s string, msg []byte, off int, compression compressionMap, compress bool) (off1 int, labels int, err error) {
|
||||
// special case if msg == nil
|
||||
lenmsg := 256
|
||||
if msg != nil {
|
||||
lenmsg = len(msg)
|
||||
}
|
||||
func packDomainName(s string, msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
// XXX: A logical copy of this function exists in IsDomainName and
|
||||
// should be kept in sync with this function.
|
||||
|
||||
ls := len(s)
|
||||
if ls == 0 { // Ok, for instance when dealing with update RR without any rdata.
|
||||
return off, 0, nil
|
||||
return off, nil
|
||||
}
|
||||
|
||||
// If not fully qualified, error out, but only if msg != nil #ugly
|
||||
if s[ls-1] != '.' {
|
||||
if msg != nil {
|
||||
return lenmsg, 0, ErrFqdn
|
||||
}
|
||||
s += "."
|
||||
ls++
|
||||
// If not fully qualified, error out.
|
||||
if !IsFqdn(s) {
|
||||
return len(msg), ErrFqdn
|
||||
}
|
||||
|
||||
// Each dot ends a segment of the name.
|
||||
@@ -283,8 +275,8 @@ loop:
|
||||
|
||||
switch c {
|
||||
case '\\':
|
||||
if off+1 > lenmsg {
|
||||
return lenmsg, labels, ErrBuf
|
||||
if off+1 > len(msg) {
|
||||
return len(msg), ErrBuf
|
||||
}
|
||||
|
||||
if bs == nil {
|
||||
@@ -307,19 +299,19 @@ loop:
|
||||
case '.':
|
||||
if wasDot {
|
||||
// two dots back to back is not legal
|
||||
return lenmsg, labels, ErrRdata
|
||||
return len(msg), ErrRdata
|
||||
}
|
||||
wasDot = true
|
||||
|
||||
labelLen := i - begin
|
||||
if labelLen >= 1<<6 { // top two bits of length must be clear
|
||||
return lenmsg, labels, ErrRdata
|
||||
return len(msg), ErrRdata
|
||||
}
|
||||
|
||||
// off can already (we're in a loop) be bigger than len(msg)
|
||||
// this happens when a name isn't fully qualified
|
||||
if off+1+labelLen > lenmsg {
|
||||
return lenmsg, labels, ErrBuf
|
||||
if off+1+labelLen > len(msg) {
|
||||
return len(msg), ErrBuf
|
||||
}
|
||||
|
||||
// Don't try to compress '.'
|
||||
@@ -344,18 +336,15 @@ loop:
|
||||
}
|
||||
|
||||
// The following is covered by the length check above.
|
||||
if msg != nil {
|
||||
msg[off] = byte(labelLen)
|
||||
msg[off] = byte(labelLen)
|
||||
|
||||
if bs == nil {
|
||||
copy(msg[off+1:], s[begin:i])
|
||||
} else {
|
||||
copy(msg[off+1:], bs[begin:i])
|
||||
}
|
||||
if bs == nil {
|
||||
copy(msg[off+1:], s[begin:i])
|
||||
} else {
|
||||
copy(msg[off+1:], bs[begin:i])
|
||||
}
|
||||
off += 1 + labelLen
|
||||
|
||||
labels++
|
||||
begin = i + 1
|
||||
compBegin = begin + compOff
|
||||
default:
|
||||
@@ -365,22 +354,21 @@ loop:
|
||||
|
||||
// Root label is special
|
||||
if isRootLabel(s, bs, 0, ls) {
|
||||
return off, labels, nil
|
||||
return off, nil
|
||||
}
|
||||
|
||||
// If we did compression and we find something add the pointer here
|
||||
if pointer != -1 {
|
||||
// We have two bytes (14 bits) to put the pointer in
|
||||
// if msg == nil, we will never do compression
|
||||
binary.BigEndian.PutUint16(msg[off:], uint16(pointer^0xC000))
|
||||
return off + 2, labels, nil
|
||||
return off + 2, nil
|
||||
}
|
||||
|
||||
if msg != nil && off < lenmsg {
|
||||
if off < len(msg) {
|
||||
msg[off] = 0
|
||||
}
|
||||
|
||||
return off + 1, labels, nil
|
||||
return off + 1, nil
|
||||
}
|
||||
|
||||
// isRootLabel returns whether s or bs, from off to end, is the root
|
||||
@@ -633,7 +621,12 @@ func packRR(rr RR, msg []byte, off int, compression compressionMap, compress boo
|
||||
return len(msg), len(msg), &Error{err: "nil rr"}
|
||||
}
|
||||
|
||||
headerEnd, off1, err = rr.pack(msg, off, compression, compress)
|
||||
headerEnd, err = rr.Header().packHeader(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return headerEnd, len(msg), err
|
||||
}
|
||||
|
||||
off1, err = rr.pack(msg, headerEnd, compression, compress)
|
||||
if err != nil {
|
||||
return headerEnd, len(msg), err
|
||||
}
|
||||
@@ -661,17 +654,28 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
|
||||
// UnpackRRWithHeader unpacks the record type specific payload given an existing
|
||||
// RR_Header.
|
||||
func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err error) {
|
||||
if newFn, ok := TypeToRR[h.Rrtype]; ok {
|
||||
rr = newFn()
|
||||
*rr.Header() = h
|
||||
} else {
|
||||
rr = &RFC3597{Hdr: h}
|
||||
}
|
||||
|
||||
if noRdata(h) {
|
||||
return rr, off, nil
|
||||
}
|
||||
|
||||
end := off + int(h.Rdlength)
|
||||
|
||||
if fn, known := typeToUnpack[h.Rrtype]; !known {
|
||||
rr, off, err = unpackRFC3597(h, msg, off)
|
||||
} else {
|
||||
rr, off, err = fn(h, msg, off)
|
||||
off, err = rr.unpack(msg, off)
|
||||
if err != nil {
|
||||
return nil, end, err
|
||||
}
|
||||
if off != end {
|
||||
return &h, end, &Error{err: "bad rdlength"}
|
||||
}
|
||||
return rr, off, err
|
||||
|
||||
return rr, off, nil
|
||||
}
|
||||
|
||||
// unpackRRslice unpacks msg[off:] into an []RR.
|
||||
@@ -984,7 +988,7 @@ func (dns *Msg) Len() int {
|
||||
}
|
||||
|
||||
func msgLenWithCompressionMap(dns *Msg, compression map[string]struct{}) int {
|
||||
l := 12 // Message header is always 12 bytes
|
||||
l := headerSize
|
||||
|
||||
for _, r := range dns.Question {
|
||||
l += r.len(l, compression)
|
||||
@@ -1068,7 +1072,7 @@ func compressionLenSearch(c map[string]struct{}, s string, msgOff int) (int, boo
|
||||
}
|
||||
|
||||
// Copy returns a new RR which is a deep-copy of r.
|
||||
func Copy(r RR) RR { r1 := r.copy(); return r1 }
|
||||
func Copy(r RR) RR { return r.copy() }
|
||||
|
||||
// Len returns the length (in octets) of the uncompressed RR in wire format.
|
||||
func Len(r RR) int { return r.len(0, nil) }
|
||||
@@ -1120,7 +1124,7 @@ func (dns *Msg) CopyTo(r1 *Msg) *Msg {
|
||||
}
|
||||
|
||||
func (q *Question) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
|
||||
off, _, err := packDomainName(q.Name, msg, off, compression, compress)
|
||||
off, err := packDomainName(q.Name, msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
@@ -1183,7 +1187,10 @@ func (dh *Header) pack(msg []byte, off int, compression compressionMap, compress
|
||||
return off, err
|
||||
}
|
||||
off, err = packUint16(dh.Arcount, msg, off)
|
||||
return off, err
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
|
||||
@@ -1212,7 +1219,10 @@ func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
|
||||
return dh, off, err
|
||||
}
|
||||
dh.Arcount, off, err = unpackUint16(msg, off)
|
||||
return dh, off, err
|
||||
if err != nil {
|
||||
return dh, off, err
|
||||
}
|
||||
return dh, off, nil
|
||||
}
|
||||
|
||||
// setHdr set the header in the dns using the binary data in dh.
|
||||
|
||||
49
vendor/github.com/miekg/dns/msg_generate.go
сгенерированный
поставляемый
49
vendor/github.com/miekg/dns/msg_generate.go
сгенерированный
поставляемый
@@ -80,17 +80,12 @@ func main() {
|
||||
o := scope.Lookup(name)
|
||||
st, _ := getTypeStruct(o.Type(), scope)
|
||||
|
||||
fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {\n", name)
|
||||
fmt.Fprint(b, `headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return headerEnd, off, err
|
||||
}
|
||||
`)
|
||||
fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {\n", name)
|
||||
for i := 1; i < st.NumFields(); i++ {
|
||||
o := func(s string) {
|
||||
fmt.Fprintf(b, s, st.Field(i).Name())
|
||||
fmt.Fprint(b, `if err != nil {
|
||||
return headerEnd, off, err
|
||||
return off, err
|
||||
}
|
||||
`)
|
||||
}
|
||||
@@ -115,9 +110,9 @@ return headerEnd, off, err
|
||||
switch {
|
||||
case st.Tag(i) == `dns:"-"`: // ignored
|
||||
case st.Tag(i) == `dns:"cdomain-name"`:
|
||||
o("off, _, err = packDomainName(rr.%s, msg, off, compression, compress)\n")
|
||||
o("off, err = packDomainName(rr.%s, msg, off, compression, compress)\n")
|
||||
case st.Tag(i) == `dns:"domain-name"`:
|
||||
o("off, _, err = packDomainName(rr.%s, msg, off, compression, false)\n")
|
||||
o("off, err = packDomainName(rr.%s, msg, off, compression, false)\n")
|
||||
case st.Tag(i) == `dns:"a"`:
|
||||
o("off, err = packDataA(rr.%s, msg, off)\n")
|
||||
case st.Tag(i) == `dns:"aaaa"`:
|
||||
@@ -144,7 +139,7 @@ return headerEnd, off, err
|
||||
if rr.%s != "-" {
|
||||
off, err = packStringHex(rr.%s, msg, off)
|
||||
if err != nil {
|
||||
return headerEnd, off, err
|
||||
return off, err
|
||||
}
|
||||
}
|
||||
`, field, field)
|
||||
@@ -153,7 +148,8 @@ if rr.%s != "-" {
|
||||
fallthrough
|
||||
case st.Tag(i) == `dns:"hex"`:
|
||||
o("off, err = packStringHex(rr.%s, msg, off)\n")
|
||||
|
||||
case st.Tag(i) == `dns:"any"`:
|
||||
o("off, err = packStringAny(rr.%s, msg, off)\n")
|
||||
case st.Tag(i) == `dns:"octet"`:
|
||||
o("off, err = packStringOctet(rr.%s, msg, off)\n")
|
||||
case st.Tag(i) == "":
|
||||
@@ -175,7 +171,7 @@ if rr.%s != "-" {
|
||||
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(b, "return headerEnd, off, nil }\n")
|
||||
fmt.Fprintln(b, "return off, nil }\n")
|
||||
}
|
||||
|
||||
fmt.Fprint(b, "// unpack*() functions\n\n")
|
||||
@@ -183,14 +179,8 @@ if rr.%s != "-" {
|
||||
o := scope.Lookup(name)
|
||||
st, _ := getTypeStruct(o.Type(), scope)
|
||||
|
||||
fmt.Fprintf(b, "func unpack%s(h RR_Header, msg []byte, off int) (RR, int, error) {\n", name)
|
||||
fmt.Fprintf(b, "rr := new(%s)\n", name)
|
||||
fmt.Fprint(b, "rr.Hdr = h\n")
|
||||
fmt.Fprint(b, `if noRdata(h) {
|
||||
return rr, off, nil
|
||||
}
|
||||
var err error
|
||||
rdStart := off
|
||||
fmt.Fprintf(b, "func (rr *%s) unpack(msg []byte, off int) (off1 int, err error) {\n", name)
|
||||
fmt.Fprint(b, `rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
`)
|
||||
@@ -198,7 +188,7 @@ _ = rdStart
|
||||
o := func(s string) {
|
||||
fmt.Fprintf(b, s, st.Field(i).Name())
|
||||
fmt.Fprint(b, `if err != nil {
|
||||
return rr, off, err
|
||||
return off, err
|
||||
}
|
||||
`)
|
||||
}
|
||||
@@ -218,7 +208,7 @@ return rr, off, err
|
||||
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
|
||||
}
|
||||
fmt.Fprint(b, `if err != nil {
|
||||
return rr, off, err
|
||||
return off, err
|
||||
}
|
||||
`)
|
||||
continue
|
||||
@@ -261,6 +251,8 @@ return rr, off, err
|
||||
o("rr.%s, off, err = unpackStringBase64(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
|
||||
case `dns:"hex"`:
|
||||
o("rr.%s, off, err = unpackStringHex(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
|
||||
case `dns:"any"`:
|
||||
o("rr.%s, off, err = unpackStringAny(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
|
||||
case `dns:"octet"`:
|
||||
o("rr.%s, off, err = unpackStringOctet(msg, off)\n")
|
||||
case "":
|
||||
@@ -284,22 +276,13 @@ return rr, off, err
|
||||
// If we've hit len(msg) we return without error.
|
||||
if i < st.NumFields()-1 {
|
||||
fmt.Fprintf(b, `if off == len(msg) {
|
||||
return rr, off, nil
|
||||
return off, nil
|
||||
}
|
||||
`)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(b, "return rr, off, err }\n\n")
|
||||
fmt.Fprintf(b, "return off, nil }\n\n")
|
||||
}
|
||||
// Generate typeToUnpack map
|
||||
fmt.Fprintln(b, "var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){")
|
||||
for _, name := range namedTypes {
|
||||
if name == "RFC3597" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(b, "Type%s: unpack%s,\n", name, name)
|
||||
}
|
||||
fmt.Fprintln(b, "}\n")
|
||||
|
||||
// gofmt
|
||||
res, err := format.Source(b.Bytes())
|
||||
|
||||
44
vendor/github.com/miekg/dns/msg_helpers.go
сгенерированный
поставляемый
44
vendor/github.com/miekg/dns/msg_helpers.go
сгенерированный
поставляемый
@@ -99,34 +99,34 @@ func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte,
|
||||
return hdr, off, msg, err
|
||||
}
|
||||
|
||||
// pack packs an RR header, returning the offset to the end of the header.
|
||||
// packHeader packs an RR header, returning the offset to the end of the header.
|
||||
// See PackDomainName for documentation about the compression.
|
||||
func (hdr RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {
|
||||
func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
|
||||
if off == len(msg) {
|
||||
return off, off, nil
|
||||
return off, nil
|
||||
}
|
||||
|
||||
off, _, err := packDomainName(hdr.Name, msg, off, compression, compress)
|
||||
off, err := packDomainName(hdr.Name, msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return off, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
off, err = packUint16(hdr.Rrtype, msg, off)
|
||||
if err != nil {
|
||||
return off, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
off, err = packUint16(hdr.Class, msg, off)
|
||||
if err != nil {
|
||||
return off, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
off, err = packUint32(hdr.Ttl, msg, off)
|
||||
if err != nil {
|
||||
return off, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR.
|
||||
if err != nil {
|
||||
return off, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
return off, off, nil
|
||||
return off, nil
|
||||
}
|
||||
|
||||
// helper helper functions.
|
||||
@@ -177,14 +177,14 @@ func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
|
||||
if off+1 > len(msg) {
|
||||
return 0, len(msg), &Error{err: "overflow unpacking uint8"}
|
||||
}
|
||||
return uint8(msg[off]), off + 1, nil
|
||||
return msg[off], off + 1, nil
|
||||
}
|
||||
|
||||
func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
|
||||
if off+1 > len(msg) {
|
||||
return len(msg), &Error{err: "overflow packing uint8"}
|
||||
}
|
||||
msg[off] = byte(i)
|
||||
msg[off] = i
|
||||
return off + 1, nil
|
||||
}
|
||||
|
||||
@@ -363,6 +363,22 @@ func packStringHex(s string, msg []byte, off int) (int, error) {
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func unpackStringAny(msg []byte, off, end int) (string, int, error) {
|
||||
if end > len(msg) {
|
||||
return "", len(msg), &Error{err: "overflow unpacking anything"}
|
||||
}
|
||||
return string(msg[off:end]), end, nil
|
||||
}
|
||||
|
||||
func packStringAny(s string, msg []byte, off int) (int, error) {
|
||||
if off+len(s) > len(msg) {
|
||||
return len(msg), &Error{err: "overflow packing anything"}
|
||||
}
|
||||
copy(msg[off:off+len(s)], s)
|
||||
off += len(s)
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
|
||||
txt, off, err := unpackTxt(msg, off)
|
||||
if err != nil {
|
||||
@@ -383,7 +399,7 @@ func packStringTxt(s []string, msg []byte, off int) (int, error) {
|
||||
func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
|
||||
var edns []EDNS0
|
||||
Option:
|
||||
code := uint16(0)
|
||||
var code uint16
|
||||
if off+4 > len(msg) {
|
||||
return nil, len(msg), &Error{err: "overflow unpacking opt"}
|
||||
}
|
||||
@@ -624,7 +640,7 @@ func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
|
||||
func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) {
|
||||
var err error
|
||||
for j := 0; j < len(names); j++ {
|
||||
off, _, err = packDomainName(names[j], msg, off, compression, compress)
|
||||
off, err = packDomainName(names[j], msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return len(msg), err
|
||||
}
|
||||
|
||||
97
vendor/github.com/miekg/dns/privaterr.go
сгенерированный
поставляемый
97
vendor/github.com/miekg/dns/privaterr.go
сгенерированный
поставляемый
@@ -39,11 +39,12 @@ func mkPrivateRR(rrtype uint16) *PrivateRR {
|
||||
}
|
||||
|
||||
anyrr := rrfunc()
|
||||
switch rr := anyrr.(type) {
|
||||
case *PrivateRR:
|
||||
return rr
|
||||
rr, ok := anyrr.(*PrivateRR)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr))
|
||||
}
|
||||
panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr))
|
||||
|
||||
return rr
|
||||
}
|
||||
|
||||
// Header return the RR header of r.
|
||||
@@ -70,19 +71,46 @@ func (r *PrivateRR) copy() RR {
|
||||
return rr
|
||||
}
|
||||
|
||||
func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {
|
||||
headerEnd, off, err := r.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return off, off, err
|
||||
}
|
||||
func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
|
||||
n, err := r.Data.Pack(msg[off:])
|
||||
if err != nil {
|
||||
return headerEnd, len(msg), err
|
||||
return len(msg), err
|
||||
}
|
||||
off += n
|
||||
return headerEnd, off, nil
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
|
||||
off1, err := r.Data.Unpack(msg[off:])
|
||||
off += off1
|
||||
return off, err
|
||||
}
|
||||
|
||||
func (r *PrivateRR) parse(c *zlexer, origin, file string) *ParseError {
|
||||
var l lex
|
||||
text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
|
||||
Fetch:
|
||||
for {
|
||||
// TODO(miek): we could also be returning _QUOTE, this might or might not
|
||||
// be an issue (basically parsing TXT becomes hard)
|
||||
switch l, _ = c.Next(); l.value {
|
||||
case zNewline, zEOF:
|
||||
break Fetch
|
||||
case zString:
|
||||
text = append(text, l.token)
|
||||
}
|
||||
}
|
||||
|
||||
err := r.Data.Parse(text)
|
||||
if err != nil {
|
||||
return &ParseError{file, err.Error(), l}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false }
|
||||
|
||||
// PrivateHandle registers a private resource record type. It requires
|
||||
// string and numeric representation of private RR type and generator function as argument.
|
||||
func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
|
||||
@@ -91,51 +119,6 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
|
||||
TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} }
|
||||
TypeToString[rtype] = rtypestr
|
||||
StringToType[rtypestr] = rtype
|
||||
|
||||
typeToUnpack[rtype] = func(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||
if noRdata(h) {
|
||||
return &h, off, nil
|
||||
}
|
||||
var err error
|
||||
|
||||
rr := mkPrivateRR(h.Rrtype)
|
||||
rr.Hdr = h
|
||||
|
||||
off1, err := rr.Data.Unpack(msg[off:])
|
||||
off += off1
|
||||
if err != nil {
|
||||
return rr, off, err
|
||||
}
|
||||
return rr, off, err
|
||||
}
|
||||
|
||||
setPrivateRR := func(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
|
||||
rr := mkPrivateRR(h.Rrtype)
|
||||
rr.Hdr = h
|
||||
|
||||
var l lex
|
||||
text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
|
||||
Fetch:
|
||||
for {
|
||||
// TODO(miek): we could also be returning _QUOTE, this might or might not
|
||||
// be an issue (basically parsing TXT becomes hard)
|
||||
switch l, _ = c.Next(); l.value {
|
||||
case zNewline, zEOF:
|
||||
break Fetch
|
||||
case zString:
|
||||
text = append(text, l.token)
|
||||
}
|
||||
}
|
||||
|
||||
err := rr.Data.Parse(text)
|
||||
if err != nil {
|
||||
return nil, &ParseError{f, err.Error(), l}, ""
|
||||
}
|
||||
|
||||
return rr, nil, ""
|
||||
}
|
||||
|
||||
typeToparserFunc[rtype] = parserFunc{setPrivateRR, true}
|
||||
}
|
||||
|
||||
// PrivateHandleRemove removes definitions required to support private RR type.
|
||||
@@ -144,8 +127,6 @@ func PrivateHandleRemove(rtype uint16) {
|
||||
if ok {
|
||||
delete(TypeToRR, rtype)
|
||||
delete(TypeToString, rtype)
|
||||
delete(typeToparserFunc, rtype)
|
||||
delete(StringToType, rtypestr)
|
||||
delete(typeToUnpack, rtype)
|
||||
}
|
||||
}
|
||||
|
||||
9
vendor/github.com/miekg/dns/reverse.go
сгенерированный
поставляемый
9
vendor/github.com/miekg/dns/reverse.go
сгенерированный
поставляемый
@@ -17,6 +17,15 @@ func init() {
|
||||
StringToRcode["NOTIMPL"] = RcodeNotImplemented
|
||||
}
|
||||
|
||||
// StringToAlgorithm is the reverse of AlgorithmToString.
|
||||
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
||||
|
||||
// StringToHash is a map of names to hash IDs.
|
||||
var StringToHash = reverseInt8(HashToString)
|
||||
|
||||
// StringToCertType is the reverseof CertTypeToString.
|
||||
var StringToCertType = reverseInt16(CertTypeToString)
|
||||
|
||||
// Reverse a map
|
||||
func reverseInt8(m map[uint8]string) map[string]uint8 {
|
||||
n := make(map[string]uint8, len(m))
|
||||
|
||||
7
vendor/github.com/miekg/dns/sanitize.go
сгенерированный
поставляемый
7
vendor/github.com/miekg/dns/sanitize.go
сгенерированный
поставляемый
@@ -15,10 +15,11 @@ func Dedup(rrs []RR, m map[string]RR) []RR {
|
||||
for _, r := range rrs {
|
||||
key := normalizedString(r)
|
||||
keys = append(keys, &key)
|
||||
if _, ok := m[key]; ok {
|
||||
if mr, ok := m[key]; ok {
|
||||
// Shortest TTL wins.
|
||||
if m[key].Header().Ttl > r.Header().Ttl {
|
||||
m[key].Header().Ttl = r.Header().Ttl
|
||||
rh, mrh := r.Header(), mr.Header()
|
||||
if mrh.Ttl > rh.Ttl {
|
||||
mrh.Ttl = rh.Ttl
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
88
vendor/github.com/miekg/dns/scan.go
сгенерированный
поставляемый
88
vendor/github.com/miekg/dns/scan.go
сгенерированный
поставляемый
@@ -79,13 +79,12 @@ func (e *ParseError) Error() (s string) {
|
||||
}
|
||||
|
||||
type lex struct {
|
||||
token string // text of the token
|
||||
err bool // when true, token text has lexer error
|
||||
value uint8 // value: zString, _BLANK, etc.
|
||||
torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
|
||||
line int // line in the file
|
||||
column int // column in the file
|
||||
comment string // any comment text seen
|
||||
token string // text of the token
|
||||
err bool // when true, token text has lexer error
|
||||
value uint8 // value: zString, _BLANK, etc.
|
||||
torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
|
||||
line int // line in the file
|
||||
column int // column in the file
|
||||
}
|
||||
|
||||
// Token holds the token that are returned when a zone file is parsed.
|
||||
@@ -244,8 +243,6 @@ type ZoneParser struct {
|
||||
sub *ZoneParser
|
||||
osFile *os.File
|
||||
|
||||
com string
|
||||
|
||||
includeDepth uint8
|
||||
|
||||
includeAllowed bool
|
||||
@@ -318,12 +315,19 @@ func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
|
||||
// Comment returns an optional text comment that occurred alongside
|
||||
// the RR.
|
||||
func (zp *ZoneParser) Comment() string {
|
||||
return zp.com
|
||||
if zp.parseErr != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if zp.sub != nil {
|
||||
return zp.sub.Comment()
|
||||
}
|
||||
|
||||
return zp.c.Comment()
|
||||
}
|
||||
|
||||
func (zp *ZoneParser) subNext() (RR, bool) {
|
||||
if rr, ok := zp.sub.Next(); ok {
|
||||
zp.com = zp.sub.com
|
||||
return rr, true
|
||||
}
|
||||
|
||||
@@ -347,8 +351,6 @@ func (zp *ZoneParser) subNext() (RR, bool) {
|
||||
// error. After Next returns (nil, false), the Err method will return
|
||||
// any error that occurred during parsing.
|
||||
func (zp *ZoneParser) Next() (RR, bool) {
|
||||
zp.com = ""
|
||||
|
||||
if zp.parseErr != nil {
|
||||
return nil, false
|
||||
}
|
||||
@@ -501,7 +503,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
||||
return zp.setParseError("expecting $TTL value, not this...", l)
|
||||
}
|
||||
|
||||
if e, _ := slurpRemainder(zp.c, zp.file); e != nil {
|
||||
if e := slurpRemainder(zp.c, zp.file); e != nil {
|
||||
zp.parseErr = e
|
||||
return nil, false
|
||||
}
|
||||
@@ -525,7 +527,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
||||
return zp.setParseError("expecting $ORIGIN value, not this...", l)
|
||||
}
|
||||
|
||||
if e, _ := slurpRemainder(zp.c, zp.file); e != nil {
|
||||
if e := slurpRemainder(zp.c, zp.file); e != nil {
|
||||
zp.parseErr = e
|
||||
return nil, false
|
||||
}
|
||||
@@ -648,7 +650,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
||||
|
||||
st = zExpectRdata
|
||||
case zExpectRdata:
|
||||
r, e, c1 := setRR(*h, zp.c, zp.origin, zp.file)
|
||||
r, e := setRR(*h, zp.c, zp.origin, zp.file)
|
||||
if e != nil {
|
||||
// If e.lex is nil than we have encounter a unknown RR type
|
||||
// in that case we substitute our current lex token
|
||||
@@ -660,7 +662,6 @@ func (zp *ZoneParser) Next() (RR, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
zp.com = c1
|
||||
return r, true
|
||||
}
|
||||
}
|
||||
@@ -678,7 +679,8 @@ type zlexer struct {
|
||||
line int
|
||||
column int
|
||||
|
||||
com string
|
||||
comBuf string
|
||||
comment string
|
||||
|
||||
l lex
|
||||
|
||||
@@ -767,14 +769,15 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
escape bool
|
||||
)
|
||||
|
||||
if zl.com != "" {
|
||||
comi = copy(com[:], zl.com)
|
||||
zl.com = ""
|
||||
if zl.comBuf != "" {
|
||||
comi = copy(com[:], zl.comBuf)
|
||||
zl.comBuf = ""
|
||||
}
|
||||
|
||||
zl.comment = ""
|
||||
|
||||
for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
|
||||
l.line, l.column = zl.line, zl.column
|
||||
l.comment = ""
|
||||
|
||||
if stri >= len(str) {
|
||||
l.token = "token length insufficient for parsing"
|
||||
@@ -898,7 +901,7 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
}
|
||||
|
||||
zl.commt = true
|
||||
zl.com = ""
|
||||
zl.comBuf = ""
|
||||
|
||||
if comi > 1 {
|
||||
// A newline was previously seen inside a comment that
|
||||
@@ -911,7 +914,7 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
comi++
|
||||
|
||||
if stri > 0 {
|
||||
zl.com = string(com[:comi])
|
||||
zl.comBuf = string(com[:comi])
|
||||
|
||||
l.value = zString
|
||||
l.token = string(str[:stri])
|
||||
@@ -947,11 +950,11 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
|
||||
l.value = zNewline
|
||||
l.token = "\n"
|
||||
l.comment = string(com[:comi])
|
||||
zl.comment = string(com[:comi])
|
||||
return *l, true
|
||||
}
|
||||
|
||||
zl.com = string(com[:comi])
|
||||
zl.comBuf = string(com[:comi])
|
||||
break
|
||||
}
|
||||
|
||||
@@ -977,9 +980,9 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
|
||||
l.value = zNewline
|
||||
l.token = "\n"
|
||||
l.comment = zl.com
|
||||
|
||||
zl.com = ""
|
||||
zl.comment = zl.comBuf
|
||||
zl.comBuf = ""
|
||||
zl.rrtype = false
|
||||
zl.owner = true
|
||||
|
||||
@@ -1115,7 +1118,7 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
// Send remainder of com
|
||||
l.value = zNewline
|
||||
l.token = "\n"
|
||||
l.comment = string(com[:comi])
|
||||
zl.comment = string(com[:comi])
|
||||
|
||||
if retL != (lex{}) {
|
||||
zl.nextL = true
|
||||
@@ -1126,7 +1129,6 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
}
|
||||
|
||||
if zl.brace != 0 {
|
||||
l.comment = "" // in case there was left over string and comment
|
||||
l.token = "unbalanced brace"
|
||||
l.err = true
|
||||
return *l, true
|
||||
@@ -1135,6 +1137,14 @@ func (zl *zlexer) Next() (lex, bool) {
|
||||
return lex{value: zEOF}, false
|
||||
}
|
||||
|
||||
func (zl *zlexer) Comment() string {
|
||||
if zl.l.err {
|
||||
return ""
|
||||
}
|
||||
|
||||
return zl.comment
|
||||
}
|
||||
|
||||
// Extract the class number from CLASSxx
|
||||
func classToInt(token string) (uint16, bool) {
|
||||
offset := 5
|
||||
@@ -1163,8 +1173,7 @@ func typeToInt(token string) (uint16, bool) {
|
||||
|
||||
// stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds.
|
||||
func stringToTTL(token string) (uint32, bool) {
|
||||
s := uint32(0)
|
||||
i := uint32(0)
|
||||
var s, i uint32
|
||||
for _, c := range token {
|
||||
switch c {
|
||||
case 's', 'S':
|
||||
@@ -1252,7 +1261,7 @@ func toAbsoluteName(name, origin string) (absolute string, ok bool) {
|
||||
}
|
||||
|
||||
// check if name is already absolute
|
||||
if name[len(name)-1] == '.' {
|
||||
if IsFqdn(name) {
|
||||
return name, true
|
||||
}
|
||||
|
||||
@@ -1292,24 +1301,21 @@ func locCheckEast(token string, longitude uint32) (uint32, bool) {
|
||||
return longitude, false
|
||||
}
|
||||
|
||||
// "Eat" the rest of the "line". Return potential comments
|
||||
func slurpRemainder(c *zlexer, f string) (*ParseError, string) {
|
||||
// "Eat" the rest of the "line"
|
||||
func slurpRemainder(c *zlexer, f string) *ParseError {
|
||||
l, _ := c.Next()
|
||||
com := ""
|
||||
switch l.value {
|
||||
case zBlank:
|
||||
l, _ = c.Next()
|
||||
com = l.comment
|
||||
if l.value != zNewline && l.value != zEOF {
|
||||
return &ParseError{f, "garbage after rdata", l}, ""
|
||||
return &ParseError{f, "garbage after rdata", l}
|
||||
}
|
||||
case zNewline:
|
||||
com = l.comment
|
||||
case zEOF:
|
||||
default:
|
||||
return &ParseError{f, "garbage after rdata", l}, ""
|
||||
return &ParseError{f, "garbage after rdata", l}
|
||||
}
|
||||
return nil, com
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
|
||||
|
||||
1130
vendor/github.com/miekg/dns/scan_rr.go
сгенерированный
поставляемый
1130
vendor/github.com/miekg/dns/scan_rr.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
16
vendor/github.com/miekg/dns/server.go
сгенерированный
поставляемый
16
vendor/github.com/miekg/dns/server.go
сгенерированный
поставляемый
@@ -162,11 +162,11 @@ type defaultReader struct {
|
||||
*Server
|
||||
}
|
||||
|
||||
func (dr *defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
|
||||
func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
|
||||
return dr.readTCP(conn, timeout)
|
||||
}
|
||||
|
||||
func (dr *defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
|
||||
func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
|
||||
return dr.readUDP(conn, timeout)
|
||||
}
|
||||
|
||||
@@ -463,11 +463,10 @@ var testShutdownNotify *sync.Cond
|
||||
|
||||
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
|
||||
func (srv *Server) getReadTimeout() time.Duration {
|
||||
rtimeout := dnsTimeout
|
||||
if srv.ReadTimeout != 0 {
|
||||
rtimeout = srv.ReadTimeout
|
||||
return srv.ReadTimeout
|
||||
}
|
||||
return rtimeout
|
||||
return dnsTimeout
|
||||
}
|
||||
|
||||
// serveTCP starts a TCP listener for the server.
|
||||
@@ -518,7 +517,7 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
|
||||
srv.NotifyStartedFunc()
|
||||
}
|
||||
|
||||
reader := Reader(&defaultReader{srv})
|
||||
reader := Reader(defaultReader{srv})
|
||||
if srv.DecorateReader != nil {
|
||||
reader = srv.DecorateReader(reader)
|
||||
}
|
||||
@@ -588,7 +587,7 @@ func (srv *Server) serve(w *response) {
|
||||
w.wg.Done()
|
||||
}()
|
||||
|
||||
reader := Reader(&defaultReader{srv})
|
||||
reader := Reader(defaultReader{srv})
|
||||
if srv.DecorateReader != nil {
|
||||
reader = srv.DecorateReader(reader)
|
||||
}
|
||||
@@ -783,8 +782,7 @@ func (w *response) Write(m []byte) (int, error) {
|
||||
|
||||
switch {
|
||||
case w.udp != nil:
|
||||
n, err := WriteToSessionUDP(w.udp, m, w.udpSession)
|
||||
return n, err
|
||||
return WriteToSessionUDP(w.udp, m, w.udpSession)
|
||||
case w.tcp != nil:
|
||||
lm := len(m)
|
||||
if lm < 2 {
|
||||
|
||||
12
vendor/github.com/miekg/dns/sig0.go
сгенерированный
поставляемый
12
vendor/github.com/miekg/dns/sig0.go
сгенерированный
поставляемый
@@ -21,13 +21,9 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
|
||||
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
|
||||
return nil, ErrKey
|
||||
}
|
||||
rr.Header().Rrtype = TypeSIG
|
||||
rr.Header().Class = ClassANY
|
||||
rr.Header().Ttl = 0
|
||||
rr.Header().Name = "."
|
||||
rr.OrigTtl = 0
|
||||
rr.TypeCovered = 0
|
||||
rr.Labels = 0
|
||||
|
||||
rr.Hdr = RR_Header{Name: ".", Rrtype: TypeSIG, Class: ClassANY, Ttl: 0}
|
||||
rr.OrigTtl, rr.TypeCovered, rr.Labels = 0, 0, 0
|
||||
|
||||
buf := make([]byte, m.Len()+Len(rr))
|
||||
mbuf, err := m.PackBuffer(buf)
|
||||
@@ -107,7 +103,7 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||
anc := binary.BigEndian.Uint16(buf[6:])
|
||||
auc := binary.BigEndian.Uint16(buf[8:])
|
||||
adc := binary.BigEndian.Uint16(buf[10:])
|
||||
offset := 12
|
||||
offset := headerSize
|
||||
var err error
|
||||
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
||||
_, offset, err = UnpackDomainName(buf, offset)
|
||||
|
||||
10
vendor/github.com/miekg/dns/singleinflight.go
сгенерированный
поставляемый
10
vendor/github.com/miekg/dns/singleinflight.go
сгенерированный
поставляемый
@@ -23,6 +23,8 @@ type call struct {
|
||||
type singleflight struct {
|
||||
sync.Mutex // protects m
|
||||
m map[string]*call // lazily initialized
|
||||
|
||||
dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges
|
||||
}
|
||||
|
||||
// Do executes and returns the results of the given function, making
|
||||
@@ -49,9 +51,11 @@ func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v
|
||||
c.val, c.rtt, c.err = fn()
|
||||
c.wg.Done()
|
||||
|
||||
g.Lock()
|
||||
delete(g.m, key)
|
||||
g.Unlock()
|
||||
if !g.dontDeleteForTesting {
|
||||
g.Lock()
|
||||
delete(g.m, key)
|
||||
g.Unlock()
|
||||
}
|
||||
|
||||
return c.val, c.rtt, c.err, c.dups > 0
|
||||
}
|
||||
|
||||
5
vendor/github.com/miekg/dns/smimea.go
сгенерированный
поставляемый
5
vendor/github.com/miekg/dns/smimea.go
сгенерированный
поставляемый
@@ -14,10 +14,7 @@ func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate)
|
||||
r.MatchingType = uint8(matchingType)
|
||||
|
||||
r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Verify verifies a SMIMEA record against an SSL certificate. If it is OK
|
||||
|
||||
5
vendor/github.com/miekg/dns/tlsa.go
сгенерированный
поставляемый
5
vendor/github.com/miekg/dns/tlsa.go
сгенерированный
поставляемый
@@ -14,10 +14,7 @@ func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (
|
||||
r.MatchingType = uint8(matchingType)
|
||||
|
||||
r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Verify verifies a TLSA record against an SSL certificate. If it is OK
|
||||
|
||||
19
vendor/github.com/miekg/dns/tsig.go
сгенерированный
поставляемый
19
vendor/github.com/miekg/dns/tsig.go
сгенерированный
поставляемый
@@ -54,6 +54,10 @@ func (rr *TSIG) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
func (rr *TSIG) parse(c *zlexer, origin, file string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on TSIG")
|
||||
}
|
||||
|
||||
// The following values must be put in wireformat, so that the MAC can be calculated.
|
||||
// RFC 2845, section 3.4.2. TSIG Variables.
|
||||
type tsigWireFmt struct {
|
||||
@@ -113,13 +117,13 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
||||
var h hash.Hash
|
||||
switch strings.ToLower(rr.Algorithm) {
|
||||
case HmacMD5:
|
||||
h = hmac.New(md5.New, []byte(rawsecret))
|
||||
h = hmac.New(md5.New, rawsecret)
|
||||
case HmacSHA1:
|
||||
h = hmac.New(sha1.New, []byte(rawsecret))
|
||||
h = hmac.New(sha1.New, rawsecret)
|
||||
case HmacSHA256:
|
||||
h = hmac.New(sha256.New, []byte(rawsecret))
|
||||
h = hmac.New(sha256.New, rawsecret)
|
||||
case HmacSHA512:
|
||||
h = hmac.New(sha512.New, []byte(rawsecret))
|
||||
h = hmac.New(sha512.New, rawsecret)
|
||||
default:
|
||||
return nil, "", ErrKeyAlg
|
||||
}
|
||||
@@ -134,12 +138,11 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
||||
t.OrigId = m.Id
|
||||
|
||||
tbuf := make([]byte, Len(t))
|
||||
if off, err := PackRR(t, tbuf, 0, nil, false); err == nil {
|
||||
tbuf = tbuf[:off] // reset to actual size used
|
||||
} else {
|
||||
off, err := PackRR(t, tbuf, 0, nil, false)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
mbuf = append(mbuf, tbuf...)
|
||||
mbuf = append(mbuf, tbuf[:off]...)
|
||||
// Update the ArCount directly in the buffer.
|
||||
binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
|
||||
|
||||
|
||||
36
vendor/github.com/miekg/dns/types.go
сгенерированный
поставляемый
36
vendor/github.com/miekg/dns/types.go
сгенерированный
поставляемый
@@ -205,9 +205,6 @@ var CertTypeToString = map[uint16]string{
|
||||
CertOID: "OID",
|
||||
}
|
||||
|
||||
// StringToCertType is the reverseof CertTypeToString.
|
||||
var StringToCertType = reverseInt16(CertTypeToString)
|
||||
|
||||
//go:generate go run types_generate.go
|
||||
|
||||
// Question holds a DNS question. There can be multiple questions in the
|
||||
@@ -241,6 +238,25 @@ type ANY struct {
|
||||
|
||||
func (rr *ANY) String() string { return rr.Hdr.String() }
|
||||
|
||||
func (rr *ANY) parse(c *zlexer, origin, file string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on ANY")
|
||||
}
|
||||
|
||||
// NULL RR. See RFC 1035.
|
||||
type NULL struct {
|
||||
Hdr RR_Header
|
||||
Data string `dns:"any"`
|
||||
}
|
||||
|
||||
func (rr *NULL) String() string {
|
||||
// There is no presentation format; prefix string with a comment.
|
||||
return ";" + rr.Hdr.String() + rr.Data
|
||||
}
|
||||
|
||||
func (rr *NULL) parse(c *zlexer, origin, file string) *ParseError {
|
||||
panic("dns: internal error: parse should never be called on NULL")
|
||||
}
|
||||
|
||||
// CNAME RR. See RFC 1034.
|
||||
type CNAME struct {
|
||||
Hdr RR_Header
|
||||
@@ -1050,10 +1066,16 @@ type TKEY struct {
|
||||
|
||||
// TKEY has no official presentation format, but this will suffice.
|
||||
func (rr *TKEY) String() string {
|
||||
s := "\n;; TKEY PSEUDOSECTION:\n"
|
||||
s += rr.Hdr.String() + " " + rr.Algorithm + " " +
|
||||
strconv.Itoa(int(rr.KeySize)) + " " + rr.Key + " " +
|
||||
strconv.Itoa(int(rr.OtherLen)) + " " + rr.OtherData
|
||||
s := ";" + rr.Hdr.String() +
|
||||
" " + rr.Algorithm +
|
||||
" " + TimeToString(rr.Inception) +
|
||||
" " + TimeToString(rr.Expiration) +
|
||||
" " + strconv.Itoa(int(rr.Mode)) +
|
||||
" " + strconv.Itoa(int(rr.Error)) +
|
||||
" " + strconv.Itoa(int(rr.KeySize)) +
|
||||
" " + rr.Key +
|
||||
" " + strconv.Itoa(int(rr.OtherLen)) +
|
||||
" " + rr.OtherData
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/miekg/dns/types_generate.go
сгенерированный
поставляемый
2
vendor/github.com/miekg/dns/types_generate.go
сгенерированный
поставляемый
@@ -193,6 +193,8 @@ func main() {
|
||||
fallthrough
|
||||
case st.Tag(i) == `dns:"hex"`:
|
||||
o("l += len(rr.%s)/2 + 1\n")
|
||||
case st.Tag(i) == `dns:"any"`:
|
||||
o("l += len(rr.%s)\n")
|
||||
case st.Tag(i) == `dns:"a"`:
|
||||
o("l += net.IPv4len // %s\n")
|
||||
case st.Tag(i) == `dns:"aaaa"`:
|
||||
|
||||
6
vendor/github.com/miekg/dns/udp_windows.go
сгенерированный
поставляемый
6
vendor/github.com/miekg/dns/udp_windows.go
сгенерированный
поставляемый
@@ -20,15 +20,13 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||
if err != nil {
|
||||
return n, nil, err
|
||||
}
|
||||
session := &SessionUDP{raddr.(*net.UDPAddr)}
|
||||
return n, session, err
|
||||
return n, &SessionUDP{raddr.(*net.UDPAddr)}, err
|
||||
}
|
||||
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
|
||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||
n, err := conn.WriteTo(b, session.raddr)
|
||||
return n, err
|
||||
return conn.WriteTo(b, session.raddr)
|
||||
}
|
||||
|
||||
// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
|
||||
|
||||
14
vendor/github.com/miekg/dns/update.go
сгенерированный
поставляемый
14
vendor/github.com/miekg/dns/update.go
сгенерированный
поставляемый
@@ -44,7 +44,8 @@ func (u *Msg) RRsetUsed(rr []RR) {
|
||||
u.Answer = make([]RR, 0, len(rr))
|
||||
}
|
||||
for _, r := range rr {
|
||||
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
|
||||
h := r.Header()
|
||||
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +56,8 @@ func (u *Msg) RRsetNotUsed(rr []RR) {
|
||||
u.Answer = make([]RR, 0, len(rr))
|
||||
}
|
||||
for _, r := range rr {
|
||||
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassNONE}})
|
||||
h := r.Header()
|
||||
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +81,8 @@ func (u *Msg) RemoveRRset(rr []RR) {
|
||||
u.Ns = make([]RR, 0, len(rr))
|
||||
}
|
||||
for _, r := range rr {
|
||||
u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
|
||||
h := r.Header()
|
||||
u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +102,9 @@ func (u *Msg) Remove(rr []RR) {
|
||||
u.Ns = make([]RR, 0, len(rr))
|
||||
}
|
||||
for _, r := range rr {
|
||||
r.Header().Class = ClassNONE
|
||||
r.Header().Ttl = 0
|
||||
h := r.Header()
|
||||
h.Class = ClassNONE
|
||||
h.Ttl = 0
|
||||
u.Ns = append(u.Ns, r)
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/miekg/dns/version.go
сгенерированный
поставляемый
2
vendor/github.com/miekg/dns/version.go
сгенерированный
поставляемый
@@ -3,7 +3,7 @@ package dns
|
||||
import "fmt"
|
||||
|
||||
// Version is current version of this library.
|
||||
var Version = V{1, 1, 1}
|
||||
var Version = V{1, 1, 3}
|
||||
|
||||
// V holds the version of this library.
|
||||
type V struct {
|
||||
|
||||
46
vendor/github.com/miekg/dns/xfr.go
сгенерированный
поставляемый
46
vendor/github.com/miekg/dns/xfr.go
сгенерированный
поставляемый
@@ -35,30 +35,36 @@ type Transfer struct {
|
||||
// channel, err := transfer.In(message, master)
|
||||
//
|
||||
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
||||
switch q.Question[0].Qtype {
|
||||
case TypeAXFR, TypeIXFR:
|
||||
default:
|
||||
return nil, &Error{"unsupported question type"}
|
||||
}
|
||||
|
||||
timeout := dnsTimeout
|
||||
if t.DialTimeout != 0 {
|
||||
timeout = t.DialTimeout
|
||||
}
|
||||
|
||||
if t.Conn == nil {
|
||||
t.Conn, err = DialTimeout("tcp", a, timeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := t.WriteMsg(q); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
env = make(chan *Envelope)
|
||||
go func() {
|
||||
if q.Question[0].Qtype == TypeAXFR {
|
||||
go t.inAxfr(q, env)
|
||||
return
|
||||
}
|
||||
if q.Question[0].Qtype == TypeIXFR {
|
||||
go t.inIxfr(q, env)
|
||||
return
|
||||
}
|
||||
}()
|
||||
switch q.Question[0].Qtype {
|
||||
case TypeAXFR:
|
||||
go t.inAxfr(q, env)
|
||||
case TypeIXFR:
|
||||
go t.inIxfr(q, env)
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
@@ -111,7 +117,7 @@ func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
|
||||
}
|
||||
|
||||
func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
||||
serial := uint32(0) // The first serial seen is the current server serial
|
||||
var serial uint32 // The first serial seen is the current server serial
|
||||
axfr := true
|
||||
n := 0
|
||||
qser := q.Ns[0].(*SOA).Serial
|
||||
@@ -237,24 +243,18 @@ func (t *Transfer) WriteMsg(m *Msg) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = t.Write(out); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err = t.Write(out)
|
||||
return err
|
||||
}
|
||||
|
||||
func isSOAFirst(in *Msg) bool {
|
||||
if len(in.Answer) > 0 {
|
||||
return in.Answer[0].Header().Rrtype == TypeSOA
|
||||
}
|
||||
return false
|
||||
return len(in.Answer) > 0 &&
|
||||
in.Answer[0].Header().Rrtype == TypeSOA
|
||||
}
|
||||
|
||||
func isSOALast(in *Msg) bool {
|
||||
if len(in.Answer) > 0 {
|
||||
return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
|
||||
}
|
||||
return false
|
||||
return len(in.Answer) > 0 &&
|
||||
in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
|
||||
}
|
||||
|
||||
const errXFR = "bad xfr rcode: %d"
|
||||
|
||||
615
vendor/github.com/miekg/dns/zduplicate.go
сгенерированный
поставляемый
615
vendor/github.com/miekg/dns/zduplicate.go
сгенерированный
поставляемый
@@ -2,164 +2,38 @@
|
||||
|
||||
package dns
|
||||
|
||||
// isDuplicateRdata calls the rdata specific functions
|
||||
func isDuplicateRdata(r1, r2 RR) bool {
|
||||
switch r1.Header().Rrtype {
|
||||
case TypeA:
|
||||
return isDuplicateA(r1.(*A), r2.(*A))
|
||||
case TypeAAAA:
|
||||
return isDuplicateAAAA(r1.(*AAAA), r2.(*AAAA))
|
||||
case TypeAFSDB:
|
||||
return isDuplicateAFSDB(r1.(*AFSDB), r2.(*AFSDB))
|
||||
case TypeAVC:
|
||||
return isDuplicateAVC(r1.(*AVC), r2.(*AVC))
|
||||
case TypeCAA:
|
||||
return isDuplicateCAA(r1.(*CAA), r2.(*CAA))
|
||||
case TypeCERT:
|
||||
return isDuplicateCERT(r1.(*CERT), r2.(*CERT))
|
||||
case TypeCNAME:
|
||||
return isDuplicateCNAME(r1.(*CNAME), r2.(*CNAME))
|
||||
case TypeCSYNC:
|
||||
return isDuplicateCSYNC(r1.(*CSYNC), r2.(*CSYNC))
|
||||
case TypeDHCID:
|
||||
return isDuplicateDHCID(r1.(*DHCID), r2.(*DHCID))
|
||||
case TypeDNAME:
|
||||
return isDuplicateDNAME(r1.(*DNAME), r2.(*DNAME))
|
||||
case TypeDNSKEY:
|
||||
return isDuplicateDNSKEY(r1.(*DNSKEY), r2.(*DNSKEY))
|
||||
case TypeDS:
|
||||
return isDuplicateDS(r1.(*DS), r2.(*DS))
|
||||
case TypeEID:
|
||||
return isDuplicateEID(r1.(*EID), r2.(*EID))
|
||||
case TypeEUI48:
|
||||
return isDuplicateEUI48(r1.(*EUI48), r2.(*EUI48))
|
||||
case TypeEUI64:
|
||||
return isDuplicateEUI64(r1.(*EUI64), r2.(*EUI64))
|
||||
case TypeGID:
|
||||
return isDuplicateGID(r1.(*GID), r2.(*GID))
|
||||
case TypeGPOS:
|
||||
return isDuplicateGPOS(r1.(*GPOS), r2.(*GPOS))
|
||||
case TypeHINFO:
|
||||
return isDuplicateHINFO(r1.(*HINFO), r2.(*HINFO))
|
||||
case TypeHIP:
|
||||
return isDuplicateHIP(r1.(*HIP), r2.(*HIP))
|
||||
case TypeKX:
|
||||
return isDuplicateKX(r1.(*KX), r2.(*KX))
|
||||
case TypeL32:
|
||||
return isDuplicateL32(r1.(*L32), r2.(*L32))
|
||||
case TypeL64:
|
||||
return isDuplicateL64(r1.(*L64), r2.(*L64))
|
||||
case TypeLOC:
|
||||
return isDuplicateLOC(r1.(*LOC), r2.(*LOC))
|
||||
case TypeLP:
|
||||
return isDuplicateLP(r1.(*LP), r2.(*LP))
|
||||
case TypeMB:
|
||||
return isDuplicateMB(r1.(*MB), r2.(*MB))
|
||||
case TypeMD:
|
||||
return isDuplicateMD(r1.(*MD), r2.(*MD))
|
||||
case TypeMF:
|
||||
return isDuplicateMF(r1.(*MF), r2.(*MF))
|
||||
case TypeMG:
|
||||
return isDuplicateMG(r1.(*MG), r2.(*MG))
|
||||
case TypeMINFO:
|
||||
return isDuplicateMINFO(r1.(*MINFO), r2.(*MINFO))
|
||||
case TypeMR:
|
||||
return isDuplicateMR(r1.(*MR), r2.(*MR))
|
||||
case TypeMX:
|
||||
return isDuplicateMX(r1.(*MX), r2.(*MX))
|
||||
case TypeNAPTR:
|
||||
return isDuplicateNAPTR(r1.(*NAPTR), r2.(*NAPTR))
|
||||
case TypeNID:
|
||||
return isDuplicateNID(r1.(*NID), r2.(*NID))
|
||||
case TypeNIMLOC:
|
||||
return isDuplicateNIMLOC(r1.(*NIMLOC), r2.(*NIMLOC))
|
||||
case TypeNINFO:
|
||||
return isDuplicateNINFO(r1.(*NINFO), r2.(*NINFO))
|
||||
case TypeNS:
|
||||
return isDuplicateNS(r1.(*NS), r2.(*NS))
|
||||
case TypeNSAPPTR:
|
||||
return isDuplicateNSAPPTR(r1.(*NSAPPTR), r2.(*NSAPPTR))
|
||||
case TypeNSEC:
|
||||
return isDuplicateNSEC(r1.(*NSEC), r2.(*NSEC))
|
||||
case TypeNSEC3:
|
||||
return isDuplicateNSEC3(r1.(*NSEC3), r2.(*NSEC3))
|
||||
case TypeNSEC3PARAM:
|
||||
return isDuplicateNSEC3PARAM(r1.(*NSEC3PARAM), r2.(*NSEC3PARAM))
|
||||
case TypeOPENPGPKEY:
|
||||
return isDuplicateOPENPGPKEY(r1.(*OPENPGPKEY), r2.(*OPENPGPKEY))
|
||||
case TypePTR:
|
||||
return isDuplicatePTR(r1.(*PTR), r2.(*PTR))
|
||||
case TypePX:
|
||||
return isDuplicatePX(r1.(*PX), r2.(*PX))
|
||||
case TypeRKEY:
|
||||
return isDuplicateRKEY(r1.(*RKEY), r2.(*RKEY))
|
||||
case TypeRP:
|
||||
return isDuplicateRP(r1.(*RP), r2.(*RP))
|
||||
case TypeRRSIG:
|
||||
return isDuplicateRRSIG(r1.(*RRSIG), r2.(*RRSIG))
|
||||
case TypeRT:
|
||||
return isDuplicateRT(r1.(*RT), r2.(*RT))
|
||||
case TypeSMIMEA:
|
||||
return isDuplicateSMIMEA(r1.(*SMIMEA), r2.(*SMIMEA))
|
||||
case TypeSOA:
|
||||
return isDuplicateSOA(r1.(*SOA), r2.(*SOA))
|
||||
case TypeSPF:
|
||||
return isDuplicateSPF(r1.(*SPF), r2.(*SPF))
|
||||
case TypeSRV:
|
||||
return isDuplicateSRV(r1.(*SRV), r2.(*SRV))
|
||||
case TypeSSHFP:
|
||||
return isDuplicateSSHFP(r1.(*SSHFP), r2.(*SSHFP))
|
||||
case TypeTA:
|
||||
return isDuplicateTA(r1.(*TA), r2.(*TA))
|
||||
case TypeTALINK:
|
||||
return isDuplicateTALINK(r1.(*TALINK), r2.(*TALINK))
|
||||
case TypeTKEY:
|
||||
return isDuplicateTKEY(r1.(*TKEY), r2.(*TKEY))
|
||||
case TypeTLSA:
|
||||
return isDuplicateTLSA(r1.(*TLSA), r2.(*TLSA))
|
||||
case TypeTSIG:
|
||||
return isDuplicateTSIG(r1.(*TSIG), r2.(*TSIG))
|
||||
case TypeTXT:
|
||||
return isDuplicateTXT(r1.(*TXT), r2.(*TXT))
|
||||
case TypeUID:
|
||||
return isDuplicateUID(r1.(*UID), r2.(*UID))
|
||||
case TypeUINFO:
|
||||
return isDuplicateUINFO(r1.(*UINFO), r2.(*UINFO))
|
||||
case TypeURI:
|
||||
return isDuplicateURI(r1.(*URI), r2.(*URI))
|
||||
case TypeX25:
|
||||
return isDuplicateX25(r1.(*X25), r2.(*X25))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isDuplicate() functions
|
||||
|
||||
func isDuplicateA(r1, r2 *A) bool {
|
||||
if len(r1.A) != len(r2.A) {
|
||||
func (r1 *A) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*A)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(r1.A); i++ {
|
||||
if r1.A[i] != r2.A[i] {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !r1.A.Equal(r2.A) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateAAAA(r1, r2 *AAAA) bool {
|
||||
if len(r1.AAAA) != len(r2.AAAA) {
|
||||
func (r1 *AAAA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*AAAA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(r1.AAAA); i++ {
|
||||
if r1.AAAA[i] != r2.AAAA[i] {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !r1.AAAA.Equal(r2.AAAA) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateAFSDB(r1, r2 *AFSDB) bool {
|
||||
func (r1 *AFSDB) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*AFSDB)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Subtype != r2.Subtype {
|
||||
return false
|
||||
}
|
||||
@@ -169,7 +43,21 @@ func isDuplicateAFSDB(r1, r2 *AFSDB) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateAVC(r1, r2 *AVC) bool {
|
||||
func (r1 *ANY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*ANY)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *AVC) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*AVC)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if len(r1.Txt) != len(r2.Txt) {
|
||||
return false
|
||||
}
|
||||
@@ -181,7 +69,12 @@ func isDuplicateAVC(r1, r2 *AVC) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateCAA(r1, r2 *CAA) bool {
|
||||
func (r1 *CAA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*CAA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Flag != r2.Flag {
|
||||
return false
|
||||
}
|
||||
@@ -194,7 +87,12 @@ func isDuplicateCAA(r1, r2 *CAA) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateCERT(r1, r2 *CERT) bool {
|
||||
func (r1 *CERT) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*CERT)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Type != r2.Type {
|
||||
return false
|
||||
}
|
||||
@@ -210,14 +108,24 @@ func isDuplicateCERT(r1, r2 *CERT) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateCNAME(r1, r2 *CNAME) bool {
|
||||
func (r1 *CNAME) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*CNAME)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Target, r2.Target) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateCSYNC(r1, r2 *CSYNC) bool {
|
||||
func (r1 *CSYNC) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*CSYNC)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Serial != r2.Serial {
|
||||
return false
|
||||
}
|
||||
@@ -235,21 +143,36 @@ func isDuplicateCSYNC(r1, r2 *CSYNC) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateDHCID(r1, r2 *DHCID) bool {
|
||||
func (r1 *DHCID) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*DHCID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Digest != r2.Digest {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateDNAME(r1, r2 *DNAME) bool {
|
||||
func (r1 *DNAME) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*DNAME)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Target, r2.Target) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateDNSKEY(r1, r2 *DNSKEY) bool {
|
||||
func (r1 *DNSKEY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*DNSKEY)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Flags != r2.Flags {
|
||||
return false
|
||||
}
|
||||
@@ -265,7 +188,12 @@ func isDuplicateDNSKEY(r1, r2 *DNSKEY) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateDS(r1, r2 *DS) bool {
|
||||
func (r1 *DS) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*DS)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.KeyTag != r2.KeyTag {
|
||||
return false
|
||||
}
|
||||
@@ -281,35 +209,60 @@ func isDuplicateDS(r1, r2 *DS) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateEID(r1, r2 *EID) bool {
|
||||
func (r1 *EID) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*EID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Endpoint != r2.Endpoint {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateEUI48(r1, r2 *EUI48) bool {
|
||||
func (r1 *EUI48) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*EUI48)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Address != r2.Address {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateEUI64(r1, r2 *EUI64) bool {
|
||||
func (r1 *EUI64) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*EUI64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Address != r2.Address {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateGID(r1, r2 *GID) bool {
|
||||
func (r1 *GID) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*GID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Gid != r2.Gid {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateGPOS(r1, r2 *GPOS) bool {
|
||||
func (r1 *GPOS) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*GPOS)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Longitude != r2.Longitude {
|
||||
return false
|
||||
}
|
||||
@@ -322,7 +275,12 @@ func isDuplicateGPOS(r1, r2 *GPOS) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateHINFO(r1, r2 *HINFO) bool {
|
||||
func (r1 *HINFO) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*HINFO)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Cpu != r2.Cpu {
|
||||
return false
|
||||
}
|
||||
@@ -332,7 +290,12 @@ func isDuplicateHINFO(r1, r2 *HINFO) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateHIP(r1, r2 *HIP) bool {
|
||||
func (r1 *HIP) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*HIP)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.HitLength != r2.HitLength {
|
||||
return false
|
||||
}
|
||||
@@ -359,7 +322,12 @@ func isDuplicateHIP(r1, r2 *HIP) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateKX(r1, r2 *KX) bool {
|
||||
func (r1 *KX) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*KX)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -369,22 +337,27 @@ func isDuplicateKX(r1, r2 *KX) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateL32(r1, r2 *L32) bool {
|
||||
func (r1 *L32) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*L32)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
if len(r1.Locator32) != len(r2.Locator32) {
|
||||
if !r1.Locator32.Equal(r2.Locator32) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(r1.Locator32); i++ {
|
||||
if r1.Locator32[i] != r2.Locator32[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateL64(r1, r2 *L64) bool {
|
||||
func (r1 *L64) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*L64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -394,7 +367,12 @@ func isDuplicateL64(r1, r2 *L64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateLOC(r1, r2 *LOC) bool {
|
||||
func (r1 *LOC) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*LOC)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Version != r2.Version {
|
||||
return false
|
||||
}
|
||||
@@ -419,7 +397,12 @@ func isDuplicateLOC(r1, r2 *LOC) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateLP(r1, r2 *LP) bool {
|
||||
func (r1 *LP) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*LP)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -429,35 +412,60 @@ func isDuplicateLP(r1, r2 *LP) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMB(r1, r2 *MB) bool {
|
||||
func (r1 *MB) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MB)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Mb, r2.Mb) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMD(r1, r2 *MD) bool {
|
||||
func (r1 *MD) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MD)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Md, r2.Md) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMF(r1, r2 *MF) bool {
|
||||
func (r1 *MF) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MF)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Mf, r2.Mf) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMG(r1, r2 *MG) bool {
|
||||
func (r1 *MG) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MG)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Mg, r2.Mg) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMINFO(r1, r2 *MINFO) bool {
|
||||
func (r1 *MINFO) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MINFO)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Rmail, r2.Rmail) {
|
||||
return false
|
||||
}
|
||||
@@ -467,14 +475,24 @@ func isDuplicateMINFO(r1, r2 *MINFO) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMR(r1, r2 *MR) bool {
|
||||
func (r1 *MR) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MR)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Mr, r2.Mr) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateMX(r1, r2 *MX) bool {
|
||||
func (r1 *MX) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*MX)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -484,7 +502,12 @@ func isDuplicateMX(r1, r2 *MX) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNAPTR(r1, r2 *NAPTR) bool {
|
||||
func (r1 *NAPTR) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NAPTR)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Order != r2.Order {
|
||||
return false
|
||||
}
|
||||
@@ -506,7 +529,12 @@ func isDuplicateNAPTR(r1, r2 *NAPTR) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNID(r1, r2 *NID) bool {
|
||||
func (r1 *NID) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -516,14 +544,24 @@ func isDuplicateNID(r1, r2 *NID) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNIMLOC(r1, r2 *NIMLOC) bool {
|
||||
func (r1 *NIMLOC) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NIMLOC)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Locator != r2.Locator {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNINFO(r1, r2 *NINFO) bool {
|
||||
func (r1 *NINFO) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NINFO)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if len(r1.ZSData) != len(r2.ZSData) {
|
||||
return false
|
||||
}
|
||||
@@ -535,21 +573,36 @@ func isDuplicateNINFO(r1, r2 *NINFO) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNS(r1, r2 *NS) bool {
|
||||
func (r1 *NS) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NS)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Ns, r2.Ns) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNSAPPTR(r1, r2 *NSAPPTR) bool {
|
||||
func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NSAPPTR)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Ptr, r2.Ptr) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNSEC(r1, r2 *NSEC) bool {
|
||||
func (r1 *NSEC) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NSEC)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.NextDomain, r2.NextDomain) {
|
||||
return false
|
||||
}
|
||||
@@ -564,7 +617,12 @@ func isDuplicateNSEC(r1, r2 *NSEC) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNSEC3(r1, r2 *NSEC3) bool {
|
||||
func (r1 *NSEC3) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NSEC3)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Hash != r2.Hash {
|
||||
return false
|
||||
}
|
||||
@@ -597,7 +655,12 @@ func isDuplicateNSEC3(r1, r2 *NSEC3) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
|
||||
func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NSEC3PARAM)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Hash != r2.Hash {
|
||||
return false
|
||||
}
|
||||
@@ -616,21 +679,48 @@ func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateOPENPGPKEY(r1, r2 *OPENPGPKEY) bool {
|
||||
func (r1 *NULL) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NULL)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Data != r2.Data {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*OPENPGPKEY)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.PublicKey != r2.PublicKey {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicatePTR(r1, r2 *PTR) bool {
|
||||
func (r1 *PTR) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*PTR)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Ptr, r2.Ptr) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicatePX(r1, r2 *PX) bool {
|
||||
func (r1 *PX) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*PX)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -643,7 +733,24 @@ func isDuplicatePX(r1, r2 *PX) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateRKEY(r1, r2 *RKEY) bool {
|
||||
func (r1 *RFC3597) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RFC3597)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Rdata != r2.Rdata {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *RKEY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RKEY)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Flags != r2.Flags {
|
||||
return false
|
||||
}
|
||||
@@ -659,7 +766,12 @@ func isDuplicateRKEY(r1, r2 *RKEY) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateRP(r1, r2 *RP) bool {
|
||||
func (r1 *RP) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RP)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Mbox, r2.Mbox) {
|
||||
return false
|
||||
}
|
||||
@@ -669,7 +781,12 @@ func isDuplicateRP(r1, r2 *RP) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
|
||||
func (r1 *RRSIG) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RRSIG)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.TypeCovered != r2.TypeCovered {
|
||||
return false
|
||||
}
|
||||
@@ -700,7 +817,12 @@ func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateRT(r1, r2 *RT) bool {
|
||||
func (r1 *RT) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*RT)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Preference != r2.Preference {
|
||||
return false
|
||||
}
|
||||
@@ -710,7 +832,12 @@ func isDuplicateRT(r1, r2 *RT) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateSMIMEA(r1, r2 *SMIMEA) bool {
|
||||
func (r1 *SMIMEA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SMIMEA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Usage != r2.Usage {
|
||||
return false
|
||||
}
|
||||
@@ -726,7 +853,12 @@ func isDuplicateSMIMEA(r1, r2 *SMIMEA) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateSOA(r1, r2 *SOA) bool {
|
||||
func (r1 *SOA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SOA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Ns, r2.Ns) {
|
||||
return false
|
||||
}
|
||||
@@ -751,7 +883,12 @@ func isDuplicateSOA(r1, r2 *SOA) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateSPF(r1, r2 *SPF) bool {
|
||||
func (r1 *SPF) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SPF)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if len(r1.Txt) != len(r2.Txt) {
|
||||
return false
|
||||
}
|
||||
@@ -763,7 +900,12 @@ func isDuplicateSPF(r1, r2 *SPF) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateSRV(r1, r2 *SRV) bool {
|
||||
func (r1 *SRV) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SRV)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Priority != r2.Priority {
|
||||
return false
|
||||
}
|
||||
@@ -779,7 +921,12 @@ func isDuplicateSRV(r1, r2 *SRV) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateSSHFP(r1, r2 *SSHFP) bool {
|
||||
func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*SSHFP)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Algorithm != r2.Algorithm {
|
||||
return false
|
||||
}
|
||||
@@ -792,7 +939,12 @@ func isDuplicateSSHFP(r1, r2 *SSHFP) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTA(r1, r2 *TA) bool {
|
||||
func (r1 *TA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.KeyTag != r2.KeyTag {
|
||||
return false
|
||||
}
|
||||
@@ -808,7 +960,12 @@ func isDuplicateTA(r1, r2 *TA) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTALINK(r1, r2 *TALINK) bool {
|
||||
func (r1 *TALINK) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TALINK)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.PreviousName, r2.PreviousName) {
|
||||
return false
|
||||
}
|
||||
@@ -818,7 +975,12 @@ func isDuplicateTALINK(r1, r2 *TALINK) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTKEY(r1, r2 *TKEY) bool {
|
||||
func (r1 *TKEY) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TKEY)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Algorithm, r2.Algorithm) {
|
||||
return false
|
||||
}
|
||||
@@ -849,7 +1011,12 @@ func isDuplicateTKEY(r1, r2 *TKEY) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTLSA(r1, r2 *TLSA) bool {
|
||||
func (r1 *TLSA) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TLSA)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Usage != r2.Usage {
|
||||
return false
|
||||
}
|
||||
@@ -865,7 +1032,12 @@ func isDuplicateTLSA(r1, r2 *TLSA) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTSIG(r1, r2 *TSIG) bool {
|
||||
func (r1 *TSIG) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TSIG)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if !isDulicateName(r1.Algorithm, r2.Algorithm) {
|
||||
return false
|
||||
}
|
||||
@@ -896,7 +1068,12 @@ func isDuplicateTSIG(r1, r2 *TSIG) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateTXT(r1, r2 *TXT) bool {
|
||||
func (r1 *TXT) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*TXT)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if len(r1.Txt) != len(r2.Txt) {
|
||||
return false
|
||||
}
|
||||
@@ -908,21 +1085,36 @@ func isDuplicateTXT(r1, r2 *TXT) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateUID(r1, r2 *UID) bool {
|
||||
func (r1 *UID) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*UID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Uid != r2.Uid {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateUINFO(r1, r2 *UINFO) bool {
|
||||
func (r1 *UINFO) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*UINFO)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Uinfo != r2.Uinfo {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateURI(r1, r2 *URI) bool {
|
||||
func (r1 *URI) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*URI)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Priority != r2.Priority {
|
||||
return false
|
||||
}
|
||||
@@ -935,7 +1127,12 @@ func isDuplicateURI(r1, r2 *URI) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isDuplicateX25(r1, r2 *X25) bool {
|
||||
func (r1 *X25) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*X25)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.PSDNAddress != r2.PSDNAddress {
|
||||
return false
|
||||
}
|
||||
|
||||
2429
vendor/github.com/miekg/dns/zmsg.go
сгенерированный
поставляемый
2429
vendor/github.com/miekg/dns/zmsg.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
10
vendor/github.com/miekg/dns/ztypes.go
сгенерированный
поставляемый
10
vendor/github.com/miekg/dns/ztypes.go
сгенерированный
поставляемый
@@ -54,6 +54,7 @@ var TypeToRR = map[uint16]func() RR{
|
||||
TypeNSEC: func() RR { return new(NSEC) },
|
||||
TypeNSEC3: func() RR { return new(NSEC3) },
|
||||
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
|
||||
TypeNULL: func() RR { return new(NULL) },
|
||||
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
|
||||
TypeOPT: func() RR { return new(OPT) },
|
||||
TypePTR: func() RR { return new(PTR) },
|
||||
@@ -209,6 +210,7 @@ func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NULL) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
|
||||
@@ -473,6 +475,11 @@ func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
|
||||
l += len(rr.Salt) / 2
|
||||
return l
|
||||
}
|
||||
func (rr *NULL) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += len(rr.Data)
|
||||
return l
|
||||
}
|
||||
func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||
@@ -783,6 +790,9 @@ func (rr *NSEC3) copy() RR {
|
||||
func (rr *NSEC3PARAM) copy() RR {
|
||||
return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
|
||||
}
|
||||
func (rr *NULL) copy() RR {
|
||||
return &NULL{rr.Hdr, rr.Data}
|
||||
}
|
||||
func (rr *OPENPGPKEY) copy() RR {
|
||||
return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
|
||||
}
|
||||
|
||||
4
vendor/github.com/minio/minio-go/.travis.yml
сгенерированный
поставляемый
4
vendor/github.com/minio/minio-go/.travis.yml
сгенерированный
поставляемый
@@ -9,9 +9,7 @@ env:
|
||||
- ARCH=i686
|
||||
|
||||
go:
|
||||
- 1.7.4
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
|
||||
8
vendor/github.com/minio/minio-go/api-error-response.go
сгенерированный
поставляемый
8
vendor/github.com/minio/minio-go/api-error-response.go
сгенерированный
поставляемый
@@ -36,6 +36,8 @@ import (
|
||||
*/
|
||||
|
||||
// ErrorResponse - Is the typed error returned by all API operations.
|
||||
// ErrorResponse struct should be comparable since it is compared inside
|
||||
// golang http API (https://github.com/golang/go/issues/29768)
|
||||
type ErrorResponse struct {
|
||||
XMLName xml.Name `xml:"Error" json:"-"`
|
||||
Code string
|
||||
@@ -51,9 +53,6 @@ type ErrorResponse struct {
|
||||
|
||||
// Underlying HTTP status code for the returned error
|
||||
StatusCode int `xml:"-" json:"-"`
|
||||
|
||||
// Headers of the returned S3 XML error
|
||||
Headers http.Header `xml:"-" json:"-"`
|
||||
}
|
||||
|
||||
// ToErrorResponse - Returns parsed ErrorResponse struct from body and
|
||||
@@ -177,9 +176,6 @@ func httpRespToErrorResponse(resp *http.Response, bucketName, objectName string)
|
||||
errResp.Message = fmt.Sprintf("Region does not match, expecting region ‘%s’.", errResp.Region)
|
||||
}
|
||||
|
||||
// Save headers returned in the API XML error
|
||||
errResp.Headers = resp.Header
|
||||
|
||||
return errResp
|
||||
}
|
||||
|
||||
|
||||
43
vendor/github.com/minio/minio-go/api-list.go
сгенерированный
поставляемый
43
vendor/github.com/minio/minio-go/api-list.go
сгенерированный
поставляемый
@@ -192,18 +192,16 @@ func (c Client) listObjectsV2Query(bucketName, objectPrefix, continuationToken s
|
||||
// Always set list-type in ListObjects V2
|
||||
urlValues.Set("list-type", "2")
|
||||
|
||||
// Set object prefix.
|
||||
if objectPrefix != "" {
|
||||
urlValues.Set("prefix", objectPrefix)
|
||||
}
|
||||
// Set object prefix, prefix value to be set to empty is okay.
|
||||
urlValues.Set("prefix", objectPrefix)
|
||||
|
||||
// Set delimiter, delimiter value to be set to empty is okay.
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
|
||||
// Set continuation token
|
||||
if continuationToken != "" {
|
||||
urlValues.Set("continuation-token", continuationToken)
|
||||
}
|
||||
// Set delimiter.
|
||||
if delimiter != "" {
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
}
|
||||
|
||||
// Fetch owner when listing
|
||||
if fetchOwner {
|
||||
@@ -380,18 +378,17 @@ func (c Client) listObjectsQuery(bucketName, objectPrefix, objectMarker, delimit
|
||||
// Get resources properly escaped and lined up before
|
||||
// using them in http request.
|
||||
urlValues := make(url.Values)
|
||||
// Set object prefix.
|
||||
if objectPrefix != "" {
|
||||
urlValues.Set("prefix", objectPrefix)
|
||||
}
|
||||
|
||||
// Set object prefix, prefix value to be set to empty is okay.
|
||||
urlValues.Set("prefix", objectPrefix)
|
||||
|
||||
// Set delimiter, delimiter value to be set to empty is okay.
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
|
||||
// Set object marker.
|
||||
if objectMarker != "" {
|
||||
urlValues.Set("marker", objectMarker)
|
||||
}
|
||||
// Set delimiter.
|
||||
if delimiter != "" {
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
}
|
||||
|
||||
// maxkeys should default to 1000 or less.
|
||||
if maxkeys == 0 || maxkeys > 1000 {
|
||||
@@ -563,14 +560,12 @@ func (c Client) listMultipartUploadsQuery(bucketName, keyMarker, uploadIDMarker,
|
||||
if uploadIDMarker != "" {
|
||||
urlValues.Set("upload-id-marker", uploadIDMarker)
|
||||
}
|
||||
// Set prefix marker.
|
||||
if prefix != "" {
|
||||
urlValues.Set("prefix", prefix)
|
||||
}
|
||||
// Set delimiter.
|
||||
if delimiter != "" {
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
}
|
||||
|
||||
// Set object prefix, prefix value to be set to empty is okay.
|
||||
urlValues.Set("prefix", prefix)
|
||||
|
||||
// Set delimiter, delimiter value to be set to empty is okay.
|
||||
urlValues.Set("delimiter", delimiter)
|
||||
|
||||
// maxUploads should be 1000 or less.
|
||||
if maxUploads == 0 || maxUploads > 1000 {
|
||||
|
||||
82
vendor/github.com/minio/minio-go/api-select.go
сгенерированный
поставляемый
82
vendor/github.com/minio/minio-go/api-select.go
сгенерированный
поставляемый
@@ -191,13 +191,20 @@ type StatsMessage struct {
|
||||
BytesReturned int64
|
||||
}
|
||||
|
||||
// messageType represents the type of message.
|
||||
type messageType string
|
||||
|
||||
const (
|
||||
errorMsg messageType = "error"
|
||||
commonMsg = "event"
|
||||
)
|
||||
|
||||
// eventType represents the type of event.
|
||||
type eventType string
|
||||
|
||||
// list of event-types returned by Select API.
|
||||
const (
|
||||
endEvent eventType = "End"
|
||||
errorEvent = "Error"
|
||||
recordsEvent = "Records"
|
||||
progressEvent = "Progress"
|
||||
statsEvent = "Stats"
|
||||
@@ -314,53 +321,58 @@ func (s *SelectResults) start(pipeWriter *io.PipeWriter) {
|
||||
// bytes can be read or parsed.
|
||||
payloadLen := prelude.PayloadLen()
|
||||
|
||||
// Get content-type of the payload.
|
||||
c := contentType(headers.Get("content-type"))
|
||||
m := messageType(headers.Get("message-type"))
|
||||
|
||||
// Get event type of the payload.
|
||||
e := eventType(headers.Get("event-type"))
|
||||
|
||||
// Handle all supported events.
|
||||
switch e {
|
||||
case endEvent:
|
||||
pipeWriter.Close()
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
case errorEvent:
|
||||
switch m {
|
||||
case errorMsg:
|
||||
pipeWriter.CloseWithError(errors.New("Error Type of " + headers.Get("error-type") + " " + headers.Get("error-message")))
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
case recordsEvent:
|
||||
if _, err = io.Copy(pipeWriter, io.LimitReader(crcReader, payloadLen)); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
case commonMsg:
|
||||
// Get content-type of the payload.
|
||||
c := contentType(headers.Get("content-type"))
|
||||
|
||||
// Get event type of the payload.
|
||||
e := eventType(headers.Get("event-type"))
|
||||
|
||||
// Handle all supported events.
|
||||
switch e {
|
||||
case endEvent:
|
||||
pipeWriter.Close()
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
case progressEvent:
|
||||
switch c {
|
||||
case xmlContent:
|
||||
if err = xmlDecoder(io.LimitReader(crcReader, payloadLen), s.progress); err != nil {
|
||||
case recordsEvent:
|
||||
if _, err = io.Copy(pipeWriter, io.LimitReader(crcReader, payloadLen)); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
default:
|
||||
pipeWriter.CloseWithError(fmt.Errorf("Unexpected content-type %s sent for event-type %s", c, progressEvent))
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
case statsEvent:
|
||||
switch c {
|
||||
case xmlContent:
|
||||
if err = xmlDecoder(io.LimitReader(crcReader, payloadLen), s.stats); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
case progressEvent:
|
||||
switch c {
|
||||
case xmlContent:
|
||||
if err = xmlDecoder(io.LimitReader(crcReader, payloadLen), s.progress); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
default:
|
||||
pipeWriter.CloseWithError(fmt.Errorf("Unexpected content-type %s sent for event-type %s", c, progressEvent))
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
case statsEvent:
|
||||
switch c {
|
||||
case xmlContent:
|
||||
if err = xmlDecoder(io.LimitReader(crcReader, payloadLen), s.stats); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
default:
|
||||
pipeWriter.CloseWithError(fmt.Errorf("Unexpected content-type %s sent for event-type %s", c, statsEvent))
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
default:
|
||||
pipeWriter.CloseWithError(fmt.Errorf("Unexpected content-type %s sent for event-type %s", c, statsEvent))
|
||||
closeResponse(s.resp)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
vendor/github.com/minio/minio-go/api.go
сгенерированный
поставляемый
13
vendor/github.com/minio/minio-go/api.go
сгенерированный
поставляемый
@@ -30,6 +30,7 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -38,6 +39,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
"github.com/minio/minio-go/pkg/credentials"
|
||||
"github.com/minio/minio-go/pkg/s3signer"
|
||||
"github.com/minio/minio-go/pkg/s3utils"
|
||||
@@ -99,7 +102,7 @@ type Options struct {
|
||||
// Global constants.
|
||||
const (
|
||||
libraryName = "minio-go"
|
||||
libraryVersion = "v6.0.11"
|
||||
libraryVersion = "v6.0.14"
|
||||
)
|
||||
|
||||
// User Agent should always following the below style.
|
||||
@@ -273,6 +276,13 @@ func privateNew(endpoint string, creds *credentials.Credentials, secure bool, re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Initialize cookies to preserve server sent cookies if any and replay
|
||||
// them upon each request.
|
||||
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// instantiate new Client.
|
||||
clnt := new(Client)
|
||||
|
||||
@@ -287,6 +297,7 @@ func privateNew(endpoint string, creds *credentials.Credentials, secure bool, re
|
||||
|
||||
// Instantiate http client and bucket location cache.
|
||||
clnt.httpClient = &http.Client{
|
||||
Jar: jar,
|
||||
Transport: DefaultTransport,
|
||||
CheckRedirect: clnt.redirectHeaders,
|
||||
}
|
||||
|
||||
2181
vendor/github.com/minio/minio-go/functional_tests.go
сгенерированный
поставляемый
2181
vendor/github.com/minio/minio-go/functional_tests.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
4
vendor/github.com/minio/minio-go/pkg/credentials/iam_aws.go
сгенерированный
поставляемый
4
vendor/github.com/minio/minio-go/pkg/credentials/iam_aws.go
сгенерированный
поставляемый
@@ -67,9 +67,7 @@ func getEndpoint(endpoint string) (string, bool) {
|
||||
return defaultIAMRoleEndpoint, false
|
||||
}
|
||||
|
||||
// NewIAM returns a pointer to a new Credentials object wrapping
|
||||
// the IAM. Takes a ConfigProvider to create a EC2Metadata client.
|
||||
// The ConfigProvider is satisfied by the session.Session type.
|
||||
// NewIAM returns a pointer to a new Credentials object wrapping the IAM.
|
||||
func NewIAM(endpoint string) *Credentials {
|
||||
p := &IAM{
|
||||
Client: &http.Client{
|
||||
|
||||
173
vendor/github.com/minio/minio-go/pkg/credentials/sts_client_grants.go
сгенерированный
поставляемый
Обычный файл
173
vendor/github.com/minio/minio-go/pkg/credentials/sts_client_grants.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2019 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AssumedRoleUser - The identifiers for the temporary security credentials that
|
||||
// the operation returns. Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
|
||||
type AssumedRoleUser struct {
|
||||
Arn string
|
||||
AssumedRoleID string `xml:"AssumeRoleId"`
|
||||
}
|
||||
|
||||
// AssumeRoleWithClientGrantsResponse contains the result of successful AssumeRoleWithClientGrants request.
|
||||
type AssumeRoleWithClientGrantsResponse struct {
|
||||
XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithClientGrantsResponse" json:"-"`
|
||||
Result ClientGrantsResult `xml:"AssumeRoleWithClientGrantsResult"`
|
||||
ResponseMetadata struct {
|
||||
RequestID string `xml:"RequestId,omitempty"`
|
||||
} `xml:"ResponseMetadata,omitempty"`
|
||||
}
|
||||
|
||||
// ClientGrantsResult - Contains the response to a successful AssumeRoleWithClientGrants
|
||||
// request, including temporary credentials that can be used to make Minio API requests.
|
||||
type ClientGrantsResult struct {
|
||||
AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
|
||||
Audience string `xml:",omitempty"`
|
||||
Credentials struct {
|
||||
AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
|
||||
SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
|
||||
Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
|
||||
SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
|
||||
} `xml:",omitempty"`
|
||||
PackedPolicySize int `xml:",omitempty"`
|
||||
Provider string `xml:",omitempty"`
|
||||
SubjectFromClientGrantsToken string `xml:",omitempty"`
|
||||
}
|
||||
|
||||
// ClientGrantsToken - client grants token with expiry.
|
||||
type ClientGrantsToken struct {
|
||||
token string
|
||||
expiry int
|
||||
}
|
||||
|
||||
// Token - access token returned after authenticating client grants.
|
||||
func (c *ClientGrantsToken) Token() string {
|
||||
return c.token
|
||||
}
|
||||
|
||||
// Expiry - expiry for the access token returned after authenticating
|
||||
// client grants.
|
||||
func (c *ClientGrantsToken) Expiry() string {
|
||||
return fmt.Sprintf("%d", c.expiry)
|
||||
}
|
||||
|
||||
// A STSClientGrants retrieves credentials from Minio service, and keeps track if
|
||||
// those credentials are expired.
|
||||
type STSClientGrants struct {
|
||||
Expiry
|
||||
|
||||
// Required http Client to use when connecting to Minio STS service.
|
||||
Client *http.Client
|
||||
|
||||
// Minio endpoint to fetch STS credentials.
|
||||
stsEndpoint string
|
||||
|
||||
// getClientGrantsTokenExpiry function to retrieve tokens
|
||||
// from IDP This function should return two values one is
|
||||
// accessToken which is a self contained access token (JWT)
|
||||
// and second return value is the expiry associated with
|
||||
// this token. This is a customer provided function and
|
||||
// is mandatory.
|
||||
getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)
|
||||
}
|
||||
|
||||
// NewSTSClientGrants returns a pointer to a new
|
||||
// Credentials object wrapping the STSClientGrants.
|
||||
func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (*Credentials, error) {
|
||||
if stsEndpoint == "" {
|
||||
return nil, errors.New("STS endpoint cannot be empty")
|
||||
}
|
||||
if getClientGrantsTokenExpiry == nil {
|
||||
return nil, errors.New("Client grants access token and expiry retrieval function should be defined")
|
||||
}
|
||||
return New(&STSClientGrants{
|
||||
Client: &http.Client{
|
||||
Transport: http.DefaultTransport,
|
||||
},
|
||||
stsEndpoint: stsEndpoint,
|
||||
getClientGrantsTokenExpiry: getClientGrantsTokenExpiry,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func getClientGrantsCredentials(clnt *http.Client, endpoint string,
|
||||
getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (AssumeRoleWithClientGrantsResponse, error) {
|
||||
|
||||
accessToken, err := getClientGrantsTokenExpiry()
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("Action", "AssumeRoleWithClientGrants")
|
||||
v.Set("Token", accessToken.Token())
|
||||
v.Set("DurationSeconds", accessToken.Expiry())
|
||||
v.Set("Version", "2011-06-15")
|
||||
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
}
|
||||
u.RawQuery = v.Encode()
|
||||
|
||||
req, err := http.NewRequest("POST", u.String(), nil)
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
}
|
||||
resp, err := clnt.Do(req)
|
||||
if err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return AssumeRoleWithClientGrantsResponse{}, errors.New(resp.Status)
|
||||
}
|
||||
|
||||
a := AssumeRoleWithClientGrantsResponse{}
|
||||
if err = xml.NewDecoder(resp.Body).Decode(&a); err != nil {
|
||||
return AssumeRoleWithClientGrantsResponse{}, err
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Retrieve retrieves credentials from the Minio service.
|
||||
// Error will be returned if the request fails.
|
||||
func (m *STSClientGrants) Retrieve() (Value, error) {
|
||||
a, err := getClientGrantsCredentials(m.Client, m.stsEndpoint, m.getClientGrantsTokenExpiry)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
// Expiry window is set to 10secs.
|
||||
m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
|
||||
|
||||
return Value{
|
||||
AccessKeyID: a.Result.Credentials.AccessKey,
|
||||
SecretAccessKey: a.Result.Credentials.SecretKey,
|
||||
SessionToken: a.Result.Credentials.SessionToken,
|
||||
SignerType: SignatureV4,
|
||||
}, nil
|
||||
}
|
||||
169
vendor/github.com/minio/minio-go/pkg/credentials/sts_web_identity.go
сгенерированный
поставляемый
Обычный файл
169
vendor/github.com/minio/minio-go/pkg/credentials/sts_web_identity.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
||||
* Copyright 2019 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AssumeRoleWithWebIdentityResponse contains the result of successful AssumeRoleWithWebIdentity request.
|
||||
type AssumeRoleWithWebIdentityResponse struct {
|
||||
XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithWebIdentityResponse" json:"-"`
|
||||
Result WebIdentityResult `xml:"AssumeRoleWithWebIdentityResult"`
|
||||
ResponseMetadata struct {
|
||||
RequestID string `xml:"RequestId,omitempty"`
|
||||
} `xml:"ResponseMetadata,omitempty"`
|
||||
}
|
||||
|
||||
// WebIdentityResult - Contains the response to a successful AssumeRoleWithWebIdentity
|
||||
// request, including temporary credentials that can be used to make Minio API requests.
|
||||
type WebIdentityResult struct {
|
||||
AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
|
||||
Audience string `xml:",omitempty"`
|
||||
Credentials struct {
|
||||
AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
|
||||
SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
|
||||
Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
|
||||
SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
|
||||
} `xml:",omitempty"`
|
||||
PackedPolicySize int `xml:",omitempty"`
|
||||
Provider string `xml:",omitempty"`
|
||||
SubjectFromWebIdentityToken string `xml:",omitempty"`
|
||||
}
|
||||
|
||||
// WebIdentityToken - web identity token with expiry.
|
||||
type WebIdentityToken struct {
|
||||
token string
|
||||
expiry int
|
||||
}
|
||||
|
||||
// Token - access token returned after authenticating web identity.
|
||||
func (c *WebIdentityToken) Token() string {
|
||||
return c.token
|
||||
}
|
||||
|
||||
// Expiry - expiry for the access token returned after authenticating
|
||||
// web identity.
|
||||
func (c *WebIdentityToken) Expiry() string {
|
||||
return fmt.Sprintf("%d", c.expiry)
|
||||
}
|
||||
|
||||
// A STSWebIdentity retrieves credentials from Minio service, and keeps track if
|
||||
// those credentials are expired.
|
||||
type STSWebIdentity struct {
|
||||
Expiry
|
||||
|
||||
// Required http Client to use when connecting to Minio STS service.
|
||||
Client *http.Client
|
||||
|
||||
// Minio endpoint to fetch STS credentials.
|
||||
stsEndpoint string
|
||||
|
||||
// getWebIDTokenExpiry function which returns ID tokens
|
||||
// from IDP. This function should return two values one
|
||||
// is ID token which is a self contained ID token (JWT)
|
||||
// and second return value is the expiry associated with
|
||||
// this token.
|
||||
// This is a customer provided function and is mandatory.
|
||||
getWebIDTokenExpiry func() (*WebIdentityToken, error)
|
||||
}
|
||||
|
||||
// NewSTSWebIdentity returns a pointer to a new
|
||||
// Credentials object wrapping the STSWebIdentity.
|
||||
func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdentityToken, error)) (*Credentials, error) {
|
||||
if stsEndpoint == "" {
|
||||
return nil, errors.New("STS endpoint cannot be empty")
|
||||
}
|
||||
if getWebIDTokenExpiry == nil {
|
||||
return nil, errors.New("Web ID token and expiry retrieval function should be defined")
|
||||
}
|
||||
return New(&STSWebIdentity{
|
||||
Client: &http.Client{
|
||||
Transport: http.DefaultTransport,
|
||||
},
|
||||
stsEndpoint: stsEndpoint,
|
||||
getWebIDTokenExpiry: getWebIDTokenExpiry,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func getWebIdentityCredentials(clnt *http.Client, endpoint string,
|
||||
getWebIDTokenExpiry func() (*WebIdentityToken, error)) (AssumeRoleWithWebIdentityResponse, error) {
|
||||
idToken, err := getWebIDTokenExpiry()
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("Action", "AssumeRoleWithWebIdentity")
|
||||
v.Set("WebIdentityToken", idToken.Token())
|
||||
v.Set("DurationSeconds", idToken.Expiry())
|
||||
v.Set("Version", "2011-06-15")
|
||||
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
}
|
||||
|
||||
u.RawQuery = v.Encode()
|
||||
|
||||
req, err := http.NewRequest("POST", u.String(), nil)
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
}
|
||||
|
||||
resp, err := clnt.Do(req)
|
||||
if err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return AssumeRoleWithWebIdentityResponse{}, errors.New(resp.Status)
|
||||
}
|
||||
|
||||
a := AssumeRoleWithWebIdentityResponse{}
|
||||
if err = xml.NewDecoder(resp.Body).Decode(&a); err != nil {
|
||||
return AssumeRoleWithWebIdentityResponse{}, err
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Retrieve retrieves credentials from the Minio service.
|
||||
// Error will be returned if the request fails.
|
||||
func (m *STSWebIdentity) Retrieve() (Value, error) {
|
||||
a, err := getWebIdentityCredentials(m.Client, m.stsEndpoint, m.getWebIDTokenExpiry)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
// Expiry window is set to 10secs.
|
||||
m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
|
||||
|
||||
return Value{
|
||||
AccessKeyID: a.Result.Credentials.AccessKey,
|
||||
SecretAccessKey: a.Result.Credentials.SecretKey,
|
||||
SessionToken: a.Result.Credentials.SessionToken,
|
||||
SignerType: SignatureV4,
|
||||
}, nil
|
||||
}
|
||||
2
vendor/github.com/minio/minio-go/retry.go
сгенерированный
поставляемый
2
vendor/github.com/minio/minio-go/retry.go
сгенерированный
поставляемый
@@ -139,7 +139,7 @@ func isS3CodeRetryable(s3Code string) (ok bool) {
|
||||
|
||||
// List of HTTP status codes which are retryable.
|
||||
var retryableHTTPStatusCodes = map[int]struct{}{
|
||||
429: {}, // http.StatusTooManyRequests is not part of the Go 1.5 library, yet
|
||||
429: {}, // http.StatusTooManyRequests is not part of the Go 1.5 library, yet
|
||||
http.StatusInternalServerError: {},
|
||||
http.StatusBadGateway: {},
|
||||
http.StatusServiceUnavailable: {},
|
||||
|
||||
38
vendor/github.com/minio/minio-go/s3-endpoints.go
сгенерированный
поставляемый
38
vendor/github.com/minio/minio-go/s3-endpoints.go
сгенерированный
поставляемый
@@ -19,22 +19,24 @@ package minio
|
||||
|
||||
// awsS3EndpointMap Amazon S3 endpoint map.
|
||||
var awsS3EndpointMap = map[string]string{
|
||||
"us-east-1": "s3.amazonaws.com",
|
||||
"us-east-2": "s3-us-east-2.amazonaws.com",
|
||||
"us-west-2": "s3-us-west-2.amazonaws.com",
|
||||
"us-west-1": "s3-us-west-1.amazonaws.com",
|
||||
"ca-central-1": "s3-ca-central-1.amazonaws.com",
|
||||
"eu-west-1": "s3-eu-west-1.amazonaws.com",
|
||||
"eu-west-2": "s3-eu-west-2.amazonaws.com",
|
||||
"eu-west-3": "s3-eu-west-3.amazonaws.com",
|
||||
"eu-central-1": "s3-eu-central-1.amazonaws.com",
|
||||
"ap-south-1": "s3-ap-south-1.amazonaws.com",
|
||||
"ap-southeast-1": "s3-ap-southeast-1.amazonaws.com",
|
||||
"ap-southeast-2": "s3-ap-southeast-2.amazonaws.com",
|
||||
"ap-northeast-1": "s3-ap-northeast-1.amazonaws.com",
|
||||
"ap-northeast-2": "s3-ap-northeast-2.amazonaws.com",
|
||||
"sa-east-1": "s3-sa-east-1.amazonaws.com",
|
||||
"us-gov-west-1": "s3-us-gov-west-1.amazonaws.com",
|
||||
"us-east-1": "s3.dualstack.us-east-1.amazonaws.com",
|
||||
"us-east-2": "s3.dualstack.us-east-2.amazonaws.com",
|
||||
"us-west-2": "s3.dualstack.us-west-2.amazonaws.com",
|
||||
"us-west-1": "s3.dualstack.us-west-1.amazonaws.com",
|
||||
"ca-central-1": "s3.dualstack.ca-central-1.amazonaws.com",
|
||||
"eu-west-1": "s3.dualstack.eu-west-1.amazonaws.com",
|
||||
"eu-west-2": "s3.dualstack.eu-west-2.amazonaws.com",
|
||||
"eu-west-3": "s3.dualstack.eu-west-3.amazonaws.com",
|
||||
"eu-central-1": "s3.dualstack.eu-central-1.amazonaws.com",
|
||||
"eu-north-1": "s3.dualstack.eu-north-1.amazonaws.com",
|
||||
"ap-south-1": "s3.dualstack.ap-south-1.amazonaws.com",
|
||||
"ap-southeast-1": "s3.dualstack.ap-southeast-1.amazonaws.com",
|
||||
"ap-southeast-2": "s3.dualstack.ap-southeast-2.amazonaws.com",
|
||||
"ap-northeast-1": "s3.dualstack.ap-northeast-1.amazonaws.com",
|
||||
"ap-northeast-2": "s3.dualstack.ap-northeast-2.amazonaws.com",
|
||||
"sa-east-1": "s3.dualstack.sa-east-1.amazonaws.com",
|
||||
"us-gov-west-1": "s3.dualstack.us-gov-west-1.amazonaws.com",
|
||||
"us-gov-east-1": "s3.dualstack.us-gov-east-1.amazonaws.com",
|
||||
"cn-north-1": "s3.cn-north-1.amazonaws.com.cn",
|
||||
"cn-northwest-1": "s3.cn-northwest-1.amazonaws.com.cn",
|
||||
}
|
||||
@@ -43,8 +45,8 @@ var awsS3EndpointMap = map[string]string{
|
||||
func getS3Endpoint(bucketLocation string) (s3Endpoint string) {
|
||||
s3Endpoint, ok := awsS3EndpointMap[bucketLocation]
|
||||
if !ok {
|
||||
// Default to 's3.amazonaws.com' endpoint.
|
||||
s3Endpoint = "s3.amazonaws.com"
|
||||
// Default to 's3.dualstack.us-east-1.amazonaws.com' endpoint.
|
||||
s3Endpoint = "s3.dualstack.us-east-1.amazonaws.com"
|
||||
}
|
||||
return s3Endpoint
|
||||
}
|
||||
|
||||
4
vendor/github.com/petar/GoLLRB/AUTHORS
сгенерированный
поставляемый
Обычный файл
4
vendor/github.com/petar/GoLLRB/AUTHORS
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,4 @@
|
||||
Petar Maymounkov <petar@5ttt.org>
|
||||
Vadim Vygonets <vadik@vygo.net>
|
||||
Ian Smith <iansmith@acm.org>
|
||||
Martin Bruse
|
||||
27
vendor/github.com/petar/GoLLRB/LICENSE
сгенерированный
поставляемый
Обычный файл
27
vendor/github.com/petar/GoLLRB/LICENSE
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2010, Petar Maymounkov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
(*) Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
(*) Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
(*) Neither the name of Petar Maymounkov nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
39
vendor/github.com/petar/GoLLRB/llrb/avgvar.go
сгенерированный
поставляемый
Обычный файл
39
vendor/github.com/petar/GoLLRB/llrb/avgvar.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,39 @@
|
||||
// Copyright 2010 Petar Maymounkov. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package llrb
|
||||
|
||||
import "math"
|
||||
|
||||
// avgVar maintains the average and variance of a stream of numbers
|
||||
// in a space-efficient manner.
|
||||
type avgVar struct {
|
||||
count int64
|
||||
sum, sumsq float64
|
||||
}
|
||||
|
||||
func (av *avgVar) Init() {
|
||||
av.count = 0
|
||||
av.sum = 0.0
|
||||
av.sumsq = 0.0
|
||||
}
|
||||
|
||||
func (av *avgVar) Add(sample float64) {
|
||||
av.count++
|
||||
av.sum += sample
|
||||
av.sumsq += sample * sample
|
||||
}
|
||||
|
||||
func (av *avgVar) GetCount() int64 { return av.count }
|
||||
|
||||
func (av *avgVar) GetAvg() float64 { return av.sum / float64(av.count) }
|
||||
|
||||
func (av *avgVar) GetTotal() float64 { return av.sum }
|
||||
|
||||
func (av *avgVar) GetVar() float64 {
|
||||
a := av.GetAvg()
|
||||
return av.sumsq/float64(av.count) - a*a
|
||||
}
|
||||
|
||||
func (av *avgVar) GetStdDev() float64 { return math.Sqrt(av.GetVar()) }
|
||||
93
vendor/github.com/petar/GoLLRB/llrb/iterator.go
сгенерированный
поставляемый
Обычный файл
93
vendor/github.com/petar/GoLLRB/llrb/iterator.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,93 @@
|
||||
package llrb
|
||||
|
||||
type ItemIterator func(i Item) bool
|
||||
|
||||
//func (t *Tree) Ascend(iterator ItemIterator) {
|
||||
// t.AscendGreaterOrEqual(Inf(-1), iterator)
|
||||
//}
|
||||
|
||||
func (t *LLRB) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {
|
||||
t.ascendRange(t.root, greaterOrEqual, lessThan, iterator)
|
||||
}
|
||||
|
||||
func (t *LLRB) ascendRange(h *Node, inf, sup Item, iterator ItemIterator) bool {
|
||||
if h == nil {
|
||||
return true
|
||||
}
|
||||
if !less(h.Item, sup) {
|
||||
return t.ascendRange(h.Left, inf, sup, iterator)
|
||||
}
|
||||
if less(h.Item, inf) {
|
||||
return t.ascendRange(h.Right, inf, sup, iterator)
|
||||
}
|
||||
|
||||
if !t.ascendRange(h.Left, inf, sup, iterator) {
|
||||
return false
|
||||
}
|
||||
if !iterator(h.Item) {
|
||||
return false
|
||||
}
|
||||
return t.ascendRange(h.Right, inf, sup, iterator)
|
||||
}
|
||||
|
||||
// AscendGreaterOrEqual will call iterator once for each element greater or equal to
|
||||
// pivot in ascending order. It will stop whenever the iterator returns false.
|
||||
func (t *LLRB) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {
|
||||
t.ascendGreaterOrEqual(t.root, pivot, iterator)
|
||||
}
|
||||
|
||||
func (t *LLRB) ascendGreaterOrEqual(h *Node, pivot Item, iterator ItemIterator) bool {
|
||||
if h == nil {
|
||||
return true
|
||||
}
|
||||
if !less(h.Item, pivot) {
|
||||
if !t.ascendGreaterOrEqual(h.Left, pivot, iterator) {
|
||||
return false
|
||||
}
|
||||
if !iterator(h.Item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return t.ascendGreaterOrEqual(h.Right, pivot, iterator)
|
||||
}
|
||||
|
||||
func (t *LLRB) AscendLessThan(pivot Item, iterator ItemIterator) {
|
||||
t.ascendLessThan(t.root, pivot, iterator)
|
||||
}
|
||||
|
||||
func (t *LLRB) ascendLessThan(h *Node, pivot Item, iterator ItemIterator) bool {
|
||||
if h == nil {
|
||||
return true
|
||||
}
|
||||
if !t.ascendLessThan(h.Left, pivot, iterator) {
|
||||
return false
|
||||
}
|
||||
if !iterator(h.Item) {
|
||||
return false
|
||||
}
|
||||
if less(h.Item, pivot) {
|
||||
return t.ascendLessThan(h.Left, pivot, iterator)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// DescendLessOrEqual will call iterator once for each element less than the
|
||||
// pivot in descending order. It will stop whenever the iterator returns false.
|
||||
func (t *LLRB) DescendLessOrEqual(pivot Item, iterator ItemIterator) {
|
||||
t.descendLessOrEqual(t.root, pivot, iterator)
|
||||
}
|
||||
|
||||
func (t *LLRB) descendLessOrEqual(h *Node, pivot Item, iterator ItemIterator) bool {
|
||||
if h == nil {
|
||||
return true
|
||||
}
|
||||
if less(h.Item, pivot) || !less(pivot, h.Item) {
|
||||
if !t.descendLessOrEqual(h.Right, pivot, iterator) {
|
||||
return false
|
||||
}
|
||||
if !iterator(h.Item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return t.descendLessOrEqual(h.Left, pivot, iterator)
|
||||
}
|
||||
46
vendor/github.com/petar/GoLLRB/llrb/llrb-stats.go
сгенерированный
поставляемый
Обычный файл
46
vendor/github.com/petar/GoLLRB/llrb/llrb-stats.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,46 @@
|
||||
// Copyright 2010 Petar Maymounkov. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package llrb
|
||||
|
||||
// GetHeight() returns an item in the tree with key @key, and it's height in the tree
|
||||
func (t *LLRB) GetHeight(key Item) (result Item, depth int) {
|
||||
return t.getHeight(t.root, key)
|
||||
}
|
||||
|
||||
func (t *LLRB) getHeight(h *Node, item Item) (Item, int) {
|
||||
if h == nil {
|
||||
return nil, 0
|
||||
}
|
||||
if less(item, h.Item) {
|
||||
result, depth := t.getHeight(h.Left, item)
|
||||
return result, depth + 1
|
||||
}
|
||||
if less(h.Item, item) {
|
||||
result, depth := t.getHeight(h.Right, item)
|
||||
return result, depth + 1
|
||||
}
|
||||
return h.Item, 0
|
||||
}
|
||||
|
||||
// HeightStats() returns the average and standard deviation of the height
|
||||
// of elements in the tree
|
||||
func (t *LLRB) HeightStats() (avg, stddev float64) {
|
||||
av := &avgVar{}
|
||||
heightStats(t.root, 0, av)
|
||||
return av.GetAvg(), av.GetStdDev()
|
||||
}
|
||||
|
||||
func heightStats(h *Node, d int, av *avgVar) {
|
||||
if h == nil {
|
||||
return
|
||||
}
|
||||
av.Add(float64(d))
|
||||
if h.Left != nil {
|
||||
heightStats(h.Left, d+1, av)
|
||||
}
|
||||
if h.Right != nil {
|
||||
heightStats(h.Right, d+1, av)
|
||||
}
|
||||
}
|
||||
456
vendor/github.com/petar/GoLLRB/llrb/llrb.go
сгенерированный
поставляемый
Обычный файл
456
vendor/github.com/petar/GoLLRB/llrb/llrb.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,456 @@
|
||||
// Copyright 2010 Petar Maymounkov. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// A Left-Leaning Red-Black (LLRB) implementation of 2-3 balanced binary search trees,
|
||||
// based on the following work:
|
||||
//
|
||||
// http://www.cs.princeton.edu/~rs/talks/LLRB/08Penn.pdf
|
||||
// http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
|
||||
// http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
|
||||
//
|
||||
// 2-3 trees (and the run-time equivalent 2-3-4 trees) are the de facto standard BST
|
||||
// algoritms found in implementations of Python, Java, and other libraries. The LLRB
|
||||
// implementation of 2-3 trees is a recent improvement on the traditional implementation,
|
||||
// observed and documented by Robert Sedgewick.
|
||||
//
|
||||
package llrb
|
||||
|
||||
// Tree is a Left-Leaning Red-Black (LLRB) implementation of 2-3 trees
|
||||
type LLRB struct {
|
||||
count int
|
||||
root *Node
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
Item
|
||||
Left, Right *Node // Pointers to left and right child nodes
|
||||
Black bool // If set, the color of the link (incoming from the parent) is black
|
||||
// In the LLRB, new nodes are always red, hence the zero-value for node
|
||||
}
|
||||
|
||||
type Item interface {
|
||||
Less(than Item) bool
|
||||
}
|
||||
|
||||
//
|
||||
func less(x, y Item) bool {
|
||||
if x == pinf {
|
||||
return false
|
||||
}
|
||||
if x == ninf {
|
||||
return true
|
||||
}
|
||||
return x.Less(y)
|
||||
}
|
||||
|
||||
// Inf returns an Item that is "bigger than" any other item, if sign is positive.
|
||||
// Otherwise it returns an Item that is "smaller than" any other item.
|
||||
func Inf(sign int) Item {
|
||||
if sign == 0 {
|
||||
panic("sign")
|
||||
}
|
||||
if sign > 0 {
|
||||
return pinf
|
||||
}
|
||||
return ninf
|
||||
}
|
||||
|
||||
var (
|
||||
ninf = nInf{}
|
||||
pinf = pInf{}
|
||||
)
|
||||
|
||||
type nInf struct{}
|
||||
|
||||
func (nInf) Less(Item) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type pInf struct{}
|
||||
|
||||
func (pInf) Less(Item) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// New() allocates a new tree
|
||||
func New() *LLRB {
|
||||
return &LLRB{}
|
||||
}
|
||||
|
||||
// SetRoot sets the root node of the tree.
|
||||
// It is intended to be used by functions that deserialize the tree.
|
||||
func (t *LLRB) SetRoot(r *Node) {
|
||||
t.root = r
|
||||
}
|
||||
|
||||
// Root returns the root node of the tree.
|
||||
// It is intended to be used by functions that serialize the tree.
|
||||
func (t *LLRB) Root() *Node {
|
||||
return t.root
|
||||
}
|
||||
|
||||
// Len returns the number of nodes in the tree.
|
||||
func (t *LLRB) Len() int { return t.count }
|
||||
|
||||
// Has returns true if the tree contains an element whose order is the same as that of key.
|
||||
func (t *LLRB) Has(key Item) bool {
|
||||
return t.Get(key) != nil
|
||||
}
|
||||
|
||||
// Get retrieves an element from the tree whose order is the same as that of key.
|
||||
func (t *LLRB) Get(key Item) Item {
|
||||
h := t.root
|
||||
for h != nil {
|
||||
switch {
|
||||
case less(key, h.Item):
|
||||
h = h.Left
|
||||
case less(h.Item, key):
|
||||
h = h.Right
|
||||
default:
|
||||
return h.Item
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Min returns the minimum element in the tree.
|
||||
func (t *LLRB) Min() Item {
|
||||
h := t.root
|
||||
if h == nil {
|
||||
return nil
|
||||
}
|
||||
for h.Left != nil {
|
||||
h = h.Left
|
||||
}
|
||||
return h.Item
|
||||
}
|
||||
|
||||
// Max returns the maximum element in the tree.
|
||||
func (t *LLRB) Max() Item {
|
||||
h := t.root
|
||||
if h == nil {
|
||||
return nil
|
||||
}
|
||||
for h.Right != nil {
|
||||
h = h.Right
|
||||
}
|
||||
return h.Item
|
||||
}
|
||||
|
||||
func (t *LLRB) ReplaceOrInsertBulk(items ...Item) {
|
||||
for _, i := range items {
|
||||
t.ReplaceOrInsert(i)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *LLRB) InsertNoReplaceBulk(items ...Item) {
|
||||
for _, i := range items {
|
||||
t.InsertNoReplace(i)
|
||||
}
|
||||
}
|
||||
|
||||
// ReplaceOrInsert inserts item into the tree. If an existing
|
||||
// element has the same order, it is removed from the tree and returned.
|
||||
func (t *LLRB) ReplaceOrInsert(item Item) Item {
|
||||
if item == nil {
|
||||
panic("inserting nil item")
|
||||
}
|
||||
var replaced Item
|
||||
t.root, replaced = t.replaceOrInsert(t.root, item)
|
||||
t.root.Black = true
|
||||
if replaced == nil {
|
||||
t.count++
|
||||
}
|
||||
return replaced
|
||||
}
|
||||
|
||||
func (t *LLRB) replaceOrInsert(h *Node, item Item) (*Node, Item) {
|
||||
if h == nil {
|
||||
return newNode(item), nil
|
||||
}
|
||||
|
||||
h = walkDownRot23(h)
|
||||
|
||||
var replaced Item
|
||||
if less(item, h.Item) { // BUG
|
||||
h.Left, replaced = t.replaceOrInsert(h.Left, item)
|
||||
} else if less(h.Item, item) {
|
||||
h.Right, replaced = t.replaceOrInsert(h.Right, item)
|
||||
} else {
|
||||
replaced, h.Item = h.Item, item
|
||||
}
|
||||
|
||||
h = walkUpRot23(h)
|
||||
|
||||
return h, replaced
|
||||
}
|
||||
|
||||
// InsertNoReplace inserts item into the tree. If an existing
|
||||
// element has the same order, both elements remain in the tree.
|
||||
func (t *LLRB) InsertNoReplace(item Item) {
|
||||
if item == nil {
|
||||
panic("inserting nil item")
|
||||
}
|
||||
t.root = t.insertNoReplace(t.root, item)
|
||||
t.root.Black = true
|
||||
t.count++
|
||||
}
|
||||
|
||||
func (t *LLRB) insertNoReplace(h *Node, item Item) *Node {
|
||||
if h == nil {
|
||||
return newNode(item)
|
||||
}
|
||||
|
||||
h = walkDownRot23(h)
|
||||
|
||||
if less(item, h.Item) {
|
||||
h.Left = t.insertNoReplace(h.Left, item)
|
||||
} else {
|
||||
h.Right = t.insertNoReplace(h.Right, item)
|
||||
}
|
||||
|
||||
return walkUpRot23(h)
|
||||
}
|
||||
|
||||
// Rotation driver routines for 2-3 algorithm
|
||||
|
||||
func walkDownRot23(h *Node) *Node { return h }
|
||||
|
||||
func walkUpRot23(h *Node) *Node {
|
||||
if isRed(h.Right) && !isRed(h.Left) {
|
||||
h = rotateLeft(h)
|
||||
}
|
||||
|
||||
if isRed(h.Left) && isRed(h.Left.Left) {
|
||||
h = rotateRight(h)
|
||||
}
|
||||
|
||||
if isRed(h.Left) && isRed(h.Right) {
|
||||
flip(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// Rotation driver routines for 2-3-4 algorithm
|
||||
|
||||
func walkDownRot234(h *Node) *Node {
|
||||
if isRed(h.Left) && isRed(h.Right) {
|
||||
flip(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func walkUpRot234(h *Node) *Node {
|
||||
if isRed(h.Right) && !isRed(h.Left) {
|
||||
h = rotateLeft(h)
|
||||
}
|
||||
|
||||
if isRed(h.Left) && isRed(h.Left.Left) {
|
||||
h = rotateRight(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// DeleteMin deletes the minimum element in the tree and returns the
|
||||
// deleted item or nil otherwise.
|
||||
func (t *LLRB) DeleteMin() Item {
|
||||
var deleted Item
|
||||
t.root, deleted = deleteMin(t.root)
|
||||
if t.root != nil {
|
||||
t.root.Black = true
|
||||
}
|
||||
if deleted != nil {
|
||||
t.count--
|
||||
}
|
||||
return deleted
|
||||
}
|
||||
|
||||
// deleteMin code for LLRB 2-3 trees
|
||||
func deleteMin(h *Node) (*Node, Item) {
|
||||
if h == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if h.Left == nil {
|
||||
return nil, h.Item
|
||||
}
|
||||
|
||||
if !isRed(h.Left) && !isRed(h.Left.Left) {
|
||||
h = moveRedLeft(h)
|
||||
}
|
||||
|
||||
var deleted Item
|
||||
h.Left, deleted = deleteMin(h.Left)
|
||||
|
||||
return fixUp(h), deleted
|
||||
}
|
||||
|
||||
// DeleteMax deletes the maximum element in the tree and returns
|
||||
// the deleted item or nil otherwise
|
||||
func (t *LLRB) DeleteMax() Item {
|
||||
var deleted Item
|
||||
t.root, deleted = deleteMax(t.root)
|
||||
if t.root != nil {
|
||||
t.root.Black = true
|
||||
}
|
||||
if deleted != nil {
|
||||
t.count--
|
||||
}
|
||||
return deleted
|
||||
}
|
||||
|
||||
func deleteMax(h *Node) (*Node, Item) {
|
||||
if h == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if isRed(h.Left) {
|
||||
h = rotateRight(h)
|
||||
}
|
||||
if h.Right == nil {
|
||||
return nil, h.Item
|
||||
}
|
||||
if !isRed(h.Right) && !isRed(h.Right.Left) {
|
||||
h = moveRedRight(h)
|
||||
}
|
||||
var deleted Item
|
||||
h.Right, deleted = deleteMax(h.Right)
|
||||
|
||||
return fixUp(h), deleted
|
||||
}
|
||||
|
||||
// Delete deletes an item from the tree whose key equals key.
|
||||
// The deleted item is return, otherwise nil is returned.
|
||||
func (t *LLRB) Delete(key Item) Item {
|
||||
var deleted Item
|
||||
t.root, deleted = t.delete(t.root, key)
|
||||
if t.root != nil {
|
||||
t.root.Black = true
|
||||
}
|
||||
if deleted != nil {
|
||||
t.count--
|
||||
}
|
||||
return deleted
|
||||
}
|
||||
|
||||
func (t *LLRB) delete(h *Node, item Item) (*Node, Item) {
|
||||
var deleted Item
|
||||
if h == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if less(item, h.Item) {
|
||||
if h.Left == nil { // item not present. Nothing to delete
|
||||
return h, nil
|
||||
}
|
||||
if !isRed(h.Left) && !isRed(h.Left.Left) {
|
||||
h = moveRedLeft(h)
|
||||
}
|
||||
h.Left, deleted = t.delete(h.Left, item)
|
||||
} else {
|
||||
if isRed(h.Left) {
|
||||
h = rotateRight(h)
|
||||
}
|
||||
// If @item equals @h.Item and no right children at @h
|
||||
if !less(h.Item, item) && h.Right == nil {
|
||||
return nil, h.Item
|
||||
}
|
||||
// PETAR: Added 'h.Right != nil' below
|
||||
if h.Right != nil && !isRed(h.Right) && !isRed(h.Right.Left) {
|
||||
h = moveRedRight(h)
|
||||
}
|
||||
// If @item equals @h.Item, and (from above) 'h.Right != nil'
|
||||
if !less(h.Item, item) {
|
||||
var subDeleted Item
|
||||
h.Right, subDeleted = deleteMin(h.Right)
|
||||
if subDeleted == nil {
|
||||
panic("logic")
|
||||
}
|
||||
deleted, h.Item = h.Item, subDeleted
|
||||
} else { // Else, @item is bigger than @h.Item
|
||||
h.Right, deleted = t.delete(h.Right, item)
|
||||
}
|
||||
}
|
||||
|
||||
return fixUp(h), deleted
|
||||
}
|
||||
|
||||
// Internal node manipulation routines
|
||||
|
||||
func newNode(item Item) *Node { return &Node{Item: item} }
|
||||
|
||||
func isRed(h *Node) bool {
|
||||
if h == nil {
|
||||
return false
|
||||
}
|
||||
return !h.Black
|
||||
}
|
||||
|
||||
func rotateLeft(h *Node) *Node {
|
||||
x := h.Right
|
||||
if x.Black {
|
||||
panic("rotating a black link")
|
||||
}
|
||||
h.Right = x.Left
|
||||
x.Left = h
|
||||
x.Black = h.Black
|
||||
h.Black = false
|
||||
return x
|
||||
}
|
||||
|
||||
func rotateRight(h *Node) *Node {
|
||||
x := h.Left
|
||||
if x.Black {
|
||||
panic("rotating a black link")
|
||||
}
|
||||
h.Left = x.Right
|
||||
x.Right = h
|
||||
x.Black = h.Black
|
||||
h.Black = false
|
||||
return x
|
||||
}
|
||||
|
||||
// REQUIRE: Left and Right children must be present
|
||||
func flip(h *Node) {
|
||||
h.Black = !h.Black
|
||||
h.Left.Black = !h.Left.Black
|
||||
h.Right.Black = !h.Right.Black
|
||||
}
|
||||
|
||||
// REQUIRE: Left and Right children must be present
|
||||
func moveRedLeft(h *Node) *Node {
|
||||
flip(h)
|
||||
if isRed(h.Right.Left) {
|
||||
h.Right = rotateRight(h.Right)
|
||||
h = rotateLeft(h)
|
||||
flip(h)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// REQUIRE: Left and Right children must be present
|
||||
func moveRedRight(h *Node) *Node {
|
||||
flip(h)
|
||||
if isRed(h.Left.Left) {
|
||||
h = rotateRight(h)
|
||||
flip(h)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func fixUp(h *Node) *Node {
|
||||
if isRed(h.Right) {
|
||||
h = rotateLeft(h)
|
||||
}
|
||||
|
||||
if isRed(h.Left) && isRed(h.Left.Left) {
|
||||
h = rotateRight(h)
|
||||
}
|
||||
|
||||
if isRed(h.Left) && isRed(h.Right) {
|
||||
flip(h)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
17
vendor/github.com/petar/GoLLRB/llrb/util.go
сгенерированный
поставляемый
Обычный файл
17
vendor/github.com/petar/GoLLRB/llrb/util.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,17 @@
|
||||
// Copyright 2010 Petar Maymounkov. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package llrb
|
||||
|
||||
type Int int
|
||||
|
||||
func (x Int) Less(than Item) bool {
|
||||
return x < than.(Int)
|
||||
}
|
||||
|
||||
type String string
|
||||
|
||||
func (x String) Less(than Item) bool {
|
||||
return x < than.(String)
|
||||
}
|
||||
12
vendor/github.com/pkg/errors/.travis.yml
сгенерированный
поставляемый
12
vendor/github.com/pkg/errors/.travis.yml
сгенерированный
поставляемый
@@ -1,10 +1,14 @@
|
||||
language: go
|
||||
go_import_path: github.com/pkg/errors
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.4
|
||||
- 1.6.2
|
||||
- 1.7.1
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
script:
|
||||
|
||||
4
vendor/github.com/pkg/errors/README.md
сгенерированный
поставляемый
4
vendor/github.com/pkg/errors/README.md
сгенерированный
поставляемый
@@ -1,4 +1,4 @@
|
||||
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors)
|
||||
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge)
|
||||
|
||||
Package errors provides simple error handling primitives.
|
||||
|
||||
@@ -47,6 +47,6 @@ We welcome pull requests, bug fixes and issue reports. With that said, the bar f
|
||||
|
||||
Before proposing a change, please discuss your change by raising an issue.
|
||||
|
||||
## Licence
|
||||
## License
|
||||
|
||||
BSD-2-Clause
|
||||
|
||||
43
vendor/github.com/pkg/errors/errors.go
сгенерированный
поставляемый
43
vendor/github.com/pkg/errors/errors.go
сгенерированный
поставляемый
@@ -6,7 +6,7 @@
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// which applied recursively up the call stack results in error reports
|
||||
// which when applied recursively up the call stack results in error reports
|
||||
// without context or debugging information. The errors package allows
|
||||
// programmers to add context to the failure path in their code in a way
|
||||
// that does not destroy the original value of the error.
|
||||
@@ -15,16 +15,17 @@
|
||||
//
|
||||
// The errors.Wrap function returns a new error that adds context to the
|
||||
// original error by recording a stack trace at the point Wrap is called,
|
||||
// and the supplied message. For example
|
||||
// together with the supplied message. For example
|
||||
//
|
||||
// _, err := ioutil.ReadAll(r)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(err, "read failed")
|
||||
// }
|
||||
//
|
||||
// If additional control is required the errors.WithStack and errors.WithMessage
|
||||
// functions destructure errors.Wrap into its component operations of annotating
|
||||
// an error with a stack trace and an a message, respectively.
|
||||
// If additional control is required, the errors.WithStack and
|
||||
// errors.WithMessage functions destructure errors.Wrap into its component
|
||||
// operations: annotating an error with a stack trace and with a message,
|
||||
// respectively.
|
||||
//
|
||||
// Retrieving the cause of an error
|
||||
//
|
||||
@@ -38,7 +39,7 @@
|
||||
// }
|
||||
//
|
||||
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
|
||||
// the topmost error which does not implement causer, which is assumed to be
|
||||
// the topmost error that does not implement causer, which is assumed to be
|
||||
// the original cause. For example:
|
||||
//
|
||||
// switch err := errors.Cause(err).(type) {
|
||||
@@ -48,16 +49,16 @@
|
||||
// // unknown error
|
||||
// }
|
||||
//
|
||||
// causer interface is not exported by this package, but is considered a part
|
||||
// of stable public API.
|
||||
// Although the causer interface is not exported by this package, it is
|
||||
// considered a part of its stable public interface.
|
||||
//
|
||||
// Formatted printing of errors
|
||||
//
|
||||
// All error values returned from this package implement fmt.Formatter and can
|
||||
// be formatted by the fmt package. The following verbs are supported
|
||||
// be formatted by the fmt package. The following verbs are supported:
|
||||
//
|
||||
// %s print the error. If the error has a Cause it will be
|
||||
// printed recursively
|
||||
// printed recursively.
|
||||
// %v see %s
|
||||
// %+v extended format. Each Frame of the error's StackTrace will
|
||||
// be printed in detail.
|
||||
@@ -65,13 +66,13 @@
|
||||
// Retrieving the stack trace of an error or wrapper
|
||||
//
|
||||
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
|
||||
// invoked. This information can be retrieved with the following interface.
|
||||
// invoked. This information can be retrieved with the following interface:
|
||||
//
|
||||
// type stackTracer interface {
|
||||
// StackTrace() errors.StackTrace
|
||||
// }
|
||||
//
|
||||
// Where errors.StackTrace is defined as
|
||||
// The returned errors.StackTrace type is defined as
|
||||
//
|
||||
// type StackTrace []Frame
|
||||
//
|
||||
@@ -85,8 +86,8 @@
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// stackTracer interface is not exported by this package, but is considered a part
|
||||
// of stable public API.
|
||||
// Although the stackTracer interface is not exported by this package, it is
|
||||
// considered a part of its stable public interface.
|
||||
//
|
||||
// See the documentation for Frame.Format for more details.
|
||||
package errors
|
||||
@@ -192,7 +193,7 @@ func Wrap(err error, message string) error {
|
||||
}
|
||||
|
||||
// Wrapf returns an error annotating err with a stack trace
|
||||
// at the point Wrapf is call, and the format specifier.
|
||||
// at the point Wrapf is called, and the format specifier.
|
||||
// If err is nil, Wrapf returns nil.
|
||||
func Wrapf(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
@@ -220,6 +221,18 @@ func WithMessage(err error, message string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMessagef annotates err with the format specifier.
|
||||
// If err is nil, WithMessagef returns nil.
|
||||
func WithMessagef(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &withMessage{
|
||||
cause: err,
|
||||
msg: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
type withMessage struct {
|
||||
cause error
|
||||
msg string
|
||||
|
||||
51
vendor/github.com/pkg/errors/stack.go
сгенерированный
поставляемый
51
vendor/github.com/pkg/errors/stack.go
сгенерированный
поставляемый
@@ -46,7 +46,8 @@ func (f Frame) line() int {
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+s path of source file relative to the compile time GOPATH
|
||||
// %+s function name and path of source file relative to the compile time
|
||||
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
||||
// %+v equivalent to %+s:%d
|
||||
func (f Frame) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
@@ -79,6 +80,14 @@ func (f Frame) Format(s fmt.State, verb rune) {
|
||||
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
||||
type StackTrace []Frame
|
||||
|
||||
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
||||
//
|
||||
// %s lists source files for each Frame in the stack
|
||||
// %v lists the source file and line number for each Frame in the stack
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+v Prints filename, function, and line number for each Frame in the stack.
|
||||
func (st StackTrace) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
@@ -136,43 +145,3 @@ func funcname(name string) string {
|
||||
i = strings.Index(name, ".")
|
||||
return name[i+1:]
|
||||
}
|
||||
|
||||
func trimGOPATH(name, file string) string {
|
||||
// Here we want to get the source file path relative to the compile time
|
||||
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
|
||||
// GOPATH at runtime, but we can infer the number of path segments in the
|
||||
// GOPATH. We note that fn.Name() returns the function name qualified by
|
||||
// the import path, which does not include the GOPATH. Thus we can trim
|
||||
// segments from the beginning of the file path until the number of path
|
||||
// separators remaining is one more than the number of path separators in
|
||||
// the function name. For example, given:
|
||||
//
|
||||
// GOPATH /home/user
|
||||
// file /home/user/src/pkg/sub/file.go
|
||||
// fn.Name() pkg/sub.Type.Method
|
||||
//
|
||||
// We want to produce:
|
||||
//
|
||||
// pkg/sub/file.go
|
||||
//
|
||||
// From this we can easily see that fn.Name() has one less path separator
|
||||
// than our desired output. We count separators from the end of the file
|
||||
// path until it finds two more than in the function name and then move
|
||||
// one character forward to preserve the initial path segment without a
|
||||
// leading separator.
|
||||
const sep = "/"
|
||||
goal := strings.Count(name, sep) + 2
|
||||
i := len(file)
|
||||
for n := 0; n < goal; n++ {
|
||||
i = strings.LastIndex(file[:i], sep)
|
||||
if i == -1 {
|
||||
// not enough separators found, set i so that the slice expression
|
||||
// below leaves file unmodified
|
||||
i = -len(sep)
|
||||
break
|
||||
}
|
||||
}
|
||||
// get back to 0 or trim the leading separator
|
||||
file = file[i+len(sep):]
|
||||
return file
|
||||
}
|
||||
|
||||
4
vendor/github.com/prometheus/client_golang/prometheus/desc.go
сгенерированный
поставляемый
4
vendor/github.com/prometheus/client_golang/prometheus/desc.go
сгенерированный
поставляемый
@@ -93,7 +93,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
||||
// First add only the const label names and sort them...
|
||||
for labelName := range constLabels {
|
||||
if !checkLabelName(labelName) {
|
||||
d.err = fmt.Errorf("%q is not a valid label name", labelName)
|
||||
d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
|
||||
return d
|
||||
}
|
||||
labelNames = append(labelNames, labelName)
|
||||
@@ -115,7 +115,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
||||
// dimension with a different mix between preset and variable labels.
|
||||
for _, labelName := range variableLabels {
|
||||
if !checkLabelName(labelName) {
|
||||
d.err = fmt.Errorf("%q is not a valid label name", labelName)
|
||||
d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
|
||||
return d
|
||||
}
|
||||
labelNames = append(labelNames, "$"+labelName)
|
||||
|
||||
12
vendor/github.com/prometheus/client_golang/prometheus/registry.go
сгенерированный
поставляемый
12
vendor/github.com/prometheus/client_golang/prometheus/registry.go
сгенерированный
поставляемый
@@ -872,7 +872,13 @@ func checkMetricConsistency(
|
||||
h = hashAddByte(h, separatorByte)
|
||||
// Make sure label pairs are sorted. We depend on it for the consistency
|
||||
// check.
|
||||
sort.Sort(labelPairSorter(dtoMetric.Label))
|
||||
if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
|
||||
// We cannot sort dtoMetric.Label in place as it is immutable by contract.
|
||||
copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
|
||||
copy(copiedLabels, dtoMetric.Label)
|
||||
sort.Sort(labelPairSorter(copiedLabels))
|
||||
dtoMetric.Label = copiedLabels
|
||||
}
|
||||
for _, lp := range dtoMetric.Label {
|
||||
h = hashAdd(h, lp.GetName())
|
||||
h = hashAddByte(h, separatorByte)
|
||||
@@ -903,8 +909,8 @@ func checkDescConsistency(
|
||||
}
|
||||
|
||||
// Is the desc consistent with the content of the metric?
|
||||
lpsFromDesc := make([]*dto.LabelPair, 0, len(dtoMetric.Label))
|
||||
lpsFromDesc = append(lpsFromDesc, desc.constLabelPairs...)
|
||||
lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
|
||||
copy(lpsFromDesc, desc.constLabelPairs)
|
||||
for _, l := range desc.variableLabels {
|
||||
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
|
||||
Name: proto.String(l),
|
||||
|
||||
11
vendor/github.com/prometheus/client_golang/prometheus/timer.go
сгенерированный
поставляемый
11
vendor/github.com/prometheus/client_golang/prometheus/timer.go
сгенерированный
поставляемый
@@ -39,13 +39,16 @@ func NewTimer(o Observer) *Timer {
|
||||
|
||||
// ObserveDuration records the duration passed since the Timer was created with
|
||||
// NewTimer. It calls the Observe method of the Observer provided during
|
||||
// construction with the duration in seconds as an argument. ObserveDuration is
|
||||
// usually called with a defer statement.
|
||||
// construction with the duration in seconds as an argument. The observed
|
||||
// duration is also returned. ObserveDuration is usually called with a defer
|
||||
// statement.
|
||||
//
|
||||
// Note that this method is only guaranteed to never observe negative durations
|
||||
// if used with Go1.9+.
|
||||
func (t *Timer) ObserveDuration() {
|
||||
func (t *Timer) ObserveDuration() time.Duration {
|
||||
d := time.Since(t.begin)
|
||||
if t.observer != nil {
|
||||
t.observer.Observe(time.Since(t.begin).Seconds())
|
||||
t.observer.Observe(d.Seconds())
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
12
vendor/github.com/prometheus/common/expfmt/text_create.go
сгенерированный
поставляемый
12
vendor/github.com/prometheus/common/expfmt/text_create.go
сгенерированный
поставляемый
@@ -436,11 +436,11 @@ func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (in
|
||||
func writeFloat(w enhancedWriter, f float64) (int, error) {
|
||||
switch {
|
||||
case f == 1:
|
||||
return 1, w.WriteByte('1')
|
||||
return w.WriteString("1.0")
|
||||
case f == 0:
|
||||
return 1, w.WriteByte('0')
|
||||
return w.WriteString("0.0")
|
||||
case f == -1:
|
||||
return w.WriteString("-1")
|
||||
return w.WriteString("-1.0")
|
||||
case math.IsNaN(f):
|
||||
return w.WriteString("NaN")
|
||||
case math.IsInf(f, +1):
|
||||
@@ -450,6 +450,12 @@ func writeFloat(w enhancedWriter, f float64) (int, error) {
|
||||
default:
|
||||
bp := numBufPool.Get().(*[]byte)
|
||||
*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)
|
||||
// Add a .0 if used fixed point and there is no decimal
|
||||
// point already. This is for future proofing with OpenMetrics,
|
||||
// where floats always contain either an exponent or decimal.
|
||||
if !bytes.ContainsAny(*bp, "e.") {
|
||||
*bp = append(*bp, '.', '0')
|
||||
}
|
||||
written, err := w.Write(*bp)
|
||||
numBufPool.Put(bp)
|
||||
return written, err
|
||||
|
||||
6
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
сгенерированный
поставляемый
6
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
сгенерированный
поставляемый
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||
All rights reserved.
|
||||
|
||||
HTTP Content-Type Autonegotiation.
|
||||
|
||||
The functions in this package implement the behaviour specified in
|
||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
|
||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1
vendor/github.com/prometheus/common/model/metric.go
сгенерированный
поставляемый
1
vendor/github.com/prometheus/common/model/metric.go
сгенерированный
поставляемый
@@ -21,7 +21,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
separator = []byte{0}
|
||||
// MetricNameRE is a regular expression matching valid metric
|
||||
// names. Note that the IsValidMetricName function performs the same
|
||||
// check but faster than a match with this regular expression.
|
||||
|
||||
3
vendor/github.com/prometheus/procfs/MAINTAINERS.md
сгенерированный
поставляемый
3
vendor/github.com/prometheus/procfs/MAINTAINERS.md
сгенерированный
поставляемый
@@ -1 +1,2 @@
|
||||
* Tobias Schmidt <tobidt@gmail.com>
|
||||
* Tobias Schmidt <tobidt@gmail.com> @grobie
|
||||
* Johannes 'fish' Ziemke <github@freigeist.org> @discordianfish
|
||||
|
||||
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Ссылка в новой задаче
Block a user