diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE new file mode 100644 index 00000000..339177be --- /dev/null +++ b/vendor/github.com/beorn7/perks/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2013 Blake Mizerany + +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. diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go index 587b1fc5..f4cabd66 100644 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ b/vendor/github.com/beorn7/perks/quantile/stream.go @@ -133,7 +133,7 @@ func (s *Stream) Query(q float64) float64 { if l == 0 { return 0 } - i := int(float64(l) * q) + i := int(math.Ceil(float64(l) * q)) if i > 0 { i -= 1 } diff --git a/vendor/github.com/coreos/etcd/client/keys.generated.go b/vendor/github.com/coreos/etcd/client/keys.generated.go index 16f10301..216139c9 100644 --- a/vendor/github.com/coreos/etcd/client/keys.generated.go +++ b/vendor/github.com/coreos/etcd/client/keys.generated.go @@ -8,11 +8,10 @@ package client import ( "errors" "fmt" + codec1978 "github.com/ugorji/go/codec" "reflect" "runtime" time "time" - - codec1978 "github.com/ugorji/go/codec" ) const ( @@ -146,25 +145,25 @@ func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym8 := z.DecBinary() - _ = yym8 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { - yyct9 := r.ContainerType() - if yyct9 == codecSelferValueTypeMap1819 { - yyl9 := r.ReadMapStart() - if yyl9 == 0 { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1819 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerMapEnd1819) } else { - x.codecDecodeSelfFromMap(yyl9, d) + x.codecDecodeSelfFromMap(yyl2, d) } - } else if yyct9 == codecSelferValueTypeArray1819 { - yyl9 := r.ReadArrayStart() - if yyl9 == 0 { + } else if yyct2 == codecSelferValueTypeArray1819 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } else { - x.codecDecodeSelfFromArray(yyl9, d) + x.codecDecodeSelfFromArray(yyl2, d) } } else { panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) @@ -176,12 +175,12 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys10Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys10Slc - var yyhl10 bool = l >= 0 - for yyj10 := 0; ; yyj10++ { - if yyhl10 { - if yyj10 >= l { + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { break } } else { @@ -190,15 +189,21 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } } z.DecSendContainerState(codecSelfer_containerMapKey1819) - yys10Slc = r.DecodeBytes(yys10Slc, true, true) - yys10 := string(yys10Slc) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1819) - switch yys10 { + switch yys3 { case "action": if r.TryDecodeAsNil() { x.Action = "" } else { - x.Action = string(r.DecodeString()) + yyv4 := &x.Action + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + *((*string)(yyv4)) = r.DecodeString() + } } case "node": if r.TryDecodeAsNil() { @@ -223,9 +228,9 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } default: - z.DecStructFieldNotFound(-1, yys10) - } // end switch yys10 - } // end for yyj10 + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 z.DecSendContainerState(codecSelfer_containerMapEnd1819) } @@ -233,16 +238,16 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj14 int - var yyb14 bool - var yyhl14 bool = l >= 0 - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -250,15 +255,21 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Action = "" } else { - x.Action = string(r.DecodeString()) + yyv9 := &x.Action + yym10 := z.DecBinary() + _ = yym10 + if false { + } else { + *((*string)(yyv9)) = r.DecodeString() + } } - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -273,13 +284,13 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Node.CodecDecodeSelf(d) } - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -295,17 +306,17 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } for { - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1819) - z.DecStructFieldNotFound(yyj14-1, "") + z.DecStructFieldNotFound(yyj8-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } @@ -317,36 +328,36 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yym18 := z.EncBinary() - _ = yym18 + yym1 := z.EncBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.EncExt(x) { } else { - yysep19 := !z.EncBinary() - yy2arr19 := z.EncBasicHandle().StructToArray - var yyq19 [8]bool - _, _, _ = yysep19, yyq19, yy2arr19 - const yyr19 bool = false - yyq19[1] = x.Dir != false - yyq19[6] = x.Expiration != nil - yyq19[7] = x.TTL != 0 - var yynn19 int - if yyr19 || yy2arr19 { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [8]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.Dir != false + yyq2[6] = x.Expiration != nil + yyq2[7] = x.TTL != 0 + var yynn2 int + if yyr2 || yy2arr2 { r.EncodeArrayStart(8) } else { - yynn19 = 5 - for _, b := range yyq19 { + yynn2 = 5 + for _, b := range yyq2 { if b { - yynn19++ + yynn2++ } } - r.EncodeMapStart(yynn19) - yynn19 = 0 + r.EncodeMapStart(yynn2) + yynn2 = 0 } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym21 := z.EncBinary() - _ = yym21 + yym4 := z.EncBinary() + _ = yym4 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Key)) @@ -355,18 +366,18 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("key")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym22 := z.EncBinary() - _ = yym22 + yym5 := z.EncBinary() + _ = yym5 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Key)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[1] { - yym24 := z.EncBinary() - _ = yym24 + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 if false { } else { r.EncodeBool(bool(x.Dir)) @@ -375,22 +386,22 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeBool(false) } } else { - if yyq19[1] { + if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("dir")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym25 := z.EncBinary() - _ = yym25 + yym8 := z.EncBinary() + _ = yym8 if false { } else { r.EncodeBool(bool(x.Dir)) } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym27 := z.EncBinary() - _ = yym27 + yym10 := z.EncBinary() + _ = yym10 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Value)) @@ -399,14 +410,14 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("value")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym28 := z.EncBinary() - _ = yym28 + yym11 := z.EncBinary() + _ = yym11 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Value)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) if x.Nodes == nil { r.EncodeNil() @@ -423,10 +434,10 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { x.Nodes.CodecEncodeSelf(e) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym31 := z.EncBinary() - _ = yym31 + yym16 := z.EncBinary() + _ = yym16 if false { } else { r.EncodeUint(uint64(x.CreatedIndex)) @@ -435,17 +446,17 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("createdIndex")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym32 := z.EncBinary() - _ = yym32 + yym17 := z.EncBinary() + _ = yym17 if false { } else { r.EncodeUint(uint64(x.CreatedIndex)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym34 := z.EncBinary() - _ = yym34 + yym19 := z.EncBinary() + _ = yym19 if false { } else { r.EncodeUint(uint64(x.ModifiedIndex)) @@ -454,28 +465,28 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("modifiedIndex")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym35 := z.EncBinary() - _ = yym35 + yym20 := z.EncBinary() + _ = yym20 if false { } else { r.EncodeUint(uint64(x.ModifiedIndex)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[6] { + if yyq2[6] { if x.Expiration == nil { r.EncodeNil() } else { - yym37 := z.EncBinary() - _ = yym37 + yym22 := z.EncBinary() + _ = yym22 if false { - } else if yym38 := z.TimeRtidIfBinc(); yym38 != 0 { - r.EncodeBuiltin(yym38, x.Expiration) + } else if yym23 := z.TimeRtidIfBinc(); yym23 != 0 { + r.EncodeBuiltin(yym23, x.Expiration) } else if z.HasExtensions() && z.EncExt(x.Expiration) { - } else if yym37 { + } else if yym22 { z.EncBinaryMarshal(x.Expiration) - } else if !yym37 && z.IsJSONHandle() { + } else if !yym22 && z.IsJSONHandle() { z.EncJSONMarshal(x.Expiration) } else { z.EncFallback(x.Expiration) @@ -485,22 +496,22 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeNil() } } else { - if yyq19[6] { + if yyq2[6] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("expiration")) z.EncSendContainerState(codecSelfer_containerMapValue1819) if x.Expiration == nil { r.EncodeNil() } else { - yym39 := z.EncBinary() - _ = yym39 + yym24 := z.EncBinary() + _ = yym24 if false { - } else if yym40 := z.TimeRtidIfBinc(); yym40 != 0 { - r.EncodeBuiltin(yym40, x.Expiration) + } else if yym25 := z.TimeRtidIfBinc(); yym25 != 0 { + r.EncodeBuiltin(yym25, x.Expiration) } else if z.HasExtensions() && z.EncExt(x.Expiration) { - } else if yym39 { + } else if yym24 { z.EncBinaryMarshal(x.Expiration) - } else if !yym39 && z.IsJSONHandle() { + } else if !yym24 && z.IsJSONHandle() { z.EncJSONMarshal(x.Expiration) } else { z.EncFallback(x.Expiration) @@ -508,11 +519,11 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[7] { - yym42 := z.EncBinary() - _ = yym42 + if yyq2[7] { + yym27 := z.EncBinary() + _ = yym27 if false { } else { r.EncodeInt(int64(x.TTL)) @@ -521,19 +532,19 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeInt(0) } } else { - if yyq19[7] { + if yyq2[7] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("ttl")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym43 := z.EncBinary() - _ = yym43 + yym28 := z.EncBinary() + _ = yym28 if false { } else { r.EncodeInt(int64(x.TTL)) } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1819) } else { z.EncSendContainerState(codecSelfer_containerMapEnd1819) @@ -546,25 +557,25 @@ func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym44 := z.DecBinary() - _ = yym44 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { - yyct45 := r.ContainerType() - if yyct45 == codecSelferValueTypeMap1819 { - yyl45 := r.ReadMapStart() - if yyl45 == 0 { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1819 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerMapEnd1819) } else { - x.codecDecodeSelfFromMap(yyl45, d) + x.codecDecodeSelfFromMap(yyl2, d) } - } else if yyct45 == codecSelferValueTypeArray1819 { - yyl45 := r.ReadArrayStart() - if yyl45 == 0 { + } else if yyct2 == codecSelferValueTypeArray1819 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } else { - x.codecDecodeSelfFromArray(yyl45, d) + x.codecDecodeSelfFromArray(yyl2, d) } } else { panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) @@ -576,12 +587,12 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys46Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys46Slc - var yyhl46 bool = l >= 0 - for yyj46 := 0; ; yyj46++ { - if yyhl46 { - if yyj46 >= l { + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { break } } else { @@ -590,46 +601,76 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } } z.DecSendContainerState(codecSelfer_containerMapKey1819) - yys46Slc = r.DecodeBytes(yys46Slc, true, true) - yys46 := string(yys46Slc) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1819) - switch yys46 { + switch yys3 { case "key": if r.TryDecodeAsNil() { x.Key = "" } else { - x.Key = string(r.DecodeString()) + yyv4 := &x.Key + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + *((*string)(yyv4)) = r.DecodeString() + } } case "dir": if r.TryDecodeAsNil() { x.Dir = false } else { - x.Dir = bool(r.DecodeBool()) + yyv6 := &x.Dir + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + *((*bool)(yyv6)) = r.DecodeBool() + } } case "value": if r.TryDecodeAsNil() { x.Value = "" } else { - x.Value = string(r.DecodeString()) + yyv8 := &x.Value + yym9 := z.DecBinary() + _ = yym9 + if false { + } else { + *((*string)(yyv8)) = r.DecodeString() + } } case "nodes": if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv50 := &x.Nodes - yyv50.CodecDecodeSelf(d) + yyv10 := &x.Nodes + yyv10.CodecDecodeSelf(d) } case "createdIndex": if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { - x.CreatedIndex = uint64(r.DecodeUint(64)) + yyv11 := &x.CreatedIndex + yym12 := z.DecBinary() + _ = yym12 + if false { + } else { + *((*uint64)(yyv11)) = uint64(r.DecodeUint(64)) + } } case "modifiedIndex": if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { - x.ModifiedIndex = uint64(r.DecodeUint(64)) + yyv13 := &x.ModifiedIndex + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + *((*uint64)(yyv13)) = uint64(r.DecodeUint(64)) + } } case "expiration": if r.TryDecodeAsNil() { @@ -640,15 +681,15 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - yym54 := z.DecBinary() - _ = yym54 + yym16 := z.DecBinary() + _ = yym16 if false { - } else if yym55 := z.TimeRtidIfBinc(); yym55 != 0 { - r.DecodeBuiltin(yym55, x.Expiration) + } else if yym17 := z.TimeRtidIfBinc(); yym17 != 0 { + r.DecodeBuiltin(yym17, x.Expiration) } else if z.HasExtensions() && z.DecExt(x.Expiration) { - } else if yym54 { + } else if yym16 { z.DecBinaryUnmarshal(x.Expiration) - } else if !yym54 && z.IsJSONHandle() { + } else if !yym16 && z.IsJSONHandle() { z.DecJSONUnmarshal(x.Expiration) } else { z.DecFallback(x.Expiration, false) @@ -658,12 +699,18 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.TTL = 0 } else { - x.TTL = int64(r.DecodeInt(64)) + yyv18 := &x.TTL + yym19 := z.DecBinary() + _ = yym19 + if false { + } else { + *((*int64)(yyv18)) = int64(r.DecodeInt(64)) + } } default: - z.DecStructFieldNotFound(-1, yys46) - } // end switch yys46 - } // end for yyj46 + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 z.DecSendContainerState(codecSelfer_containerMapEnd1819) } @@ -671,16 +718,16 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj57 int - var yyb57 bool - var yyhl57 bool = l >= 0 - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + var yyj20 int + var yyb20 bool + var yyhl20 bool = l >= 0 + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -688,15 +735,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Key = "" } else { - x.Key = string(r.DecodeString()) + yyv21 := &x.Key + yym22 := z.DecBinary() + _ = yym22 + if false { + } else { + *((*string)(yyv21)) = r.DecodeString() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -704,15 +757,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Dir = false } else { - x.Dir = bool(r.DecodeBool()) + yyv23 := &x.Dir + yym24 := z.DecBinary() + _ = yym24 + if false { + } else { + *((*bool)(yyv23)) = r.DecodeBool() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -720,15 +779,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Value = "" } else { - x.Value = string(r.DecodeString()) + yyv25 := &x.Value + yym26 := z.DecBinary() + _ = yym26 + if false { + } else { + *((*string)(yyv25)) = r.DecodeString() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -736,16 +801,16 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv61 := &x.Nodes - yyv61.CodecDecodeSelf(d) + yyv27 := &x.Nodes + yyv27.CodecDecodeSelf(d) } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -753,15 +818,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { - x.CreatedIndex = uint64(r.DecodeUint(64)) + yyv28 := &x.CreatedIndex + yym29 := z.DecBinary() + _ = yym29 + if false { + } else { + *((*uint64)(yyv28)) = uint64(r.DecodeUint(64)) + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -769,15 +840,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { - x.ModifiedIndex = uint64(r.DecodeUint(64)) + yyv30 := &x.ModifiedIndex + yym31 := z.DecBinary() + _ = yym31 + if false { + } else { + *((*uint64)(yyv30)) = uint64(r.DecodeUint(64)) + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -790,27 +867,27 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - yym65 := z.DecBinary() - _ = yym65 + yym33 := z.DecBinary() + _ = yym33 if false { - } else if yym66 := z.TimeRtidIfBinc(); yym66 != 0 { - r.DecodeBuiltin(yym66, x.Expiration) + } else if yym34 := z.TimeRtidIfBinc(); yym34 != 0 { + r.DecodeBuiltin(yym34, x.Expiration) } else if z.HasExtensions() && z.DecExt(x.Expiration) { - } else if yym65 { + } else if yym33 { z.DecBinaryUnmarshal(x.Expiration) - } else if !yym65 && z.IsJSONHandle() { + } else if !yym33 && z.IsJSONHandle() { z.DecJSONUnmarshal(x.Expiration) } else { z.DecFallback(x.Expiration, false) } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -818,20 +895,26 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.TTL = 0 } else { - x.TTL = int64(r.DecodeInt(64)) + yyv35 := &x.TTL + yym36 := z.DecBinary() + _ = yym36 + if false { + } else { + *((*int64)(yyv35)) = int64(r.DecodeInt(64)) + } } for { - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1819) - z.DecStructFieldNotFound(yyj57-1, "") + z.DecStructFieldNotFound(yyj20-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } @@ -843,8 +926,8 @@ func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yym68 := z.EncBinary() - _ = yym68 + yym1 := z.EncBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.EncExt(x) { } else { @@ -857,8 +940,8 @@ func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym69 := z.DecBinary() - _ = yym69 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { @@ -871,12 +954,12 @@ func (x codecSelfer1819) encNodes(v Nodes, e *codec1978.Encoder) { z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r r.EncodeArrayStart(len(v)) - for _, yyv70 := range v { + for _, yyv1 := range v { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyv70 == nil { + if yyv1 == nil { r.EncodeNil() } else { - yyv70.CodecEncodeSelf(e) + yyv1.CodecEncodeSelf(e) } } z.EncSendContainerState(codecSelfer_containerArrayEnd1819) @@ -887,98 +970,101 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yyv71 := *v - yyh71, yyl71 := z.DecSliceHelperStart() - var yyc71 bool - if yyl71 == 0 { - if yyv71 == nil { - yyv71 = []*Node{} - yyc71 = true - } else if len(yyv71) != 0 { - yyv71 = yyv71[:0] - yyc71 = true + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []*Node{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true } - } else if yyl71 > 0 { - var yyrr71, yyrl71 int - var yyrt71 bool - if yyl71 > cap(yyv71) { + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { - yyrg71 := len(yyv71) > 0 - yyv271 := yyv71 - yyrl71, yyrt71 = z.DecInferLen(yyl71, z.DecBasicHandle().MaxInitLen, 8) - if yyrt71 { - if yyrl71 <= cap(yyv71) { - yyv71 = yyv71[:yyrl71] + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] } else { - yyv71 = make([]*Node, yyrl71) + yyv1 = make([]*Node, yyrl1) } } else { - yyv71 = make([]*Node, yyrl71) + yyv1 = make([]*Node, yyrl1) } - yyc71 = true - yyrr71 = len(yyv71) - if yyrg71 { - copy(yyv71, yyv271) + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) } - } else if yyl71 != len(yyv71) { - yyv71 = yyv71[:yyl71] - yyc71 = true + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true } - yyj71 := 0 - for ; yyj71 < yyrr71; yyj71++ { - yyh71.ElemContainerState(yyj71) + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw72 := yyv71[yyj71] - yyw72.CodecDecodeSelf(d) + yyw2 := yyv1[yyj1] + yyw2.CodecDecodeSelf(d) } } - if yyrt71 { - for ; yyj71 < yyl71; yyj71++ { - yyv71 = append(yyv71, nil) - yyh71.ElemContainerState(yyj71) + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, nil) + yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw73 := yyv71[yyj71] - yyw73.CodecDecodeSelf(d) + yyw3 := yyv1[yyj1] + yyw3.CodecDecodeSelf(d) } } } } else { - yyj71 := 0 - for ; !r.CheckBreak(); yyj71++ { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { - if yyj71 >= len(yyv71) { - yyv71 = append(yyv71, nil) // var yyz71 *Node - yyc71 = true + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, nil) // var yyz1 *Node + yyc1 = true } - yyh71.ElemContainerState(yyj71) - if yyj71 < len(yyv71) { + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw74 := yyv71[yyj71] - yyw74.CodecDecodeSelf(d) + yyw4 := yyv1[yyj1] + yyw4.CodecDecodeSelf(d) } } else { @@ -986,16 +1072,16 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { } } - if yyj71 < len(yyv71) { - yyv71 = yyv71[:yyj71] - yyc71 = true - } else if yyj71 == 0 && yyv71 == nil { - yyv71 = []*Node{} - yyc71 = true + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []*Node{} + yyc1 = true } } - yyh71.End() - if yyc71 { - *v = yyv71 + yyh1.End() + if yyc1 { + *v = yyv1 } } diff --git a/vendor/github.com/coreos/etcd/clientv3/client.go b/vendor/github.com/coreos/etcd/clientv3/client.go index a0c3f3c2..44494cbe 100644 --- a/vendor/github.com/coreos/etcd/clientv3/client.go +++ b/vendor/github.com/coreos/etcd/clientv3/client.go @@ -97,7 +97,12 @@ func (c *Client) Close() error { func (c *Client) Ctx() context.Context { return c.ctx } // Endpoints lists the registered endpoints for the client. -func (c *Client) Endpoints() []string { return c.cfg.Endpoints } +func (c *Client) Endpoints() (eps []string) { + // copy the slice; protect original endpoints from being changed + eps = make([]string, len(c.cfg.Endpoints)) + copy(eps, c.cfg.Endpoints) + return +} // SetEndpoints updates client's endpoints. func (c *Client) SetEndpoints(eps ...string) { diff --git a/vendor/github.com/dustin/go-humanize/bigbytes.go b/vendor/github.com/dustin/go-humanize/bigbytes.go index 67ea5c82..d4fb3714 100644 --- a/vendor/github.com/dustin/go-humanize/bigbytes.go +++ b/vendor/github.com/dustin/go-humanize/bigbytes.go @@ -138,15 +138,24 @@ func BigIBytes(s *big.Int) string { // ParseBigBytes("42mib") -> 44040192, nil func ParseBigBytes(s string) (*big.Int, error) { lastDigit := 0 + hasComma := false for _, r := range s { - if !(unicode.IsDigit(r) || r == '.') { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { break } + if r == ',' { + hasComma = true + } lastDigit++ } + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + val := &big.Rat{} - _, err := fmt.Sscanf(s[:lastDigit], "%f", val) + _, err := fmt.Sscanf(num, "%f", val) if err != nil { return nil, err } diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go index dacbb9c1..190ab65f 100644 --- a/vendor/github.com/dustin/go-humanize/bytes.go +++ b/vendor/github.com/dustin/go-humanize/bytes.go @@ -109,14 +109,23 @@ func IBytes(s uint64) string { // ParseBytes("42mib") -> 44040192, nil func ParseBytes(s string) (uint64, error) { lastDigit := 0 + hasComma := false for _, r := range s { - if !(unicode.IsDigit(r) || r == '.') { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { break } + if r == ',' { + hasComma = true + } lastDigit++ } - f, err := strconv.ParseFloat(s[:lastDigit], 64) + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + f, err := strconv.ParseFloat(num, 64) if err != nil { return 0, err } diff --git a/vendor/github.com/dustin/go-humanize/comma.go b/vendor/github.com/dustin/go-humanize/comma.go index b65ea6fa..74f446b6 100644 --- a/vendor/github.com/dustin/go-humanize/comma.go +++ b/vendor/github.com/dustin/go-humanize/comma.go @@ -39,7 +39,7 @@ func Comma(v int64) string { // Commaf produces a string form of the given number in base 10 with // commas after every three orders of magnitude. // -// e.g. Comma(834142.32) -> 834,142.32 +// e.g. Commaf(834142.32) -> 834,142.32 func Commaf(v float64) string { buf := &bytes.Buffer{} if v < 0 { diff --git a/vendor/github.com/dustin/go-humanize/commaf.go b/vendor/github.com/dustin/go-humanize/commaf.go new file mode 100644 index 00000000..620690de --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/commaf.go @@ -0,0 +1,40 @@ +// +build go1.6 + +package humanize + +import ( + "bytes" + "math/big" + "strings" +) + +// BigCommaf produces a string form of the given big.Float in base 10 +// with commas after every three orders of magnitude. +func BigCommaf(v *big.Float) string { + buf := &bytes.Buffer{} + if v.Sign() < 0 { + buf.Write([]byte{'-'}) + v.Abs(v) + } + + comma := []byte{','} + + parts := strings.Split(v.Text('f', -1), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go index fe86fe55..9cce4e8d 100644 --- a/vendor/github.com/dustin/go-humanize/si.go +++ b/vendor/github.com/dustin/go-humanize/si.go @@ -41,7 +41,7 @@ func revfmap(in map[float64]string) map[string]float64 { var riParseRegex *regexp.Regexp func init() { - ri := `^([0-9.]+)\s?([` + ri := `^([\-0-9.]+)\s?([` for _, v := range siPrefixTable { ri += v } @@ -61,18 +61,21 @@ func ComputeSI(input float64) (float64, string) { if input == 0 { return 0, "" } - exponent := math.Floor(logn(input, 10)) + mag := math.Abs(input) + exponent := math.Floor(logn(mag, 10)) exponent = math.Floor(exponent/3) * 3 - value := input / math.Pow(10, exponent) + value := mag / math.Pow(10, exponent) // Handle special case where value is exactly 1000.0 // Should return 1M instead of 1000k if value == 1000.0 { exponent += 3 - value = input / math.Pow(10, exponent) + value = mag / math.Pow(10, exponent) } + value = math.Copysign(value, input) + prefix := siPrefixTable[exponent] return value, prefix } diff --git a/vendor/github.com/dustin/go-humanize/times.go b/vendor/github.com/dustin/go-humanize/times.go index 592ebe1d..b311f11c 100644 --- a/vendor/github.com/dustin/go-humanize/times.go +++ b/vendor/github.com/dustin/go-humanize/times.go @@ -9,9 +9,7 @@ import ( // Seconds-based time units const ( - Minute = 60 - Hour = 60 * Minute - Day = 24 * Hour + Day = 24 * time.Hour Week = 7 * Day Month = 30 * Day Year = 12 * Month @@ -25,18 +23,35 @@ func Time(then time.Time) string { return RelTime(then, time.Now(), "ago", "from now") } -var magnitudes = []struct { - d int64 - format string - divby int64 -}{ - {1, "now", 1}, - {2, "1 second %s", 1}, - {Minute, "%d seconds %s", 1}, - {2 * Minute, "1 minute %s", 1}, - {Hour, "%d minutes %s", Minute}, - {2 * Hour, "1 hour %s", 1}, - {Day, "%d hours %s", Hour}, +// A RelTimeMagnitude struct contains a relative time point at which +// the relative format of time will switch to a new format string. A +// slice of these in ascending order by their "D" field is passed to +// CustomRelTime to format durations. +// +// The Format field is a string that may contain a "%s" which will be +// replaced with the appropriate signed label (e.g. "ago" or "from +// now") and a "%d" that will be replaced by the quantity. +// +// The DivBy field is the amount of time the time difference must be +// divided by in order to display correctly. +// +// e.g. if D is 2*time.Minute and you want to display "%d minutes %s" +// DivBy should be time.Minute so whatever the duration is will be +// expressed in minutes. +type RelTimeMagnitude struct { + D time.Duration + Format string + DivBy time.Duration +} + +var defaultMagnitudes = []RelTimeMagnitude{ + {time.Second, "now", time.Second}, + {2 * time.Second, "1 second %s", 1}, + {time.Minute, "%d seconds %s", time.Second}, + {2 * time.Minute, "1 minute %s", 1}, + {time.Hour, "%d minutes %s", time.Minute}, + {2 * time.Hour, "1 hour %s", 1}, + {Day, "%d hours %s", time.Hour}, {2 * Day, "1 day %s", 1}, {Week, "%d days %s", Day}, {2 * Week, "1 week %s", 1}, @@ -57,35 +72,46 @@ var magnitudes = []struct { // // RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier" func RelTime(a, b time.Time, albl, blbl string) string { - lbl := albl - diff := b.Unix() - a.Unix() + return CustomRelTime(a, b, albl, blbl, defaultMagnitudes) +} - after := a.After(b) - if after { +// CustomRelTime formats a time into a relative string. +// +// It takes two times two labels and a table of relative time formats. +// In addition to the generic time delta string (e.g. 5 minutes), the +// labels are used applied so that the label corresponding to the +// smaller time is applied. +func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string { + lbl := albl + diff := b.Sub(a) + + if a.After(b) { lbl = blbl - diff = a.Unix() - b.Unix() + diff = a.Sub(b) } n := sort.Search(len(magnitudes), func(i int) bool { - return magnitudes[i].d > diff + return magnitudes[i].D >= diff }) + if n >= len(magnitudes) { + n = len(magnitudes) - 1 + } mag := magnitudes[n] args := []interface{}{} escaped := false - for _, ch := range mag.format { + for _, ch := range mag.Format { if escaped { switch ch { - case '%': case 's': args = append(args, lbl) case 'd': - args = append(args, diff/mag.divby) + args = append(args, diff/mag.DivBy) } escaped = false } else { escaped = ch == '%' } } - return fmt.Sprintf(mag.format, args...) + return fmt.Sprintf(mag.Format, args...) } diff --git a/vendor/github.com/hashicorp/consul/api/agent.go b/vendor/github.com/hashicorp/consul/api/agent.go index 41d8bc0b..1893d1cf 100644 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ b/vendor/github.com/hashicorp/consul/api/agent.go @@ -1,6 +1,7 @@ package api import ( + "bufio" "fmt" ) @@ -73,7 +74,8 @@ type AgentServiceCheck struct { HTTP string `json:",omitempty"` TCP string `json:",omitempty"` Status string `json:",omitempty"` - TLSSkipVerify string `json:",omitempty"` + Notes string `json:",omitempty"` + TLSSkipVerify bool `json:",omitempty"` // In Consul 0.7 and later, checks that are associated with a service // may also contain this optional DeregisterCriticalServiceAfter field, @@ -115,6 +117,17 @@ func (a *Agent) Self() (map[string]map[string]interface{}, error) { return out, nil } +// Reload triggers a configuration reload for the agent we are connected to. +func (a *Agent) Reload() error { + r := a.c.newRequest("PUT", "/v1/agent/reload") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + // NodeName is used to get the node name of the agent func (a *Agent) NodeName() (string, error) { if a.nodeName != "" { @@ -346,6 +359,17 @@ func (a *Agent) Join(addr string, wan bool) error { return nil } +// Leave is used to have the agent gracefully leave the cluster and shutdown +func (a *Agent) Leave() error { + r := a.c.newRequest("PUT", "/v1/agent/leave") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + // ForceLeave is used to have the agent eject a failed node func (a *Agent) ForceLeave(node string) error { r := a.c.newRequest("PUT", "/v1/agent/force-leave/"+node) @@ -410,3 +434,38 @@ func (a *Agent) DisableNodeMaintenance() error { resp.Body.Close() return nil } + +// Monitor returns a channel which will receive streaming logs from the agent +// Providing a non-nil stopCh can be used to close the connection and stop the +// log stream +func (a *Agent) Monitor(loglevel string, stopCh chan struct{}, q *QueryOptions) (chan string, error) { + r := a.c.newRequest("GET", "/v1/agent/monitor") + r.setQueryOptions(q) + if loglevel != "" { + r.params.Add("loglevel", loglevel) + } + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + + logCh := make(chan string, 64) + go func() { + defer resp.Body.Close() + + scanner := bufio.NewScanner(resp.Body) + for { + select { + case <-stopCh: + close(logCh) + return + default: + } + if scanner.Scan() { + logCh <- scanner.Text() + } + } + }() + + return logCh, nil +} diff --git a/vendor/github.com/hashicorp/consul/api/api.go b/vendor/github.com/hashicorp/consul/api/api.go index dd811fde..9587043a 100644 --- a/vendor/github.com/hashicorp/consul/api/api.go +++ b/vendor/github.com/hashicorp/consul/api/api.go @@ -20,6 +20,28 @@ import ( "github.com/hashicorp/go-cleanhttp" ) +const ( + // HTTPAddrEnvName defines an environment variable name which sets + // the HTTP address if there is no -http-addr specified. + HTTPAddrEnvName = "CONSUL_HTTP_ADDR" + + // HTTPTokenEnvName defines an environment variable name which sets + // the HTTP token. + HTTPTokenEnvName = "CONSUL_HTTP_TOKEN" + + // HTTPAuthEnvName defines an environment variable name which sets + // the HTTP authentication header. + HTTPAuthEnvName = "CONSUL_HTTP_AUTH" + + // HTTPSSLEnvName defines an environment variable name which sets + // whether or not to use HTTPS. + HTTPSSLEnvName = "CONSUL_HTTP_SSL" + + // HTTPSSLVerifyEnvName defines an environment variable name which sets + // whether or not to disable certificate checking. + HTTPSSLVerifyEnvName = "CONSUL_HTTP_SSL_VERIFY" +) + // QueryOptions are used to parameterize a query type QueryOptions struct { // Providing a datacenter overwrites the DC provided @@ -181,15 +203,15 @@ func defaultConfig(transportFn func() *http.Transport) *Config { }, } - if addr := os.Getenv("CONSUL_HTTP_ADDR"); addr != "" { + if addr := os.Getenv(HTTPAddrEnvName); addr != "" { config.Address = addr } - if token := os.Getenv("CONSUL_HTTP_TOKEN"); token != "" { + if token := os.Getenv(HTTPTokenEnvName); token != "" { config.Token = token } - if auth := os.Getenv("CONSUL_HTTP_AUTH"); auth != "" { + if auth := os.Getenv(HTTPAuthEnvName); auth != "" { var username, password string if strings.Contains(auth, ":") { split := strings.SplitN(auth, ":", 2) @@ -205,10 +227,10 @@ func defaultConfig(transportFn func() *http.Transport) *Config { } } - if ssl := os.Getenv("CONSUL_HTTP_SSL"); ssl != "" { + if ssl := os.Getenv(HTTPSSLEnvName); ssl != "" { enabled, err := strconv.ParseBool(ssl) if err != nil { - log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL: %s", err) + log.Printf("[WARN] client: could not parse %s: %s", HTTPSSLEnvName, err) } if enabled { @@ -216,10 +238,10 @@ func defaultConfig(transportFn func() *http.Transport) *Config { } } - if verify := os.Getenv("CONSUL_HTTP_SSL_VERIFY"); verify != "" { + if verify := os.Getenv(HTTPSSLVerifyEnvName); verify != "" { doVerify, err := strconv.ParseBool(verify) if err != nil { - log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL_VERIFY: %s", err) + log.Printf("[WARN] client: could not parse %s: %s", HTTPSSLVerifyEnvName, err) } if !doVerify { diff --git a/vendor/github.com/hashicorp/consul/api/catalog.go b/vendor/github.com/hashicorp/consul/api/catalog.go index 337772ec..56f0dbf6 100644 --- a/vendor/github.com/hashicorp/consul/api/catalog.go +++ b/vendor/github.com/hashicorp/consul/api/catalog.go @@ -16,6 +16,8 @@ type CatalogService struct { ServiceTags []string ServicePort int ServiceEnableTagOverride bool + CreateIndex uint64 + ModifyIndex uint64 } type CatalogNode struct { diff --git a/vendor/github.com/hashicorp/consul/api/health.go b/vendor/github.com/hashicorp/consul/api/health.go index 74da949c..8abe2393 100644 --- a/vendor/github.com/hashicorp/consul/api/health.go +++ b/vendor/github.com/hashicorp/consul/api/health.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "strings" ) const ( @@ -11,6 +12,15 @@ const ( HealthPassing = "passing" HealthWarning = "warning" HealthCritical = "critical" + HealthMaint = "maintenance" +) + +const ( + // NodeMaint is the special key set by a node in maintenance mode. + NodeMaint = "_node_maintenance" + + // ServiceMaintPrefix is the prefix for a service in maintenance mode. + ServiceMaintPrefix = "_service_maintenance:" ) // HealthCheck is used to represent a single check @@ -25,11 +35,56 @@ type HealthCheck struct { ServiceName string } +// HealthChecks is a collection of HealthCheck structs. +type HealthChecks []*HealthCheck + +// AggregatedStatus returns the "best" status for the list of health checks. +// Because a given entry may have many service and node-level health checks +// attached, this function determines the best representative of the status as +// as single string using the following heuristic: +// +// maintenance > critical > warning > passing +// +func (c HealthChecks) AggregatedStatus() string { + var passing, warning, critical, maintenance bool + for _, check := range c { + id := string(check.CheckID) + if id == NodeMaint || strings.HasPrefix(id, ServiceMaintPrefix) { + maintenance = true + continue + } + + switch check.Status { + case HealthPassing: + passing = true + case HealthWarning: + warning = true + case HealthCritical: + critical = true + default: + return "" + } + } + + switch { + case maintenance: + return HealthMaint + case critical: + return HealthCritical + case warning: + return HealthWarning + case passing: + return HealthPassing + default: + return HealthPassing + } +} + // ServiceEntry is used for the health service endpoint type ServiceEntry struct { Node *Node Service *AgentService - Checks []*HealthCheck + Checks HealthChecks } // Health can be used to query the Health endpoints @@ -43,7 +98,7 @@ func (c *Client) Health() *Health { } // Node is used to query for checks belonging to a given node -func (h *Health) Node(node string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { +func (h *Health) Node(node string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { r := h.c.newRequest("GET", "/v1/health/node/"+node) r.setQueryOptions(q) rtt, resp, err := requireOK(h.c.doRequest(r)) @@ -56,7 +111,7 @@ func (h *Health) Node(node string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, parseQueryMeta(resp, qm) qm.RequestTime = rtt - var out []*HealthCheck + var out HealthChecks if err := decodeBody(resp, &out); err != nil { return nil, nil, err } @@ -64,7 +119,7 @@ func (h *Health) Node(node string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, } // Checks is used to return the checks associated with a service -func (h *Health) Checks(service string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { +func (h *Health) Checks(service string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { r := h.c.newRequest("GET", "/v1/health/checks/"+service) r.setQueryOptions(q) rtt, resp, err := requireOK(h.c.doRequest(r)) @@ -77,7 +132,7 @@ func (h *Health) Checks(service string, q *QueryOptions) ([]*HealthCheck, *Query parseQueryMeta(resp, qm) qm.RequestTime = rtt - var out []*HealthCheck + var out HealthChecks if err := decodeBody(resp, &out); err != nil { return nil, nil, err } @@ -115,7 +170,7 @@ func (h *Health) Service(service, tag string, passingOnly bool, q *QueryOptions) // State is used to retrieve all the checks in a given state. // The wildcard "any" state can also be used for all checks. -func (h *Health) State(state string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { +func (h *Health) State(state string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { switch state { case HealthAny: case HealthWarning: @@ -136,7 +191,7 @@ func (h *Health) State(state string, q *QueryOptions) ([]*HealthCheck, *QueryMet parseQueryMeta(resp, qm) qm.RequestTime = rtt - var out []*HealthCheck + var out HealthChecks if err := decodeBody(resp, &out); err != nil { return nil, nil, err } diff --git a/vendor/github.com/hashicorp/consul/api/kv.go b/vendor/github.com/hashicorp/consul/api/kv.go index 86759249..44e06bbb 100644 --- a/vendor/github.com/hashicorp/consul/api/kv.go +++ b/vendor/github.com/hashicorp/consul/api/kv.go @@ -50,21 +50,21 @@ type KVOp string const ( KVSet KVOp = "set" - KVDelete = "delete" - KVDeleteCAS = "delete-cas" - KVDeleteTree = "delete-tree" - KVCAS = "cas" - KVLock = "lock" - KVUnlock = "unlock" - KVGet = "get" - KVGetTree = "get-tree" - KVCheckSession = "check-session" - KVCheckIndex = "check-index" + KVDelete KVOp = "delete" + KVDeleteCAS KVOp = "delete-cas" + KVDeleteTree KVOp = "delete-tree" + KVCAS KVOp = "cas" + KVLock KVOp = "lock" + KVUnlock KVOp = "unlock" + KVGet KVOp = "get" + KVGetTree KVOp = "get-tree" + KVCheckSession KVOp = "check-session" + KVCheckIndex KVOp = "check-index" ) // KVTxnOp defines a single operation inside a transaction. type KVTxnOp struct { - Verb string + Verb KVOp Key string Value []byte Flags uint64 diff --git a/vendor/github.com/hashicorp/consul/api/operator.go b/vendor/github.com/hashicorp/consul/api/operator.go index 48d74f3c..a8d04a38 100644 --- a/vendor/github.com/hashicorp/consul/api/operator.go +++ b/vendor/github.com/hashicorp/consul/api/operator.go @@ -43,6 +43,26 @@ type RaftConfiguration struct { Index uint64 } +// keyringRequest is used for performing Keyring operations +type keyringRequest struct { + Key string +} + +// KeyringResponse is returned when listing the gossip encryption keys +type KeyringResponse struct { + // Whether this response is for a WAN ring + WAN bool + + // The datacenter name this request corresponds to + Datacenter string + + // A map of the encryption keys to the number of nodes they're installed on + Keys map[string]int + + // The total number of nodes in this ring + NumNodes int +} + // RaftGetConfiguration is used to query the current Raft peer set. func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, error) { r := op.c.newRequest("GET", "/v1/operator/raft/configuration") @@ -79,3 +99,65 @@ func (op *Operator) RaftRemovePeerByAddress(address string, q *WriteOptions) err resp.Body.Close() return nil } + +// KeyringInstall is used to install a new gossip encryption key into the cluster +func (op *Operator) KeyringInstall(key string, q *WriteOptions) error { + r := op.c.newRequest("POST", "/v1/operator/keyring") + r.setWriteOptions(q) + r.obj = keyringRequest{ + Key: key, + } + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// KeyringList is used to list the gossip keys installed in the cluster +func (op *Operator) KeyringList(q *QueryOptions) ([]*KeyringResponse, error) { + r := op.c.newRequest("GET", "/v1/operator/keyring") + r.setQueryOptions(q) + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out []*KeyringResponse + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// KeyringRemove is used to remove a gossip encryption key from the cluster +func (op *Operator) KeyringRemove(key string, q *WriteOptions) error { + r := op.c.newRequest("DELETE", "/v1/operator/keyring") + r.setWriteOptions(q) + r.obj = keyringRequest{ + Key: key, + } + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// KeyringUse is used to change the active gossip encryption key +func (op *Operator) KeyringUse(key string, q *WriteOptions) error { + r := op.c.newRequest("PUT", "/v1/operator/keyring") + r.setWriteOptions(q) + r.obj = keyringRequest{ + Key: key, + } + _, resp, err := requireOK(op.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/flattener.go b/vendor/github.com/llgcode/draw2d/draw2dbase/flattener.go index 986c7ab2..c62d1bce 100644 --- a/vendor/github.com/llgcode/draw2d/draw2dbase/flattener.go +++ b/vendor/github.com/llgcode/draw2d/draw2dbase/flattener.go @@ -19,7 +19,7 @@ type Flattener interface { MoveTo(x, y float64) // LineTo Draw a line from the current position to the point (x, y) LineTo(x, y float64) - // LineJoin add the most recent starting point to close the path to create a polygon + // LineJoin use Round, Bevel or miter to join points LineJoin() // Close add the most recent starting point to close the path to create a polygon Close() diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/stack_gc.go b/vendor/github.com/llgcode/draw2d/draw2dbase/stack_gc.go index 12723c7f..77622bb2 100644 --- a/vendor/github.com/llgcode/draw2d/draw2dbase/stack_gc.go +++ b/vendor/github.com/llgcode/draw2d/draw2dbase/stack_gc.go @@ -4,6 +4,7 @@ package draw2dbase import ( + "fmt" "image" "image/color" @@ -132,6 +133,10 @@ func (gc *StackGraphicContext) BeginPath() { gc.Current.Path.Clear() } +func (gc *StackGraphicContext) GetPath() draw2d.Path { + return *gc.Current.Path.Copy() +} + func (gc *StackGraphicContext) IsEmpty() bool { return gc.Current.Path.IsEmpty() } @@ -191,3 +196,8 @@ func (gc *StackGraphicContext) Restore() { oldContext.Previous = nil } } + +func (gc *StackGraphicContext) GetFontName() string { + fontData := gc.Current.FontData + return fmt.Sprintf("%s:%d:%d:%d", fontData.Name, fontData.Family, fontData.Style, gc.Current.FontSize) +} diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/text.go b/vendor/github.com/llgcode/draw2d/draw2dbase/text.go new file mode 100644 index 00000000..4283bad7 --- /dev/null +++ b/vendor/github.com/llgcode/draw2d/draw2dbase/text.go @@ -0,0 +1,68 @@ +package draw2dbase + +import "github.com/llgcode/draw2d" + +var glyphCache map[string]map[rune]*Glyph + +func init() { + glyphCache = make(map[string]map[rune]*Glyph) +} + +// FetchGlyph fetches a glyph from the cache, calling renderGlyph first if it doesn't already exist +func FetchGlyph(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph { + if glyphCache[fontName] == nil { + glyphCache[fontName] = make(map[rune]*Glyph, 60) + } + if glyphCache[fontName][chr] == nil { + glyphCache[fontName][chr] = renderGlyph(gc, fontName, chr) + } + return glyphCache[fontName][chr].Copy() +} + +// renderGlyph renders a glyph then caches and returns it +func renderGlyph(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph { + gc.Save() + defer gc.Restore() + gc.BeginPath() + width := gc.CreateStringPath(string(chr), 0, 0) + path := gc.GetPath() + return &Glyph{ + path: &path, + Width: width, + } +} + +// Glyph represents a rune which has been converted to a Path and width +type Glyph struct { + // path represents a glyph, it is always at (0, 0) + path *draw2d.Path + // Width of the glyph + Width float64 +} + +func (g *Glyph) Copy() *Glyph { + return &Glyph{ + path: g.path.Copy(), + Width: g.Width, + } +} + +// Fill copies a glyph from the cache, and fills it +func (g *Glyph) Fill(gc draw2d.GraphicContext, x, y float64) float64 { + gc.Save() + gc.BeginPath() + gc.Translate(x, y) + gc.Fill(g.path) + gc.Restore() + return g.Width +} + +// Stroke fetches a glyph from the cache, and strokes it +func (g *Glyph) Stroke(gc draw2d.GraphicContext, x, y float64) float64 { + gc.Save() + gc.BeginPath() + gc.Translate(x, y) + gc.Stroke(g.path) + gc.Restore() + return g.Width +} diff --git a/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go b/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go index 8bedf919..abaf7e50 100644 --- a/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go +++ b/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go @@ -117,27 +117,57 @@ func (gc *GraphicContext) DrawImage(img image.Image) { } // FillString draws the text at point (0, 0) -func (gc *GraphicContext) FillString(text string) (cursor float64) { +func (gc *GraphicContext) FillString(text string) (width float64) { return gc.FillStringAt(text, 0, 0) } // FillStringAt draws the text at the specified point (x, y) -func (gc *GraphicContext) FillStringAt(text string, x, y float64) (cursor float64) { - width := gc.CreateStringPath(text, x, y) - gc.Fill() - return width +func (gc *GraphicContext) FillStringAt(text string, x, y float64) (width float64) { + f, err := gc.loadCurrentFont() + if err != nil { + log.Println(err) + return 0.0 + } + startx := x + prev, hasPrev := truetype.Index(0), false + fontName := gc.GetFontName() + for _, r := range text { + index := f.Index(r) + if hasPrev { + x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index)) + } + glyph := draw2dbase.FetchGlyph(gc, fontName, r) + x += glyph.Fill(gc, x, y) + prev, hasPrev = index, true + } + return x - startx } // StrokeString draws the contour of the text at point (0, 0) -func (gc *GraphicContext) StrokeString(text string) (cursor float64) { +func (gc *GraphicContext) StrokeString(text string) (width float64) { return gc.StrokeStringAt(text, 0, 0) } // StrokeStringAt draws the contour of the text at point (x, y) -func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (cursor float64) { - width := gc.CreateStringPath(text, x, y) - gc.Stroke() - return width +func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (width float64) { + f, err := gc.loadCurrentFont() + if err != nil { + log.Println(err) + return 0.0 + } + startx := x + prev, hasPrev := truetype.Index(0), false + fontName := gc.GetFontName() + for _, r := range text { + index := f.Index(r) + if hasPrev { + x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index)) + } + glyph := draw2dbase.FetchGlyph(gc, fontName, r) + x += glyph.Stroke(gc, x, y) + prev, hasPrev = index, true + } + return x - startx } func (gc *GraphicContext) loadCurrentFont() (*truetype.Font, error) { diff --git a/vendor/github.com/llgcode/draw2d/gc.go b/vendor/github.com/llgcode/draw2d/gc.go index 6266c16f..543359e7 100644 --- a/vendor/github.com/llgcode/draw2d/gc.go +++ b/vendor/github.com/llgcode/draw2d/gc.go @@ -14,6 +14,8 @@ type GraphicContext interface { PathBuilder // BeginPath creates a new path BeginPath() + // GetPath copies the current path, then returns it + GetPath() Path // GetMatrixTransform returns the current transformation matrix GetMatrixTransform() Matrix // SetMatrixTransform sets the current transformation matrix @@ -48,6 +50,8 @@ type GraphicContext interface { SetFontData(fontData FontData) // GetFontData gets the current FontData GetFontData() FontData + // GetFontName gets the current FontData as a string + GetFontName() string // DrawImage draws the raster image in the current canvas DrawImage(image image.Image) // Save the context and push it to the context stack diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 00000000..91b5cef3 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +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. diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go index 3fbf33d5..3e730656 100644 --- a/vendor/github.com/mattn/go-runewidth/runewidth.go +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -1,7 +1,12 @@ package runewidth -var EastAsianWidth = IsEastAsian() -var DefaultCondition = &Condition{EastAsianWidth} +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth = IsEastAsian() + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{EastAsianWidth} +) type interval struct { first rune @@ -302,10 +307,12 @@ var ctypes = []intervalType{ {0x100000, 0x10FFFE, ambiguous}, } +// Condition have flag EastAsianWidth whether the current locale is CJK or not. type Condition struct { EastAsianWidth bool } +// NewCondition return new instance of Condition which is current locale. func NewCondition() *Condition { return &Condition{EastAsianWidth} } @@ -344,6 +351,7 @@ func (c *Condition) RuneWidth(r rune) int { return 1 } +// StringWidth return width as you can see func (c *Condition) StringWidth(s string) (width int) { for _, r := range []rune(s) { width += c.RuneWidth(r) @@ -351,6 +359,7 @@ func (c *Condition) StringWidth(s string) (width int) { return width } +// Truncate return string truncated with w cells func (c *Condition) Truncate(s string, w int, tail string) string { if c.StringWidth(s) <= w { return s @@ -370,6 +379,7 @@ func (c *Condition) Truncate(s string, w int, tail string) string { return string(r[0:i]) + tail } +// Wrap return string wrapped with w cells func (c *Condition) Wrap(s string, w int) string { width := 0 out := "" @@ -392,6 +402,7 @@ func (c *Condition) Wrap(s string, w int) string { return out } +// FillLeft return string filled in left by spaces in w cells func (c *Condition) FillLeft(s string, w int) string { width := c.StringWidth(s) count := w - width @@ -405,6 +416,7 @@ func (c *Condition) FillLeft(s string, w int) string { return s } +// FillRight return string filled in left by spaces in w cells func (c *Condition) FillRight(s string, w int) string { width := c.StringWidth(s) count := w - width @@ -438,27 +450,32 @@ func IsAmbiguousWidth(r rune) bool { return ct(r) == ambiguous } -// IsAmbiguousWidth returns whether is ambiguous width or not. +// IsNeutralWidth returns whether is neutral width or not. func IsNeutralWidth(r rune) bool { return ct(r) == neutral } +// StringWidth return width as you can see func StringWidth(s string) (width int) { return DefaultCondition.StringWidth(s) } +// Truncate return string truncated with w cells func Truncate(s string, w int, tail string) string { return DefaultCondition.Truncate(s, w, tail) } +// Wrap return string wrapped with w cells func Wrap(s string, w int) string { return DefaultCondition.Wrap(s, w) } +// FillLeft return string filled in left by spaces in w cells func FillLeft(s string, w int) string { return DefaultCondition.FillLeft(s, w) } +// FillRight return string filled in left by spaces in w cells func FillRight(s string, w int) string { return DefaultCondition.FillRight(s, w) } diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go index a4495909..c579e9a3 100644 --- a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -10,20 +10,25 @@ import ( var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) -func IsEastAsian() bool { - locale := os.Getenv("LC_CTYPE") - if locale == "" { - locale = os.Getenv("LANG") - } - - // ignore C locale - if locale == "POSIX" || locale == "C" { - return false - } - if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { - return false - } +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} +func isEastAsian(locale string) bool { charset := strings.ToLower(locale) r := reLoc.FindStringSubmatch(locale) if len(r) == 2 { @@ -40,26 +45,11 @@ func IsEastAsian() bool { break } } - - mbc_max := 1 - switch charset { - case "utf-8", "utf8": - mbc_max = 6 - case "jis": - mbc_max = 8 - case "eucjp": - mbc_max = 3 - case "euckr", "euccn": - mbc_max = 2 - case "sjis", "cp932", "cp51932", "cp936", "cp949", "cp950": - mbc_max = 2 - case "big5": - mbc_max = 2 - case "gbk", "gb2312": - mbc_max = 2 + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m } - - if mbc_max > 1 && (charset[0] != 'u' || + if max > 1 && (charset[0] != 'u' || strings.HasPrefix(locale, "ja") || strings.HasPrefix(locale, "ko") || strings.HasPrefix(locale, "zh")) { @@ -67,3 +57,21 @@ func IsEastAsian() bool { } return false } + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go index bdd84454..0258876b 100644 --- a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -9,6 +9,7 @@ var ( procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") ) +// IsEastAsian return true if the current locale is CJK func IsEastAsian() bool { r1, _, _ := procGetConsoleOutputCP.Call() if r1 == 0 { diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE b/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE index 13f15dfc..8dada3ed 100644 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE +++ b/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE @@ -178,7 +178,7 @@ 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 "[]" + 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 @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2013 Matt T. Proud + 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. diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE b/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE new file mode 100644 index 00000000..5d8cb5b7 --- /dev/null +++ b/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE @@ -0,0 +1 @@ +Copyright 2012 Matt T. Proud (matt.proud@gmail.com) diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go index 66d9b545..258c0636 100644 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go +++ b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go @@ -38,7 +38,7 @@ var errInvalidVarint = errors.New("invalid varint32 encountered") func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { // Per AbstractParser#parsePartialDelimitedFrom with // CodedInputStream#readRawVarint32. - headerBuf := make([]byte, binary.MaxVarintLen32) + var headerBuf [binary.MaxVarintLen32]byte var bytesRead, varIntBytes int var messageLength uint64 for varIntBytes == 0 { // i.e. no varint has been decoded yet. diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go index 4b76ea9a..8fb59ad2 100644 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go +++ b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go @@ -33,8 +33,8 @@ func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) { return 0, err } - buf := make([]byte, binary.MaxVarintLen32) - encodedLength := binary.PutUvarint(buf, uint64(len(buffer))) + var buf [binary.MaxVarintLen32]byte + encodedLength := binary.PutUvarint(buf[:], uint64(len(buffer))) sync, err := w.Write(buf[:encodedLength]) if err != nil { diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index b72c9bed..487fdc6c 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -46,10 +46,7 @@ func ResponseFormat(h http.Header) Format { return FmtUnknown } - const ( - textType = "text/plain" - jsonType = "application/json" - ) + const textType = "text/plain" switch mediatype { case ProtoType: @@ -66,22 +63,6 @@ func ResponseFormat(h http.Header) Format { return FmtUnknown } return FmtText - - case jsonType: - var prometheusAPIVersion string - - if params["schema"] == "prometheus/telemetry" && params["version"] != "" { - prometheusAPIVersion = params["version"] - } else { - prometheusAPIVersion = h.Get("X-Prometheus-API-Version") - } - - switch prometheusAPIVersion { - case "0.0.2", "": - return fmtJSON2 - default: - return FmtUnknown - } } return FmtUnknown @@ -93,8 +74,6 @@ func NewDecoder(r io.Reader, format Format) Decoder { switch format { case FmtProtoDelim: return &protoDecoder{r: r} - case fmtJSON2: - return newJSON2Decoder(r) } return &textDecoder{r: r} } @@ -107,10 +86,32 @@ type protoDecoder struct { // Decode implements the Decoder interface. func (d *protoDecoder) Decode(v *dto.MetricFamily) error { _, err := pbutil.ReadDelimited(d.r, v) - return err + if err != nil { + return err + } + if !model.IsValidMetricName(model.LabelValue(v.GetName())) { + return fmt.Errorf("invalid metric name %q", v.GetName()) + } + for _, m := range v.GetMetric() { + if m == nil { + continue + } + for _, l := range m.GetLabel() { + if l == nil { + continue + } + if !model.LabelValue(l.GetValue()).IsValid() { + return fmt.Errorf("invalid label value %q", l.GetValue()) + } + if !model.LabelName(l.GetName()).IsValid() { + return fmt.Errorf("invalid label name %q", l.GetName()) + } + } + } + return nil } -// textDecoder implements the Decoder interface for the text protcol. +// textDecoder implements the Decoder interface for the text protocol. type textDecoder struct { r io.Reader p TextParser diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go index 392ca90e..11839ed6 100644 --- a/vendor/github.com/prometheus/common/expfmt/encode.go +++ b/vendor/github.com/prometheus/common/expfmt/encode.go @@ -18,9 +18,9 @@ import ( "io" "net/http" - "bitbucket.org/ww/goautoneg" "github.com/golang/protobuf/proto" "github.com/matttproud/golang_protobuf_extensions/pbutil" + "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" dto "github.com/prometheus/client_model/go" ) diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go index 366fbde9..fae10f6e 100644 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -29,9 +29,6 @@ const ( FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` FmtProtoText Format = ProtoFmt + ` encoding=text` FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` - - // fmtJSON2 is hidden as it is deprecated. - fmtJSON2 Format = `application/json; version=0.0.2` ) const ( diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index 14f92014..dc2eedee 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -20,8 +20,8 @@ import "bytes" // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: // -// go-fuzz-build github.com/prometheus/client_golang/text -// go-fuzz -bin text-fuzz.zip -workdir fuzz +// go-fuzz-build github.com/prometheus/common/expfmt +// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz // // Further input samples should go in the folder fuzz/corpus. func Fuzz(in []byte) int { diff --git a/vendor/github.com/prometheus/common/expfmt/json_decode.go b/vendor/github.com/prometheus/common/expfmt/json_decode.go deleted file mode 100644 index 67e3a0d4..00000000 --- a/vendor/github.com/prometheus/common/expfmt/json_decode.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// 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 expfmt - -import ( - "encoding/json" - "fmt" - "io" - "sort" - - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/common/model" -) - -type json2Decoder struct { - dec *json.Decoder - fams []*dto.MetricFamily -} - -func newJSON2Decoder(r io.Reader) Decoder { - return &json2Decoder{ - dec: json.NewDecoder(r), - } -} - -type histogram002 struct { - Labels model.LabelSet `json:"labels"` - Values map[string]float64 `json:"value"` -} - -type counter002 struct { - Labels model.LabelSet `json:"labels"` - Value float64 `json:"value"` -} - -func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair { - labels := base.Clone().Merge(ext) - delete(labels, model.MetricNameLabel) - - names := make([]string, 0, len(labels)) - for ln := range labels { - names = append(names, string(ln)) - } - sort.Strings(names) - - pairs := make([]*dto.LabelPair, 0, len(labels)) - - for _, ln := range names { - lv := labels[model.LabelName(ln)] - - pairs = append(pairs, &dto.LabelPair{ - Name: proto.String(ln), - Value: proto.String(string(lv)), - }) - } - - return pairs -} - -func (d *json2Decoder) more() error { - var entities []struct { - BaseLabels model.LabelSet `json:"baseLabels"` - Docstring string `json:"docstring"` - Metric struct { - Type string `json:"type"` - Values json.RawMessage `json:"value"` - } `json:"metric"` - } - - if err := d.dec.Decode(&entities); err != nil { - return err - } - for _, e := range entities { - f := &dto.MetricFamily{ - Name: proto.String(string(e.BaseLabels[model.MetricNameLabel])), - Help: proto.String(e.Docstring), - Type: dto.MetricType_UNTYPED.Enum(), - Metric: []*dto.Metric{}, - } - - d.fams = append(d.fams, f) - - switch e.Metric.Type { - case "counter", "gauge": - var values []counter002 - - if err := json.Unmarshal(e.Metric.Values, &values); err != nil { - return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) - } - - for _, ctr := range values { - f.Metric = append(f.Metric, &dto.Metric{ - Label: protoLabelSet(e.BaseLabels, ctr.Labels), - Untyped: &dto.Untyped{ - Value: proto.Float64(ctr.Value), - }, - }) - } - - case "histogram": - var values []histogram002 - - if err := json.Unmarshal(e.Metric.Values, &values); err != nil { - return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) - } - - for _, hist := range values { - quants := make([]string, 0, len(values)) - for q := range hist.Values { - quants = append(quants, q) - } - - sort.Strings(quants) - - for _, q := range quants { - value := hist.Values[q] - // The correct label is "quantile" but to not break old expressions - // this remains "percentile" - hist.Labels["percentile"] = model.LabelValue(q) - - f.Metric = append(f.Metric, &dto.Metric{ - Label: protoLabelSet(e.BaseLabels, hist.Labels), - Untyped: &dto.Untyped{ - Value: proto.Float64(value), - }, - }) - } - } - - default: - return fmt.Errorf("unknown metric type %q", e.Metric.Type) - } - } - return nil -} - -// Decode implements the Decoder interface. -func (d *json2Decoder) Decode(v *dto.MetricFamily) error { - if len(d.fams) == 0 { - if err := d.more(); err != nil { - return err - } - } - - *v = *d.fams[0] - d.fams = d.fams[1:] - - return nil -} diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go index 0bb9c14c..f11321cd 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_create.go +++ b/vendor/github.com/prometheus/common/expfmt/text_create.go @@ -14,7 +14,6 @@ package expfmt import ( - "bytes" "fmt" "io" "math" @@ -26,9 +25,12 @@ import ( // MetricFamilyToText converts a MetricFamily proto message into text format and // writes the resulting lines to 'out'. It returns the number of bytes written -// and any error encountered. This function does not perform checks on the -// content of the metric and label names, i.e. invalid metric or label names +// and any error encountered. The output will have the same order as the input, +// no further sorting is performed. Furthermore, this function assumes the input +// is already sanitized and does not perform any sanity checks. If the input +// contains duplicate metrics or invalid metric or label names, the conversion // will result in invalid text format output. +// // This method fulfills the type 'prometheus.encoder'. func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) { var written int @@ -285,21 +287,17 @@ func labelPairsToText( return written, nil } +var ( + escape = strings.NewReplacer("\\", `\\`, "\n", `\n`) + escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`) +) + // escapeString replaces '\' by '\\', new line character by '\n', and - if // includeDoubleQuote is true - '"' by '\"'. func escapeString(v string, includeDoubleQuote bool) string { - result := bytes.NewBuffer(make([]byte, 0, len(v))) - for _, c := range v { - switch { - case c == '\\': - result.WriteString(`\\`) - case includeDoubleQuote && c == '"': - result.WriteString(`\"`) - case c == '\n': - result.WriteString(`\n`) - default: - result.WriteRune(c) - } + if includeDoubleQuote { + return escapeWithDoubleQuote.Replace(v) } - return result.String() + + return escape.Replace(v) } diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index 84433bc4..ef9a1507 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -47,7 +47,7 @@ func (e ParseError) Error() string { } // TextParser is used to parse the simple and flat text-based exchange format. Its -// nil value is ready to use. +// zero value is ready to use. type TextParser struct { metricFamiliesByName map[string]*dto.MetricFamily buf *bufio.Reader // Where the parsed input is read through. @@ -108,6 +108,13 @@ func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricF delete(p.metricFamiliesByName, k) } } + // If p.err is io.EOF now, we have run into a premature end of the input + // stream. Turn this error into something nicer and more + // meaningful. (io.EOF is often used as a signal for the legitimate end + // of an input stream.) + if p.err == io.EOF { + p.parseError("unexpected end of input stream") + } return p.metricFamiliesByName, p.err } diff --git a/vendor/bitbucket.org/ww/goautoneg/autoneg.go b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go similarity index 100% rename from vendor/bitbucket.org/ww/goautoneg/autoneg.go rename to vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go diff --git a/vendor/github.com/prometheus/common/model/alert.go b/vendor/github.com/prometheus/common/model/alert.go index b027e9f3..35e739c7 100644 --- a/vendor/github.com/prometheus/common/model/alert.go +++ b/vendor/github.com/prometheus/common/model/alert.go @@ -35,8 +35,9 @@ type Alert struct { Annotations LabelSet `json:"annotations"` // The known time range for this alert. Both ends are optional. - StartsAt time.Time `json:"startsAt,omitempty"` - EndsAt time.Time `json:"endsAt,omitempty"` + StartsAt time.Time `json:"startsAt,omitempty"` + EndsAt time.Time `json:"endsAt,omitempty"` + GeneratorURL string `json:"generatorURL"` } // Name returns the name of the alert. It is equivalent to the "alertname" label. @@ -60,10 +61,16 @@ func (a *Alert) String() string { // Resolved returns true iff the activity interval ended in the past. func (a *Alert) Resolved() bool { + return a.ResolvedAt(time.Now()) +} + +// ResolvedAt returns true off the activity interval ended before +// the given timestamp. +func (a *Alert) ResolvedAt(ts time.Time) bool { if a.EndsAt.IsZero() { return false } - return !a.EndsAt.After(time.Now()) + return !a.EndsAt.After(ts) } // Status returns the status of the alert. @@ -74,6 +81,26 @@ func (a *Alert) Status() AlertStatus { return AlertFiring } +// Validate checks whether the alert data is inconsistent. +func (a *Alert) Validate() error { + if a.StartsAt.IsZero() { + return fmt.Errorf("start time missing") + } + if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { + return fmt.Errorf("start time must be before end time") + } + if err := a.Labels.Validate(); err != nil { + return fmt.Errorf("invalid label set: %s", err) + } + if len(a.Labels) == 0 { + return fmt.Errorf("at least one label pair required") + } + if err := a.Annotations.Validate(); err != nil { + return fmt.Errorf("invalid annotations: %s", err) + } + return nil +} + // Alert is a list of alerts that can be sorted in chronological order. type Alerts []*Alert diff --git a/vendor/github.com/prometheus/common/model/fnv.go b/vendor/github.com/prometheus/common/model/fnv.go new file mode 100644 index 00000000..038fc1c9 --- /dev/null +++ b/vendor/github.com/prometheus/common/model/fnv.go @@ -0,0 +1,42 @@ +// Copyright 2015 The Prometheus Authors +// 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 model + +// Inline and byte-free variant of hash/fnv's fnv64a. + +const ( + offset64 = 14695981039346656037 + prime64 = 1099511628211 +) + +// hashNew initializies a new fnv64a hash value. +func hashNew() uint64 { + return offset64 +} + +// hashAdd adds a string to a fnv64a hash value, returning the updated hash. +func hashAdd(h uint64, s string) uint64 { + for i := 0; i < len(s); i++ { + h ^= uint64(s[i]) + h *= prime64 + } + return h +} + +// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. +func hashAddByte(h uint64, b byte) uint64 { + h ^= uint64(b) + h *= prime64 + return h +} diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go index 6459c8f7..41051a01 100644 --- a/vendor/github.com/prometheus/common/model/labels.go +++ b/vendor/github.com/prometheus/common/model/labels.go @@ -17,8 +17,8 @@ import ( "encoding/json" "fmt" "regexp" - "sort" "strings" + "unicode/utf8" ) const ( @@ -80,20 +80,37 @@ const ( QuantileLabel = "quantile" ) -// LabelNameRE is a regular expression matching valid label names. +// LabelNameRE is a regular expression matching valid label names. Note that the +// IsValid method of LabelName performs the same check but faster than a match +// with this regular expression. var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") // A LabelName is a key for a LabelSet or Metric. It has a value associated // therewith. type LabelName string +// IsValid is true iff the label name matches the pattern of LabelNameRE. This +// method, however, does not use LabelNameRE for the check but a much faster +// hardcoded implementation. +func (ln LabelName) IsValid() bool { + if len(ln) == 0 { + return false + } + for i, b := range ln { + if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { + return false + } + } + return true +} + // UnmarshalYAML implements the yaml.Unmarshaler interface. func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { var s string if err := unmarshal(&s); err != nil { return err } - if !LabelNameRE.MatchString(s) { + if !LabelName(s).IsValid() { return fmt.Errorf("%q is not a valid label name", s) } *ln = LabelName(s) @@ -106,7 +123,7 @@ func (ln *LabelName) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &s); err != nil { return err } - if !LabelNameRE.MatchString(s) { + if !LabelName(s).IsValid() { return fmt.Errorf("%q is not a valid label name", s) } *ln = LabelName(s) @@ -139,6 +156,11 @@ func (l LabelNames) String() string { // A LabelValue is an associated value for a LabelName. type LabelValue string +// IsValid returns true iff the string is a valid UTF8. +func (lv LabelValue) IsValid() bool { + return utf8.ValidString(string(lv)) +} + // LabelValues is a sortable LabelValue slice. It implements sort.Interface. type LabelValues []LabelValue @@ -147,7 +169,7 @@ func (l LabelValues) Len() int { } func (l LabelValues) Less(i, j int) bool { - return sort.StringsAreSorted([]string{string(l[i]), string(l[j])}) + return string(l[i]) < string(l[j]) } func (l LabelValues) Swap(i, j int) { diff --git a/vendor/github.com/prometheus/common/model/labelset.go b/vendor/github.com/prometheus/common/model/labelset.go index 142b9d1e..6eda08a7 100644 --- a/vendor/github.com/prometheus/common/model/labelset.go +++ b/vendor/github.com/prometheus/common/model/labelset.go @@ -27,6 +27,21 @@ import ( // match. type LabelSet map[LabelName]LabelValue +// Validate checks whether all names and values in the label set +// are valid. +func (ls LabelSet) Validate() error { + for ln, lv := range ls { + if !ln.IsValid() { + return fmt.Errorf("invalid name %q", ln) + } + if !lv.IsValid() { + return fmt.Errorf("invalid value %q", lv) + } + } + return nil +} + +// Equal returns true iff both label sets have exactly the same key/value pairs. func (ls LabelSet) Equal(o LabelSet) bool { if len(ls) != len(o) { return false @@ -90,6 +105,7 @@ func (ls LabelSet) Before(o LabelSet) bool { return false } +// Clone returns a copy of the label set. func (ls LabelSet) Clone() LabelSet { lsn := make(LabelSet, len(ls)) for ln, lv := range ls { @@ -144,7 +160,7 @@ func (l *LabelSet) UnmarshalJSON(b []byte) error { // LabelName as a string and does not call its UnmarshalJSON method. // Thus, we have to replicate the behavior here. for ln := range m { - if !LabelNameRE.MatchString(string(ln)) { + if !ln.IsValid() { return fmt.Errorf("%q is not a valid label name", ln) } } diff --git a/vendor/github.com/prometheus/common/model/metric.go b/vendor/github.com/prometheus/common/model/metric.go index 25fc3c94..9dff899c 100644 --- a/vendor/github.com/prometheus/common/model/metric.go +++ b/vendor/github.com/prometheus/common/model/metric.go @@ -15,11 +15,18 @@ package model import ( "fmt" + "regexp" "sort" "strings" ) -var separator = []byte{0} +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. + MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`) +) // A Metric is similar to a LabelSet, but the key difference is that a Metric is // a singleton and refers to one and only one stream of samples. @@ -79,3 +86,18 @@ func (m Metric) Fingerprint() Fingerprint { func (m Metric) FastFingerprint() Fingerprint { return LabelSet(m).FastFingerprint() } + +// IsValidMetricName returns true iff name matches the pattern of MetricNameRE. +// This function, however, does not use MetricNameRE for the check but a much +// faster hardcoded implementation. +func IsValidMetricName(n LabelValue) bool { + if len(n) == 0 { + return false + } + for i, b := range n { + if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) { + return false + } + } + return true +} diff --git a/vendor/github.com/prometheus/common/model/model.go b/vendor/github.com/prometheus/common/model/model.go index 88f013a4..a7b96917 100644 --- a/vendor/github.com/prometheus/common/model/model.go +++ b/vendor/github.com/prometheus/common/model/model.go @@ -12,5 +12,5 @@ // limitations under the License. // Package model contains common data structures that are shared across -// Prometheus componenets and libraries. +// Prometheus components and libraries. package model diff --git a/vendor/github.com/prometheus/common/model/signature.go b/vendor/github.com/prometheus/common/model/signature.go index 28f37006..8762b13c 100644 --- a/vendor/github.com/prometheus/common/model/signature.go +++ b/vendor/github.com/prometheus/common/model/signature.go @@ -14,11 +14,7 @@ package model import ( - "bytes" - "hash" - "hash/fnv" "sort" - "sync" ) // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is @@ -28,30 +24,9 @@ const SeparatorByte byte = 255 var ( // cache the signature of an empty label set. - emptyLabelSignature = fnv.New64a().Sum64() - - hashAndBufPool sync.Pool + emptyLabelSignature = hashNew() ) -type hashAndBuf struct { - h hash.Hash64 - b bytes.Buffer -} - -func getHashAndBuf() *hashAndBuf { - hb := hashAndBufPool.Get() - if hb == nil { - return &hashAndBuf{h: fnv.New64a()} - } - return hb.(*hashAndBuf) -} - -func putHashAndBuf(hb *hashAndBuf) { - hb.h.Reset() - hb.b.Reset() - hashAndBufPool.Put(hb) -} - // LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a // given label set. (Collisions are possible but unlikely if the number of label // sets the function is applied to is small.) @@ -66,18 +41,14 @@ func LabelsToSignature(labels map[string]string) uint64 { } sort.Strings(labelNames) - hb := getHashAndBuf() - defer putHashAndBuf(hb) - + sum := hashNew() for _, labelName := range labelNames { - hb.b.WriteString(labelName) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(labels[labelName]) - hb.b.WriteByte(SeparatorByte) - hb.h.Write(hb.b.Bytes()) - hb.b.Reset() + sum = hashAdd(sum, labelName) + sum = hashAddByte(sum, SeparatorByte) + sum = hashAdd(sum, labels[labelName]) + sum = hashAddByte(sum, SeparatorByte) } - return hb.h.Sum64() + return sum } // labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as @@ -93,18 +64,14 @@ func labelSetToFingerprint(ls LabelSet) Fingerprint { } sort.Sort(labelNames) - hb := getHashAndBuf() - defer putHashAndBuf(hb) - + sum := hashNew() for _, labelName := range labelNames { - hb.b.WriteString(string(labelName)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(ls[labelName])) - hb.b.WriteByte(SeparatorByte) - hb.h.Write(hb.b.Bytes()) - hb.b.Reset() + sum = hashAdd(sum, string(labelName)) + sum = hashAddByte(sum, SeparatorByte) + sum = hashAdd(sum, string(ls[labelName])) + sum = hashAddByte(sum, SeparatorByte) } - return Fingerprint(hb.h.Sum64()) + return Fingerprint(sum) } // labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a @@ -116,17 +83,12 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint { } var result uint64 - hb := getHashAndBuf() - defer putHashAndBuf(hb) - for labelName, labelValue := range ls { - hb.b.WriteString(string(labelName)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(labelValue)) - hb.h.Write(hb.b.Bytes()) - result ^= hb.h.Sum64() - hb.h.Reset() - hb.b.Reset() + sum := hashNew() + sum = hashAdd(sum, string(labelName)) + sum = hashAddByte(sum, SeparatorByte) + sum = hashAdd(sum, string(labelValue)) + result ^= sum } return Fingerprint(result) } @@ -136,24 +98,20 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint { // specified LabelNames into the signature calculation. The labels passed in // will be sorted by this function. func SignatureForLabels(m Metric, labels ...LabelName) uint64 { - if len(m) == 0 || len(labels) == 0 { + if len(labels) == 0 { return emptyLabelSignature } sort.Sort(LabelNames(labels)) - hb := getHashAndBuf() - defer putHashAndBuf(hb) - + sum := hashNew() for _, label := range labels { - hb.b.WriteString(string(label)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(m[label])) - hb.b.WriteByte(SeparatorByte) - hb.h.Write(hb.b.Bytes()) - hb.b.Reset() + sum = hashAdd(sum, string(label)) + sum = hashAddByte(sum, SeparatorByte) + sum = hashAdd(sum, string(m[label])) + sum = hashAddByte(sum, SeparatorByte) } - return hb.h.Sum64() + return sum } // SignatureWithoutLabels works like LabelsToSignature but takes a Metric as @@ -175,16 +133,12 @@ func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { } sort.Sort(labelNames) - hb := getHashAndBuf() - defer putHashAndBuf(hb) - + sum := hashNew() for _, labelName := range labelNames { - hb.b.WriteString(string(labelName)) - hb.b.WriteByte(SeparatorByte) - hb.b.WriteString(string(m[labelName])) - hb.b.WriteByte(SeparatorByte) - hb.h.Write(hb.b.Bytes()) - hb.b.Reset() + sum = hashAdd(sum, string(labelName)) + sum = hashAddByte(sum, SeparatorByte) + sum = hashAdd(sum, string(m[labelName])) + sum = hashAddByte(sum, SeparatorByte) } - return hb.h.Sum64() + return sum } diff --git a/vendor/github.com/prometheus/common/model/silence.go b/vendor/github.com/prometheus/common/model/silence.go index b4b96eae..7538e299 100644 --- a/vendor/github.com/prometheus/common/model/silence.go +++ b/vendor/github.com/prometheus/common/model/silence.go @@ -44,6 +44,21 @@ func (m *Matcher) UnmarshalJSON(b []byte) error { return nil } +// Validate returns true iff all fields of the matcher have valid values. +func (m *Matcher) Validate() error { + if !m.Name.IsValid() { + return fmt.Errorf("invalid name %q", m.Name) + } + if m.IsRegex { + if _, err := regexp.Compile(m.Value); err != nil { + return fmt.Errorf("invalid regular expression %q", m.Value) + } + } else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 { + return fmt.Errorf("invalid value %q", m.Value) + } + return nil +} + // Silence defines the representation of a silence definiton // in the Prometheus eco-system. type Silence struct { @@ -58,3 +73,34 @@ type Silence struct { CreatedBy string `json:"createdBy"` Comment string `json:"comment,omitempty"` } + +// Validate returns true iff all fields of the silence have valid values. +func (s *Silence) Validate() error { + if len(s.Matchers) == 0 { + return fmt.Errorf("at least one matcher required") + } + for _, m := range s.Matchers { + if err := m.Validate(); err != nil { + return fmt.Errorf("invalid matcher: %s", err) + } + } + if s.StartsAt.IsZero() { + return fmt.Errorf("start time missing") + } + if s.EndsAt.IsZero() { + return fmt.Errorf("end time missing") + } + if s.EndsAt.Before(s.StartsAt) { + return fmt.Errorf("start time must be before end time") + } + if s.CreatedBy == "" { + return fmt.Errorf("creator information missing") + } + if s.Comment == "" { + return fmt.Errorf("comment missing") + } + if s.CreatedAt.IsZero() { + return fmt.Errorf("creation timestamp missing") + } + return nil +} diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index ebc8bf6c..548968ae 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -163,51 +163,70 @@ func (t *Time) UnmarshalJSON(b []byte) error { // This type should not propagate beyond the scope of input/output processing. type Duration time.Duration +var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$") + // StringToDuration parses a string into a time.Duration, assuming that a year -// a day always has 24h. +// always has 365d, a week always has 7d, and a day always has 24h. func ParseDuration(durationStr string) (Duration, error) { matches := durationRE.FindStringSubmatch(durationStr) if len(matches) != 3 { return 0, fmt.Errorf("not a valid duration string: %q", durationStr) } - durSeconds, _ := strconv.Atoi(matches[1]) - dur := time.Duration(durSeconds) * time.Second - unit := matches[2] - switch unit { + var ( + n, _ = strconv.Atoi(matches[1]) + dur = time.Duration(n) * time.Millisecond + ) + switch unit := matches[2]; unit { + case "y": + dur *= 1000 * 60 * 60 * 24 * 365 + case "w": + dur *= 1000 * 60 * 60 * 24 * 7 case "d": - dur *= 60 * 60 * 24 + dur *= 1000 * 60 * 60 * 24 case "h": - dur *= 60 * 60 + dur *= 1000 * 60 * 60 case "m": - dur *= 60 + dur *= 1000 * 60 case "s": - dur *= 1 + dur *= 1000 + case "ms": + // Value already correct default: return 0, fmt.Errorf("invalid time unit in duration string: %q", unit) } return Duration(dur), nil } -var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$") - func (d Duration) String() string { - seconds := int64(time.Duration(d) / time.Second) + var ( + ms = int64(time.Duration(d) / time.Millisecond) + unit = "ms" + ) factors := map[string]int64{ - "d": 60 * 60 * 24, - "h": 60 * 60, - "m": 60, - "s": 1, + "y": 1000 * 60 * 60 * 24 * 365, + "w": 1000 * 60 * 60 * 24 * 7, + "d": 1000 * 60 * 60 * 24, + "h": 1000 * 60 * 60, + "m": 1000 * 60, + "s": 1000, + "ms": 1, } - unit := "s" + switch int64(0) { - case seconds % factors["d"]: + case ms % factors["y"]: + unit = "y" + case ms % factors["w"]: + unit = "w" + case ms % factors["d"]: unit = "d" - case seconds % factors["h"]: + case ms % factors["h"]: unit = "h" - case seconds % factors["m"]: + case ms % factors["m"]: unit = "m" + case ms % factors["s"]: + unit = "s" } - return fmt.Sprintf("%v%v", seconds/factors[unit], unit) + return fmt.Sprintf("%v%v", ms/factors[unit], unit) } // MarshalYAML implements the yaml.Marshaler interface. diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go index 10ffb0bd..7728abae 100644 --- a/vendor/github.com/prometheus/common/model/value.go +++ b/vendor/github.com/prometheus/common/model/value.go @@ -16,11 +16,28 @@ package model import ( "encoding/json" "fmt" + "math" "sort" "strconv" "strings" ) +var ( + // ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a + // non-existing sample pair. It is a SamplePair with timestamp Earliest and + // value 0.0. Note that the natural zero value of SamplePair has a timestamp + // of 0, which is possible to appear in a real SamplePair and thus not + // suitable to signal a non-existing SamplePair. + ZeroSamplePair = SamplePair{Timestamp: Earliest} + + // ZeroSample is the pseudo zero-value of Sample used to signal a + // non-existing sample. It is a Sample with timestamp Earliest, value 0.0, + // and metric nil. Note that the natural zero value of Sample has a timestamp + // of 0, which is possible to appear in a real Sample and thus not suitable + // to signal a non-existing Sample. + ZeroSample = Sample{Timestamp: Earliest} +) + // A SampleValue is a representation of a value for a given sample at a given // time. type SampleValue float64 @@ -43,8 +60,14 @@ func (v *SampleValue) UnmarshalJSON(b []byte) error { return nil } +// Equal returns true if the value of v and o is equal or if both are NaN. Note +// that v==o is false if both are NaN. If you want the conventional float +// behavior, use == to compare two SampleValues. func (v SampleValue) Equal(o SampleValue) bool { - return v == o + if v == o { + return true + } + return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) } func (v SampleValue) String() string { @@ -77,9 +100,9 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error { } // Equal returns true if this SamplePair and o have equal Values and equal -// Timestamps. +// Timestamps. The sematics of Value equality is defined by SampleValue.Equal. func (s *SamplePair) Equal(o *SamplePair) bool { - return s == o || (s.Value == o.Value && s.Timestamp.Equal(o.Timestamp)) + return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) } func (s SamplePair) String() string { @@ -93,7 +116,8 @@ type Sample struct { Timestamp Time `json:"timestamp"` } -// Equal compares first the metrics, then the timestamp, then the value. +// Equal compares first the metrics, then the timestamp, then the value. The +// sematics of value equality is defined by SampleValue.Equal. func (s *Sample) Equal(o *Sample) bool { if s == o { return true @@ -105,7 +129,7 @@ func (s *Sample) Equal(o *Sample) bool { if !s.Timestamp.Equal(o.Timestamp) { return false } - if s.Value != o.Value { + if s.Value.Equal(o.Value) { return false } diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go index 6a8d97b1..49aaab05 100644 --- a/vendor/github.com/prometheus/procfs/fs.go +++ b/vendor/github.com/prometheus/procfs/fs.go @@ -27,14 +27,7 @@ func NewFS(mountPoint string) (FS, error) { return FS(mountPoint), nil } -func (fs FS) stat(p string) (os.FileInfo, error) { - return os.Stat(path.Join(string(fs), p)) -} - -func (fs FS) open(p string) (*os.File, error) { - return os.Open(path.Join(string(fs), p)) -} - -func (fs FS) readlink(p string) (string, error) { - return os.Readlink(path.Join(string(fs), p)) +// Path returns the path of the given subsystem relative to the procfs root. +func (fs FS) Path(p ...string) string { + return path.Join(append([]string{string(fs)}, p...)...) } diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go index 26da5000..e7012f73 100644 --- a/vendor/github.com/prometheus/procfs/ipvs.go +++ b/vendor/github.com/prometheus/procfs/ipvs.go @@ -8,6 +8,7 @@ import ( "io" "io/ioutil" "net" + "os" "strconv" "strings" ) @@ -58,7 +59,7 @@ func NewIPVSStats() (IPVSStats, error) { // NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem. func (fs FS) NewIPVSStats() (IPVSStats, error) { - file, err := fs.open("net/ip_vs_stats") + file, err := os.Open(fs.Path("net/ip_vs_stats")) if err != nil { return IPVSStats{}, err } @@ -127,7 +128,7 @@ func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem. func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { - file, err := fs.open("net/ip_vs") + file, err := os.Open(fs.Path("net/ip_vs")) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go index 09ed6b5e..d7a248c0 100644 --- a/vendor/github.com/prometheus/procfs/mdstat.go +++ b/vendor/github.com/prometheus/procfs/mdstat.go @@ -3,7 +3,6 @@ package procfs import ( "fmt" "io/ioutil" - "path" "regexp" "strconv" "strings" @@ -32,36 +31,22 @@ type MDStat struct { // ParseMDStat parses an mdstat-file and returns a struct with the relevant infos. func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { - mdStatusFilePath := path.Join(string(fs), "mdstat") + mdStatusFilePath := fs.Path("mdstat") content, err := ioutil.ReadFile(mdStatusFilePath) if err != nil { return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) } - mdStatusFile := string(content) - - lines := strings.Split(mdStatusFile, "\n") - var currentMD string - - // Each md has at least the deviceline, statusline and one empty line afterwards - // so we will have probably something of the order len(lines)/3 devices - // so we use that for preallocation. - estimateMDs := len(lines) / 3 - mdStates := make([]MDStat, 0, estimateMDs) - + mdStates := []MDStat{} + lines := strings.Split(string(content), "\n") for i, l := range lines { if l == "" { - // Skip entirely empty lines. continue } - if l[0] == ' ' { - // Those lines are not the beginning of a md-section. continue } - if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") { - // We aren't interested in lines with general info. continue } @@ -69,32 +54,30 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { if len(mainLine) < 3 { return mdStates, fmt.Errorf("error parsing mdline: %s", l) } - currentMD = mainLine[0] // name of md-device - activityState := mainLine[2] // activity status of said md-device + mdName := mainLine[0] + activityState := mainLine[2] if len(lines) <= i+3 { - return mdStates, fmt.Errorf("error parsing %s: entry for %s has fewer lines than expected", mdStatusFilePath, currentMD) + return mdStates, fmt.Errorf( + "error parsing %s: too few lines for md device %s", + mdStatusFilePath, + mdName, + ) } - active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present + active, total, size, err := evalStatusline(lines[i+1]) if err != nil { return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) } - // - // Now get the number of synced blocks. - // - - // Get the line number of the syncing-line. - var j int - if strings.Contains(lines[i+2], "bitmap") { // then skip the bitmap line + // j is the line number of the syncing-line. + j := i + 2 + if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line j = i + 3 - } else { - j = i + 2 } - // If device is syncing at the moment, get the number of currently synced bytes, - // otherwise that number equals the size of the device. + // If device is syncing at the moment, get the number of currently + // synced bytes, otherwise that number equals the size of the device. syncedBlocks := size if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") { syncedBlocks, err = evalBuildline(lines[j]) @@ -103,8 +86,14 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { } } - mdStates = append(mdStates, MDStat{currentMD, activityState, active, total, size, syncedBlocks}) - + mdStates = append(mdStates, MDStat{ + Name: mdName, + ActivityState: activityState, + DisksActive: active, + DisksTotal: total, + BlocksTotal: size, + BlocksSynced: syncedBlocks, + }) } return mdStates, nil @@ -112,47 +101,38 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { func evalStatusline(statusline string) (active, total, size int64, err error) { matches := statuslineRE.FindStringSubmatch(statusline) - - // +1 to make it more obvious that the whole string containing the info is also returned as matches[0]. - if len(matches) != 3+1 { - return 0, 0, 0, fmt.Errorf("unexpected number matches found in statusline: %s", statusline) + if len(matches) != 4 { + return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline) } size, err = strconv.ParseInt(matches[1], 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) } total, err = strconv.ParseInt(matches[2], 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) } active, err = strconv.ParseInt(matches[3], 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) } return active, total, size, nil } -// Gets the size that has already been synced out of the sync-line. -func evalBuildline(buildline string) (int64, error) { +func evalBuildline(buildline string) (syncedBlocks int64, err error) { matches := buildlineRE.FindStringSubmatch(buildline) - - // +1 to make it more obvious that the whole string containing the info is also returned as matches[0]. - if len(matches) < 1+1 { - return 0, fmt.Errorf("too few matches found in buildline: %s", buildline) + if len(matches) != 2 { + return 0, fmt.Errorf("unexpected buildline: %s", buildline) } - if len(matches) > 1+1 { - return 0, fmt.Errorf("too many matches found in buildline: %s", buildline) - } - - syncedSize, err := strconv.ParseInt(matches[1], 10, 64) + syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64) if err != nil { return 0, fmt.Errorf("%s in buildline: %s", err, buildline) } - return syncedSize, nil + return syncedBlocks, nil } diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index efc85027..0d0a6a90 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -4,7 +4,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "strconv" "strings" ) @@ -42,7 +41,7 @@ func NewProc(pid int) (Proc, error) { return fs.NewProc(pid) } -// AllProcs returns a list of all currently avaible processes under /proc. +// AllProcs returns a list of all currently available processes under /proc. func AllProcs() (Procs, error) { fs, err := NewFS(DefaultMountPoint) if err != nil { @@ -53,7 +52,7 @@ func AllProcs() (Procs, error) { // Self returns a process for the current process. func (fs FS) Self() (Proc, error) { - p, err := fs.readlink("self") + p, err := os.Readlink(fs.Path("self")) if err != nil { return Proc{}, err } @@ -66,15 +65,15 @@ func (fs FS) Self() (Proc, error) { // NewProc returns a process for the given pid. func (fs FS) NewProc(pid int) (Proc, error) { - if _, err := fs.stat(strconv.Itoa(pid)); err != nil { + if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil { return Proc{}, err } return Proc{PID: pid, fs: fs}, nil } -// AllProcs returns a list of all currently avaible processes. +// AllProcs returns a list of all currently available processes. func (fs FS) AllProcs() (Procs, error) { - d, err := fs.open("") + d, err := os.Open(fs.Path()) if err != nil { return Procs{}, err } @@ -99,7 +98,7 @@ func (fs FS) AllProcs() (Procs, error) { // CmdLine returns the command line of a process. func (p Proc) CmdLine() ([]string, error) { - f, err := p.open("cmdline") + f, err := os.Open(p.path("cmdline")) if err != nil { return nil, err } @@ -117,10 +116,25 @@ func (p Proc) CmdLine() ([]string, error) { return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil } +// Comm returns the command name of a process. +func (p Proc) Comm() (string, error) { + f, err := os.Open(p.path("comm")) + if err != nil { + return "", err + } + defer f.Close() + + data, err := ioutil.ReadAll(f) + if err != nil { + return "", err + } + + return strings.TrimSpace(string(data)), nil +} + // Executable returns the absolute path of the executable command of a process. func (p Proc) Executable() (string, error) { - exe, err := p.readlink("exe") - + exe, err := os.Readlink(p.path("exe")) if os.IsNotExist(err) { return "", nil } @@ -158,7 +172,7 @@ func (p Proc) FileDescriptorTargets() ([]string, error) { targets := make([]string, len(names)) for i, name := range names { - target, err := p.readlink("fd/" + name) + target, err := os.Readlink(p.path("fd", name)) if err == nil { targets[i] = target } @@ -179,7 +193,7 @@ func (p Proc) FileDescriptorsLen() (int, error) { } func (p Proc) fileDescriptors() ([]string, error) { - d, err := p.open("fd") + d, err := os.Open(p.path("fd")) if err != nil { return nil, err } @@ -193,10 +207,6 @@ func (p Proc) fileDescriptors() ([]string, error) { return names, nil } -func (p Proc) open(pa string) (*os.File, error) { - return p.fs.open(path.Join(strconv.Itoa(p.PID), pa)) -} - -func (p Proc) readlink(pa string) (string, error) { - return p.fs.readlink(path.Join(strconv.Itoa(p.PID), pa)) +func (p Proc) path(pa ...string) string { + return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) } diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go index 7c6dc869..b4e31d7b 100644 --- a/vendor/github.com/prometheus/procfs/proc_io.go +++ b/vendor/github.com/prometheus/procfs/proc_io.go @@ -3,6 +3,7 @@ package procfs import ( "fmt" "io/ioutil" + "os" ) // ProcIO models the content of /proc//io. @@ -29,7 +30,7 @@ type ProcIO struct { func (p Proc) NewIO() (ProcIO, error) { pio := ProcIO{} - f, err := p.open("io") + f, err := os.Open(p.path("io")) if err != nil { return pio, err } diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go index 9f080b9f..2df997ce 100644 --- a/vendor/github.com/prometheus/procfs/proc_limits.go +++ b/vendor/github.com/prometheus/procfs/proc_limits.go @@ -3,29 +3,56 @@ package procfs import ( "bufio" "fmt" + "os" "regexp" "strconv" ) // ProcLimits represents the soft limits for each of the process's resource -// limits. +// limits. For more information see getrlimit(2): +// http://man7.org/linux/man-pages/man2/getrlimit.2.html. type ProcLimits struct { - CPUTime int - FileSize int - DataSize int - StackSize int - CoreFileSize int - ResidentSet int - Processes int - OpenFiles int - LockedMemory int - AddressSpace int - FileLocks int - PendingSignals int - MsqqueueSize int - NicePriority int + // CPU time limit in seconds. + CPUTime int + // Maximum size of files that the process may create. + FileSize int + // Maximum size of the process's data segment (initialized data, + // uninitialized data, and heap). + DataSize int + // Maximum size of the process stack in bytes. + StackSize int + // Maximum size of a core file. + CoreFileSize int + // Limit of the process's resident set in pages. + ResidentSet int + // Maximum number of processes that can be created for the real user ID of + // the calling process. + Processes int + // Value one greater than the maximum file descriptor number that can be + // opened by this process. + OpenFiles int + // Maximum number of bytes of memory that may be locked into RAM. + LockedMemory int + // Maximum size of the process's virtual memory address space in bytes. + AddressSpace int + // Limit on the combined number of flock(2) locks and fcntl(2) leases that + // this process may establish. + FileLocks int + // Limit of signals that may be queued for the real user ID of the calling + // process. + PendingSignals int + // Limit on the number of bytes that can be allocated for POSIX message + // queues for the real user ID of the calling process. + MsqqueueSize int + // Limit of the nice priority set using setpriority(2) or nice(2). + NicePriority int + // Limit of the real-time priority set using sched_setscheduler(2) or + // sched_setparam(2). RealtimePriority int - RealtimeTimeout int + // Limit (in microseconds) on the amount of CPU time that a process + // scheduled under a real-time scheduling policy may consume without making + // a blocking system call. + RealtimeTimeout int } const ( @@ -39,7 +66,7 @@ var ( // NewLimits returns the current soft limits of the process. func (p Proc) NewLimits() (ProcLimits, error) { - f, err := p.open("limits") + f, err := os.Open(p.path("limits")) if err != nil { return ProcLimits{}, err } @@ -60,7 +87,7 @@ func (p Proc) NewLimits() (ProcLimits, error) { case "Max cpu time": l.CPUTime, err = parseInt(fields[1]) case "Max file size": - l.FileLocks, err = parseInt(fields[1]) + l.FileSize, err = parseInt(fields[1]) case "Max data size": l.DataSize, err = parseInt(fields[1]) case "Max stack size": @@ -90,7 +117,6 @@ func (p Proc) NewLimits() (ProcLimits, error) { case "Max realtime timeout": l.RealtimeTimeout, err = parseInt(fields[1]) } - if err != nil { return ProcLimits{}, err } diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go index 30a403b6..724e271b 100644 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ b/vendor/github.com/prometheus/procfs/proc_stat.go @@ -7,15 +7,15 @@ import ( "os" ) -// Originally, this USER_HZ value was dynamically retrieved via a sysconf call which -// required cgo. However, that caused a lot of problems regarding +// Originally, this USER_HZ value was dynamically retrieved via a sysconf call +// which required cgo. However, that caused a lot of problems regarding // cross-compilation. Alternatives such as running a binary to determine the -// value, or trying to derive it in some other way were all problematic. -// After much research it was determined that USER_HZ is actually hardcoded to -// 100 on all Go-supported platforms as of the time of this writing. This is -// why we decided to hardcode it here as well. It is not impossible that there -// could be systems with exceptions, but they should be very exotic edge cases, -// and in that case, the worst outcome will be two misreported metrics. +// value, or trying to derive it in some other way were all problematic. After +// much research it was determined that USER_HZ is actually hardcoded to 100 on +// all Go-supported platforms as of the time of this writing. This is why we +// decided to hardcode it here as well. It is not impossible that there could +// be systems with exceptions, but they should be very exotic edge cases, and +// in that case, the worst outcome will be two misreported metrics. // // See also the following discussions: // @@ -91,7 +91,7 @@ type ProcStat struct { // NewStat returns the current status information of the process. func (p Proc) NewStat() (ProcStat, error) { - f, err := p.open("stat") + f, err := os.Open(p.path("stat")) if err != nil { return ProcStat{}, err } diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go index 26fefb0f..1ca217e8 100644 --- a/vendor/github.com/prometheus/procfs/stat.go +++ b/vendor/github.com/prometheus/procfs/stat.go @@ -3,6 +3,7 @@ package procfs import ( "bufio" "fmt" + "os" "strconv" "strings" ) @@ -25,7 +26,7 @@ func NewStat() (Stat, error) { // NewStat returns an information about current kernel/system statistics. func (fs FS) NewStat() (Stat, error) { - f, err := fs.open("stat") + f, err := os.Open(fs.Path("stat")) if err != nil { return Stat{}, err } diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go index caa7e0a3..209f9eba 100644 --- a/vendor/github.com/ugorji/go/codec/0doc.go +++ b/vendor/github.com/ugorji/go/codec/0doc.go @@ -64,10 +64,11 @@ Rich Feature Set includes: - Never silently skip data when decoding. User decides whether to return an error or silently skip data when keys or indexes in the data stream do not map to fields in the struct. + - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown) - Encode/Decode from/to chan types (for iterative streaming support) - Drop-in replacement for encoding/json. `json:` key in struct tag supported. - Provides a RPC Server and Client Codec for net/rpc communication protocol. - - Handle unique idiosynchracies of codecs e.g. + - Handle unique idiosyncrasies of codecs e.g. - For messagepack, configure how ambiguities in handling raw bytes are resolved - For messagepack, provide rpc server/client codec to support msgpack-rpc protocol defined at: @@ -171,6 +172,8 @@ package codec // TODO: // +// - optimization for codecgen: +// if len of entity is <= 3 words, then support a value receiver for encode. // - (En|De)coder should store an error when it occurs. // Until reset, subsequent calls return that error that was stored. // This means that free panics must go away. @@ -178,16 +181,19 @@ package codec // - Decoding using a chan is good, but incurs concurrency costs. // This is because there's no fast way to use a channel without it // having to switch goroutines constantly. -// Callback pattern is still the best. Maybe cnsider supporting something like: +// Callback pattern is still the best. Maybe consider supporting something like: // type X struct { // Name string // Ys []Y // Ys chan <- Y -// Ys func(interface{}) -> call this interface for each entry in there. +// Ys func(Y) -> call this function for each entry // } // - Consider adding a isZeroer interface { isZero() bool } // It is used within isEmpty, for omitEmpty support. // - Consider making Handle used AS-IS within the encoding/decoding session. // This means that we don't cache Handle information within the (En|De)coder, // except we really need it at Reset(...) -// - Handle recursive types during encoding/decoding? +// - Consider adding math/big support +// - Consider reducing the size of the generated functions: +// Maybe use one loop, and put the conditionals in the loop. +// for ... { if cLen > 0 { if j == cLen { break } } else if dd.CheckBreak() { break } } diff --git a/vendor/github.com/ugorji/go/codec/binc.go b/vendor/github.com/ugorji/go/codec/binc.go index c884d14d..33120dcb 100644 --- a/vendor/github.com/ugorji/go/codec/binc.go +++ b/vendor/github.com/ugorji/go/codec/binc.go @@ -348,6 +348,13 @@ func (d *bincDecDriver) readNextBd() { d.bdRead = true } +func (d *bincDecDriver) uncacheRead() { + if d.bdRead { + d.r.unreadn1() + d.bdRead = false + } +} + func (d *bincDecDriver) ContainerType() (vt valueType) { if d.vd == bincVdSpecial && d.vs == bincSpNil { return valueTypeNil @@ -705,7 +712,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) } func (d *bincDecDriver) DecodeString() (s string) { - // DecodeBytes does not accomodate symbols, whose impl stores string version in map. + // DecodeBytes does not accommodate symbols, whose impl stores string version in map. // Use decStringAndBytes directly. // return string(d.DecodeBytes(d.b[:], true, true)) _, s = d.decStringAndBytes(d.b[:], true, true) @@ -908,10 +915,14 @@ func (h *BincHandle) newDecDriver(d *Decoder) decDriver { func (e *bincEncDriver) reset() { e.w = e.e.w + e.s = 0 + e.m = nil } func (d *bincDecDriver) reset() { d.r = d.d.r + d.s = nil + d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0 } var _ decDriver = (*bincDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/cbor.go b/vendor/github.com/ugorji/go/codec/cbor.go index 0e5d32b2..4fa349ac 100644 --- a/vendor/github.com/ugorji/go/codec/cbor.go +++ b/vendor/github.com/ugorji/go/codec/cbor.go @@ -188,6 +188,13 @@ func (d *cborDecDriver) readNextBd() { d.bdRead = true } +func (d *cborDecDriver) uncacheRead() { + if d.bdRead { + d.r.unreadn1() + d.bdRead = false + } +} + func (d *cborDecDriver) ContainerType() (vt valueType) { if d.bd == cborBdNil { return valueTypeNil @@ -508,7 +515,7 @@ func (d *cborDecDriver) DecodeNaked() { n.v = valueTypeExt n.u = d.decUint() n.l = nil - d.bdRead = false + // d.bdRead = false // d.d.decode(&re.Value) // handled by decode itself. // decodeFurther = true default: @@ -578,6 +585,7 @@ func (e *cborEncDriver) reset() { func (d *cborDecDriver) reset() { d.r = d.d.r + d.bd, d.bdRead = 0, false } var _ decDriver = (*cborDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/decode.go b/vendor/github.com/ugorji/go/codec/decode.go index b3b99f03..52c1dfe8 100644 --- a/vendor/github.com/ugorji/go/codec/decode.go +++ b/vendor/github.com/ugorji/go/codec/decode.go @@ -91,10 +91,12 @@ type decDriver interface { uncacheRead() } -type decNoSeparator struct{} +type decNoSeparator struct { +} -func (_ decNoSeparator) ReadEnd() {} -func (_ decNoSeparator) uncacheRead() {} +func (_ decNoSeparator) ReadEnd() {} + +// func (_ decNoSeparator) uncacheRead() {} type DecodeOptions struct { // MapType specifies type to use during schema-less decoding of a map in the stream. @@ -161,6 +163,15 @@ type DecodeOptions struct { // Note: Handles will be smart when using the intern functionality. // So everything will not be interned. InternString bool + + // PreferArrayOverSlice controls whether to decode to an array or a slice. + // + // This only impacts decoding into a nil interface{}. + // Consequently, it has no effect on codecgen. + // + // *Note*: This only applies if using go1.5 and above, + // as it requires reflect.ArrayOf support which was absent before go1.5. + PreferArrayOverSlice bool } // ------------------------------------ @@ -433,6 +444,10 @@ func (f *decFnInfo) rawExt(rv reflect.Value) { f.d.d.DecodeExt(rv.Addr().Interface(), 0, nil) } +func (f *decFnInfo) raw(rv reflect.Value) { + rv.SetBytes(f.d.raw()) +} + func (f *decFnInfo) ext(rv reflect.Value) { f.d.d.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn) } @@ -583,14 +598,16 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { if d.mtid == 0 || d.mtid == mapIntfIntfTypId { l := len(n.ms) n.ms = append(n.ms, nil) - d.decode(&n.ms[l]) - rvn = reflect.ValueOf(&n.ms[l]).Elem() + var v2 interface{} = &n.ms[l] + d.decode(v2) + rvn = reflect.ValueOf(v2).Elem() n.ms = n.ms[:l] } else if d.mtid == mapStrIntfTypId { // for json performance l := len(n.ns) n.ns = append(n.ns, nil) - d.decode(&n.ns[l]) - rvn = reflect.ValueOf(&n.ns[l]).Elem() + var v2 interface{} = &n.ns[l] + d.decode(v2) + rvn = reflect.ValueOf(v2).Elem() n.ns = n.ns[:l] } else { rvn = reflect.New(d.h.MapType).Elem() @@ -601,9 +618,13 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { if d.stid == 0 || d.stid == intfSliceTypId { l := len(n.ss) n.ss = append(n.ss, nil) - d.decode(&n.ss[l]) - rvn = reflect.ValueOf(&n.ss[l]).Elem() + var v2 interface{} = &n.ss[l] + d.decode(v2) n.ss = n.ss[:l] + rvn = reflect.ValueOf(v2).Elem() + if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice { + rvn = reflectArrayOf(rvn) + } } else { rvn = reflect.New(d.h.SliceType).Elem() d.decodeValue(rvn, nil) @@ -615,9 +636,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { l := len(n.is) n.is = append(n.is, nil) v2 := &n.is[l] - n.is = n.is[:l] d.decode(v2) v = *v2 + n.is = n.is[:l] } bfn := d.h.getExtForTag(tag) if bfn == nil { @@ -1166,7 +1187,7 @@ type decRtidFn struct { // primitives are being decoded. // // maps and arrays are not handled by this mechanism. -// However, RawExt is, and we accomodate for extensions that decode +// However, RawExt is, and we accommodate for extensions that decode // RawExt from DecodeNaked, but need to decode the value subsequently. // kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat. // @@ -1453,8 +1474,8 @@ func (d *Decoder) swallow() { l := len(n.is) n.is = append(n.is, nil) v2 := &n.is[l] - n.is = n.is[:l] d.decode(v2) + n.is = n.is[:l] } } } @@ -1504,6 +1525,8 @@ func (d *Decoder) decode(iv interface{}) { *v = 0 case *[]uint8: *v = nil + case *Raw: + *v = nil case reflect.Value: if v.Kind() != reflect.Ptr || v.IsNil() { d.errNotValidPtrValue(v) @@ -1543,7 +1566,6 @@ func (d *Decoder) decode(iv interface{}) { d.decodeValueNotNil(v.Elem(), nil) case *string: - *v = d.d.DecodeString() case *bool: *v = d.d.DecodeBool() @@ -1574,6 +1596,9 @@ func (d *Decoder) decode(iv interface{}) { case *[]uint8: *v = d.d.DecodeBytes(*v, false, false) + case *Raw: + *v = d.raw() + case *interface{}: d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), nil) @@ -1695,6 +1720,8 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool fn.f = (*decFnInfo).selferUnmarshal } else if rtid == rawExtTypId { fn.f = (*decFnInfo).rawExt + } else if rtid == rawTypId { + fn.f = (*decFnInfo).raw } else if d.d.IsBuiltinType(rtid) { fn.f = (*decFnInfo).builtin } else if xfFn := d.h.getExt(rtid); xfFn != nil { @@ -1793,12 +1820,13 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool } func (d *Decoder) structFieldNotFound(index int, rvkencname string) { + // NOTE: rvkencname may be a stringView, so don't pass it to another function. if d.h.ErrorIfNoField { if index >= 0 { d.errorf("no matching struct field found when decoding stream array at index %v", index) return } else if rvkencname != "" { - d.errorf("no matching struct field found when decoding stream map with key %s", rvkencname) + d.errorf("no matching struct field found when decoding stream map with key " + rvkencname) return } } @@ -1862,6 +1890,7 @@ func (d *Decoder) intern(s string) { } } +// nextValueBytes returns the next value in the stream as a set of bytes. func (d *Decoder) nextValueBytes() []byte { d.d.uncacheRead() d.r.track() @@ -1869,6 +1898,15 @@ func (d *Decoder) nextValueBytes() []byte { return d.r.stopTrack() } +func (d *Decoder) raw() []byte { + // ensure that this is not a view into the bytes + // i.e. make new copy always. + bs := d.nextValueBytes() + bs2 := make([]byte, len(bs)) + copy(bs2, bs) + return bs2 +} + // -------------------------------------------------- // decSliceHelper assists when decoding into a slice, from a map or an array in the stream. diff --git a/vendor/github.com/ugorji/go/codec/decode_go.go b/vendor/github.com/ugorji/go/codec/decode_go.go new file mode 100644 index 00000000..ba289cef --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/decode_go.go @@ -0,0 +1,16 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build go1.5 + +package codec + +import "reflect" + +const reflectArrayOfSupported = true + +func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) { + rvn2 = reflect.New(reflect.ArrayOf(rvn.Len(), intfTyp)).Elem() + reflect.Copy(rvn2, rvn) + return +} diff --git a/vendor/github.com/ugorji/go/codec/decode_go14.go b/vendor/github.com/ugorji/go/codec/decode_go14.go new file mode 100644 index 00000000..50063bc8 --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/decode_go14.go @@ -0,0 +1,14 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build !go1.5 + +package codec + +import "reflect" + +const reflectArrayOfSupported = false + +func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) { + panic("reflect.ArrayOf unsupported") +} diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go index 99af6fa5..c2cef812 100644 --- a/vendor/github.com/ugorji/go/codec/encode.go +++ b/vendor/github.com/ugorji/go/codec/encode.go @@ -110,6 +110,28 @@ type EncodeOptions struct { // Canonical bool + // CheckCircularRef controls whether we check for circular references + // and error fast during an encode. + // + // If enabled, an error is received if a pointer to a struct + // references itself either directly or through one of its fields (iteratively). + // + // This is opt-in, as there may be a performance hit to checking circular references. + CheckCircularRef bool + + // RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers + // when checking if a value is empty. + // + // Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls. + RecursiveEmptyCheck bool + + // Raw controls whether we encode Raw values. + // This is a "dangerous" option and must be explicitly set. + // If set, we blindly encode Raw values as-is, without checking + // if they are a correct representation of a value in that format. + // If unset, we error out. + Raw bool + // AsSymbols defines what should be encoded as symbols. // // Encoding as symbols can reduce the encoded size significantly. @@ -132,13 +154,16 @@ type simpleIoEncWriterWriter struct { w io.Writer bw io.ByteWriter sw ioEncStringWriter + bs [1]byte } func (o *simpleIoEncWriterWriter) WriteByte(c byte) (err error) { if o.bw != nil { return o.bw.WriteByte(c) } - _, err = o.w.Write([]byte{c}) + // _, err = o.w.Write([]byte{c}) + o.bs[0] = c + _, err = o.w.Write(o.bs[:]) return } @@ -210,45 +235,57 @@ type bytesEncWriter struct { } func (z *bytesEncWriter) writeb(s []byte) { - if len(s) > 0 { - c := z.grow(len(s)) - copy(z.b[c:], s) + if len(s) == 0 { + return } + oc, a := z.growNoAlloc(len(s)) + if a { + z.growAlloc(len(s), oc) + } + copy(z.b[oc:], s) } func (z *bytesEncWriter) writestr(s string) { - if len(s) > 0 { - c := z.grow(len(s)) - copy(z.b[c:], s) + if len(s) == 0 { + return } + oc, a := z.growNoAlloc(len(s)) + if a { + z.growAlloc(len(s), oc) + } + copy(z.b[oc:], s) } func (z *bytesEncWriter) writen1(b1 byte) { - c := z.grow(1) - z.b[c] = b1 + oc, a := z.growNoAlloc(1) + if a { + z.growAlloc(1, oc) + } + z.b[oc] = b1 } func (z *bytesEncWriter) writen2(b1 byte, b2 byte) { - c := z.grow(2) - z.b[c] = b1 - z.b[c+1] = b2 + oc, a := z.growNoAlloc(2) + if a { + z.growAlloc(2, oc) + } + z.b[oc+1] = b2 + z.b[oc] = b1 } func (z *bytesEncWriter) atEndOfEncode() { *(z.out) = z.b[:z.c] } -func (z *bytesEncWriter) grow(n int) (oldcursor int) { +// have a growNoalloc(n int), which can be inlined. +// if allocation is needed, then call growAlloc(n int) + +func (z *bytesEncWriter) growNoAlloc(n int) (oldcursor int, allocNeeded bool) { oldcursor = z.c - z.c = oldcursor + n + z.c = z.c + n if z.c > len(z.b) { if z.c > cap(z.b) { - // appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls. - // bytes.Buffer model (2*cap + n): much better - // bs := make([]byte, 2*cap(z.b)+n) - bs := make([]byte, growCap(cap(z.b), 1, n)) - copy(bs, z.b[:oldcursor]) - z.b = bs + allocNeeded = true } else { z.b = z.b[:cap(z.b)] } @@ -256,6 +293,15 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) { return } +func (z *bytesEncWriter) growAlloc(n int, oldcursor int) { + // appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls. + // bytes.Buffer model (2*cap + n): much better + // bs := make([]byte, 2*cap(z.b)+n) + bs := make([]byte, growCap(cap(z.b), 1, n)) + copy(bs, z.b[:oldcursor]) + z.b = bs +} + // --------------------------------------------- type encFnInfo struct { @@ -270,6 +316,10 @@ func (f *encFnInfo) builtin(rv reflect.Value) { f.e.e.EncodeBuiltin(f.ti.rtid, rv.Interface()) } +func (f *encFnInfo) raw(rv reflect.Value) { + f.e.raw(rv.Interface().(Raw)) +} + func (f *encFnInfo) rawExt(rv reflect.Value) { // rev := rv.Interface().(RawExt) // f.e.e.EncodeRawExt(&rev, f.e) @@ -296,7 +346,7 @@ func (f *encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v v = rv.Interface() } else if indir == -1 { // If a non-pointer was passed to Encode(), then that value is not addressable. - // Take addr if addresable, else copy value to an addressable value. + // Take addr if addressable, else copy value to an addressable value. if rv.CanAddr() { v = rv.Addr().Interface() } else { @@ -464,7 +514,7 @@ func (f *encFnInfo) kSlice(rv reflect.Value) { for j := 0; j < l; j++ { if cr != nil { if ti.mbs { - if l%2 == 0 { + if j%2 == 0 { cr.sendContainerState(containerMapKey) } else { cr.sendContainerState(containerMapValue) @@ -503,7 +553,7 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { newlen := len(fti.sfi) // Use sync.Pool to reduce allocating slices unnecessarily. - // The cost of the occasional locking is less than the cost of new allocation. + // The cost of sync.Pool is less than the cost of new allocation. pool, poolv, fkvs := encStructPoolGet(newlen) // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct) @@ -512,25 +562,20 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { } newlen = 0 var kv stringRv + recur := e.h.RecursiveEmptyCheck for _, si := range tisfi { kv.r = si.field(rv, false) - // if si.i != -1 { - // rvals[newlen] = rv.Field(int(si.i)) - // } else { - // rvals[newlen] = rv.FieldByIndex(si.is) - // } if toMap { - if si.omitEmpty && isEmptyValue(kv.r) { + if si.omitEmpty && isEmptyValue(kv.r, recur, recur) { continue } kv.v = si.encName } else { // use the zero value. // if a reference or struct, set to nil (so you do not output too much) - if si.omitEmpty && isEmptyValue(kv.r) { + if si.omitEmpty && isEmptyValue(kv.r, recur, recur) { switch kv.r.Kind() { - case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, - reflect.Map, reflect.Slice: + case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice: kv.r = reflect.Value{} //encode as nil } } @@ -541,7 +586,7 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { // debugf(">>>> kStruct: newlen: %v", newlen) // sep := !e.be - ee := e.e //don't dereference everytime + ee := e.e //don't dereference every time if toMap { ee.EncodeMapStart(newlen) @@ -596,13 +641,15 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { // f.e.encodeValue(rv.Elem()) // } -func (f *encFnInfo) kInterface(rv reflect.Value) { - if rv.IsNil() { - f.e.e.EncodeNil() - return - } - f.e.encodeValue(rv.Elem(), nil) -} +// func (f *encFnInfo) kInterface(rv reflect.Value) { +// println("kInterface called") +// debug.PrintStack() +// if rv.IsNil() { +// f.e.e.EncodeNil() +// return +// } +// f.e.encodeValue(rv.Elem(), nil) +// } func (f *encFnInfo) kMap(rv reflect.Value) { ee := f.e.e @@ -877,6 +924,7 @@ type Encoder struct { // as the handler MAY need to do some coordination. w encWriter s []encRtidFn + ci set be bool // is binary encoding js bool // is json handle @@ -925,7 +973,7 @@ func newEncoder(h Handle) *Encoder { // Reset the Encoder with a new output stream. // -// This accomodates using the state of the Encoder, +// This accommodates using the state of the Encoder, // where it has "cached" information about sub-engines. func (e *Encoder) Reset(w io.Writer) { ww, ok := w.(ioEncWriterWriter) @@ -1032,20 +1080,6 @@ func (e *Encoder) MustEncode(v interface{}) { e.w.atEndOfEncode() } -// comment out these (Must)Write methods. They were only put there to support cbor. -// However, users already have access to the streams, and can write directly. -// -// // Write allows users write to the Encoder stream directly. -// func (e *Encoder) Write(bs []byte) (err error) { -// defer panicToErr(&err) -// e.w.writeb(bs) -// return -// } -// // MustWrite is like write, but panics if unable to Write. -// func (e *Encoder) MustWrite(bs []byte) { -// e.w.writeb(bs) -// } - func (e *Encoder) encode(iv interface{}) { // if ics, ok := iv.(Selfer); ok { // ics.CodecEncodeSelf(e) @@ -1057,7 +1091,8 @@ func (e *Encoder) encode(iv interface{}) { e.e.EncodeNil() case Selfer: v.CodecEncodeSelf(e) - + case Raw: + e.raw(v) case reflect.Value: e.encodeValue(v, nil) @@ -1133,20 +1168,23 @@ func (e *Encoder) encode(iv interface{}) { } } -func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) { - if rv, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { - rt := rv.Type() - rtid := reflect.ValueOf(rt).Pointer() - fn := e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) - fn.f(&fn.i, rv) - } -} - -func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) { +func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) { // use a goto statement instead of a recursive function for ptr/interface. TOP: switch rv.Kind() { - case reflect.Ptr, reflect.Interface: + case reflect.Ptr: + if rv.IsNil() { + e.e.EncodeNil() + return + } + rv = rv.Elem() + if e.h.CheckCircularRef && rv.Kind() == reflect.Struct { + // TODO: Movable pointers will be an issue here. Future problem. + sptr = rv.UnsafeAddr() + break TOP + } + goto TOP + case reflect.Interface: if rv.IsNil() { e.e.EncodeNil() return @@ -1163,18 +1201,40 @@ TOP: return } - return rv, true + proceed = true + rv2 = rv + return +} + +func (e *Encoder) doEncodeValue(rv reflect.Value, fn *encFn, sptr uintptr, + checkFastpath, checkCodecSelfer bool) { + if sptr != 0 { + if (&e.ci).add(sptr) { + e.errorf("circular reference found: # %d", sptr) + } + } + if fn == nil { + rt := rv.Type() + rtid := reflect.ValueOf(rt).Pointer() + // fn = e.getEncFn(rtid, rt, true, true) + fn = e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) + } + fn.f(&fn.i, rv) + if sptr != 0 { + (&e.ci).remove(sptr) + } +} + +func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) { + if rv, sptr, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { + e.doEncodeValue(rv, nil, sptr, checkFastpath, checkCodecSelfer) + } } func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) { // if a valid fn is passed, it MUST BE for the dereferenced type of rv - if rv, proceed := e.preEncodeValue(rv); proceed { - if fn == nil { - rt := rv.Type() - rtid := reflect.ValueOf(rt).Pointer() - fn = e.getEncFn(rtid, rt, true, true) - } - fn.f(&fn.i, rv) + if rv, sptr, proceed := e.preEncodeValue(rv); proceed { + e.doEncodeValue(rv, fn, sptr, true, true) } } @@ -1217,6 +1277,8 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if checkCodecSelfer && ti.cs { fn.f = (*encFnInfo).selferMarshal + } else if rtid == rawTypId { + fn.f = (*encFnInfo).raw } else if rtid == rawExtTypId { fn.f = (*encFnInfo).rawExt } else if e.e.IsBuiltinType(rtid) { @@ -1234,7 +1296,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo } else { rk := rt.Kind() if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { - if rt.PkgPath() == "" { + if rt.PkgPath() == "" { // un-named slice or map if idx := fastpathAV.index(rtid); idx != -1 { fn.f = fastpathAV[idx].encfn } @@ -1284,10 +1346,11 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo fn.f = (*encFnInfo).kSlice case reflect.Struct: fn.f = (*encFnInfo).kStruct + // reflect.Ptr and reflect.Interface are handled already by preEncodeValue // case reflect.Ptr: // fn.f = (*encFnInfo).kPtr - case reflect.Interface: - fn.f = (*encFnInfo).kInterface + // case reflect.Interface: + // fn.f = (*encFnInfo).kInterface case reflect.Map: fn.f = (*encFnInfo).kMap default: @@ -1320,6 +1383,18 @@ func (e *Encoder) asis(v []byte) { } } +func (e *Encoder) raw(vv Raw) { + v := []byte(vv) + if !e.h.Raw { + e.errorf("Raw values cannot be encoded: %v", v) + } + if e.as == nil { + e.w.writeb(v) + } else { + e.as.EncodeAsis(v) + } +} + func (e *Encoder) errorf(format string, params ...interface{}) { err := fmt.Errorf(format, params...) panic(err) @@ -1353,25 +1428,6 @@ func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) { // panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed // } // idxpool := newlen / 8 - - // if pool == nil { - // fkvs = make([]stringRv, newlen) - // } else { - // poolv = pool.Get() - // switch vv := poolv.(type) { - // case *[8]stringRv: - // fkvs = vv[:newlen] - // case *[16]stringRv: - // fkvs = vv[:newlen] - // case *[32]stringRv: - // fkvs = vv[:newlen] - // case *[64]stringRv: - // fkvs = vv[:newlen] - // case *[128]stringRv: - // fkvs = vv[:newlen] - // } - // } - if newlen <= 8 { p = &encStructPool[0] v = p.Get() diff --git a/vendor/github.com/ugorji/go/codec/fast-path.generated.go b/vendor/github.com/ugorji/go/codec/fast-path.generated.go index d968a500..f2e5d2dc 100644 --- a/vendor/github.com/ugorji/go/codec/fast-path.generated.go +++ b/vendor/github.com/ugorji/go/codec/fast-path.generated.go @@ -23,7 +23,7 @@ package codec // Currently support // - slice of all builtin types, // - map of all builtin types to string or interface value -// - symetrical maps of all builtin types (e.g. str-str, uint8-uint8) +// - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8) // This should provide adequate "typical" implementations. // // Note that fast track decode functions must handle values for which an address cannot be obtained. @@ -38,6 +38,8 @@ import ( "sort" ) +const fastpathEnabled = true + const fastpathCheckNilFalse = false // for reflect const fastpathCheckNilTrue = true // for type switch @@ -81,9 +83,6 @@ var fastpathAV fastpathA // due to possible initialization loop error, make fastpath in an init() func init() { - if !fastpathEnabled { - return - } i := 0 fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) { xrt := reflect.TypeOf(v) @@ -373,9 +372,6 @@ func init() { // -- -- fast path type switch func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { - if !fastpathEnabled { - return false - } switch v := iv.(type) { case []interface{}: @@ -1741,9 +1737,6 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { } func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { - if !fastpathEnabled { - return false - } switch v := iv.(type) { case []interface{}: @@ -1829,9 +1822,6 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { } func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { - if !fastpathEnabled { - return false - } switch v := iv.(type) { case map[interface{}]interface{}: @@ -3124,7 +3114,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { // -- -- fast path functions func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { - fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { ee := e.e @@ -3145,8 +3139,39 @@ func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { - fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { ee := e.e @@ -3167,8 +3192,39 @@ func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceStringV(v []string, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeString(c_UTF8, v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { - fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { ee := e.e @@ -3189,8 +3245,39 @@ func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeFloat32(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { - fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { ee := e.e @@ -3211,8 +3298,39 @@ func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeFloat64(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { - fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { ee := e.e @@ -3233,8 +3351,39 @@ func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceUintV(v []uint, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { - fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { ee := e.e @@ -3255,8 +3404,39 @@ func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { - fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { ee := e.e @@ -3277,8 +3457,39 @@ func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { - fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { ee := e.e @@ -3299,8 +3510,39 @@ func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceUintptrR(rv reflect.Value) { - fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { ee := e.e @@ -3321,8 +3563,39 @@ func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { - fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { ee := e.e @@ -3343,8 +3616,39 @@ func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceIntV(v []int, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { - fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { ee := e.e @@ -3365,8 +3669,39 @@ func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceInt8V(v []int8, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { - fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { ee := e.e @@ -3387,8 +3722,39 @@ func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceInt16V(v []int16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { - fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { ee := e.e @@ -3409,8 +3775,39 @@ func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceInt32V(v []int32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { - fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { ee := e.e @@ -3431,8 +3828,39 @@ func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceInt64V(v []int64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { - fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) + if f.ti.mbs { + fastpathTV.EncAsMapSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { ee := e.e @@ -3453,6 +3881,33 @@ func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { } } +func (_ fastpathT) EncAsMapSliceBoolV(v []bool, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeBool(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e) } @@ -15489,9 +15944,6 @@ func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) { // -- -- fast path type switch func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { - if !fastpathEnabled { - return false - } switch v := iv.(type) { case []interface{}: @@ -17712,7 +18164,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -17771,7 +18223,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]interface{}, 1, 4) @@ -17846,7 +18298,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -17905,7 +18357,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]string, 1, 4) @@ -17979,7 +18431,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18038,7 +18490,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]float32, 1, 4) @@ -18112,7 +18564,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18171,7 +18623,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]float64, 1, 4) @@ -18245,7 +18697,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18304,7 +18756,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]uint, 1, 4) @@ -18378,7 +18830,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18437,7 +18889,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]uint16, 1, 4) @@ -18511,7 +18963,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18570,7 +19022,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]uint32, 1, 4) @@ -18644,7 +19096,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18703,7 +19155,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]uint64, 1, 4) @@ -18777,7 +19229,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18836,7 +19288,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]uintptr, 1, 4) @@ -18910,7 +19362,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -18969,7 +19421,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]int, 1, 4) @@ -19043,7 +19495,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -19102,7 +19554,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]int8, 1, 4) @@ -19176,7 +19628,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -19235,7 +19687,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]int16, 1, 4) @@ -19309,7 +19761,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -19368,7 +19820,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]int32, 1, 4) @@ -19442,7 +19894,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -19501,7 +19953,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]int64, 1, 4) @@ -19575,7 +20027,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if containerLenS > 0 { @@ -19634,7 +20086,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return + return v, changed } if cap(v) == 0 { v = make([]bool, 1, 4) diff --git a/vendor/github.com/ugorji/go/codec/fast-path.not.go b/vendor/github.com/ugorji/go/codec/fast-path.not.go index d6f5f0c9..63e59114 100644 --- a/vendor/github.com/ugorji/go/codec/fast-path.not.go +++ b/vendor/github.com/ugorji/go/codec/fast-path.not.go @@ -4,6 +4,8 @@ package codec import "reflect" +const fastpathEnabled = false + // The generated fast-path code is very large, and adds a few seconds to the build time. // This causes test execution, execution of small tools which use codec, etc // to take a long time. diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go index 22bce776..96a6b61d 100644 --- a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go +++ b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go @@ -1,4 +1,4 @@ -// //+build ignore +// // +build ignore // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. @@ -17,7 +17,7 @@ import ( // This file is used to generate helper code for codecgen. // The values here i.e. genHelper(En|De)coder are not to be used directly by -// library users. They WILL change continously and without notice. +// library users. They WILL change continuously and without notice. // // To help enforce this, we create an unexported type with exported members. // The only way to get the type is via the one exported type that we control (somewhat). @@ -83,6 +83,11 @@ func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) { f.e.marshal(bs, fnerr, false, c_RAW) } +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncRaw(iv Raw) { + f.e.raw(iv) +} + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperEncoder) TimeRtidIfBinc() uintptr { if _, ok := f.e.hh.(*BincHandle); ok { @@ -191,6 +196,11 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { } } +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecRaw() []byte { + return f.d.raw() +} + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperDecoder) TimeRtidIfBinc() uintptr { if _, ok := f.d.hh.(*BincHandle); ok { diff --git a/vendor/github.com/ugorji/go/codec/gen.generated.go b/vendor/github.com/ugorji/go/codec/gen.generated.go index fb6f4b80..2ace97b7 100644 --- a/vendor/github.com/ugorji/go/codec/gen.generated.go +++ b/vendor/github.com/ugorji/go/codec/gen.generated.go @@ -68,8 +68,9 @@ z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) const genDecListTmpl = ` {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} var {{var "c"}} bool {{/* // changed */}} +_ = {{var "c"}}{{end}} if {{var "l"}} == 0 { {{if isSlice }}if {{var "v"}} == nil { {{var "v"}} = []{{ .Typ }}{} @@ -95,6 +96,8 @@ if {{var "l"}} == 0 { } {{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}} var {{var "rt"}} bool {{/* truncated */}} + _, _ = {{var "rl"}}, {{var "rt"}} + {{var "rr"}} = {{var "l"}} // len({{var "v"}}) if {{var "l"}} > cap({{var "v"}}) { {{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) {{ else }}{{if not .Immutable }} diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go index a075e7c0..1a27675f 100644 --- a/vendor/github.com/ugorji/go/codec/gen.go +++ b/vendor/github.com/ugorji/go/codec/gen.go @@ -12,7 +12,6 @@ import ( "io" "io/ioutil" "math/rand" - "os" "reflect" "regexp" "sort" @@ -21,11 +20,14 @@ import ( "sync" "text/template" "time" + "unicode" + "unicode/utf8" ) // --------------------------------------------------- // codecgen supports the full cycle of reflection-based codec: // - RawExt +// - Raw // - Builtins // - Extensions // - (Binary|Text|JSON)(Unm|M)arshal @@ -76,7 +78,7 @@ import ( // codecgen will panic if the file was generated with an old version of the library in use. // // Note: -// It was a concious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil. +// It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil. // This way, there isn't a function call overhead just to see that we should not enter a block of code. // GenVersion is the current version of codecgen. @@ -124,6 +126,7 @@ var ( genExpectArrayOrMapErr = errors.New("unexpected type. Expecting array/map/slice") genBase64enc = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__") genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`) + genCheckVendor bool ) // genRunner holds some state used during a Gen run. @@ -162,6 +165,16 @@ type genRunner struct { // // Library users: *DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.* func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeInfos, typ ...reflect.Type) { + // trim out all types which already implement Selfer + typ2 := make([]reflect.Type, 0, len(typ)) + for _, t := range typ { + if reflect.PtrTo(t).Implements(selferTyp) || t.Implements(selferTyp) { + continue + } + typ2 = append(typ2, t) + } + typ = typ2 + if len(typ) == 0 { return } @@ -199,7 +212,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn x.genRefPkgs(t) } if buildTags != "" { - x.line("//+build " + buildTags) + x.line("// +build " + buildTags) x.line("") } x.line(` @@ -266,6 +279,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn x.line("type " + x.hn + " struct{}") x.line("") + x.varsfxreset() x.line("func init() {") x.linef("if %sGenVersion != %v {", x.cpfx, GenVersion) x.line("_, file, _, _ := runtime.Caller(0)") @@ -309,6 +323,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn for _, t := range x.ts { rtid := reflect.ValueOf(t).Pointer() // generate enc functions for all these slice/map types. + x.varsfxreset() x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx) x.genRequiredMethodVars(true) switch t.Kind() { @@ -323,6 +338,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn x.line("") // generate dec functions for all these slice/map types. + x.varsfxreset() x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx) x.genRequiredMethodVars(false) switch t.Kind() { @@ -377,7 +393,7 @@ func (x *genRunner) genRefPkgs(t reflect.Type) { x.imn[tpkg] = tpkg } else { x.imc++ - x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + tpkg[idx+1:] + x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false) } } } @@ -408,6 +424,10 @@ func (x *genRunner) varsfx() string { return strconv.FormatUint(x.c, 10) } +func (x *genRunner) varsfxreset() { + x.c = 0 +} + func (x *genRunner) out(s string) { if _, err := io.WriteString(x.w, s); err != nil { panic(err) @@ -494,6 +514,7 @@ func (x *genRunner) selfer(encode bool) { // always make decode use a pointer receiver, // and structs always use a ptr receiver (encode|decode) isptr := !encode || t.Kind() == reflect.Struct + x.varsfxreset() fnSigPfx := "func (x " if isptr { fnSigPfx += "*" @@ -566,9 +587,28 @@ func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) { } else { x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname) } - if _, ok := x.tm[t]; !ok { - x.tm[t] = struct{}{} - x.ts = append(x.ts, t) + x.registerXtraT(t) +} + +func (x *genRunner) registerXtraT(t reflect.Type) { + // recursively register the types + if _, ok := x.tm[t]; ok { + return + } + var tkey reflect.Type + switch t.Kind() { + case reflect.Chan, reflect.Slice, reflect.Array: + case reflect.Map: + tkey = t.Key() + default: + return + } + x.tm[t] = struct{}{} + x.ts = append(x.ts, t) + // check if this refers to any xtra types eg. a slice of array: add the array + x.registerXtraT(t.Elem()) + if tkey != nil { + x.registerXtraT(tkey) } } @@ -608,22 +648,33 @@ func (x *genRunner) encVar(varname string, t reflect.Type) { } -// enc will encode a variable (varname) of type T, -// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying) +// enc will encode a variable (varname) of type t, +// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying) func (x *genRunner) enc(varname string, t reflect.Type) { - // varName here must be to a pointer to a struct/array, or to a value directly. rtid := reflect.ValueOf(t).Pointer() // We call CodecEncodeSelf if one of the following are honored: // - the type already implements Selfer, call that // - the type has a Selfer implementation just created, use that // - the type is in the list of the ones we will generate for, but it is not currently being generated + mi := x.varsfx() tptr := reflect.PtrTo(t) tk := t.Kind() if x.checkForSelfer(t, varname) { - if t.Implements(selferTyp) || (tptr.Implements(selferTyp) && (tk == reflect.Array || tk == reflect.Struct)) { - x.line(varname + ".CodecEncodeSelf(e)") - return + if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T + if tptr.Implements(selferTyp) || t.Implements(selferTyp) { + x.line(varname + ".CodecEncodeSelf(e)") + return + } + } else { // varname is of type T + if t.Implements(selferTyp) { + x.line(varname + ".CodecEncodeSelf(e)") + return + } else if tptr.Implements(selferTyp) { + x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname) + x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi) + return + } } if _, ok := x.te[rtid]; ok { @@ -651,14 +702,17 @@ func (x *genRunner) enc(varname string, t reflect.Type) { } // check if - // - type is RawExt + // - type is RawExt, Raw // - the type implements (Text|JSON|Binary)(Unm|M)arshal - mi := x.varsfx() x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi) x.linef("_ = %sm%s", genTempVarPfx, mi) x.line("if false {") //start if block defer func() { x.line("}") }() //end if block + if t == rawTyp { + x.linef("} else { z.EncRaw(%v)", varname) + return + } if t == rawExtTyp { x.linef("} else { r.EncodeRawExt(%v, e)", varname) return @@ -676,15 +730,31 @@ func (x *genRunner) enc(varname string, t reflect.Type) { // first check if extensions are configued, before doing the interface conversion x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname) } - if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { - x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T + if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } + } else { // varname is of type T + if t.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname) + } } - if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { - x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) - } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { - x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) - } - x.line("} else {") switch t.Kind() { @@ -922,6 +992,14 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { } func (x *genRunner) encListFallback(varname string, t reflect.Type) { + if t.AssignableTo(uint8SliceTyp) { + x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, []byte(%s))", x.xs, varname) + return + } + if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 { + x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, ([%v]byte(%s))[:])", x.xs, t.Len(), varname) + return + } i := x.varsfx() g := genTempVarPfx x.line("r.EncodeArrayStart(len(" + varname + "))") @@ -1020,6 +1098,8 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { } } +// dec will decode a variable (varname) of type ptrTo(t). +// t is always a basetype (i.e. not of kind reflect.Ptr). func (x *genRunner) dec(varname string, t reflect.Type) { // assumptions: // - the varname is to a pointer already. No need to take address of it @@ -1056,7 +1136,7 @@ func (x *genRunner) dec(varname string, t reflect.Type) { } // check if - // - type is RawExt + // - type is Raw, RawExt // - the type implements (Text|JSON|Binary)(Unm|M)arshal mi := x.varsfx() x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi) @@ -1064,6 +1144,10 @@ func (x *genRunner) dec(varname string, t reflect.Type) { x.line("if false {") //start if block defer func() { x.line("}") }() //end if block + if t == rawTyp { + x.linef("} else { *%v = z.DecRaw()", varname) + return + } if t == rawExtTyp { x.linef("} else { r.DecodeExt(%v, 0, nil)", varname) return @@ -1189,59 +1273,49 @@ func (x *genRunner) dec(varname string, t reflect.Type) { } func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAsPtr bool) { - // We have to use the actual type name when doing a direct assignment. - // We don't have the luxury of casting the pointer to the underlying type. - // - // Consequently, in the situation of a - // type Message int32 - // var x Message - // var i int32 = 32 - // x = i // this will bomb - // x = Message(i) // this will work - // *((*int32)(&x)) = i // this will work - // - // Consequently, we replace: - // case reflect.Uint32: x.line(varname + " = uint32(r.DecodeUint(32))") - // with: - // case reflect.Uint32: x.line(varname + " = " + genTypeNamePrim(t, x.tc) + "(r.DecodeUint(32))") + // This should only be used for exact primitives (ie un-named types). + // Named types may be implementations of Selfer, Unmarshaler, etc. + // They should be handled by dec(...) - xfn := func(t reflect.Type) string { - return x.genTypeNamePrim(t) + if t.Name() != "" { + tryAsPtr = true + return } + switch t.Kind() { case reflect.Int: - x.linef("%s = %s(r.DecodeInt(codecSelferBitsize%s))", varname, xfn(t), x.xs) + x.linef("%s = r.DecodeInt(codecSelferBitsize%s)", varname, x.xs) case reflect.Int8: - x.linef("%s = %s(r.DecodeInt(8))", varname, xfn(t)) + x.linef("%s = r.DecodeInt(8)", varname) case reflect.Int16: - x.linef("%s = %s(r.DecodeInt(16))", varname, xfn(t)) + x.linef("%s = r.DecodeInt(16)", varname) case reflect.Int32: - x.linef("%s = %s(r.DecodeInt(32))", varname, xfn(t)) + x.linef("%s = r.DecodeInt(32)", varname) case reflect.Int64: - x.linef("%s = %s(r.DecodeInt(64))", varname, xfn(t)) + x.linef("%s = r.DecodeInt(64)", varname) case reflect.Uint: - x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs) + x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs) case reflect.Uint8: - x.linef("%s = %s(r.DecodeUint(8))", varname, xfn(t)) + x.linef("%s = r.DecodeUint(8)", varname) case reflect.Uint16: - x.linef("%s = %s(r.DecodeUint(16))", varname, xfn(t)) + x.linef("%s = r.DecodeUint(16)", varname) case reflect.Uint32: - x.linef("%s = %s(r.DecodeUint(32))", varname, xfn(t)) + x.linef("%s = r.DecodeUint(32)", varname) case reflect.Uint64: - x.linef("%s = %s(r.DecodeUint(64))", varname, xfn(t)) + x.linef("%s = r.DecodeUint(64)", varname) case reflect.Uintptr: - x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs) + x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs) case reflect.Float32: - x.linef("%s = %s(r.DecodeFloat(true))", varname, xfn(t)) + x.linef("%s = r.DecodeFloat(true)", varname) case reflect.Float64: - x.linef("%s = %s(r.DecodeFloat(false))", varname, xfn(t)) + x.linef("%s = r.DecodeFloat(false)", varname) case reflect.Bool: - x.linef("%s = %s(r.DecodeBool())", varname, xfn(t)) + x.linef("%s = r.DecodeBool()", varname) case reflect.String: - x.linef("%s = %s(r.DecodeString())", varname, xfn(t)) + x.linef("%s = r.DecodeString()", varname) default: tryAsPtr = true } @@ -1249,6 +1323,14 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs } func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) { + if t.AssignableTo(uint8SliceTyp) { + x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false, false)") + return + } + if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 { + x.linef("r.DecodeBytes( ((*[%s]byte)(%s))[:], false, true)", t.Len(), varname) + return + } type tstruc struct { TempVar string Rand string @@ -1364,7 +1446,7 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt if si.i != -1 { t2 = t.Field(int(si.i)) } else { - //we must accomodate anonymous fields, where the embedded field is a nil pointer in the value. + //we must accommodate anonymous fields, where the embedded field is a nil pointer in the value. // t2 = t.FieldByIndex(si.is) t2typ := t varname3 := varname @@ -1452,7 +1534,7 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid if si.i != -1 { t2 = t.Field(int(si.i)) } else { - //we must accomodate anonymous fields, where the embedded field is a nil pointer in the value. + //we must accommodate anonymous fields, where the embedded field is a nil pointer in the value. // t2 = t.FieldByIndex(si.is) t2typ := t varname3 := varname @@ -1569,8 +1651,6 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string { } -var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1" - // genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise. // // This handles the misbehaviour that occurs when 1.5-style vendoring is enabled, @@ -1592,6 +1672,26 @@ func genImportPath(t reflect.Type) (s string) { return } +// A go identifier is (letter|_)[letter|number|_]* +func genGoIdentifier(s string, checkFirstChar bool) string { + b := make([]byte, 0, len(s)) + t := make([]byte, 4) + var n int + for i, r := range s { + if checkFirstChar && i == 0 && !unicode.IsLetter(r) { + b = append(b, '_') + } + // r must be unicode_letter, unicode_digit or _ + if unicode.IsLetter(r) || unicode.IsDigit(r) { + n = utf8.EncodeRune(t, r) + b = append(b, t[:n]...) + } else { + b = append(b, '_') + } + } + return string(b) +} + func genNonPtr(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { t = t.Elem() @@ -1601,7 +1701,7 @@ func genNonPtr(t reflect.Type) reflect.Type { func genTitleCaseName(s string) string { switch s { - case "interface{}": + case "interface{}", "interface {}": return "Intf" default: return strings.ToUpper(s[0:1]) + s[1:] @@ -1704,7 +1804,7 @@ func (x genInternal) FastpathLen() (l int) { func genInternalZeroValue(s string) string { switch s { - case "interface{}": + case "interface{}", "interface {}": return "nil" case "bool": return "false" @@ -1856,7 +1956,7 @@ func genInternalInit() { } var gt genInternal - // For each slice or map type, there must be a (symetrical) Encode and Decode fast-path function + // For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function for _, s := range types { gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]}) if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already. diff --git a/vendor/github.com/ugorji/go/codec/gen_15.go b/vendor/github.com/ugorji/go/codec/gen_15.go new file mode 100644 index 00000000..ab76c310 --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/gen_15.go @@ -0,0 +1,12 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build go1.5,!go1.6 + +package codec + +import "os" + +func init() { + genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1" +} diff --git a/vendor/github.com/ugorji/go/codec/gen_16.go b/vendor/github.com/ugorji/go/codec/gen_16.go new file mode 100644 index 00000000..87c04e2e --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/gen_16.go @@ -0,0 +1,12 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build go1.6 + +package codec + +import "os" + +func init() { + genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0" +} diff --git a/vendor/github.com/ugorji/go/codec/gen_17.go b/vendor/github.com/ugorji/go/codec/gen_17.go new file mode 100644 index 00000000..3881a43c --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/gen_17.go @@ -0,0 +1,10 @@ +// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// +build go1.7 + +package codec + +func init() { + genCheckVendor = true +} diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go index 560014ae..8b94fc1e 100644 --- a/vendor/github.com/ugorji/go/codec/helper.go +++ b/vendor/github.com/ugorji/go/codec/helper.go @@ -38,10 +38,6 @@ package codec // a length prefix, or if it used explicit breaks. If length-prefixed, we assume that // it has to be binary, and we do not even try to read separators. // -// The only codec that may suffer (slightly) is cbor, and only when decoding indefinite-length. -// It may suffer because we treat it like a text-based codec, and read separators. -// However, this read is a no-op and the cost is insignificant. -// // Philosophy // ------------ // On decode, this codec will update containers appropriately: @@ -137,17 +133,6 @@ const ( // Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic. recoverPanicToErr = true - // Fast path functions try to create a fast path encode or decode implementation - // for common maps and slices, by by-passing reflection altogether. - fastpathEnabled = true - - // if checkStructForEmptyValue, check structs fields to see if an empty value. - // This could be an expensive call, so possibly disable it. - checkStructForEmptyValue = false - - // if derefForIsEmptyValue, deref pointers and interfaces when checking isEmptyValue - derefForIsEmptyValue = false - // if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first. // Only concern is that, if the slice already contained some garbage, we will decode into that garbage. // The chances of this are slim, so leave this "optimization". @@ -155,8 +140,10 @@ const ( resetSliceElemToZeroValue bool = false ) -var oneByteArr = [1]byte{0} -var zeroByteSlice = oneByteArr[:0:0] +var ( + oneByteArr = [1]byte{0} + zeroByteSlice = oneByteArr[:0:0] +) type charEncoding uint8 @@ -215,6 +202,41 @@ const ( containerArrayEnd ) +// sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo +type sfiIdx struct { + name string + index int +} + +// do not recurse if a containing type refers to an embedded type +// which refers back to its containing type (via a pointer). +// The second time this back-reference happens, break out, +// so as not to cause an infinite loop. +const rgetMaxRecursion = 2 + +// Anecdotally, we believe most types have <= 12 fields. +// Java's PMD rules set TooManyFields threshold to 15. +const rgetPoolTArrayLen = 12 + +type rgetT struct { + fNames []string + encNames []string + etypes []uintptr + sfis []*structFieldInfo +} + +type rgetPoolT struct { + fNames [rgetPoolTArrayLen]string + encNames [rgetPoolTArrayLen]string + etypes [rgetPoolTArrayLen]uintptr + sfis [rgetPoolTArrayLen]*structFieldInfo + sfiidx [rgetPoolTArrayLen]sfiIdx +} + +var rgetPool = sync.Pool{ + New: func() interface{} { return new(rgetPoolT) }, +} + type containerStateRecv interface { sendContainerState(containerState) } @@ -240,6 +262,7 @@ var ( stringTyp = reflect.TypeOf("") timeTyp = reflect.TypeOf(time.Time{}) rawExtTyp = reflect.TypeOf(RawExt{}) + rawTyp = reflect.TypeOf(Raw{}) uint8SliceTyp = reflect.TypeOf([]uint8(nil)) mapBySliceTyp = reflect.TypeOf((*MapBySlice)(nil)).Elem() @@ -257,6 +280,7 @@ var ( uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer() rawExtTypId = reflect.ValueOf(rawExtTyp).Pointer() + rawTypId = reflect.ValueOf(rawTyp).Pointer() intfTypId = reflect.ValueOf(intfTyp).Pointer() timeTypId = reflect.ValueOf(timeTyp).Pointer() stringTypId = reflect.ValueOf(stringTyp).Pointer() @@ -337,6 +361,11 @@ type Handle interface { isBinary() bool } +// Raw represents raw formatted bytes. +// We "blindly" store it during encode and store the raw bytes during decode. +// Note: it is dangerous during encode, so we may gate the behaviour behind an Encode flag which must be explicitly set. +type Raw []byte + // RawExt represents raw unprocessed extension data. // Some codecs will decode extension data as a *RawExt if there is no registered extension for the tag. // @@ -347,7 +376,7 @@ type RawExt struct { // Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types Data []byte // Value represents the extension, if Data is nil. - // Value is used by codecs (e.g. cbor) which use the format to do custom serialization of the types. + // Value is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types. Value interface{} } @@ -525,7 +554,7 @@ func (o *extHandle) AddExt( func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) { // o is a pointer, because we may need to initialize it if rt.PkgPath() == "" || rt.Kind() == reflect.Interface { - err = fmt.Errorf("codec.Handle.AddExt: Takes named type, especially not a pointer or interface: %T", + err = fmt.Errorf("codec.Handle.AddExt: Takes named type, not a pointer or interface: %T", reflect.Zero(rt).Interface()) return } @@ -568,7 +597,8 @@ func (o extHandle) getExtForTag(tag uint64) *extTypeTagFn { } type structFieldInfo struct { - encName string // encode name + encName string // encode name + fieldName string // field name // only one of 'i' or 'is' can be set. If 'i' is -1, then 'is' has been set. @@ -714,6 +744,7 @@ type typeInfo struct { } func (ti *typeInfo) indexForEncName(name string) int { + // NOTE: name may be a stringView, so don't pass it to another function. //tisfi := ti.sfi const binarySearchThreshold = 16 if sfilen := len(ti.sfi); sfilen < binarySearchThreshold { @@ -828,19 +859,19 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { } if rt.Kind() == reflect.Struct { - var siInfo *structFieldInfo + var omitEmpty bool if f, ok := rt.FieldByName(structInfoFieldName); ok { - siInfo = parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag)) + siInfo := parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag)) ti.toArray = siInfo.toArray + omitEmpty = siInfo.omitEmpty } - sfip := make([]*structFieldInfo, 0, rt.NumField()) - x.rget(rt, nil, make(map[string]bool, 16), &sfip, siInfo) - - ti.sfip = make([]*structFieldInfo, len(sfip)) - ti.sfi = make([]*structFieldInfo, len(sfip)) - copy(ti.sfip, sfip) - sort.Sort(sfiSortedByEncName(sfip)) - copy(ti.sfi, sfip) + pi := rgetPool.Get() + pv := pi.(*rgetPoolT) + pv.etypes[0] = ti.baseId + vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]} + x.rget(rt, rtid, omitEmpty, nil, &vv) + ti.sfip, ti.sfi = rgetResolveSFI(vv.sfis, pv.sfiidx[:0]) + rgetPool.Put(pi) } // sfi = sfip @@ -853,17 +884,30 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { return } -func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, - sfi *[]*structFieldInfo, siInfo *structFieldInfo, +func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool, + indexstack []int, pv *rgetT, ) { - for j := 0; j < rt.NumField(); j++ { + // Read up fields and store how to access the value. + // + // It uses go's rules for message selectors, + // which say that the field with the shallowest depth is selected. + // + // Note: we consciously use slices, not a map, to simulate a set. + // Typically, types have < 16 fields, + // and iteration using equals is faster than maps there + +LOOP: + for j, jlen := 0, rt.NumField(); j < jlen; j++ { f := rt.Field(j) fkind := f.Type.Kind() // skip if a func type, or is unexported, or structTag value == "-" - if fkind == reflect.Func { - continue + switch fkind { + case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer: + continue LOOP } - // if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) { + + // if r1, _ := utf8.DecodeRuneInString(f.Name); + // r1 == utf8.RuneError || !unicode.IsUpper(r1) { if f.PkgPath != "" && !f.Anonymous { // unexported, not embedded continue } @@ -872,7 +916,8 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st continue } var si *structFieldInfo - // if anonymous and no struct tag (or it's blank), and a struct (or pointer to struct), inline it. + // if anonymous and no struct tag (or it's blank), + // and a struct (or pointer to struct), inline it. if f.Anonymous && fkind != reflect.Interface { doInline := stag == "" if !doInline { @@ -886,11 +931,31 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st ft = ft.Elem() } if ft.Kind() == reflect.Struct { - indexstack2 := make([]int, len(indexstack)+1, len(indexstack)+4) - copy(indexstack2, indexstack) - indexstack2[len(indexstack)] = j - // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) - x.rget(ft, indexstack2, fnameToHastag, sfi, siInfo) + // if etypes contains this, don't call rget again (as fields are already seen here) + ftid := reflect.ValueOf(ft).Pointer() + // We cannot recurse forever, but we need to track other field depths. + // So - we break if we see a type twice (not the first time). + // This should be sufficient to handle an embedded type that refers to its + // owning type, which then refers to its embedded type. + processIt := true + numk := 0 + for _, k := range pv.etypes { + if k == ftid { + numk++ + if numk == rgetMaxRecursion { + processIt = false + break + } + } + } + if processIt { + pv.etypes = append(pv.etypes, ftid) + indexstack2 := make([]int, len(indexstack)+1) + copy(indexstack2, indexstack) + indexstack2[len(indexstack)] = j + // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + x.rget(ft, ftid, omitEmpty, indexstack2, pv) + } continue } } @@ -901,36 +966,86 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st continue } - // do not let fields with same name in embedded structs override field at higher level. - // this must be done after anonymous check, to allow anonymous field - // still include their child fields - if _, ok := fnameToHastag[f.Name]; ok { - continue - } if f.Name == "" { panic(noFieldNameToStructFieldInfoErr) } + + pv.fNames = append(pv.fNames, f.Name) + if si == nil { si = parseStructFieldInfo(f.Name, stag) } else if si.encName == "" { si.encName = f.Name } + si.fieldName = f.Name + + pv.encNames = append(pv.encNames, si.encName) + // si.ikind = int(f.Type.Kind()) if len(indexstack) == 0 { si.i = int16(j) } else { si.i = -1 - si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + si.is = make([]int, len(indexstack)+1) + copy(si.is, indexstack) + si.is[len(indexstack)] = j + // si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) } - if siInfo != nil { - if siInfo.omitEmpty { - si.omitEmpty = true + if omitEmpty { + si.omitEmpty = true + } + pv.sfis = append(pv.sfis, si) + } +} + +// resolves the struct field info got from a call to rget. +// Returns a trimmed, unsorted and sorted []*structFieldInfo. +func rgetResolveSFI(x []*structFieldInfo, pv []sfiIdx) (y, z []*structFieldInfo) { + var n int + for i, v := range x { + xn := v.encName //TODO: fieldName or encName? use encName for now. + var found bool + for j, k := range pv { + if k.name == xn { + // one of them must be reset to nil, and the index updated appropriately to the other one + if len(v.is) == len(x[k.index].is) { + } else if len(v.is) < len(x[k.index].is) { + pv[j].index = i + if x[k.index] != nil { + x[k.index] = nil + n++ + } + } else { + if x[i] != nil { + x[i] = nil + n++ + } + } + found = true + break } } - *sfi = append(*sfi, si) - fnameToHastag[f.Name] = stag != "" + if !found { + pv = append(pv, sfiIdx{xn, i}) + } } + + // remove all the nils + y = make([]*structFieldInfo, len(x)-n) + n = 0 + for _, v := range x { + if v == nil { + continue + } + y[n] = v + n++ + } + + z = make([]*structFieldInfo, len(y)) + copy(z, y) + sort.Sort(sfiSortedByEncName(z)) + return } func panicToErr(err *error) { @@ -1127,3 +1242,73 @@ type bytesISlice []bytesI func (p bytesISlice) Len() int { return len(p) } func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 } func (p bytesISlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// ----------------- + +type set []uintptr + +func (s *set) add(v uintptr) (exists bool) { + // e.ci is always nil, or len >= 1 + // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Add: %v, exists: %v\n", v, exists) }() + x := *s + if x == nil { + x = make([]uintptr, 1, 8) + x[0] = v + *s = x + return + } + // typically, length will be 1. make this perform. + if len(x) == 1 { + if j := x[0]; j == 0 { + x[0] = v + } else if j == v { + exists = true + } else { + x = append(x, v) + *s = x + } + return + } + // check if it exists + for _, j := range x { + if j == v { + exists = true + return + } + } + // try to replace a "deleted" slot + for i, j := range x { + if j == 0 { + x[i] = v + return + } + } + // if unable to replace deleted slot, just append it. + x = append(x, v) + *s = x + return +} + +func (s *set) remove(v uintptr) (exists bool) { + // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Rm: %v, exists: %v\n", v, exists) }() + x := *s + if len(x) == 0 { + return + } + if len(x) == 1 { + if x[0] == v { + x[0] = 0 + } + return + } + for i, j := range x { + if j == v { + exists = true + x[i] = 0 // set it to 0, as way to delete it. + // copy(x[i:], x[i+1:]) + // x = x[:len(x)-1] + return + } + } + return +} diff --git a/vendor/github.com/ugorji/go/codec/helper_internal.go b/vendor/github.com/ugorji/go/codec/helper_internal.go index dea981fb..5d0727f7 100644 --- a/vendor/github.com/ugorji/go/codec/helper_internal.go +++ b/vendor/github.com/ugorji/go/codec/helper_internal.go @@ -70,8 +70,8 @@ func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool { return false } -func isEmptyValue(v reflect.Value) bool { - return hIsEmptyValue(v, derefForIsEmptyValue, checkStructForEmptyValue) +func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool { + return hIsEmptyValue(v, deref, checkStruct) } func pruneSignExt(v []byte, pos bool) (n int) { diff --git a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go index 7c2ffc0f..8b06a004 100644 --- a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go +++ b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go @@ -1,4 +1,4 @@ -//+build !unsafe +// +build !unsafe // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. diff --git a/vendor/github.com/ugorji/go/codec/helper_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_unsafe.go index 373b2b10..0f596c71 100644 --- a/vendor/github.com/ugorji/go/codec/helper_unsafe.go +++ b/vendor/github.com/ugorji/go/codec/helper_unsafe.go @@ -1,4 +1,4 @@ -//+build unsafe +// +build unsafe // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. @@ -16,7 +16,7 @@ type unsafeString struct { Len int } -type unsafeBytes struct { +type unsafeSlice struct { Data uintptr Len int Cap int @@ -29,8 +29,10 @@ func stringView(v []byte) string { if len(v) == 0 { return "" } - x := unsafeString{uintptr(unsafe.Pointer(&v[0])), len(v)} - return *(*string)(unsafe.Pointer(&x)) + + bx := (*unsafeSlice)(unsafe.Pointer(&v)) + sx := unsafeString{bx.Data, bx.Len} + return *(*string)(unsafe.Pointer(&sx)) } // bytesView returns a view of the string as a []byte. @@ -40,6 +42,8 @@ func bytesView(v string) []byte { if len(v) == 0 { return zeroByteSlice } - x := unsafeBytes{uintptr(unsafe.Pointer(&v)), len(v), len(v)} - return *(*[]byte)(unsafe.Pointer(&x)) + + sx := (*unsafeString)(unsafe.Pointer(&v)) + bx := unsafeSlice{sx.Data, sx.Len, sx.Len} + return *(*[]byte)(unsafe.Pointer(&bx)) } diff --git a/vendor/github.com/ugorji/go/codec/json.go b/vendor/github.com/ugorji/go/codec/json.go index a18a5f70..5bb38962 100644 --- a/vendor/github.com/ugorji/go/codec/json.go +++ b/vendor/github.com/ugorji/go/codec/json.go @@ -43,18 +43,23 @@ import ( //-------------------------------- -var jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} +var ( + jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} -var jsonFloat64Pow10 = [...]float64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22, -} + jsonFloat64Pow10 = [...]float64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, + } -var jsonUint64Pow10 = [...]uint64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, -} + jsonUint64Pow10 = [...]uint64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + } + + // jsonTabs and jsonSpaces are used as caches for indents + jsonTabs, jsonSpaces string +) const ( // jsonUnreadAfterDecNum controls whether we unread after decoding a number. @@ -85,8 +90,23 @@ const ( jsonNumUintMaxVal = 1< 1<<53 || v < -(1<<53)) { + e.w.writen1('"') + e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) + e.w.writen1('"') + return + } e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeUint(v uint64) { + if x := e.h.IntegerAsString; x == 'A' || x == 'L' && v > 1<<53 { + e.w.writen1('"') + e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) + e.w.writen1('"') + return + } e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) } @@ -165,11 +251,17 @@ func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) { } func (e *jsonEncDriver) EncodeArrayStart(length int) { + if e.d { + e.dl++ + } e.w.writen1('[') e.c = containerArrayStart } func (e *jsonEncDriver) EncodeMapStart(length int) { + if e.d { + e.dl++ + } e.w.writen1('{') e.c = containerMapStart } @@ -564,6 +656,11 @@ func (d *jsonDecDriver) decNum(storeBytes bool) { d.tok = b } b := d.tok + var str bool + if b == '"' { + str = true + b = d.r.readn1() + } if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) { d.d.errorf("json: decNum: got first char '%c'", b) return @@ -578,6 +675,10 @@ func (d *jsonDecDriver) decNum(storeBytes bool) { n.reset() d.bs = d.bs[:0] + if str && storeBytes { + d.bs = append(d.bs, '"') + } + // The format of a number is as below: // parsing: sign? digit* dot? digit* e? sign? digit* // states: 0 1* 2 3* 4 5* 6 7 @@ -668,6 +769,14 @@ LOOP: default: break LOOP } + case '"': + if str { + if storeBytes { + d.bs = append(d.bs, '"') + } + b, eof = r.readn1eof() + } + break LOOP default: break LOOP } @@ -822,6 +931,11 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [ if isstring { return d.bs } + // if appendStringAsBytes returned a zero-len slice, then treat as nil. + // This should only happen for null, and "". + if len(d.bs) == 0 { + return nil + } bs0 := d.bs slen := base64.StdEncoding.DecodedLen(len(bs0)) if slen <= cap(bs) { @@ -859,6 +973,14 @@ func (d *jsonDecDriver) appendStringAsBytes() { } d.tok = b } + + // handle null as a string + if d.tok == 'n' { + d.readStrIdx(10, 13) // ull + d.bs = d.bs[:0] + return + } + if d.tok != '"' { d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok) } @@ -1033,6 +1155,24 @@ type JsonHandle struct { // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way. // If not configured, raw bytes are encoded to/from base64 text. RawBytesExt InterfaceExt + + // Indent indicates how a value is encoded. + // - If positive, indent by that number of spaces. + // - If negative, indent by that number of tabs. + Indent int8 + + // IntegerAsString controls how integers (signed and unsigned) are encoded. + // + // Per the JSON Spec, JSON numbers are 64-bit floating point numbers. + // Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision. + // This can be mitigated by configuring how to encode integers. + // + // IntegerAsString interpretes the following values: + // - if 'L', then encode integers > 2^53 as a json string. + // - if 'A', then encode all integers as a json string + // containing the exact integer representation as a decimal. + // - else encode all integers as a json number (default) + IntegerAsString uint8 } func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { @@ -1040,26 +1180,48 @@ func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceE } func (h *JsonHandle) newEncDriver(e *Encoder) encDriver { - hd := jsonEncDriver{e: e, w: e.w, h: h} + hd := jsonEncDriver{e: e, h: h} hd.bs = hd.b[:0] - hd.se.i = h.RawBytesExt + + hd.reset() + return &hd } func (h *JsonHandle) newDecDriver(d *Decoder) decDriver { // d := jsonDecDriver{r: r.(*bytesDecReader), h: h} - hd := jsonDecDriver{d: d, r: d.r, h: h} + hd := jsonDecDriver{d: d, h: h} hd.bs = hd.b[:0] - hd.se.i = h.RawBytesExt + hd.reset() return &hd } func (e *jsonEncDriver) reset() { e.w = e.e.w + e.se.i = e.h.RawBytesExt + if e.bs != nil { + e.bs = e.bs[:0] + } + e.d, e.dt, e.dl, e.ds = false, false, 0, "" + e.c = 0 + if e.h.Indent > 0 { + e.d = true + e.ds = jsonSpaces[:e.h.Indent] + } else if e.h.Indent < 0 { + e.d = true + e.dt = true + e.ds = jsonTabs[:-(e.h.Indent)] + } } func (d *jsonDecDriver) reset() { d.r = d.d.r + d.se.i = d.h.RawBytesExt + if d.bs != nil { + d.bs = d.bs[:0] + } + d.c, d.tok = 0, 0 + d.n.reset() } var jsonEncodeTerminate = []byte{' '} diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go index 5eb4c963..e79830b5 100644 --- a/vendor/github.com/ugorji/go/codec/msgpack.go +++ b/vendor/github.com/ugorji/go/codec/msgpack.go @@ -374,7 +374,7 @@ func (d *msgpackDecDriver) DecodeNaked() { } if n.v == valueTypeUint && d.h.SignedInteger { n.v = valueTypeInt - n.i = int64(n.v) + n.i = int64(n.u) } return } @@ -561,6 +561,13 @@ func (d *msgpackDecDriver) readNextBd() { d.bdRead = true } +func (d *msgpackDecDriver) uncacheRead() { + if d.bdRead { + d.r.unreadn1() + d.bdRead = false + } +} + func (d *msgpackDecDriver) ContainerType() (vt valueType) { bd := d.bd if bd == mpNil { @@ -729,6 +736,7 @@ func (e *msgpackEncDriver) reset() { func (d *msgpackDecDriver) reset() { d.r = d.d.r + d.bd, d.bdRead = 0, false } //-------------------------------------------------- diff --git a/vendor/github.com/ugorji/go/codec/rpc.go b/vendor/github.com/ugorji/go/codec/rpc.go index dad53d0c..8062bed3 100644 --- a/vendor/github.com/ugorji/go/codec/rpc.go +++ b/vendor/github.com/ugorji/go/codec/rpc.go @@ -25,7 +25,7 @@ type Rpc interface { } // RpcCodecBuffered allows access to the underlying bufio.Reader/Writer -// used by the rpc connection. It accomodates use-cases where the connection +// used by the rpc connection. It accommodates use-cases where the connection // should be used by rpc and non-rpc functions, e.g. streaming a file after // sending an rpc response. type RpcCodecBuffered interface { diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go index c1504965..231d503a 100644 --- a/vendor/github.com/ugorji/go/codec/simple.go +++ b/vendor/github.com/ugorji/go/codec/simple.go @@ -166,6 +166,13 @@ func (d *simpleDecDriver) readNextBd() { d.bdRead = true } +func (d *simpleDecDriver) uncacheRead() { + if d.bdRead { + d.r.unreadn1() + d.bdRead = false + } +} + func (d *simpleDecDriver) ContainerType() (vt valueType) { if d.bd == simpleVdNil { return valueTypeNil @@ -474,7 +481,7 @@ func (d *simpleDecDriver) DecodeNaked() { // SimpleHandle is a Handle for a very simple encoding format. // // simple is a simplistic codec similar to binc, but not as compact. -// - Encoding of a value is always preceeded by the descriptor byte (bd) +// - Encoding of a value is always preceded by the descriptor byte (bd) // - True, false, nil are encoded fully in 1 byte (the descriptor) // - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte). // There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers. @@ -512,6 +519,7 @@ func (e *simpleEncDriver) reset() { func (d *simpleDecDriver) reset() { d.r = d.d.r + d.bd, d.bdRead = 0, false } var _ decDriver = (*simpleDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/time.go b/vendor/github.com/ugorji/go/codec/time.go index fc4c63e1..718b731e 100644 --- a/vendor/github.com/ugorji/go/codec/time.go +++ b/vendor/github.com/ugorji/go/codec/time.go @@ -5,11 +5,22 @@ package codec import ( "fmt" + "reflect" "time" ) var ( - timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} + timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} + timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) { + defer panicToErr(&err) + bs = timeExt{}.WriteExt(rv.Interface()) + return + } + timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) { + defer panicToErr(&err) + timeExt{}.ReadExt(rv.Interface(), bs) + return + } ) type timeExt struct{} diff --git a/vendor/golang.org/x/image/math/fixed/fixed.go b/vendor/golang.org/x/image/math/fixed/fixed.go index df3540a3..2c76ed46 100644 --- a/vendor/golang.org/x/image/math/fixed/fixed.go +++ b/vendor/golang.org/x/image/math/fixed/fixed.go @@ -56,6 +56,11 @@ func (x Int26_6) Round() int { return int((x + 0x20) >> 6) } // Its return type is int, not Int26_6. func (x Int26_6) Ceil() int { return int((x + 0x3f) >> 6) } +// Mul returns x*y in 26.6 fixed-point arithmetic. +func (x Int26_6) Mul(y Int26_6) Int26_6 { + return Int26_6((int64(x)*int64(y) + 1<<5) >> 6) +} + // Int52_12 is a signed 52.12 fixed-point number. // // The integer part ranges from -2251799813685248 to 2251799813685247, @@ -95,6 +100,39 @@ func (x Int52_12) Round() int { return int((x + 0x800) >> 12) } // Its return type is int, not Int52_12. func (x Int52_12) Ceil() int { return int((x + 0xfff) >> 12) } +// Mul returns x*y in 52.12 fixed-point arithmetic. +func (x Int52_12) Mul(y Int52_12) Int52_12 { + const M, N = 52, 12 + lo, hi := muli64(int64(x), int64(y)) + ret := Int52_12(hi<>N) + ret += Int52_12((lo >> (N - 1)) & 1) // Round to nearest, instead of rounding down. + return ret +} + +// muli64 multiplies two int64 values, returning the 128-bit signed integer +// result as two uint64 values. +// +// This implementation is similar to $GOROOT/src/runtime/softfloat64.go's mullu +// function, which is in turn adapted from Hacker's Delight. +func muli64(u, v int64) (lo, hi uint64) { + const ( + s = 32 + mask = 1<> s) + u0 := uint64(u & mask) + v1 := uint64(v >> s) + v0 := uint64(v & mask) + + w0 := u0 * v0 + t := u1*v0 + w0>>s + w1 := t & mask + w2 := uint64(int64(t) >> s) + w1 += u0 * v1 + return uint64(u) * uint64(v), u1*v1 + w2 + uint64(int64(w1)>>s) +} + // P returns the integer values x and y as a Point26_6. // // For example, passing the integer values (2, -3) yields Point26_6{128, -192}. diff --git a/vendor/golang.org/x/image/tiff/reader.go b/vendor/golang.org/x/image/tiff/reader.go index df39e828..cfe6fed6 100644 --- a/vendor/golang.org/x/image/tiff/reader.go +++ b/vendor/golang.org/x/image/tiff/reader.go @@ -118,8 +118,9 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) { } // parseIFD decides whether the the IFD entry in p is "interesting" and -// stows away the data in the decoder. -func (d *decoder) parseIFD(p []byte) error { +// stows away the data in the decoder. It returns the tag number of the +// entry and an error, if any. +func (d *decoder) parseIFD(p []byte) (int, error) { tag := d.byteOrder.Uint16(p[0:2]) switch tag { case tBitsPerSample, @@ -138,17 +139,17 @@ func (d *decoder) parseIFD(p []byte) error { tImageWidth: val, err := d.ifdUint(p) if err != nil { - return err + return 0, err } d.features[int(tag)] = val case tColorMap: val, err := d.ifdUint(p) if err != nil { - return err + return 0, err } numcolors := len(val) / 3 if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 { - return FormatError("bad ColorMap length") + return 0, FormatError("bad ColorMap length") } d.palette = make([]color.Color, numcolors) for i := 0; i < numcolors; i++ { @@ -166,15 +167,15 @@ func (d *decoder) parseIFD(p []byte) error { // must terminate the import process gracefully. val, err := d.ifdUint(p) if err != nil { - return err + return 0, err } for _, v := range val { if v != 1 { - return UnsupportedError("sample format") + return 0, UnsupportedError("sample format") } } } - return nil + return int(tag), nil } // readBits reads n bits from the internal buffer starting at the current offset. @@ -428,10 +429,16 @@ func newDecoder(r io.Reader) (*decoder, error) { return nil, err } + prevTag := -1 for i := 0; i < len(p); i += ifdLen { - if err := d.parseIFD(p[i : i+ifdLen]); err != nil { + tag, err := d.parseIFD(p[i : i+ifdLen]) + if err != nil { return nil, err } + if tag <= prevTag { + return nil, FormatError("tags are not sorted in ascending order") + } + prevTag = tag } d.config.Width = int(d.firstVal(tImageWidth)) diff --git a/vendor/google.golang.org/appengine/appengine.go b/vendor/google.golang.org/appengine/appengine.go index 475cf2e3..d4f80844 100644 --- a/vendor/google.golang.org/appengine/appengine.go +++ b/vendor/google.golang.org/appengine/appengine.go @@ -28,7 +28,8 @@ import ( // See https://cloud.google.com/appengine/docs/flexible/custom-runtimes#health_check_requests // for details on how to do your own health checking. // -// Main is not yet supported on App Engine Standard. +// On App Engine Standard it ensures the server has started and is prepared to +// receive requests. // // Main never returns. // diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go index ec5aa59b..aba0f831 100644 --- a/vendor/google.golang.org/appengine/internal/api.go +++ b/vendor/google.golang.org/appengine/internal/api.go @@ -32,7 +32,8 @@ import ( ) const ( - apiPath = "/rpc_http" + apiPath = "/rpc_http" + defaultTicketSuffix = "/default.20150612t184001.0" ) var ( @@ -60,6 +61,9 @@ var ( Dial: limitDial, }, } + + defaultTicketOnce sync.Once + defaultTicket string ) func apiURL() *url.URL { @@ -266,6 +270,24 @@ func WithContext(parent netcontext.Context, req *http.Request) netcontext.Contex return withContext(parent, c) } +// DefaultTicket returns a ticket used for background context or dev_appserver. +func DefaultTicket() string { + defaultTicketOnce.Do(func() { + if IsDevAppServer() { + defaultTicket = "testapp" + defaultTicketSuffix + return + } + appID := partitionlessAppID() + escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) + majVersion := VersionID(nil) + if i := strings.Index(majVersion, "."); i > 0 { + majVersion = majVersion[:i] + } + defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) + }) + return defaultTicket +} + func BackgroundContext() netcontext.Context { ctxs.Lock() defer ctxs.Unlock() @@ -275,13 +297,7 @@ func BackgroundContext() netcontext.Context { } // Compute background security ticket. - appID := partitionlessAppID() - escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) - majVersion := VersionID(nil) - if i := strings.Index(majVersion, "."); i > 0 { - majVersion = majVersion[:i] - } - ticket := fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) + ticket := DefaultTicket() ctxs.bg = &context{ req: &http.Request{ @@ -475,6 +491,16 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message) } ticket := c.req.Header.Get(ticketHeader) + // Use a test ticket under test environment. + if ticket == "" { + if appid := ctx.Value(&appIDOverrideKey); appid != nil { + ticket = appid.(string) + defaultTicketSuffix + } + } + // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver. + if ticket == "" { + ticket = DefaultTicket() + } req := &remotepb.Request{ ServiceName: &service, Method: &method, @@ -550,6 +576,9 @@ var logLevelName = map[int64]string{ } func logf(c *context, level int64, format string, args ...interface{}) { + if c == nil { + panic("not an App Engine context") + } s := fmt.Sprintf(format, args...) s = strings.TrimRight(s, "\n") // Remove any trailing newline characters. c.addLogLine(&logpb.UserAppLogLine{ diff --git a/vendor/google.golang.org/appengine/internal/api_common.go b/vendor/google.golang.org/appengine/internal/api_common.go index 2db33a77..8c3eecec 100644 --- a/vendor/google.golang.org/appengine/internal/api_common.go +++ b/vendor/google.golang.org/appengine/internal/api_common.go @@ -5,6 +5,8 @@ package internal import ( + "os" + "github.com/golang/protobuf/proto" netcontext "golang.org/x/net/context" ) @@ -84,3 +86,31 @@ func Logf(ctx netcontext.Context, level int64, format string, args ...interface{ func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context { return withNamespace(ctx, namespace) } + +// SetTestEnv sets the env variables for testing background ticket in Flex. +func SetTestEnv() func() { + var environ = []struct { + key, value string + }{ + {"GAE_LONG_APP_ID", "my-app-id"}, + {"GAE_MINOR_VERSION", "067924799508853122"}, + {"GAE_MODULE_INSTANCE", "0"}, + {"GAE_MODULE_NAME", "default"}, + {"GAE_MODULE_VERSION", "20150612t184001"}, + } + + for _, v := range environ { + old := os.Getenv(v.key) + os.Setenv(v.key, v.value) + v.value = old + } + return func() { // Restore old environment after the test completes. + for _, v := range environ { + if v.value == "" { + os.Unsetenv(v.key) + continue + } + os.Setenv(v.key, v.value) + } + } +}