Merge pull request #20483 from hashicorp/vendor-winrmtest-bump

vendor: github.com/dylanmei/winrmtest@99b7fe2fddf1
This commit is contained in:
Radek Simko 2019-02-26 21:13:11 +00:00 committed by GitHub
commit 14ca8611ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1222 additions and 469 deletions

5
go.mod
View File

@ -8,8 +8,6 @@ require (
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect
github.com/agext/levenshtein v1.2.2 github.com/agext/levenshtein v1.2.2
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 // indirect github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 // indirect
github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd // indirect
github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 // indirect
github.com/apparentlymart/go-cidr v1.0.0 github.com/apparentlymart/go-cidr v1.0.0
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
@ -28,7 +26,7 @@ require (
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 // indirect github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 // indirect
github.com/dylanmei/iso8601 v0.1.0 // indirect github.com/dylanmei/iso8601 v0.1.0 // indirect
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1
github.com/go-test/deep v1.0.1 github.com/go-test/deep v1.0.1
github.com/gogo/protobuf v1.2.0 // indirect github.com/gogo/protobuf v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 // indirect github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 // indirect
@ -95,7 +93,6 @@ require (
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17 // indirect github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17 // indirect
github.com/posener/complete v1.2.1 github.com/posener/complete v1.2.1
github.com/satori/go.uuid v0.0.0-20160927100844-b061729afc07 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/sirupsen/logrus v1.1.1 // indirect github.com/sirupsen/logrus v1.1.1 // indirect
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect

16
go.sum
View File

@ -29,10 +29,10 @@ github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 h1:LoeFxdq5zUCBQPhbQKE6zvoGwHMxCBlqwbH9+9kHoHA= github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 h1:LoeFxdq5zUCBQPhbQKE6zvoGwHMxCBlqwbH9+9kHoHA=
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd h1:S3Fr6QnkpW9VRjiEY4psQHhhbbahASuNVj52YIce7lI= github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=
github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 h1:BFFG6KP8ASFBg2ptWsJn8p8RDufBjBDKIxLU7BTYGOM= github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0 h1:JaCC8jz0zdMLk2m+qCCVLLLM/PL93p84w4pK3aJWj60=
github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M= github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M=
github.com/apparentlymart/go-cidr v1.0.0 h1:lGDvXx8Lv9QHjrAVP7jyzleG4F9+FkRhJcEsDFxeb8w= github.com/apparentlymart/go-cidr v1.0.0 h1:lGDvXx8Lv9QHjrAVP7jyzleG4F9+FkRhJcEsDFxeb8w=
github.com/apparentlymart/go-cidr v1.0.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-cidr v1.0.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA=
@ -93,8 +93,8 @@ github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s9
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI= github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=
github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ=
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY= github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1 h1:r1oACdS2XYiAWcfF8BJXkoU8l1J71KehGR+d99yWEDA=
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08/go.mod h1:VBVDFSBXCIW8JaHQpI8lldSKfYaLMzP9oyq6IJ4fhzY= github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1/go.mod h1:lcy9/2gH1jn/VCLouHA6tOEwLoNVd4GW6zhuKLmHC2Y=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@ -326,8 +326,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/satori/go.uuid v0.0.0-20160927100844-b061729afc07 h1:DEZDfcCVq3xDJrjqdCgyN/dHYVoqR92MCsdqCdxmnhM= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v0.0.0-20160927100844-b061729afc07/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= 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/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=

View File

@ -2,8 +2,8 @@ language: go
go: go:
- 1.6 - 1.6
- 1.7 - 1.9
- 1.8 - '1.10'
install: install:
- go get github.com/mattn/goveralls - go get github.com/mattn/goveralls

View File

@ -7,9 +7,17 @@ XPath
XPath is Go package provides selecting nodes from XML, HTML or other documents using XPath expression. XPath is Go package provides selecting nodes from XML, HTML or other documents using XPath expression.
[XQuery](https://github.com/antchfx/xquery) : lets you extract data from HTML/XML documents using XPath package. Implementation
===
### Features - [htmlquery](https://github.com/antchfx/htmlquery) - an XPath query package for HTML document
- [xmlquery](https://github.com/antchfx/xmlquery) - an XPath query package for XML document.
- [jsonquery](https://github.com/antchfx/jsonquery) - an XPath query package for JSON document
Supported Features
===
#### The basic XPath patterns. #### The basic XPath patterns.
@ -45,7 +53,10 @@ XPath is Go package provides selecting nodes from XML, HTML or other documents u
- `//b` : Returns elements in the entire document matching b. - `//b` : Returns elements in the entire document matching b.
- `a|b` : All nodes matching a or b. - `a|b` : All nodes matching a or b, union operation(not boolean or).
- `(a, b, c)` : Evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence
#### Node Axes #### Node Axes
@ -97,23 +108,60 @@ XPath is Go package provides selecting nodes from XML, HTML or other documents u
* a div b Divide * a div b Divide
* a mod b Floating point mod, like Java. * a mod b Floating point mod, like Java.
- `a or b` : Boolean `or` operation.
- `a and b` : Boolean `and` operation.
- `(expr)` : Parenthesized expressions. - `(expr)` : Parenthesized expressions.
- `fun(arg1, ..., argn)` : Function calls. - `fun(arg1, ..., argn)` : Function calls:
* position() | Function | Supported |
* last() | --- | --- |
* count( node-set ) `boolean()`| ✓ |
* name() `ceiling()`| ✓ |
* starts-with( string, string ) `choose()`| ✗ |
* normalize-space( string ) `concat()`| ✓ |
* substring( string , start [, length] ) `contains()`| ✓ |
* not( expression ) `count()`| ✓ |
* string-length( [string] ) `current()`| ✗ |
* contains( string, string ) `document()`| ✗ |
* sum( node-set ) `element-available()`| ✗ |
* concat( string1 , string2 [, stringn]* ) `ends-with()`| ✓ |
`false()`| ✓ |
`floor()`| ✓ |
`format-number()`| ✗ |
`function-available()`| ✗ |
`generate-id()`| ✗ |
`id()`| ✗ |
`key()`| ✗ |
`lang()`| ✗ |
`last()`| ✓ |
`local-name()`| ✓ |
`name()`| ✓ |
`namespace-uri()`| ✓ |
`normalize-space()`| ✓ |
`not()`| ✓ |
`number()`| ✓ |
`position()`| ✓ |
`round()`| ✓ |
`starts-with()`| ✓ |
`string()`| ✓ |
`string-length()`| ✓ |
`substring()`| ✓ |
`substring-after()`| ✓ |
`substring-before()`| ✓ |
`sum()`| ✓ |
`system-property()`| ✗ |
`translate()`| ✓ |
`true()`| ✓ |
`unparsed-entity-url()` | ✗ |
- `a or b` : Boolean or. Changelogs
===
- `a and b` : Boolean and. 2019-01-29
- improvement `normalize-space` function. [#32](https://github.com/antchfx/xpath/issues/32)
2018-12-07
- supports XPath 2.0 Sequence expressions. [#30](https://github.com/antchfx/xpath/pull/30) by [@minherz](https://github.com/minherz).

View File

@ -23,9 +23,12 @@ type builder struct {
func axisPredicate(root *axisNode) func(NodeNavigator) bool { func axisPredicate(root *axisNode) func(NodeNavigator) bool {
// get current axix node type. // get current axix node type.
typ := ElementNode typ := ElementNode
if root.AxeType == "attribute" { switch root.AxeType {
case "attribute":
typ = AttributeNode typ = AttributeNode
} else { case "self", "parent":
typ = allNode
default:
switch root.Prop { switch root.Prop {
case "comment": case "comment":
typ = CommentNode typ = CommentNode
@ -34,12 +37,17 @@ func axisPredicate(root *axisNode) func(NodeNavigator) bool {
// case "processing-instruction": // case "processing-instruction":
// typ = ProcessingInstructionNode // typ = ProcessingInstructionNode
case "node": case "node":
typ = ElementNode typ = allNode
} }
} }
nametest := root.LocalName != "" || root.Prefix != ""
predicate := func(n NodeNavigator) bool { predicate := func(n NodeNavigator) bool {
if typ == n.NodeType() || typ == TextNode { if typ == n.NodeType() || typ == allNode || typ == TextNode {
if root.LocalName == "" || (root.LocalName == n.LocalName() && root.Prefix == n.Prefix()) { if nametest {
if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() {
return true
}
} else {
return true return true
} }
} }
@ -61,7 +69,6 @@ func (b *builder) processAxisNode(root *axisNode) (query, error) {
if root.Input == nil { if root.Input == nil {
qyInput = &contextQuery{} qyInput = &contextQuery{}
} else { } else {
if b.flag&filterFlag == 0 {
if root.AxeType == "child" && (root.Input.Type() == nodeAxis) { if root.AxeType == "child" && (root.Input.Type() == nodeAxis) {
if input := root.Input.(*axisNode); input.AxeType == "descendant-or-self" { if input := root.Input.(*axisNode); input.AxeType == "descendant-or-self" {
var qyGrandInput query var qyGrandInput query
@ -74,7 +81,6 @@ func (b *builder) processAxisNode(root *axisNode) (query, error) {
return qyOutput, nil return qyOutput, nil
} }
} }
}
qyInput, err = b.processNode(root.Input) qyInput, err = b.processNode(root.Input)
if err != nil { if err != nil {
return nil, err return nil, err
@ -157,6 +163,16 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
return nil, err return nil, err
} }
qyOutput = &functionQuery{Input: b.firstInput, Func: startwithFunc(arg1, arg2)} qyOutput = &functionQuery{Input: b.firstInput, Func: startwithFunc(arg1, arg2)}
case "ends-with":
arg1, err := b.processNode(root.Args[0])
if err != nil {
return nil, err
}
arg2, err := b.processNode(root.Args[1])
if err != nil {
return nil, err
}
qyOutput = &functionQuery{Input: b.firstInput, Func: endwithFunc(arg1, arg2)}
case "contains": case "contains":
arg1, err := b.processNode(root.Args[0]) arg1, err := b.processNode(root.Args[0])
if err != nil { if err != nil {
@ -189,6 +205,25 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
} }
} }
qyOutput = &functionQuery{Input: b.firstInput, Func: substringFunc(arg1, arg2, arg3)} qyOutput = &functionQuery{Input: b.firstInput, Func: substringFunc(arg1, arg2, arg3)}
case "substring-before", "substring-after":
//substring-xxxx( haystack, needle )
if len(root.Args) != 2 {
return nil, errors.New("xpath: substring-before function must have two parameters")
}
var (
arg1, arg2 query
err error
)
if arg1, err = b.processNode(root.Args[0]); err != nil {
return nil, err
}
if arg2, err = b.processNode(root.Args[1]); err != nil {
return nil, err
}
qyOutput = &functionQuery{
Input: b.firstInput,
Func: substringIndFunc(arg1, arg2, root.FuncName == "substring-after"),
}
case "string-length": case "string-length":
// string-length( [string] ) // string-length( [string] )
if len(root.Args) < 1 { if len(root.Args) < 1 {
@ -208,6 +243,25 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
return nil, err return nil, err
} }
qyOutput = &functionQuery{Input: argQuery, Func: normalizespaceFunc} qyOutput = &functionQuery{Input: argQuery, Func: normalizespaceFunc}
case "translate":
//translate( string , string, string )
if len(root.Args) != 3 {
return nil, errors.New("xpath: translate function must have three parameters")
}
var (
arg1, arg2, arg3 query
err error
)
if arg1, err = b.processNode(root.Args[0]); err != nil {
return nil, err
}
if arg2, err = b.processNode(root.Args[1]); err != nil {
return nil, err
}
if arg3, err = b.processNode(root.Args[2]); err != nil {
return nil, err
}
qyOutput = &functionQuery{Input: b.firstInput, Func: translateFunc(arg1, arg2, arg3)}
case "not": case "not":
if len(root.Args) == 0 { if len(root.Args) == 0 {
return nil, errors.New("xpath: not function must have at least one parameter") return nil, errors.New("xpath: not function must have at least one parameter")
@ -217,12 +271,62 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
return nil, err return nil, err
} }
qyOutput = &functionQuery{Input: argQuery, Func: notFunc} qyOutput = &functionQuery{Input: argQuery, Func: notFunc}
case "name", "local-name", "namespace-uri":
inp := b.firstInput
if len(root.Args) > 1 {
return nil, fmt.Errorf("xpath: %s function must have at most one parameter", root.FuncName)
}
if len(root.Args) == 1 {
argQuery, err := b.processNode(root.Args[0])
if err != nil {
return nil, err
}
inp = argQuery
}
f := &functionQuery{Input: inp}
switch root.FuncName {
case "name": case "name":
qyOutput = &functionQuery{Input: b.firstInput, Func: nameFunc} f.Func = nameFunc
case "local-name":
f.Func = localNameFunc
case "namespace-uri":
f.Func = namespaceFunc
}
qyOutput = f
case "true", "false":
val := root.FuncName == "true"
qyOutput = &functionQuery{
Input: b.firstInput,
Func: func(_ query, _ iterator) interface{} {
return val
},
}
case "last": case "last":
qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc}
case "position": case "position":
qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc} qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc}
case "boolean", "number", "string":
inp := b.firstInput
if len(root.Args) > 1 {
return nil, fmt.Errorf("xpath: %s function must have at most one parameter", root.FuncName)
}
if len(root.Args) == 1 {
argQuery, err := b.processNode(root.Args[0])
if err != nil {
return nil, err
}
inp = argQuery
}
f := &functionQuery{Input: inp}
switch root.FuncName {
case "boolean":
f.Func = booleanFunc
case "string":
f.Func = stringFunc
case "number":
f.Func = numberFunc
}
qyOutput = f
case "count": case "count":
//if b.firstInput == nil { //if b.firstInput == nil {
// return nil, errors.New("xpath: expression must evaluate to node-set") // return nil, errors.New("xpath: expression must evaluate to node-set")
@ -244,6 +348,24 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
return nil, err return nil, err
} }
qyOutput = &functionQuery{Input: argQuery, Func: sumFunc} qyOutput = &functionQuery{Input: argQuery, Func: sumFunc}
case "ceiling", "floor", "round":
if len(root.Args) == 0 {
return nil, fmt.Errorf("xpath: ceiling(node-sets) function must with have parameters node-sets")
}
argQuery, err := b.processNode(root.Args[0])
if err != nil {
return nil, err
}
f := &functionQuery{Input: argQuery}
switch root.FuncName {
case "ceiling":
f.Func = ceilingFunc
case "floor":
f.Func = floorFunc
case "round":
f.Func = roundFunc
}
qyOutput = f
case "concat": case "concat":
if len(root.Args) < 2 { if len(root.Args) < 2 {
return nil, fmt.Errorf("xpath: concat() must have at least two arguments") return nil, fmt.Errorf("xpath: concat() must have at least two arguments")
@ -304,12 +426,14 @@ func (b *builder) processOperatorNode(root *operatorNode) (query, error) {
exprFunc = neFunc exprFunc = neFunc
} }
qyOutput = &logicalQuery{Left: left, Right: right, Do: exprFunc} qyOutput = &logicalQuery{Left: left, Right: right, Do: exprFunc}
case "or", "and", "|": case "or", "and":
isOr := false isOr := false
if root.Op == "or" || root.Op == "|" { if root.Op == "or" {
isOr = true isOr = true
} }
qyOutput = &booleanQuery{Left: left, Right: right, IsOr: isOr} qyOutput = &booleanQuery{Left: left, Right: right, IsOr: isOr}
case "|":
qyOutput = &unionQuery{Left: left, Right: right}
} }
return qyOutput, nil return qyOutput, nil
} }

View File

@ -2,6 +2,9 @@ package xpath
import ( import (
"errors" "errors"
"fmt"
"math"
"regexp"
"strconv" "strconv"
"strings" "strings"
) )
@ -80,16 +83,146 @@ func sumFunc(q query, t iterator) interface{} {
case float64: case float64:
sum = typ sum = typ
case string: case string:
if v, err := strconv.ParseFloat(typ, 64); err != nil { v, err := strconv.ParseFloat(typ, 64)
sum = v if err != nil {
panic(errors.New("sum() function argument type must be a node-set or number"))
} }
sum = v
} }
return sum return sum
} }
func asNumber(t iterator, o interface{}) float64 {
switch typ := o.(type) {
case query:
node := typ.Select(t)
if node == nil {
return float64(0)
}
if v, err := strconv.ParseFloat(node.Value(), 64); err == nil {
return v
}
case float64:
return typ
case string:
v, err := strconv.ParseFloat(typ, 64)
if err != nil {
panic(errors.New("ceiling() function argument type must be a node-set or number"))
}
return v
}
return 0
}
// ceilingFunc is a XPath Node Set functions ceiling(node-set).
func ceilingFunc(q query, t iterator) interface{} {
val := asNumber(t, q.Evaluate(t))
return math.Ceil(val)
}
// floorFunc is a XPath Node Set functions floor(node-set).
func floorFunc(q query, t iterator) interface{} {
val := asNumber(t, q.Evaluate(t))
return math.Floor(val)
}
// roundFunc is a XPath Node Set functions round(node-set).
func roundFunc(q query, t iterator) interface{} {
val := asNumber(t, q.Evaluate(t))
//return math.Round(val)
return round(val)
}
// nameFunc is a XPath functions name([node-set]). // nameFunc is a XPath functions name([node-set]).
func nameFunc(q query, t iterator) interface{} { func nameFunc(q query, t iterator) interface{} {
return t.Current().LocalName() v := q.Select(t)
if v == nil {
return ""
}
ns := v.Prefix()
if ns == "" {
return v.LocalName()
}
return ns + ":" + v.LocalName()
}
// localNameFunc is a XPath functions local-name([node-set]).
func localNameFunc(q query, t iterator) interface{} {
v := q.Select(t)
if v == nil {
return ""
}
return v.LocalName()
}
// namespaceFunc is a XPath functions namespace-uri([node-set]).
func namespaceFunc(q query, t iterator) interface{} {
v := q.Select(t)
if v == nil {
return ""
}
return v.Prefix()
}
func asBool(t iterator, v interface{}) bool {
switch v := v.(type) {
case nil:
return false
case *NodeIterator:
return v.MoveNext()
case bool:
return bool(v)
case float64:
return v != 0
case string:
return v != ""
case query:
return v.Select(t) != nil
default:
panic(fmt.Errorf("unexpected type: %T", v))
}
}
func asString(t iterator, v interface{}) string {
switch v := v.(type) {
case nil:
return ""
case bool:
if v {
return "true"
}
return "false"
case float64:
return strconv.FormatFloat(v, 'g', -1, 64)
case string:
return v
case query:
node := v.Select(t)
if node == nil {
return ""
}
return node.Value()
default:
panic(fmt.Errorf("unexpected type: %T", v))
}
}
// booleanFunc is a XPath functions boolean([node-set]).
func booleanFunc(q query, t iterator) interface{} {
v := q.Evaluate(t)
return asBool(t, v)
}
// numberFunc is a XPath functions number([node-set]).
func numberFunc(q query, t iterator) interface{} {
v := q.Evaluate(t)
return asNumber(t, v)
}
// stringFunc is a XPath functions string([node-set]).
func stringFunc(q query, t iterator) interface{} {
v := q.Evaluate(t)
return asString(t, v)
} }
// startwithFunc is a XPath functions starts-with(string, string). // startwithFunc is a XPath functions starts-with(string, string).
@ -119,6 +252,33 @@ func startwithFunc(arg1, arg2 query) func(query, iterator) interface{} {
} }
} }
// endwithFunc is a XPath functions ends-with(string, string).
func endwithFunc(arg1, arg2 query) func(query, iterator) interface{} {
return func(q query, t iterator) interface{} {
var (
m, n string
ok bool
)
switch typ := arg1.Evaluate(t).(type) {
case string:
m = typ
case query:
node := typ.Select(t)
if node == nil {
return false
}
m = node.Value()
default:
panic(errors.New("ends-with() function argument type must be string"))
}
n, ok = arg2.Evaluate(t).(string)
if !ok {
panic(errors.New("ends-with() function argument type must be string"))
}
return strings.HasSuffix(m, n)
}
}
// containsFunc is a XPath functions contains(string or @attr, string). // containsFunc is a XPath functions contains(string or @attr, string).
func containsFunc(arg1, arg2 query) func(query, iterator) interface{} { func containsFunc(arg1, arg2 query) func(query, iterator) interface{} {
return func(q query, t iterator) interface{} { return func(q query, t iterator) interface{} {
@ -149,6 +309,11 @@ func containsFunc(arg1, arg2 query) func(query, iterator) interface{} {
} }
} }
var (
regnewline = regexp.MustCompile(`[\r\n\t]`)
regseqspace = regexp.MustCompile(`\s{2,}`)
)
// normalizespaceFunc is XPath functions normalize-space(string?) // normalizespaceFunc is XPath functions normalize-space(string?)
func normalizespaceFunc(q query, t iterator) interface{} { func normalizespaceFunc(q query, t iterator) interface{} {
var m string var m string
@ -158,11 +323,14 @@ func normalizespaceFunc(q query, t iterator) interface{} {
case query: case query:
node := typ.Select(t) node := typ.Select(t)
if node == nil { if node == nil {
return false return ""
} }
m = node.Value() m = node.Value()
} }
return strings.TrimSpace(m) m = strings.TrimSpace(m)
m = regnewline.ReplaceAllString(m, " ")
m = regseqspace.ReplaceAllString(m, " ")
return m
} }
// substringFunc is XPath functions substring function returns a part of a given string. // substringFunc is XPath functions substring function returns a part of a given string.
@ -175,7 +343,7 @@ func substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {
case query: case query:
node := typ.Select(t) node := typ.Select(t)
if node == nil { if node == nil {
return false return ""
} }
m = node.Value() m = node.Value()
} }
@ -185,7 +353,10 @@ func substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {
if start, ok = arg2.Evaluate(t).(float64); !ok { if start, ok = arg2.Evaluate(t).(float64); !ok {
panic(errors.New("substring() function first argument type must be int")) panic(errors.New("substring() function first argument type must be int"))
} else if start < 1 {
panic(errors.New("substring() function first argument type must be >= 1"))
} }
start--
if arg3 != nil { if arg3 != nil {
if length, ok = arg3.Evaluate(t).(float64); !ok { if length, ok = arg3.Evaluate(t).(float64); !ok {
panic(errors.New("substring() function second argument type must be int")) panic(errors.New("substring() function second argument type must be int"))
@ -201,6 +372,46 @@ func substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {
} }
} }
// substringIndFunc is XPath functions substring-before/substring-after function returns a part of a given string.
func substringIndFunc(arg1, arg2 query, after bool) func(query, iterator) interface{} {
return func(q query, t iterator) interface{} {
var str string
switch v := arg1.Evaluate(t).(type) {
case string:
str = v
case query:
node := v.Select(t)
if node == nil {
return ""
}
str = node.Value()
}
var word string
switch v := arg2.Evaluate(t).(type) {
case string:
word = v
case query:
node := v.Select(t)
if node == nil {
return ""
}
word = node.Value()
}
if word == "" {
return ""
}
i := strings.Index(str, word)
if i < 0 {
return ""
}
if after {
return str[i+len(word):]
}
return str[:i]
}
}
// stringLengthFunc is XPATH string-length( [string] ) function that returns a number // stringLengthFunc is XPATH string-length( [string] ) function that returns a number
// equal to the number of characters in a given string. // equal to the number of characters in a given string.
func stringLengthFunc(arg1 query) func(query, iterator) interface{} { func stringLengthFunc(arg1 query) func(query, iterator) interface{} {
@ -219,6 +430,25 @@ func stringLengthFunc(arg1 query) func(query, iterator) interface{} {
} }
} }
// translateFunc is XPath functions translate() function returns a replaced string.
func translateFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {
return func(q query, t iterator) interface{} {
str := asString(t, arg1.Evaluate(t))
src := asString(t, arg2.Evaluate(t))
dst := asString(t, arg3.Evaluate(t))
var replace []string
for i, s := range src {
d := ""
if i < len(dst) {
d = string(dst[i])
}
replace = append(replace, string(s), d)
}
return strings.NewReplacer(replace...).Replace(str)
}
}
// notFunc is XPATH functions not(expression) function operation. // notFunc is XPATH functions not(expression) function operation.
func notFunc(q query, t iterator) interface{} { func notFunc(q query, t iterator) interface{} {
switch v := q.Evaluate(t).(type) { switch v := q.Evaluate(t).(type) {

9
vendor/github.com/antchfx/xpath/func_go110.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
// +build go1.10
package xpath
import "math"
func round(f float64) int {
return int(math.Round(f))
}

15
vendor/github.com/antchfx/xpath/func_pre_go110.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
// +build !go1.10
package xpath
import "math"
// math.Round() is supported by Go 1.10+,
// This method just compatible for version <1.10.
// https://github.com/golang/go/issues/20100
func round(f float64) int {
if math.Abs(f) < 0.5 {
return 0
}
return int(f + math.Copysign(0.5, f))
}

View File

@ -42,7 +42,7 @@ const (
itemString // Quoted string constant itemString // Quoted string constant
itemNumber // Number constant itemNumber // Number constant
itemAxe // Axe (like child::) itemAxe // Axe (like child::)
itemEof // END itemEOF // END
) )
// A node is an XPath node in the parse tree. // A node is an XPath node in the parse tree.
@ -389,7 +389,7 @@ Loop:
} }
// Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep
func (p *parser) parseStep(n node) node { func (p *parser) parseStep(n node) (opnd node) {
axeTyp := "child" // default axes value. axeTyp := "child" // default axes value.
if p.r.typ == itemDot || p.r.typ == itemDotDot { if p.r.typ == itemDot || p.r.typ == itemDotDot {
if p.r.typ == itemDot { if p.r.typ == itemDot {
@ -398,8 +398,11 @@ func (p *parser) parseStep(n node) node {
axeTyp = "parent" axeTyp = "parent"
} }
p.next() p.next()
return newAxisNode(axeTyp, "", "", "", n) opnd = newAxisNode(axeTyp, "", "", "", n)
if p.r.typ != itemLBracket {
return opnd
} }
} else {
switch p.r.typ { switch p.r.typ {
case itemAt: case itemAt:
p.next() p.next()
@ -407,14 +410,33 @@ func (p *parser) parseStep(n node) node {
case itemAxe: case itemAxe:
axeTyp = p.r.name axeTyp = p.r.name
p.next() p.next()
case itemLParens:
return p.parseSequence(n)
}
opnd = p.parseNodeTest(n, axeTyp)
} }
opnd := p.parseNodeTest(n, axeTyp)
for p.r.typ == itemLBracket { for p.r.typ == itemLBracket {
opnd = newFilterNode(opnd, p.parsePredicate(opnd)) opnd = newFilterNode(opnd, p.parsePredicate(opnd))
} }
return opnd return opnd
} }
// Expr ::= '(' Step ("," Step)* ')'
func (p *parser) parseSequence(n node) (opnd node) {
p.skipItem(itemLParens)
opnd = p.parseStep(n)
for {
if p.r.typ != itemComma {
break
}
p.next()
opnd2 := p.parseStep(n)
opnd = newOperatorNode("|", opnd, opnd2)
}
p.skipItem(itemRParens)
return opnd
}
// NodeTest ::= NameTest | nodeType '(' ')' | 'processing-instruction' '(' Literal ')' // NodeTest ::= NameTest | nodeType '(' ')' | 'processing-instruction' '(' Literal ')'
func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) { func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) {
switch p.r.typ { switch p.r.typ {
@ -628,7 +650,7 @@ func (s *scanner) nextChar() bool {
return false return false
} }
s.curr = rune(s.text[s.pos]) s.curr = rune(s.text[s.pos])
s.pos += 1 s.pos++
return true return true
} }
@ -636,7 +658,7 @@ func (s *scanner) nextItem() bool {
s.skipSpace() s.skipSpace()
switch s.curr { switch s.curr {
case 0: case 0:
s.typ = itemEof s.typ = itemEOF
return false return false
case ',', '@', '(', ')', '|', '*', '[', ']', '+', '-', '=', '#', '$': case ',', '@', '(', ')', '|', '*', '[', ']', '+', '-', '=', '#', '$':
s.typ = asItemType(s.curr) s.typ = asItemType(s.curr)

View File

@ -71,7 +71,7 @@ func (a *ancestorQuery) Select(t iterator) NodeNavigator {
} }
for node.MoveToParent() { for node.MoveToParent() {
if !a.Predicate(node) { if !a.Predicate(node) {
break continue
} }
return node return node
} }
@ -707,16 +707,79 @@ func (b *booleanQuery) Select(t iterator) NodeNavigator {
func (b *booleanQuery) Evaluate(t iterator) interface{} { func (b *booleanQuery) Evaluate(t iterator) interface{} {
m := b.Left.Evaluate(t) m := b.Left.Evaluate(t)
if m.(bool) == b.IsOr { left := asBool(t, m)
return m if b.IsOr && left {
return true
} else if !b.IsOr && !left {
return false
} }
return b.Right.Evaluate(t) m = b.Right.Evaluate(t)
return asBool(t, m)
} }
func (b *booleanQuery) Clone() query { func (b *booleanQuery) Clone() query {
return &booleanQuery{IsOr: b.IsOr, Left: b.Left.Clone(), Right: b.Right.Clone()} return &booleanQuery{IsOr: b.IsOr, Left: b.Left.Clone(), Right: b.Right.Clone()}
} }
type unionQuery struct {
Left, Right query
iterator func() NodeNavigator
}
func (u *unionQuery) Select(t iterator) NodeNavigator {
if u.iterator == nil {
var list []NodeNavigator
var i int
root := t.Current().Copy()
for {
node := u.Left.Select(t)
if node == nil {
break
}
node = node.Copy()
list = append(list, node)
}
t.Current().MoveTo(root)
for {
node := u.Right.Select(t)
if node == nil {
break
}
node = node.Copy()
var exists bool
for _, x := range list {
if reflect.DeepEqual(x, node) {
exists = true
break
}
}
if !exists {
list = append(list, node)
}
}
u.iterator = func() NodeNavigator {
if i >= len(list) {
return nil
}
node := list[i]
i++
return node
}
}
return u.iterator()
}
func (u *unionQuery) Evaluate(t iterator) interface{} {
u.iterator = nil
u.Left.Evaluate(t)
u.Right.Evaluate(t)
return u
}
func (u *unionQuery) Clone() query {
return &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()}
}
func getNodePosition(q query) int { func getNodePosition(q query) int {
type Position interface { type Position interface {
position() int position() int

View File

@ -22,6 +22,9 @@ const (
// CommentNode is a comment node, such as <!-- my comment --> // CommentNode is a comment node, such as <!-- my comment -->
CommentNode CommentNode
// allNode is any types of node, used by xpath package only to predicate match.
allNode
) )
// NodeNavigator provides cursor model for navigating XML data. // NodeNavigator provides cursor model for navigating XML data.

View File

@ -66,10 +66,15 @@ func (n *Node) InnerText() string {
func outputXML(buf *bytes.Buffer, n *Node) { func outputXML(buf *bytes.Buffer, n *Node) {
if n.Type == TextNode || n.Type == CommentNode { if n.Type == TextNode || n.Type == CommentNode {
buf.WriteString(strings.TrimSpace(n.Data)) xml.EscapeText(buf, []byte(strings.TrimSpace(n.Data)))
return return
} }
if n.Type == DeclarationNode {
buf.WriteString("<?" + n.Data)
} else {
buf.WriteString("<" + n.Data) buf.WriteString("<" + n.Data)
}
for _, attr := range n.Attr { for _, attr := range n.Attr {
if attr.Name.Space != "" { if attr.Name.Space != "" {
buf.WriteString(fmt.Sprintf(` %s:%s="%s"`, attr.Name.Space, attr.Name.Local, attr.Value)) buf.WriteString(fmt.Sprintf(` %s:%s="%s"`, attr.Name.Space, attr.Name.Local, attr.Value))
@ -77,12 +82,18 @@ func outputXML(buf *bytes.Buffer, n *Node) {
buf.WriteString(fmt.Sprintf(` %s="%s"`, attr.Name.Local, attr.Value)) buf.WriteString(fmt.Sprintf(` %s="%s"`, attr.Name.Local, attr.Value))
} }
} }
if n.Type == DeclarationNode {
buf.WriteString("?>")
} else {
buf.WriteString(">") buf.WriteString(">")
}
for child := n.FirstChild; child != nil; child = child.NextSibling { for child := n.FirstChild; child != nil; child = child.NextSibling {
outputXML(buf, child) outputXML(buf, child)
} }
if n.Type != DeclarationNode {
buf.WriteString(fmt.Sprintf("</%s>", n.Data)) buf.WriteString(fmt.Sprintf("</%s>", n.Data))
} }
}
// OutputXML returns the text that including tags name. // OutputXML returns the text that including tags name.
func (n *Node) OutputXML(self bool) string { func (n *Node) OutputXML(self bool) string {
@ -128,6 +139,9 @@ func addChild(parent, n *Node) {
} }
func addSibling(sibling, n *Node) { func addSibling(sibling, n *Node) {
for t := sibling.NextSibling; t != nil; t = t.NextSibling {
sibling = t
}
n.Parent = sibling.Parent n.Parent = sibling.Parent
sibling.NextSibling = n sibling.NextSibling = n
n.PrevSibling = sibling n.PrevSibling = sibling
@ -245,8 +259,3 @@ quit:
func Parse(r io.Reader) (*Node, error) { func Parse(r io.Reader) (*Node, error) {
return parse(r) return parse(r)
} }
// ParseXML returns the parse tree for the XML from the given Reader.Deprecated.
func ParseXML(r io.Reader) (*Node, error) {
return parse(r)
}

11
vendor/github.com/dylanmei/winrmtest/go.mod generated vendored Normal file
View File

@ -0,0 +1,11 @@
module github.com/dylanmei/winrmtest
require (
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e // indirect
github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0
github.com/kr/pretty v0.1.0 // indirect
github.com/satori/go.uuid v1.2.0
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect
golang.org/x/text v0.3.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

17
vendor/github.com/dylanmei/winrmtest/go.sum generated vendored Normal file
View File

@ -0,0 +1,17 @@
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0 h1:JaCC8jz0zdMLk2m+qCCVLLLM/PL93p84w4pK3aJWj60=
github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -7,6 +7,8 @@ go:
- 1.5 - 1.5
- 1.6 - 1.6
- 1.7 - 1.7
- 1.8
- 1.9
- tip - tip
matrix: matrix:
allow_failures: allow_failures:

View File

@ -1,4 +1,4 @@
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru> Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View File

@ -59,7 +59,7 @@ func main() {
## Copyright ## Copyright
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>. Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>.
UUID package released under MIT License. UUID package released under MIT License.
See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details.

206
vendor/github.com/satori/go.uuid/codec.go generated vendored Normal file
View File

@ -0,0 +1,206 @@
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"bytes"
"encoding/hex"
"fmt"
)
// FromBytes returns UUID converted from raw byte slice input.
// It will return error if the slice isn't 16 bytes long.
func FromBytes(input []byte) (u UUID, err error) {
err = u.UnmarshalBinary(input)
return
}
// FromBytesOrNil returns UUID converted from raw byte slice input.
// Same behavior as FromBytes, but returns a Nil UUID on error.
func FromBytesOrNil(input []byte) UUID {
uuid, err := FromBytes(input)
if err != nil {
return Nil
}
return uuid
}
// FromString returns UUID parsed from string input.
// Input is expected in a form accepted by UnmarshalText.
func FromString(input string) (u UUID, err error) {
err = u.UnmarshalText([]byte(input))
return
}
// FromStringOrNil returns UUID parsed from string input.
// Same behavior as FromString, but returns a Nil UUID on error.
func FromStringOrNil(input string) UUID {
uuid, err := FromString(input)
if err != nil {
return Nil
}
return uuid
}
// MarshalText implements the encoding.TextMarshaler interface.
// The encoding is the same as returned by String.
func (u UUID) MarshalText() (text []byte, err error) {
text = []byte(u.String())
return
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
// Following formats are supported:
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
// "6ba7b8109dad11d180b400c04fd430c8"
// ABNF for supported UUID text representation follows:
// uuid := canonical | hashlike | braced | urn
// plain := canonical | hashlike
// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct
// hashlike := 12hexoct
// braced := '{' plain '}'
// urn := URN ':' UUID-NID ':' plain
// URN := 'urn'
// UUID-NID := 'uuid'
// 12hexoct := 6hexoct 6hexoct
// 6hexoct := 4hexoct 2hexoct
// 4hexoct := 2hexoct 2hexoct
// 2hexoct := hexoct hexoct
// hexoct := hexdig hexdig
// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
// 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
func (u *UUID) UnmarshalText(text []byte) (err error) {
switch len(text) {
case 32:
return u.decodeHashLike(text)
case 36:
return u.decodeCanonical(text)
case 38:
return u.decodeBraced(text)
case 41:
fallthrough
case 45:
return u.decodeURN(text)
default:
return fmt.Errorf("uuid: incorrect UUID length: %s", text)
}
}
// decodeCanonical decodes UUID string in format
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
func (u *UUID) decodeCanonical(t []byte) (err error) {
if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' {
return fmt.Errorf("uuid: incorrect UUID format %s", t)
}
src := t[:]
dst := u[:]
for i, byteGroup := range byteGroups {
if i > 0 {
src = src[1:] // skip dash
}
_, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup])
if err != nil {
return
}
src = src[byteGroup:]
dst = dst[byteGroup/2:]
}
return
}
// decodeHashLike decodes UUID string in format
// "6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodeHashLike(t []byte) (err error) {
src := t[:]
dst := u[:]
if _, err = hex.Decode(dst, src); err != nil {
return err
}
return
}
// decodeBraced decodes UUID string in format
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format
// "{6ba7b8109dad11d180b400c04fd430c8}".
func (u *UUID) decodeBraced(t []byte) (err error) {
l := len(t)
if t[0] != '{' || t[l-1] != '}' {
return fmt.Errorf("uuid: incorrect UUID format %s", t)
}
return u.decodePlain(t[1 : l-1])
}
// decodeURN decodes UUID string in format
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format
// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodeURN(t []byte) (err error) {
total := len(t)
urn_uuid_prefix := t[:9]
if !bytes.Equal(urn_uuid_prefix, urnPrefix) {
return fmt.Errorf("uuid: incorrect UUID format: %s", t)
}
return u.decodePlain(t[9:total])
}
// decodePlain decodes UUID string in canonical format
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format
// "6ba7b8109dad11d180b400c04fd430c8".
func (u *UUID) decodePlain(t []byte) (err error) {
switch len(t) {
case 32:
return u.decodeHashLike(t)
case 36:
return u.decodeCanonical(t)
default:
return fmt.Errorf("uuid: incorrrect UUID length: %s", t)
}
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (u UUID) MarshalBinary() (data []byte, err error) {
data = u.Bytes()
return
}
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
// It will return error if the slice isn't 16 bytes long.
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
if len(data) != Size {
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
return
}
copy(u[:], data)
return
}

239
vendor/github.com/satori/go.uuid/generator.go generated vendored Normal file
View File

@ -0,0 +1,239 @@
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"encoding/binary"
"hash"
"net"
"os"
"sync"
"time"
)
// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
var (
global = newDefaultGenerator()
epochFunc = unixTimeFunc
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
return global.NewV1()
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
return global.NewV2(domain)
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
return global.NewV3(ns, name)
}
// NewV4 returns random generated UUID.
func NewV4() UUID {
return global.NewV4()
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
return global.NewV5(ns, name)
}
// Generator provides interface for generating UUIDs.
type Generator interface {
NewV1() UUID
NewV2(domain byte) UUID
NewV3(ns UUID, name string) UUID
NewV4() UUID
NewV5(ns UUID, name string) UUID
}
// Default generator implementation.
type generator struct {
storageOnce sync.Once
storageMutex sync.Mutex
lastTime uint64
clockSequence uint16
hardwareAddr [6]byte
}
func newDefaultGenerator() Generator {
return &generator{}
}
// NewV1 returns UUID based on current timestamp and MAC address.
func (g *generator) NewV1() UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
copy(u[10:], hardwareAddr)
u.SetVersion(V1)
u.SetVariant(VariantRFC4122)
return u
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func (g *generator) NewV2(domain byte) UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := g.getStorage()
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[0:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[0:], posixGID)
}
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
u[9] = domain
copy(u[10:], hardwareAddr)
u.SetVersion(V2)
u.SetVariant(VariantRFC4122)
return u
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func (g *generator) NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(V3)
u.SetVariant(VariantRFC4122)
return u
}
// NewV4 returns random generated UUID.
func (g *generator) NewV4() UUID {
u := UUID{}
g.safeRandom(u[:])
u.SetVersion(V4)
u.SetVariant(VariantRFC4122)
return u
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func (g *generator) NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(V5)
u.SetVariant(VariantRFC4122)
return u
}
func (g *generator) initStorage() {
g.initClockSequence()
g.initHardwareAddr()
}
func (g *generator) initClockSequence() {
buf := make([]byte, 2)
g.safeRandom(buf)
g.clockSequence = binary.BigEndian.Uint16(buf)
}
func (g *generator) initHardwareAddr() {
interfaces, err := net.Interfaces()
if err == nil {
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
copy(g.hardwareAddr[:], iface.HardwareAddr)
return
}
}
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence
g.safeRandom(g.hardwareAddr[:])
// Set multicast bit as recommended in RFC 4122
g.hardwareAddr[0] |= 0x01
}
func (g *generator) safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}
// Returns UUID v1/v2 storage state.
// Returns epoch timestamp, clock sequence, and hardware address.
func (g *generator) getStorage() (uint64, uint16, []byte) {
g.storageOnce.Do(g.initStorage)
g.storageMutex.Lock()
defer g.storageMutex.Unlock()
timeNow := epochFunc()
// Clock changed backwards since last UUID generation.
// Should increase clock sequence.
if timeNow <= g.lastTime {
g.clockSequence++
}
g.lastTime = timeNow
return timeNow, g.clockSequence, g.hardwareAddr[:]
}
// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
return epochStart + uint64(time.Now().UnixNano()/100)
}
// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))
return u
}

78
vendor/github.com/satori/go.uuid/sql.go generated vendored Normal file
View File

@ -0,0 +1,78 @@
// Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"database/sql/driver"
"fmt"
)
// Value implements the driver.Valuer interface.
func (u UUID) Value() (driver.Value, error) {
return u.String(), nil
}
// Scan implements the sql.Scanner interface.
// A 16-byte slice is handled by UnmarshalBinary, while
// a longer byte slice or a string is handled by UnmarshalText.
func (u *UUID) Scan(src interface{}) error {
switch src := src.(type) {
case []byte:
if len(src) == Size {
return u.UnmarshalBinary(src)
}
return u.UnmarshalText(src)
case string:
return u.UnmarshalText([]byte(src))
}
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
}
// NullUUID can be used with the standard sql package to represent a
// UUID value that can be NULL in the database
type NullUUID struct {
UUID UUID
Valid bool
}
// Value implements the driver.Valuer interface.
func (u NullUUID) Value() (driver.Value, error) {
if !u.Valid {
return nil, nil
}
// Delegate to UUID Value function
return u.UUID.Value()
}
// Scan implements the sql.Scanner interface.
func (u *NullUUID) Scan(src interface{}) error {
if src == nil {
u.UUID, u.Valid = Nil, false
return nil
}
// Delegate to UUID Scan function
u.Valid = true
return u.UUID.Scan(src)
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru> // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru>
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the // a copy of this software and associated documentation files (the
@ -26,23 +26,29 @@ package uuid
import ( import (
"bytes" "bytes"
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"database/sql/driver"
"encoding/binary"
"encoding/hex" "encoding/hex"
"fmt" )
"hash"
"net" // Size of a UUID in bytes.
"os" const Size = 16
"sync"
"time" // UUID representation compliant with specification
// described in RFC 4122.
type UUID [Size]byte
// UUID versions
const (
_ byte = iota
V1
V2
V3
V4
V5
) )
// UUID layout variants. // UUID layout variants.
const ( const (
VariantNCS = iota VariantNCS byte = iota
VariantRFC4122 VariantRFC4122
VariantMicrosoft VariantMicrosoft
VariantFuture VariantFuture
@ -55,137 +61,49 @@ const (
DomainOrg DomainOrg
) )
// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
// Used in string method conversion
const dash byte = '-'
// UUID v1/v2 storage.
var (
storageMutex sync.Mutex
storageOnce sync.Once
epochFunc = unixTimeFunc
clockSequence uint16
lastTime uint64
hardwareAddr [6]byte
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// String parse helpers. // String parse helpers.
var ( var (
urnPrefix = []byte("urn:uuid:") urnPrefix = []byte("urn:uuid:")
byteGroups = []int{8, 4, 4, 4, 12} byteGroups = []int{8, 4, 4, 4, 12}
) )
func initClockSequence() { // Nil is special form of UUID that is specified to have all
buf := make([]byte, 2)
safeRandom(buf)
clockSequence = binary.BigEndian.Uint16(buf)
}
func initHardwareAddr() {
interfaces, err := net.Interfaces()
if err == nil {
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
copy(hardwareAddr[:], iface.HardwareAddr)
return
}
}
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence
safeRandom(hardwareAddr[:])
// Set multicast bit as recommended in RFC 4122
hardwareAddr[0] |= 0x01
}
func initStorage() {
initClockSequence()
initHardwareAddr()
}
func safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}
// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
return epochStart + uint64(time.Now().UnixNano()/100)
}
// UUID representation compliant with specification
// described in RFC 4122.
type UUID [16]byte
// NullUUID can be used with the standard sql package to represent a
// UUID value that can be NULL in the database
type NullUUID struct {
UUID UUID
Valid bool
}
// The nil UUID is special form of UUID that is specified to have all
// 128 bits set to zero. // 128 bits set to zero.
var Nil = UUID{} var Nil = UUID{}
// Predefined namespace UUIDs. // Predefined namespace UUIDs.
var ( var (
NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8") NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8") NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8") NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
) )
// And returns result of binary AND of two UUIDs.
func And(u1 UUID, u2 UUID) UUID {
u := UUID{}
for i := 0; i < 16; i++ {
u[i] = u1[i] & u2[i]
}
return u
}
// Or returns result of binary OR of two UUIDs.
func Or(u1 UUID, u2 UUID) UUID {
u := UUID{}
for i := 0; i < 16; i++ {
u[i] = u1[i] | u2[i]
}
return u
}
// Equal returns true if u1 and u2 equals, otherwise returns false. // Equal returns true if u1 and u2 equals, otherwise returns false.
func Equal(u1 UUID, u2 UUID) bool { func Equal(u1 UUID, u2 UUID) bool {
return bytes.Equal(u1[:], u2[:]) return bytes.Equal(u1[:], u2[:])
} }
// Version returns algorithm version used to generate UUID. // Version returns algorithm version used to generate UUID.
func (u UUID) Version() uint { func (u UUID) Version() byte {
return uint(u[6] >> 4) return u[6] >> 4
} }
// Variant returns UUID layout variant. // Variant returns UUID layout variant.
func (u UUID) Variant() uint { func (u UUID) Variant() byte {
switch { switch {
case (u[8] & 0x80) == 0x00: case (u[8] >> 7) == 0x00:
return VariantNCS return VariantNCS
case (u[8]&0xc0)|0x80 == 0x80: case (u[8] >> 6) == 0x02:
return VariantRFC4122 return VariantRFC4122
case (u[8]&0xe0)|0xc0 == 0xc0: case (u[8] >> 5) == 0x06:
return VariantMicrosoft return VariantMicrosoft
} case (u[8] >> 5) == 0x07:
fallthrough
default:
return VariantFuture return VariantFuture
} }
}
// Bytes returns bytes slice representation of UUID. // Bytes returns bytes slice representation of UUID.
func (u UUID) Bytes() []byte { func (u UUID) Bytes() []byte {
@ -198,13 +116,13 @@ func (u UUID) String() string {
buf := make([]byte, 36) buf := make([]byte, 36)
hex.Encode(buf[0:8], u[0:4]) hex.Encode(buf[0:8], u[0:4])
buf[8] = dash buf[8] = '-'
hex.Encode(buf[9:13], u[4:6]) hex.Encode(buf[9:13], u[4:6])
buf[13] = dash buf[13] = '-'
hex.Encode(buf[14:18], u[6:8]) hex.Encode(buf[14:18], u[6:8])
buf[18] = dash buf[18] = '-'
hex.Encode(buf[19:23], u[8:10]) hex.Encode(buf[19:23], u[8:10])
buf[23] = dash buf[23] = '-'
hex.Encode(buf[24:], u[10:]) hex.Encode(buf[24:], u[10:])
return string(buf) return string(buf)
@ -215,267 +133,29 @@ func (u *UUID) SetVersion(v byte) {
u[6] = (u[6] & 0x0f) | (v << 4) u[6] = (u[6] & 0x0f) | (v << 4)
} }
// SetVariant sets variant bits as described in RFC 4122. // SetVariant sets variant bits.
func (u *UUID) SetVariant() { func (u *UUID) SetVariant(v byte) {
u[8] = (u[8] & 0xbf) | 0x80 switch v {
case VariantNCS:
u[8] = (u[8]&(0xff>>1) | (0x00 << 7))
case VariantRFC4122:
u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
case VariantMicrosoft:
u[8] = (u[8]&(0xff>>3) | (0x06 << 5))
case VariantFuture:
fallthrough
default:
u[8] = (u[8]&(0xff>>3) | (0x07 << 5))
}
} }
// MarshalText implements the encoding.TextMarshaler interface. // Must is a helper that wraps a call to a function returning (UUID, error)
// The encoding is the same as returned by String. // and panics if the error is non-nil. It is intended for use in variable
func (u UUID) MarshalText() (text []byte, err error) { // initializations such as
text = []byte(u.String()) // var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"));
return func Must(u UUID, err error) UUID {
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
// Following formats are supported:
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
func (u *UUID) UnmarshalText(text []byte) (err error) {
if len(text) < 32 {
err = fmt.Errorf("uuid: UUID string too short: %s", text)
return
}
t := text[:]
braced := false
if bytes.Equal(t[:9], urnPrefix) {
t = t[9:]
} else if t[0] == '{' {
braced = true
t = t[1:]
}
b := u[:]
for i, byteGroup := range byteGroups {
if i > 0 {
if t[0] != '-' {
err = fmt.Errorf("uuid: invalid string format")
return
}
t = t[1:]
}
if len(t) < byteGroup {
err = fmt.Errorf("uuid: UUID string too short: %s", text)
return
}
if i == 4 && len(t) > byteGroup &&
((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
err = fmt.Errorf("uuid: UUID string too long: %s", text)
return
}
_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
if err != nil { if err != nil {
return panic(err)
} }
t = t[byteGroup:]
b = b[byteGroup/2:]
}
return
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (u UUID) MarshalBinary() (data []byte, err error) {
data = u.Bytes()
return
}
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
// It will return error if the slice isn't 16 bytes long.
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
if len(data) != 16 {
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
return
}
copy(u[:], data)
return
}
// Value implements the driver.Valuer interface.
func (u UUID) Value() (driver.Value, error) {
return u.String(), nil
}
// Scan implements the sql.Scanner interface.
// A 16-byte slice is handled by UnmarshalBinary, while
// a longer byte slice or a string is handled by UnmarshalText.
func (u *UUID) Scan(src interface{}) error {
switch src := src.(type) {
case []byte:
if len(src) == 16 {
return u.UnmarshalBinary(src)
}
return u.UnmarshalText(src)
case string:
return u.UnmarshalText([]byte(src))
}
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
}
// Value implements the driver.Valuer interface.
func (u NullUUID) Value() (driver.Value, error) {
if !u.Valid {
return nil, nil
}
// Delegate to UUID Value function
return u.UUID.Value()
}
// Scan implements the sql.Scanner interface.
func (u *NullUUID) Scan(src interface{}) error {
if src == nil {
u.UUID, u.Valid = Nil, false
return nil
}
// Delegate to UUID Scan function
u.Valid = true
return u.UUID.Scan(src)
}
// FromBytes returns UUID converted from raw byte slice input.
// It will return error if the slice isn't 16 bytes long.
func FromBytes(input []byte) (u UUID, err error) {
err = u.UnmarshalBinary(input)
return
}
// FromBytesOrNil returns UUID converted from raw byte slice input.
// Same behavior as FromBytes, but returns a Nil UUID on error.
func FromBytesOrNil(input []byte) UUID {
uuid, err := FromBytes(input)
if err != nil {
return Nil
}
return uuid
}
// FromString returns UUID parsed from string input.
// Input is expected in a form accepted by UnmarshalText.
func FromString(input string) (u UUID, err error) {
err = u.UnmarshalText([]byte(input))
return
}
// FromStringOrNil returns UUID parsed from string input.
// Same behavior as FromString, but returns a Nil UUID on error.
func FromStringOrNil(input string) UUID {
uuid, err := FromString(input)
if err != nil {
return Nil
}
return uuid
}
// Returns UUID v1/v2 storage state.
// Returns epoch timestamp, clock sequence, and hardware address.
func getStorage() (uint64, uint16, []byte) {
storageOnce.Do(initStorage)
storageMutex.Lock()
defer storageMutex.Unlock()
timeNow := epochFunc()
// Clock changed backwards since last UUID generation.
// Should increase clock sequence.
if timeNow <= lastTime {
clockSequence++
}
lastTime = timeNow
return timeNow, clockSequence, hardwareAddr[:]
}
// NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := getStorage()
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
copy(u[10:], hardwareAddr)
u.SetVersion(1)
u.SetVariant()
return u
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := getStorage()
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[0:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[0:], posixGID)
}
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
u[9] = domain
copy(u[10:], hardwareAddr)
u.SetVersion(2)
u.SetVariant()
return u
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(3)
u.SetVariant()
return u
}
// NewV4 returns random generated UUID.
func NewV4() UUID {
u := UUID{}
safeRandom(u[:])
u.SetVersion(4)
u.SetVariant()
return u
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(5)
u.SetVariant()
return u
}
// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))
return u return u
} }

10
vendor/modules.txt vendored
View File

@ -47,9 +47,9 @@ github.com/agext/levenshtein
# github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 # github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6
github.com/agl/ed25519 github.com/agl/ed25519
github.com/agl/ed25519/edwards25519 github.com/agl/ed25519/edwards25519
# github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd # github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e
github.com/antchfx/xpath github.com/antchfx/xpath
# github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 # github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0
github.com/antchfx/xquery/xml github.com/antchfx/xquery/xml
# github.com/apparentlymart/go-cidr v1.0.0 # github.com/apparentlymart/go-cidr v1.0.0
github.com/apparentlymart/go-cidr/cidr github.com/apparentlymart/go-cidr/cidr
@ -134,7 +134,7 @@ github.com/dgrijalva/jwt-go
github.com/dimchansky/utfbom github.com/dimchansky/utfbom
# github.com/dylanmei/iso8601 v0.1.0 # github.com/dylanmei/iso8601 v0.1.0
github.com/dylanmei/iso8601 github.com/dylanmei/iso8601
# github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 # github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1
github.com/dylanmei/winrmtest github.com/dylanmei/winrmtest
# github.com/fatih/color v1.7.0 # github.com/fatih/color v1.7.0
github.com/fatih/color github.com/fatih/color
@ -170,10 +170,10 @@ github.com/gophercloud/gophercloud
github.com/gophercloud/gophercloud/openstack github.com/gophercloud/gophercloud/openstack
github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers
github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects
github.com/gophercloud/gophercloud/pagination
github.com/gophercloud/gophercloud/openstack/identity/v2/tokens github.com/gophercloud/gophercloud/openstack/identity/v2/tokens
github.com/gophercloud/gophercloud/openstack/identity/v3/tokens github.com/gophercloud/gophercloud/openstack/identity/v3/tokens
github.com/gophercloud/gophercloud/openstack/utils github.com/gophercloud/gophercloud/openstack/utils
github.com/gophercloud/gophercloud/pagination
github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts
github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions
github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes
@ -408,7 +408,7 @@ github.com/posener/complete
github.com/posener/complete/cmd/install github.com/posener/complete/cmd/install
github.com/posener/complete/cmd github.com/posener/complete/cmd
github.com/posener/complete/match github.com/posener/complete/match
# github.com/satori/go.uuid v0.0.0-20160927100844-b061729afc07 # github.com/satori/go.uuid v1.2.0
github.com/satori/go.uuid github.com/satori/go.uuid
# github.com/spf13/afero v1.2.1 # github.com/spf13/afero v1.2.1
github.com/spf13/afero github.com/spf13/afero