Merge pull request #4574 from hashicorp/f-base-go-plugin

Base go-plugin client/server
This commit is contained in:
Alex Dadgar 2018-08-13 11:10:54 -07:00 committed by GitHub
commit 0c77ff37c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 4855 additions and 72 deletions

35
plugins/base/base.go Normal file
View file

@ -0,0 +1,35 @@
package base
import (
"github.com/hashicorp/nomad/plugins/shared/hclspec"
)
// BasePlugin is the interface that all Nomad plugins must support.
type BasePlugin interface {
// PluginInfo describes the type and version of a plugin.
PluginInfo() (*PluginInfoResponse, error)
// ConfigSchema returns the schema for parsing the plugins configuration.
ConfigSchema() (*hclspec.Spec, error)
// SetConfig is used to set the configuration by passing a MessagePack
// encoding of it.
SetConfig(data []byte) error
}
// PluginInfoResponse returns basic information about the plugin such that Nomad
// can decide whether to load the plugin or not.
type PluginInfoResponse struct {
// Type returns the plugins type
Type string
// PluginApiVersion returns the version of the Nomad plugin API it is built
// against.
PluginApiVersion string
// PluginVersion is the version of the plugin.
PluginVersion string
// Name is the plugins name.
Name string
}

59
plugins/base/client.go Normal file
View file

@ -0,0 +1,59 @@
package base
import (
"context"
"fmt"
"github.com/hashicorp/nomad/plugins/base/proto"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
)
// basePluginClient implements the client side of a remote base plugin, using
// gRPC to communicate to the remote plugin.
type basePluginClient struct {
client proto.BasePluginClient
}
func (b *basePluginClient) PluginInfo() (*PluginInfoResponse, error) {
presp, err := b.client.PluginInfo(context.Background(), &proto.PluginInfoRequest{})
if err != nil {
return nil, err
}
var ptype string
switch presp.GetType() {
case proto.PluginType_DRIVER:
ptype = PluginTypeDriver
case proto.PluginType_DEVICE:
ptype = PluginTypeDevice
default:
return nil, fmt.Errorf("plugin is of unknown type: %q", presp.GetType().String())
}
resp := &PluginInfoResponse{
Type: ptype,
PluginApiVersion: presp.GetPluginApiVersion(),
PluginVersion: presp.GetPluginVersion(),
Name: presp.GetName(),
}
return resp, nil
}
func (b *basePluginClient) ConfigSchema() (*hclspec.Spec, error) {
presp, err := b.client.ConfigSchema(context.Background(), &proto.ConfigSchemaRequest{})
if err != nil {
return nil, err
}
return presp.GetSpec(), nil
}
func (b *basePluginClient) SetConfig(data []byte) error {
// Send the config
_, err := b.client.SetConfig(context.Background(), &proto.SetConfigRequest{
MsgpackConfig: data,
})
return err
}

18
plugins/base/mock.go Normal file
View file

@ -0,0 +1,18 @@
package base
import (
"github.com/hashicorp/nomad/plugins/shared/hclspec"
)
// MockPlugin is used for testing.
// Each function can be set as a closure to make assertions about how data
// is passed through the base plugin layer.
type MockPlugin struct {
PluginInfoF func() (*PluginInfoResponse, error)
ConfigSchemaF func() (*hclspec.Spec, error)
SetConfigF func([]byte) error
}
func (p *MockPlugin) PluginInfo() (*PluginInfoResponse, error) { return p.PluginInfoF() }
func (p *MockPlugin) ConfigSchema() (*hclspec.Spec, error) { return p.ConfigSchemaF() }
func (p *MockPlugin) SetConfig(data []byte) error { return p.SetConfigF(data) }

45
plugins/base/plugin.go Normal file
View file

@ -0,0 +1,45 @@
package base
import (
"context"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/nomad/plugins/base/proto"
"google.golang.org/grpc"
)
const (
// PluginTypeDriver implements the driver plugin interface
PluginTypeDriver = "driver"
// PluginTypeDevice implements the device plugin interface
PluginTypeDevice = "device"
)
var (
// Handshake is a common handshake that is shared by all plugins and Nomad.
Handshake = plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "NOMAD_PLUGIN_MAGIC_COOKIE",
MagicCookieValue: "e4327c2e01eabfd75a8a67adb114fb34a757d57eee7728d857a8cec6e91a7255",
}
)
// PluginBase is wraps a BasePlugin and implements go-plugins GRPCPlugin
// interface to expose the interface over gRPC.
type PluginBase struct {
plugin.NetRPCUnsupportedPlugin
impl BasePlugin
}
func (p *PluginBase) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
proto.RegisterBasePluginServer(s, &basePluginServer{
impl: p.impl,
broker: broker,
})
return nil
}
func (p *PluginBase) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
return &basePluginClient{client: proto.NewBasePluginClient(c)}, nil
}

198
plugins/base/plugin_test.go Normal file
View file

@ -0,0 +1,198 @@
package base
import (
"testing"
pb "github.com/golang/protobuf/proto"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
"github.com/stretchr/testify/require"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/msgpack"
)
var (
// testSpec is an hcl Spec for testing
testSpec = &hclspec.Spec{
Block: &hclspec.Spec_Object{
Object: &hclspec.Object{
Attributes: map[string]*hclspec.Spec{
"foo": {
Block: &hclspec.Spec_Attr{
Attr: &hclspec.Attr{
Type: "string",
Required: false,
},
},
},
"bar": {
Block: &hclspec.Spec_Attr{
Attr: &hclspec.Attr{
Type: "number",
Required: true,
},
},
},
"baz": {
Block: &hclspec.Spec_Attr{
Attr: &hclspec.Attr{
Type: "bool",
},
},
},
},
},
},
}
)
// testConfig is used to decode a config from the testSpec
type testConfig struct {
Foo string `cty:"foo" codec:"foo"`
Bar int64 `cty:"bar" codec:"bar"`
Baz bool `cty:"baz" codec:"baz"`
}
func TestBasePlugin_PluginInfo_GRPC(t *testing.T) {
t.Parallel()
require := require.New(t)
const (
apiVersion = "v0.1.0"
pluginVersion = "v0.2.1"
pluginName = "mock"
)
knownType := func() (*PluginInfoResponse, error) {
info := &PluginInfoResponse{
Type: PluginTypeDriver,
PluginApiVersion: apiVersion,
PluginVersion: pluginVersion,
Name: pluginName,
}
return info, nil
}
unknownType := func() (*PluginInfoResponse, error) {
info := &PluginInfoResponse{
Type: "bad",
PluginApiVersion: apiVersion,
PluginVersion: pluginVersion,
Name: pluginName,
}
return info, nil
}
mock := &MockPlugin{
PluginInfoF: knownType,
}
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"base": &PluginBase{impl: mock},
})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("base")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(BasePlugin)
if !ok {
t.Fatalf("bad: %#v", raw)
}
resp, err := impl.PluginInfo()
require.NoError(err)
require.Equal(apiVersion, resp.PluginApiVersion)
require.Equal(pluginVersion, resp.PluginVersion)
require.Equal(pluginName, resp.Name)
require.Equal(PluginTypeDriver, resp.Type)
// Swap the implementation to return an unknown type
mock.PluginInfoF = unknownType
_, err = impl.PluginInfo()
require.Error(err)
require.Contains(err.Error(), "unknown type")
}
func TestBasePlugin_ConfigSchema(t *testing.T) {
t.Parallel()
require := require.New(t)
mock := &MockPlugin{
ConfigSchemaF: func() (*hclspec.Spec, error) {
return testSpec, nil
},
}
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"base": &PluginBase{impl: mock},
})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("base")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(BasePlugin)
if !ok {
t.Fatalf("bad: %#v", raw)
}
specOut, err := impl.ConfigSchema()
require.NoError(err)
require.True(pb.Equal(testSpec, specOut))
}
func TestBasePlugin_SetConfig(t *testing.T) {
t.Parallel()
require := require.New(t)
var receivedData []byte
mock := &MockPlugin{
ConfigSchemaF: func() (*hclspec.Spec, error) {
return testSpec, nil
},
SetConfigF: func(data []byte) error {
receivedData = data
return nil
},
}
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"base": &PluginBase{impl: mock},
})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("base")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(BasePlugin)
if !ok {
t.Fatalf("bad: %#v", raw)
}
config := cty.ObjectVal(map[string]cty.Value{
"foo": cty.StringVal("v1"),
"bar": cty.NumberIntVal(1337),
"baz": cty.BoolVal(true),
})
cdata, err := msgpack.Marshal(config, config.Type())
require.NoError(err)
require.NoError(impl.SetConfig(cdata))
require.Equal(cdata, receivedData)
// Decode the value back
var actual testConfig
require.NoError(structs.Decode(receivedData, &actual))
require.Equal("v1", actual.Foo)
require.EqualValues(1337, actual.Bar)
require.True(actual.Baz)
}

View file

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/hashicorp/nomad/plugins/base/base.proto
// source: github.com/hashicorp/nomad/plugins/base/proto/base.proto
package base
package proto
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
@ -29,26 +29,26 @@ type PluginType int32
const (
PluginType_UNKNOWN PluginType = 0
PluginType_DRIVER PluginType = 1
PluginType_DEVICE PluginType = 2
PluginType_DRIVER PluginType = 2
PluginType_DEVICE PluginType = 3
)
var PluginType_name = map[int32]string{
0: "UNKNOWN",
1: "DRIVER",
2: "DEVICE",
2: "DRIVER",
3: "DEVICE",
}
var PluginType_value = map[string]int32{
"UNKNOWN": 0,
"DRIVER": 1,
"DEVICE": 2,
"DRIVER": 2,
"DEVICE": 3,
}
func (x PluginType) String() string {
return proto.EnumName(PluginType_name, int32(x))
}
func (PluginType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{0}
return fileDescriptor_base_9cc78dc32b158b08, []int{0}
}
// PluginInfoRequest is used to request the plugins basic information.
@ -62,7 +62,7 @@ func (m *PluginInfoRequest) Reset() { *m = PluginInfoRequest{} }
func (m *PluginInfoRequest) String() string { return proto.CompactTextString(m) }
func (*PluginInfoRequest) ProtoMessage() {}
func (*PluginInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{0}
return fileDescriptor_base_9cc78dc32b158b08, []int{0}
}
func (m *PluginInfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PluginInfoRequest.Unmarshal(m, b)
@ -86,7 +86,7 @@ var xxx_messageInfo_PluginInfoRequest proto.InternalMessageInfo
// that Nomad can decide whether to load the plugin or not.
type PluginInfoResponse struct {
// type indicates what type of plugin this is.
Type PluginType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.nomad.plugins.base.PluginType" json:"type,omitempty"`
Type PluginType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.nomad.plugins.base.proto.PluginType" json:"type,omitempty"`
// plugin_api_version indicates the version of the Nomad Plugin API
// this plugin is built against.
PluginApiVersion string `protobuf:"bytes,2,opt,name=plugin_api_version,json=pluginApiVersion,proto3" json:"plugin_api_version,omitempty"`
@ -104,7 +104,7 @@ func (m *PluginInfoResponse) Reset() { *m = PluginInfoResponse{} }
func (m *PluginInfoResponse) String() string { return proto.CompactTextString(m) }
func (*PluginInfoResponse) ProtoMessage() {}
func (*PluginInfoResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{1}
return fileDescriptor_base_9cc78dc32b158b08, []int{1}
}
func (m *PluginInfoResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PluginInfoResponse.Unmarshal(m, b)
@ -163,7 +163,7 @@ func (m *ConfigSchemaRequest) Reset() { *m = ConfigSchemaRequest{} }
func (m *ConfigSchemaRequest) String() string { return proto.CompactTextString(m) }
func (*ConfigSchemaRequest) ProtoMessage() {}
func (*ConfigSchemaRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{2}
return fileDescriptor_base_9cc78dc32b158b08, []int{2}
}
func (m *ConfigSchemaRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ConfigSchemaRequest.Unmarshal(m, b)
@ -196,7 +196,7 @@ func (m *ConfigSchemaResponse) Reset() { *m = ConfigSchemaResponse{} }
func (m *ConfigSchemaResponse) String() string { return proto.CompactTextString(m) }
func (*ConfigSchemaResponse) ProtoMessage() {}
func (*ConfigSchemaResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{3}
return fileDescriptor_base_9cc78dc32b158b08, []int{3}
}
func (m *ConfigSchemaResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ConfigSchemaResponse.Unmarshal(m, b)
@ -236,7 +236,7 @@ func (m *SetConfigRequest) Reset() { *m = SetConfigRequest{} }
func (m *SetConfigRequest) String() string { return proto.CompactTextString(m) }
func (*SetConfigRequest) ProtoMessage() {}
func (*SetConfigRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{4}
return fileDescriptor_base_9cc78dc32b158b08, []int{4}
}
func (m *SetConfigRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SetConfigRequest.Unmarshal(m, b)
@ -274,7 +274,7 @@ func (m *SetConfigResponse) Reset() { *m = SetConfigResponse{} }
func (m *SetConfigResponse) String() string { return proto.CompactTextString(m) }
func (*SetConfigResponse) ProtoMessage() {}
func (*SetConfigResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_base_0160727fc8db573d, []int{5}
return fileDescriptor_base_9cc78dc32b158b08, []int{5}
}
func (m *SetConfigResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SetConfigResponse.Unmarshal(m, b)
@ -295,13 +295,13 @@ func (m *SetConfigResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_SetConfigResponse proto.InternalMessageInfo
func init() {
proto.RegisterType((*PluginInfoRequest)(nil), "hashicorp.nomad.plugins.base.PluginInfoRequest")
proto.RegisterType((*PluginInfoResponse)(nil), "hashicorp.nomad.plugins.base.PluginInfoResponse")
proto.RegisterType((*ConfigSchemaRequest)(nil), "hashicorp.nomad.plugins.base.ConfigSchemaRequest")
proto.RegisterType((*ConfigSchemaResponse)(nil), "hashicorp.nomad.plugins.base.ConfigSchemaResponse")
proto.RegisterType((*SetConfigRequest)(nil), "hashicorp.nomad.plugins.base.SetConfigRequest")
proto.RegisterType((*SetConfigResponse)(nil), "hashicorp.nomad.plugins.base.SetConfigResponse")
proto.RegisterEnum("hashicorp.nomad.plugins.base.PluginType", PluginType_name, PluginType_value)
proto.RegisterType((*PluginInfoRequest)(nil), "hashicorp.nomad.plugins.base.proto.PluginInfoRequest")
proto.RegisterType((*PluginInfoResponse)(nil), "hashicorp.nomad.plugins.base.proto.PluginInfoResponse")
proto.RegisterType((*ConfigSchemaRequest)(nil), "hashicorp.nomad.plugins.base.proto.ConfigSchemaRequest")
proto.RegisterType((*ConfigSchemaResponse)(nil), "hashicorp.nomad.plugins.base.proto.ConfigSchemaResponse")
proto.RegisterType((*SetConfigRequest)(nil), "hashicorp.nomad.plugins.base.proto.SetConfigRequest")
proto.RegisterType((*SetConfigResponse)(nil), "hashicorp.nomad.plugins.base.proto.SetConfigResponse")
proto.RegisterEnum("hashicorp.nomad.plugins.base.proto.PluginType", PluginType_name, PluginType_value)
}
// Reference imports to suppress errors if they are not otherwise used.
@ -334,7 +334,7 @@ func NewBasePluginClient(cc *grpc.ClientConn) BasePluginClient {
func (c *basePluginClient) PluginInfo(ctx context.Context, in *PluginInfoRequest, opts ...grpc.CallOption) (*PluginInfoResponse, error) {
out := new(PluginInfoResponse)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.BasePlugin/PluginInfo", in, out, opts...)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.proto.BasePlugin/PluginInfo", in, out, opts...)
if err != nil {
return nil, err
}
@ -343,7 +343,7 @@ func (c *basePluginClient) PluginInfo(ctx context.Context, in *PluginInfoRequest
func (c *basePluginClient) ConfigSchema(ctx context.Context, in *ConfigSchemaRequest, opts ...grpc.CallOption) (*ConfigSchemaResponse, error) {
out := new(ConfigSchemaResponse)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.BasePlugin/ConfigSchema", in, out, opts...)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.proto.BasePlugin/ConfigSchema", in, out, opts...)
if err != nil {
return nil, err
}
@ -352,7 +352,7 @@ func (c *basePluginClient) ConfigSchema(ctx context.Context, in *ConfigSchemaReq
func (c *basePluginClient) SetConfig(ctx context.Context, in *SetConfigRequest, opts ...grpc.CallOption) (*SetConfigResponse, error) {
out := new(SetConfigResponse)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.BasePlugin/SetConfig", in, out, opts...)
err := c.cc.Invoke(ctx, "/hashicorp.nomad.plugins.base.proto.BasePlugin/SetConfig", in, out, opts...)
if err != nil {
return nil, err
}
@ -383,7 +383,7 @@ func _BasePlugin_PluginInfo_Handler(srv interface{}, ctx context.Context, dec fu
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.nomad.plugins.base.BasePlugin/PluginInfo",
FullMethod: "/hashicorp.nomad.plugins.base.proto.BasePlugin/PluginInfo",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BasePluginServer).PluginInfo(ctx, req.(*PluginInfoRequest))
@ -401,7 +401,7 @@ func _BasePlugin_ConfigSchema_Handler(srv interface{}, ctx context.Context, dec
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.nomad.plugins.base.BasePlugin/ConfigSchema",
FullMethod: "/hashicorp.nomad.plugins.base.proto.BasePlugin/ConfigSchema",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BasePluginServer).ConfigSchema(ctx, req.(*ConfigSchemaRequest))
@ -419,7 +419,7 @@ func _BasePlugin_SetConfig_Handler(srv interface{}, ctx context.Context, dec fun
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.nomad.plugins.base.BasePlugin/SetConfig",
FullMethod: "/hashicorp.nomad.plugins.base.proto.BasePlugin/SetConfig",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BasePluginServer).SetConfig(ctx, req.(*SetConfigRequest))
@ -428,7 +428,7 @@ func _BasePlugin_SetConfig_Handler(srv interface{}, ctx context.Context, dec fun
}
var _BasePlugin_serviceDesc = grpc.ServiceDesc{
ServiceName: "hashicorp.nomad.plugins.base.BasePlugin",
ServiceName: "hashicorp.nomad.plugins.base.proto.BasePlugin",
HandlerType: (*BasePluginServer)(nil),
Methods: []grpc.MethodDesc{
{
@ -445,40 +445,41 @@ var _BasePlugin_serviceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
Metadata: "github.com/hashicorp/nomad/plugins/base/base.proto",
Metadata: "github.com/hashicorp/nomad/plugins/base/proto/base.proto",
}
func init() {
proto.RegisterFile("github.com/hashicorp/nomad/plugins/base/base.proto", fileDescriptor_base_0160727fc8db573d)
proto.RegisterFile("github.com/hashicorp/nomad/plugins/base/proto/base.proto", fileDescriptor_base_9cc78dc32b158b08)
}
var fileDescriptor_base_0160727fc8db573d = []byte{
// 430 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xdf, 0x8b, 0xd3, 0x40,
0x10, 0xbe, 0xd4, 0x50, 0xb9, 0xb9, 0x1f, 0xc4, 0x3d, 0x85, 0x12, 0x7c, 0x38, 0x02, 0x42, 0x91,
0x63, 0xe3, 0xc5, 0x27, 0xc1, 0x87, 0xb3, 0xb5, 0x0f, 0x45, 0xa8, 0x92, 0x6a, 0x15, 0x5f, 0xc2,
0x76, 0xbb, 0x4d, 0x82, 0xcd, 0xee, 0x36, 0x9b, 0x2a, 0xfd, 0xdb, 0xfc, 0x87, 0xfc, 0x33, 0x64,
0x77, 0x93, 0x1a, 0x45, 0x4b, 0x7c, 0x49, 0x86, 0x99, 0xef, 0xfb, 0x66, 0xe6, 0x1b, 0x16, 0xa2,
0x34, 0xaf, 0xb2, 0xdd, 0x12, 0x53, 0x51, 0x84, 0x19, 0x51, 0x59, 0x4e, 0x45, 0x29, 0x43, 0x2e,
0x0a, 0xb2, 0x0a, 0xe5, 0x66, 0x97, 0xe6, 0x5c, 0x85, 0x4b, 0xa2, 0x98, 0xf9, 0x60, 0x59, 0x8a,
0x4a, 0xa0, 0xc7, 0x07, 0x20, 0x36, 0x40, 0x5c, 0x03, 0xb1, 0xc6, 0xf8, 0x77, 0x1d, 0x14, 0x55,
0x46, 0x4a, 0xb6, 0x0a, 0x33, 0xba, 0x51, 0x92, 0x51, 0xfd, 0x4f, 0x74, 0x60, 0xf5, 0x83, 0x2b,
0x78, 0xf0, 0xce, 0x00, 0xa7, 0x7c, 0x2d, 0x62, 0xb6, 0xdd, 0x31, 0x55, 0x05, 0xdf, 0x1d, 0x40,
0xed, 0xac, 0x92, 0x82, 0x2b, 0x86, 0x5e, 0x82, 0x5b, 0xed, 0x25, 0x1b, 0x38, 0xd7, 0xce, 0xf0,
0x32, 0x1a, 0xe2, 0x63, 0xa3, 0x61, 0xcb, 0x7f, 0xbf, 0x97, 0x2c, 0x36, 0x2c, 0x74, 0x03, 0xc8,
0x02, 0x12, 0x22, 0xf3, 0xe4, 0x2b, 0x2b, 0x55, 0x2e, 0xf8, 0xa0, 0x77, 0xed, 0x0c, 0x4f, 0x63,
0xcf, 0x56, 0x5e, 0xc9, 0x7c, 0x61, 0xf3, 0xe8, 0x09, 0x5c, 0xd6, 0xe8, 0x06, 0x79, 0xcf, 0x20,
0x2f, 0x6c, 0xb6, 0x81, 0x21, 0x70, 0x39, 0x29, 0xd8, 0xc0, 0x35, 0x45, 0x13, 0x07, 0x8f, 0xe0,
0x6a, 0x2c, 0xf8, 0x3a, 0x4f, 0xe7, 0x34, 0x63, 0x05, 0x69, 0x96, 0xfa, 0x04, 0x0f, 0x7f, 0x4f,
0xd7, 0x5b, 0xdd, 0x81, 0xab, 0xfd, 0x30, 0x5b, 0x9d, 0x45, 0x37, 0xff, 0xdc, 0xca, 0xfa, 0x88,
0x6b, 0x1f, 0xf1, 0x5c, 0x32, 0x1a, 0x1b, 0x66, 0xf0, 0x02, 0xbc, 0x39, 0xab, 0xac, 0x78, 0xdd,
0x4d, 0xcf, 0x5f, 0xa8, 0x54, 0x12, 0xfa, 0x25, 0xa1, 0xa6, 0x60, 0xf4, 0xcf, 0xe3, 0x8b, 0x3a,
0x6b, 0xd1, 0xda, 0xfe, 0x16, 0xd5, 0x4e, 0xf4, 0xf4, 0x16, 0xe0, 0x97, 0x7b, 0xe8, 0x0c, 0xee,
0x7f, 0x98, 0xbd, 0x99, 0xbd, 0xfd, 0x38, 0xf3, 0x4e, 0x10, 0x40, 0xff, 0x75, 0x3c, 0x5d, 0x4c,
0x62, 0xcf, 0x31, 0xf1, 0x64, 0x31, 0x1d, 0x4f, 0xbc, 0x5e, 0xf4, 0xa3, 0x07, 0x30, 0x22, 0x8a,
0x59, 0x1e, 0xda, 0x36, 0x0a, 0xfa, 0x7e, 0x28, 0xec, 0x72, 0xa9, 0xd6, 0xfd, 0xfd, 0x67, 0xdd,
0x09, 0x76, 0xe4, 0xe0, 0x04, 0x7d, 0x83, 0xf3, 0xb6, 0xbd, 0xe8, 0xf6, 0xb8, 0xc6, 0x5f, 0x2e,
0xe4, 0x47, 0xff, 0x43, 0x39, 0x34, 0xe6, 0x70, 0x7a, 0xb0, 0x10, 0xe1, 0xe3, 0x12, 0x7f, 0x9e,
0xc9, 0x0f, 0x3b, 0xe3, 0x9b, 0x7e, 0xa3, 0xfe, 0x67, 0x57, 0xd7, 0x96, 0x7d, 0xf3, 0x80, 0x9e,
0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x66, 0xa2, 0xc0, 0xe2, 0xd6, 0x03, 0x00, 0x00,
var fileDescriptor_base_9cc78dc32b158b08 = []byte{
// 436 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcf, 0x8b, 0xd3, 0x40,
0x14, 0xc7, 0x37, 0xdb, 0xb8, 0xcb, 0xbe, 0xdd, 0x2d, 0x71, 0xaa, 0x50, 0x72, 0x2a, 0x01, 0xa1,
0x48, 0x99, 0x60, 0xb5, 0x5a, 0x6f, 0xb5, 0xb5, 0x87, 0x22, 0x54, 0x49, 0xb5, 0x8a, 0x97, 0x30,
0x9d, 0x4e, 0x93, 0x60, 0x93, 0x19, 0x33, 0xa9, 0x50, 0xc1, 0x93, 0x67, 0xff, 0x28, 0xff, 0x33,
0xc9, 0x4c, 0xd2, 0x46, 0x51, 0x4c, 0x4f, 0x79, 0xbc, 0xf7, 0xf9, 0x7e, 0xe7, 0xfd, 0x08, 0x0c,
0x83, 0x28, 0x0b, 0x77, 0x2b, 0x4c, 0x79, 0xec, 0x86, 0x44, 0x86, 0x11, 0xe5, 0xa9, 0x70, 0x13,
0x1e, 0x93, 0xb5, 0x2b, 0xb6, 0xbb, 0x20, 0x4a, 0xa4, 0xbb, 0x22, 0x92, 0xb9, 0x22, 0xe5, 0x19,
0x57, 0x21, 0x56, 0x21, 0x72, 0x0e, 0x38, 0x56, 0x38, 0x2e, 0x70, 0x7c, 0x64, 0xec, 0x51, 0x0d,
0x77, 0x19, 0x92, 0x94, 0xad, 0xdd, 0x90, 0x6e, 0xa5, 0x60, 0x34, 0xff, 0xfa, 0x79, 0xa0, 0x1d,
0x9c, 0x16, 0xdc, 0x7d, 0xa3, 0xc0, 0x59, 0xb2, 0xe1, 0x1e, 0xfb, 0xbc, 0x63, 0x32, 0x73, 0x7e,
0x1a, 0x80, 0xaa, 0x59, 0x29, 0x78, 0x22, 0x19, 0x1a, 0x83, 0x99, 0xed, 0x05, 0x6b, 0x1b, 0x1d,
0xa3, 0xdb, 0xec, 0x63, 0xfc, 0xff, 0x06, 0xb1, 0x76, 0x79, 0xbb, 0x17, 0xcc, 0x53, 0x5a, 0xd4,
0x03, 0xa4, 0x31, 0x9f, 0x88, 0xc8, 0xff, 0xc2, 0x52, 0x19, 0xf1, 0xa4, 0x7d, 0xde, 0x31, 0xba,
0x57, 0x9e, 0xa5, 0x2b, 0x2f, 0x44, 0xb4, 0xd4, 0x79, 0xf4, 0x00, 0x9a, 0x05, 0x5d, 0x92, 0x0d,
0x45, 0xde, 0xea, 0x6c, 0x89, 0x21, 0x30, 0x13, 0x12, 0xb3, 0xb6, 0xa9, 0x8a, 0x2a, 0x76, 0xee,
0x43, 0x6b, 0xc2, 0x93, 0x4d, 0x14, 0x2c, 0x68, 0xc8, 0x62, 0x52, 0x8e, 0xf6, 0x01, 0xee, 0xfd,
0x9e, 0x2e, 0x66, 0x1b, 0x81, 0x99, 0x6f, 0x45, 0xcd, 0x76, 0xdd, 0xef, 0xfd, 0x73, 0x36, 0xbd,
0x4d, 0x5c, 0x6c, 0x13, 0x2f, 0x04, 0xa3, 0x9e, 0x52, 0x3a, 0xcf, 0xc1, 0x5a, 0xb0, 0x4c, 0x9b,
0x17, 0xaf, 0xe5, 0xfd, 0xc7, 0x32, 0x10, 0x84, 0x7e, 0xf2, 0xa9, 0x2a, 0x28, 0xff, 0x1b, 0xef,
0xb6, 0xc8, 0x6a, 0x3a, 0x3f, 0x42, 0x45, 0xaa, 0x3b, 0x7a, 0xf8, 0x08, 0xe0, 0xb8, 0x3d, 0x74,
0x0d, 0x97, 0xef, 0xe6, 0xaf, 0xe6, 0xaf, 0xdf, 0xcf, 0xad, 0x33, 0x04, 0x70, 0xf1, 0xd2, 0x9b,
0x2d, 0xa7, 0x9e, 0x75, 0xae, 0xe2, 0xe9, 0x72, 0x36, 0x99, 0x5a, 0x8d, 0xfe, 0x8f, 0x06, 0xc0,
0x98, 0x48, 0xa6, 0x75, 0xe8, 0x5b, 0xe9, 0x90, 0x5f, 0x11, 0x0d, 0xea, 0xdf, 0xab, 0xf2, 0x2f,
0xd8, 0x4f, 0x4f, 0x95, 0xe9, 0xf6, 0x9d, 0x33, 0xf4, 0xdd, 0x80, 0x9b, 0xea, 0xae, 0xd1, 0xb3,
0x3a, 0x56, 0x7f, 0x39, 0x9a, 0x3d, 0x3c, 0x5d, 0x78, 0xe8, 0xe2, 0x2b, 0x5c, 0x1d, 0x76, 0x8b,
0x9e, 0xd4, 0x31, 0xfa, 0xf3, 0x8a, 0xf6, 0xe0, 0x44, 0x55, 0xf9, 0xf6, 0xf8, 0xf2, 0xe3, 0x1d,
0x55, 0x5c, 0x5d, 0xa8, 0xcf, 0xe3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x29, 0x9a, 0xb0,
0x0e, 0x04, 0x00, 0x00,
}

View file

@ -1,6 +1,6 @@
syntax = "proto3";
package hashicorp.nomad.plugins.base;
option go_package = "base";
package hashicorp.nomad.plugins.base.proto;
option go_package = "proto";
import "github.com/hashicorp/nomad/plugins/shared/hclspec/hcl_spec.proto";
@ -20,8 +20,8 @@ service BasePlugin {
// PluginType enumerates the type of plugins Nomad supports
enum PluginType {
UNKNOWN = 0;
DRIVER = 1;
DEVICE = 2;
DRIVER = 2;
DEVICE = 3;
}
// PluginInfoRequest is used to request the plugins basic information.

64
plugins/base/server.go Normal file
View file

@ -0,0 +1,64 @@
package base
import (
"fmt"
"golang.org/x/net/context"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/nomad/plugins/base/proto"
)
// basePluginServer wraps a base plugin and exposes it via gRPC.
type basePluginServer struct {
broker *plugin.GRPCBroker
impl BasePlugin
}
func (b *basePluginServer) PluginInfo(context.Context, *proto.PluginInfoRequest) (*proto.PluginInfoResponse, error) {
resp, err := b.impl.PluginInfo()
if err != nil {
return nil, err
}
var ptype proto.PluginType
switch resp.Type {
case PluginTypeDriver:
ptype = proto.PluginType_DRIVER
case PluginTypeDevice:
ptype = proto.PluginType_DEVICE
default:
return nil, fmt.Errorf("plugin is of unknown type: %q", resp.Type)
}
presp := &proto.PluginInfoResponse{
Type: ptype,
PluginApiVersion: resp.PluginApiVersion,
PluginVersion: resp.PluginVersion,
Name: resp.Name,
}
return presp, nil
}
func (b *basePluginServer) ConfigSchema(context.Context, *proto.ConfigSchemaRequest) (*proto.ConfigSchemaResponse, error) {
spec, err := b.impl.ConfigSchema()
if err != nil {
return nil, err
}
presp := &proto.ConfigSchemaResponse{
Spec: spec,
}
return presp, nil
}
func (b *basePluginServer) SetConfig(ctx context.Context, req *proto.SetConfigRequest) (*proto.SetConfigResponse, error) {
// Set the config
if err := b.impl.SetConfig(req.GetMsgpackConfig()); err != nil {
return nil, fmt.Errorf("SetConfig failed: %v", err)
}
return &proto.SetConfigResponse{}, nil
}

View file

@ -82,8 +82,6 @@ func decodeSpecBlock(spec *Spec, impliedName string) (hcldec.Spec, hcl.Diagnosti
})
return nil, diags
}
return nil, nil
}
func decodeObjectSpec(obj *Object) (hcldec.Spec, hcl.Diagnostics) {

View file

@ -46,7 +46,7 @@ func TestDec_Convert_Object(t *testing.T) {
Block: &Spec_Object{
&Object{
Attributes: map[string]*Spec{
"foo": &Spec{
"foo": {
Block: &Spec_Attr{
&Attr{
Type: "string",
@ -54,7 +54,7 @@ func TestDec_Convert_Object(t *testing.T) {
},
},
},
"bar": &Spec{
"bar": {
Block: &Spec_Attr{
&Attr{
Type: "number",
@ -62,7 +62,7 @@ func TestDec_Convert_Object(t *testing.T) {
},
},
},
"baz": &Spec{
"baz": {
Block: &Spec_Attr{
&Attr{
Type: "bool",
@ -106,7 +106,7 @@ func TestDec_Convert_Array(t *testing.T) {
Block: &Spec_Array{
Array: &Array{
Values: []*Spec{
&Spec{
{
Block: &Spec_Attr{
&Attr{
Name: "foo",
@ -115,7 +115,7 @@ func TestDec_Convert_Array(t *testing.T) {
},
},
},
&Spec{
{
Block: &Spec_Attr{
&Attr{
Name: "bar",

18
vendor/github.com/vmihailenco/msgpack/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,18 @@
## v3.3
- `msgpack:",inline"` tag is restored to force inlining structs.
## v3.2
- Decoding extension types returns pointer to the value instead of the value. Fixes #153
## v3
- gopkg.in is not supported any more. Update import path to github.com/vmihailenco/msgpack.
- Msgpack maps are decoded into map[string]interface{} by default.
- EncodeSliceLen is removed in favor of EncodeArrayLen. DecodeSliceLen is removed in favor of DecodeArrayLen.
- Embedded structs are automatically inlined where possible.
- Time is encoded using extension as described in https://github.com/msgpack/msgpack/pull/209. Old format is supported as well.
- EncodeInt8/16/32/64 is replaced with EncodeInt. EncodeUint8/16/32/64 is replaced with EncodeUint. There should be no performance differences.
- DecodeInterface can now return int8/16/32 and uint8/16/32.
- PeekCode returns codes.Code instead of byte.

25
vendor/github.com/vmihailenco/msgpack/LICENSE generated vendored Normal file
View file

@ -0,0 +1,25 @@
Copyright (c) 2013 The github.com/vmihailenco/msgpack Authors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

5
vendor/github.com/vmihailenco/msgpack/Makefile generated vendored Normal file
View file

@ -0,0 +1,5 @@
all:
go test ./...
env GOOS=linux GOARCH=386 go test ./...
go test ./... -short -race
go vet

69
vendor/github.com/vmihailenco/msgpack/README.md generated vendored Normal file
View file

@ -0,0 +1,69 @@
# MessagePack encoding for Golang
[![Build Status](https://travis-ci.org/vmihailenco/msgpack.svg?branch=v2)](https://travis-ci.org/vmihailenco/msgpack)
[![GoDoc](https://godoc.org/github.com/vmihailenco/msgpack?status.svg)](https://godoc.org/github.com/vmihailenco/msgpack)
Supports:
- Primitives, arrays, maps, structs, time.Time and interface{}.
- Appengine *datastore.Key and datastore.Cursor.
- [CustomEncoder](https://godoc.org/github.com/vmihailenco/msgpack#example-CustomEncoder)/CustomDecoder interfaces for custom encoding.
- [Extensions](https://godoc.org/github.com/vmihailenco/msgpack#example-RegisterExt) to encode type information.
- Renaming fields via `msgpack:"my_field_name"`.
- Omitting individual empty fields via `msgpack:",omitempty"` tag or all [empty fields in a struct](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--OmitEmpty).
- [Map keys sorting](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.SortMapKeys).
- Encoding/decoding all [structs as arrays](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.StructAsArray) or [individual structs](https://godoc.org/github.com/vmihailenco/msgpack#example-Marshal--AsArray).
- [Encoder.UseJSONTag](https://godoc.org/github.com/vmihailenco/msgpack#Encoder.UseJSONTag) with [Decoder.UseJSONTag](https://godoc.org/github.com/vmihailenco/msgpack#Decoder.UseJSONTag) can turn msgpack into drop-in replacement for JSON.
- Simple but very fast and efficient [queries](https://godoc.org/github.com/vmihailenco/msgpack#example-Decoder-Query).
API docs: https://godoc.org/github.com/vmihailenco/msgpack.
Examples: https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples.
## Installation
Install:
```shell
go get -u github.com/vmihailenco/msgpack
```
## Quickstart
```go
func ExampleMarshal() {
type Item struct {
Foo string
}
b, err := msgpack.Marshal(&Item{Foo: "bar"})
if err != nil {
panic(err)
}
var item Item
err = msgpack.Unmarshal(b, &item)
if err != nil {
panic(err)
}
fmt.Println(item.Foo)
// Output: bar
}
```
## Benchmark
```
BenchmarkStructVmihailencoMsgpack-4 200000 12814 ns/op 2128 B/op 26 allocs/op
BenchmarkStructUgorjiGoMsgpack-4 100000 17678 ns/op 3616 B/op 70 allocs/op
BenchmarkStructUgorjiGoCodec-4 100000 19053 ns/op 7346 B/op 23 allocs/op
BenchmarkStructJSON-4 20000 69438 ns/op 7864 B/op 26 allocs/op
BenchmarkStructGOB-4 10000 104331 ns/op 14664 B/op 278 allocs/op
```
## Howto
Please go through [examples](https://godoc.org/github.com/vmihailenco/msgpack#pkg-examples) to get an idea how to use this package.
## See also
- [Golang PostgreSQL ORM](https://github.com/go-pg/pg)
- [Golang message task queue](https://github.com/go-msgqueue/msgqueue)

86
vendor/github.com/vmihailenco/msgpack/codes/codes.go generated vendored Normal file
View file

@ -0,0 +1,86 @@
package codes
type Code byte
var (
PosFixedNumHigh Code = 0x7f
NegFixedNumLow Code = 0xe0
Nil Code = 0xc0
False Code = 0xc2
True Code = 0xc3
Float Code = 0xca
Double Code = 0xcb
Uint8 Code = 0xcc
Uint16 Code = 0xcd
Uint32 Code = 0xce
Uint64 Code = 0xcf
Int8 Code = 0xd0
Int16 Code = 0xd1
Int32 Code = 0xd2
Int64 Code = 0xd3
FixedStrLow Code = 0xa0
FixedStrHigh Code = 0xbf
FixedStrMask Code = 0x1f
Str8 Code = 0xd9
Str16 Code = 0xda
Str32 Code = 0xdb
Bin8 Code = 0xc4
Bin16 Code = 0xc5
Bin32 Code = 0xc6
FixedArrayLow Code = 0x90
FixedArrayHigh Code = 0x9f
FixedArrayMask Code = 0xf
Array16 Code = 0xdc
Array32 Code = 0xdd
FixedMapLow Code = 0x80
FixedMapHigh Code = 0x8f
FixedMapMask Code = 0xf
Map16 Code = 0xde
Map32 Code = 0xdf
FixExt1 Code = 0xd4
FixExt2 Code = 0xd5
FixExt4 Code = 0xd6
FixExt8 Code = 0xd7
FixExt16 Code = 0xd8
Ext8 Code = 0xc7
Ext16 Code = 0xc8
Ext32 Code = 0xc9
)
func IsFixedNum(c Code) bool {
return c <= PosFixedNumHigh || c >= NegFixedNumLow
}
func IsFixedMap(c Code) bool {
return c >= FixedMapLow && c <= FixedMapHigh
}
func IsFixedArray(c Code) bool {
return c >= FixedArrayLow && c <= FixedArrayHigh
}
func IsFixedString(c Code) bool {
return c >= FixedStrLow && c <= FixedStrHigh
}
func IsString(c Code) bool {
return IsFixedString(c) || c == Str8 || c == Str16 || c == Str32
}
func IsFixedExt(c Code) bool {
return c >= FixExt1 && c <= FixExt16
}
func IsExt(c Code) bool {
return IsFixedExt(c) || c == Ext8 || c == Ext16 || c == Ext32
}

536
vendor/github.com/vmihailenco/msgpack/decode.go generated vendored Normal file
View file

@ -0,0 +1,536 @@
package msgpack
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"reflect"
"time"
"github.com/vmihailenco/msgpack/codes"
)
const bytesAllocLimit = 1024 * 1024 // 1mb
type bufReader interface {
io.Reader
io.ByteScanner
}
func newBufReader(r io.Reader) bufReader {
if br, ok := r.(bufReader); ok {
return br
}
return bufio.NewReader(r)
}
func makeBuffer() []byte {
return make([]byte, 0, 64)
}
// Unmarshal decodes the MessagePack-encoded data and stores the result
// in the value pointed to by v.
func Unmarshal(data []byte, v ...interface{}) error {
return NewDecoder(bytes.NewReader(data)).Decode(v...)
}
type Decoder struct {
r io.Reader
s io.ByteScanner
buf []byte
extLen int
rec []byte // accumulates read data if not nil
useLoose bool
useJSONTag bool
decodeMapFunc func(*Decoder) (interface{}, error)
}
// NewDecoder returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may read data from r
// beyond the MessagePack values requested. Buffering can be disabled
// by passing a reader that implements io.ByteScanner interface.
func NewDecoder(r io.Reader) *Decoder {
d := &Decoder{
decodeMapFunc: decodeMap,
buf: makeBuffer(),
}
d.resetReader(r)
return d
}
func (d *Decoder) SetDecodeMapFunc(fn func(*Decoder) (interface{}, error)) {
d.decodeMapFunc = fn
}
// UseDecodeInterfaceLoose causes decoder to use DecodeInterfaceLoose
// to decode msgpack value into Go interface{}.
func (d *Decoder) UseDecodeInterfaceLoose(flag bool) {
d.useLoose = flag
}
// UseJSONTag causes the Decoder to use json struct tag as fallback option
// if there is no msgpack tag.
func (d *Decoder) UseJSONTag(v bool) *Decoder {
d.useJSONTag = v
return d
}
func (d *Decoder) Reset(r io.Reader) error {
d.resetReader(r)
return nil
}
func (d *Decoder) resetReader(r io.Reader) {
reader := newBufReader(r)
d.r = reader
d.s = reader
}
func (d *Decoder) Decode(v ...interface{}) error {
for _, vv := range v {
if err := d.decode(vv); err != nil {
return err
}
}
return nil
}
func (d *Decoder) decode(dst interface{}) error {
var err error
switch v := dst.(type) {
case *string:
if v != nil {
*v, err = d.DecodeString()
return err
}
case *[]byte:
if v != nil {
return d.decodeBytesPtr(v)
}
case *int:
if v != nil {
*v, err = d.DecodeInt()
return err
}
case *int8:
if v != nil {
*v, err = d.DecodeInt8()
return err
}
case *int16:
if v != nil {
*v, err = d.DecodeInt16()
return err
}
case *int32:
if v != nil {
*v, err = d.DecodeInt32()
return err
}
case *int64:
if v != nil {
*v, err = d.DecodeInt64()
return err
}
case *uint:
if v != nil {
*v, err = d.DecodeUint()
return err
}
case *uint8:
if v != nil {
*v, err = d.DecodeUint8()
return err
}
case *uint16:
if v != nil {
*v, err = d.DecodeUint16()
return err
}
case *uint32:
if v != nil {
*v, err = d.DecodeUint32()
return err
}
case *uint64:
if v != nil {
*v, err = d.DecodeUint64()
return err
}
case *bool:
if v != nil {
*v, err = d.DecodeBool()
return err
}
case *float32:
if v != nil {
*v, err = d.DecodeFloat32()
return err
}
case *float64:
if v != nil {
*v, err = d.DecodeFloat64()
return err
}
case *[]string:
return d.decodeStringSlicePtr(v)
case *map[string]string:
return d.decodeMapStringStringPtr(v)
case *map[string]interface{}:
return d.decodeMapStringInterfacePtr(v)
case *time.Duration:
if v != nil {
vv, err := d.DecodeInt64()
*v = time.Duration(vv)
return err
}
case *time.Time:
if v != nil {
*v, err = d.DecodeTime()
return err
}
}
v := reflect.ValueOf(dst)
if !v.IsValid() {
return errors.New("msgpack: Decode(nil)")
}
if v.Kind() != reflect.Ptr {
return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst)
}
v = v.Elem()
if !v.IsValid() {
return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst)
}
return d.DecodeValue(v)
}
func (d *Decoder) decodeInterface() (interface{}, error) {
if d.useLoose {
return d.DecodeInterfaceLoose()
}
return d.DecodeInterface()
}
func (d *Decoder) DecodeValue(v reflect.Value) error {
decode := getDecoder(v.Type())
return decode(d, v)
}
func (d *Decoder) DecodeNil() error {
c, err := d.readCode()
if err != nil {
return err
}
if c != codes.Nil {
return fmt.Errorf("msgpack: invalid code=%x decoding nil", c)
}
return nil
}
func (d *Decoder) decodeNilValue(v reflect.Value) error {
err := d.DecodeNil()
if v.IsNil() {
return err
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
v.Set(reflect.Zero(v.Type()))
return err
}
func (d *Decoder) DecodeBool() (bool, error) {
c, err := d.readCode()
if err != nil {
return false, err
}
return d.bool(c)
}
func (d *Decoder) bool(c codes.Code) (bool, error) {
if c == codes.False {
return false, nil
}
if c == codes.True {
return true, nil
}
return false, fmt.Errorf("msgpack: invalid code=%x decoding bool", c)
}
// DecodeInterface decodes value into interface. It returns following types:
// - nil,
// - bool,
// - int8, int16, int32, int64,
// - uint8, uint16, uint32, uint64,
// - float32 and float64,
// - string,
// - []byte,
// - slices of any of the above,
// - maps of any of the above.
//
// DecodeInterface should be used only when you don't know the type of value
// you are decoding. For example, if you are decoding number it is better to use
// DecodeInt64 for negative numbers and DecodeUint64 for positive numbers.
func (d *Decoder) DecodeInterface() (interface{}, error) {
c, err := d.readCode()
if err != nil {
return nil, err
}
if codes.IsFixedNum(c) {
return int8(c), nil
}
if codes.IsFixedMap(c) {
_ = d.s.UnreadByte()
return d.DecodeMap()
}
if codes.IsFixedArray(c) {
return d.decodeSlice(c)
}
if codes.IsFixedString(c) {
return d.string(c)
}
switch c {
case codes.Nil:
return nil, nil
case codes.False, codes.True:
return d.bool(c)
case codes.Float:
return d.float32(c)
case codes.Double:
return d.float64(c)
case codes.Uint8:
return d.uint8()
case codes.Uint16:
return d.uint16()
case codes.Uint32:
return d.uint32()
case codes.Uint64:
return d.uint64()
case codes.Int8:
return d.int8()
case codes.Int16:
return d.int16()
case codes.Int32:
return d.int32()
case codes.Int64:
return d.int64()
case codes.Bin8, codes.Bin16, codes.Bin32:
return d.bytes(c, nil)
case codes.Str8, codes.Str16, codes.Str32:
return d.string(c)
case codes.Array16, codes.Array32:
return d.decodeSlice(c)
case codes.Map16, codes.Map32:
d.s.UnreadByte()
return d.DecodeMap()
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
codes.Ext8, codes.Ext16, codes.Ext32:
return d.extInterface(c)
}
return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c)
}
// DecodeInterfaceLoose is like DecodeInterface except that:
// - int8, int16, and int32 are converted to int64,
// - uint8, uint16, and uint32 are converted to uint64,
// - float32 is converted to float64.
func (d *Decoder) DecodeInterfaceLoose() (interface{}, error) {
c, err := d.readCode()
if err != nil {
return nil, err
}
if codes.IsFixedNum(c) {
return int64(c), nil
}
if codes.IsFixedMap(c) {
d.s.UnreadByte()
return d.DecodeMap()
}
if codes.IsFixedArray(c) {
return d.decodeSlice(c)
}
if codes.IsFixedString(c) {
return d.string(c)
}
switch c {
case codes.Nil:
return nil, nil
case codes.False, codes.True:
return d.bool(c)
case codes.Float, codes.Double:
return d.float64(c)
case codes.Uint8, codes.Uint16, codes.Uint32, codes.Uint64:
return d.uint(c)
case codes.Int8, codes.Int16, codes.Int32, codes.Int64:
return d.int(c)
case codes.Bin8, codes.Bin16, codes.Bin32:
return d.bytes(c, nil)
case codes.Str8, codes.Str16, codes.Str32:
return d.string(c)
case codes.Array16, codes.Array32:
return d.decodeSlice(c)
case codes.Map16, codes.Map32:
d.s.UnreadByte()
return d.DecodeMap()
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
codes.Ext8, codes.Ext16, codes.Ext32:
return d.extInterface(c)
}
return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c)
}
// Skip skips next value.
func (d *Decoder) Skip() error {
c, err := d.readCode()
if err != nil {
return err
}
if codes.IsFixedNum(c) {
return nil
} else if codes.IsFixedMap(c) {
return d.skipMap(c)
} else if codes.IsFixedArray(c) {
return d.skipSlice(c)
} else if codes.IsFixedString(c) {
return d.skipBytes(c)
}
switch c {
case codes.Nil, codes.False, codes.True:
return nil
case codes.Uint8, codes.Int8:
return d.skipN(1)
case codes.Uint16, codes.Int16:
return d.skipN(2)
case codes.Uint32, codes.Int32, codes.Float:
return d.skipN(4)
case codes.Uint64, codes.Int64, codes.Double:
return d.skipN(8)
case codes.Bin8, codes.Bin16, codes.Bin32:
return d.skipBytes(c)
case codes.Str8, codes.Str16, codes.Str32:
return d.skipBytes(c)
case codes.Array16, codes.Array32:
return d.skipSlice(c)
case codes.Map16, codes.Map32:
return d.skipMap(c)
case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16,
codes.Ext8, codes.Ext16, codes.Ext32:
return d.skipExt(c)
}
return fmt.Errorf("msgpack: unknown code %x", c)
}
// PeekCode returns the next MessagePack code without advancing the reader.
// Subpackage msgpack/codes contains list of available codes.
func (d *Decoder) PeekCode() (codes.Code, error) {
c, err := d.s.ReadByte()
if err != nil {
return 0, err
}
return codes.Code(c), d.s.UnreadByte()
}
func (d *Decoder) hasNilCode() bool {
code, err := d.PeekCode()
return err == nil && code == codes.Nil
}
func (d *Decoder) readCode() (codes.Code, error) {
d.extLen = 0
c, err := d.s.ReadByte()
if err != nil {
return 0, err
}
if d.rec != nil {
d.rec = append(d.rec, c)
}
return codes.Code(c), nil
}
func (d *Decoder) readFull(b []byte) error {
_, err := io.ReadFull(d.r, b)
if err != nil {
return err
}
if d.rec != nil {
d.rec = append(d.rec, b...)
}
return nil
}
func (d *Decoder) readN(n int) ([]byte, error) {
buf, err := readN(d.r, d.buf, n)
if err != nil {
return nil, err
}
d.buf = buf
if d.rec != nil {
d.rec = append(d.rec, buf...)
}
return buf, nil
}
func readN(r io.Reader, b []byte, n int) ([]byte, error) {
if b == nil {
if n == 0 {
return make([]byte, 0), nil
}
if n <= bytesAllocLimit {
b = make([]byte, n)
} else {
b = make([]byte, bytesAllocLimit)
}
}
if n <= cap(b) {
b = b[:n]
_, err := io.ReadFull(r, b)
return b, err
}
b = b[:cap(b)]
var pos int
for {
alloc := n - len(b)
if alloc > bytesAllocLimit {
alloc = bytesAllocLimit
}
b = append(b, make([]byte, alloc)...)
_, err := io.ReadFull(r, b[pos:])
if err != nil {
return nil, err
}
if len(b) == n {
break
}
pos = len(b)
}
return b, nil
}
func min(a, b int) int {
if a <= b {
return a
}
return b
}

289
vendor/github.com/vmihailenco/msgpack/decode_map.go generated vendored Normal file
View file

@ -0,0 +1,289 @@
package msgpack
import (
"errors"
"fmt"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
const mapElemsAllocLimit = 1e4
var mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil))
var mapStringStringType = mapStringStringPtrType.Elem()
var mapStringInterfacePtrType = reflect.TypeOf((*map[string]interface{})(nil))
var mapStringInterfaceType = mapStringInterfacePtrType.Elem()
var errInvalidCode = errors.New("invalid code")
func decodeMapValue(d *Decoder, v reflect.Value) error {
n, err := d.DecodeMapLen()
if err != nil {
return err
}
typ := v.Type()
if n == -1 {
v.Set(reflect.Zero(typ))
return nil
}
if v.IsNil() {
v.Set(reflect.MakeMap(typ))
}
keyType := typ.Key()
valueType := typ.Elem()
for i := 0; i < n; i++ {
mk := reflect.New(keyType).Elem()
if err := d.DecodeValue(mk); err != nil {
return err
}
mv := reflect.New(valueType).Elem()
if err := d.DecodeValue(mv); err != nil {
return err
}
v.SetMapIndex(mk, mv)
}
return nil
}
func decodeMap(d *Decoder) (interface{}, error) {
n, err := d.DecodeMapLen()
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
m := make(map[string]interface{}, min(n, mapElemsAllocLimit))
for i := 0; i < n; i++ {
mk, err := d.DecodeString()
if err != nil {
return nil, err
}
mv, err := d.decodeInterface()
if err != nil {
return nil, err
}
m[mk] = mv
}
return m, nil
}
func (d *Decoder) DecodeMapLen() (int, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
if codes.IsExt(c) {
if err = d.skipExtHeader(c); err != nil {
return 0, err
}
c, err = d.readCode()
if err != nil {
return 0, err
}
}
return d.mapLen(c)
}
func (d *Decoder) mapLen(c codes.Code) (int, error) {
n, err := d._mapLen(c)
err = expandInvalidCodeMapLenError(c, err)
return n, err
}
func (d *Decoder) _mapLen(c codes.Code) (int, error) {
if c == codes.Nil {
return -1, nil
}
if c >= codes.FixedMapLow && c <= codes.FixedMapHigh {
return int(c & codes.FixedMapMask), nil
}
if c == codes.Map16 {
n, err := d.uint16()
return int(n), err
}
if c == codes.Map32 {
n, err := d.uint32()
return int(n), err
}
return 0, errInvalidCode
}
func expandInvalidCodeMapLenError(c codes.Code, err error) error {
if err == errInvalidCode {
return fmt.Errorf("msgpack: invalid code=%x decoding map length", c)
}
return err
}
func decodeMapStringStringValue(d *Decoder, v reflect.Value) error {
mptr := v.Addr().Convert(mapStringStringPtrType).Interface().(*map[string]string)
return d.decodeMapStringStringPtr(mptr)
}
func (d *Decoder) decodeMapStringStringPtr(ptr *map[string]string) error {
n, err := d.DecodeMapLen()
if err != nil {
return err
}
if n == -1 {
*ptr = nil
return nil
}
m := *ptr
if m == nil {
*ptr = make(map[string]string, min(n, mapElemsAllocLimit))
m = *ptr
}
for i := 0; i < n; i++ {
mk, err := d.DecodeString()
if err != nil {
return err
}
mv, err := d.DecodeString()
if err != nil {
return err
}
m[mk] = mv
}
return nil
}
func decodeMapStringInterfaceValue(d *Decoder, v reflect.Value) error {
ptr := v.Addr().Convert(mapStringInterfacePtrType).Interface().(*map[string]interface{})
return d.decodeMapStringInterfacePtr(ptr)
}
func (d *Decoder) decodeMapStringInterfacePtr(ptr *map[string]interface{}) error {
n, err := d.DecodeMapLen()
if err != nil {
return err
}
if n == -1 {
*ptr = nil
return nil
}
m := *ptr
if m == nil {
*ptr = make(map[string]interface{}, min(n, mapElemsAllocLimit))
m = *ptr
}
for i := 0; i < n; i++ {
mk, err := d.DecodeString()
if err != nil {
return err
}
mv, err := d.decodeInterface()
if err != nil {
return err
}
m[mk] = mv
}
return nil
}
func (d *Decoder) DecodeMap() (interface{}, error) {
return d.decodeMapFunc(d)
}
func (d *Decoder) skipMap(c codes.Code) error {
n, err := d.mapLen(c)
if err != nil {
return err
}
for i := 0; i < n; i++ {
if err := d.Skip(); err != nil {
return err
}
if err := d.Skip(); err != nil {
return err
}
}
return nil
}
func decodeStructValue(d *Decoder, v reflect.Value) error {
c, err := d.readCode()
if err != nil {
return err
}
var isArray bool
n, err := d._mapLen(c)
if err != nil {
var err2 error
n, err2 = d.arrayLen(c)
if err2 != nil {
return expandInvalidCodeMapLenError(c, err)
}
isArray = true
}
if n == -1 {
if err = mustSet(v); err != nil {
return err
}
v.Set(reflect.Zero(v.Type()))
return nil
}
var fields *fields
if d.useJSONTag {
fields = jsonStructs.Fields(v.Type())
} else {
fields = structs.Fields(v.Type())
}
if isArray {
for i, f := range fields.List {
if i >= n {
break
}
if err := f.DecodeValue(d, v); err != nil {
return err
}
}
// Skip extra values.
for i := len(fields.List); i < n; i++ {
if err := d.Skip(); err != nil {
return err
}
}
return nil
}
for i := 0; i < n; i++ {
name, err := d.DecodeString()
if err != nil {
return err
}
if f := fields.Table[name]; f != nil {
if err := f.DecodeValue(d, v); err != nil {
return err
}
} else {
if err := d.Skip(); err != nil {
return err
}
}
}
return nil
}

307
vendor/github.com/vmihailenco/msgpack/decode_number.go generated vendored Normal file
View file

@ -0,0 +1,307 @@
package msgpack
import (
"fmt"
"math"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
func (d *Decoder) skipN(n int) error {
_, err := d.readN(n)
return err
}
func (d *Decoder) uint8() (uint8, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return uint8(c), nil
}
func (d *Decoder) int8() (int8, error) {
n, err := d.uint8()
return int8(n), err
}
func (d *Decoder) uint16() (uint16, error) {
b, err := d.readN(2)
if err != nil {
return 0, err
}
return (uint16(b[0]) << 8) | uint16(b[1]), nil
}
func (d *Decoder) int16() (int16, error) {
n, err := d.uint16()
return int16(n), err
}
func (d *Decoder) uint32() (uint32, error) {
b, err := d.readN(4)
if err != nil {
return 0, err
}
n := (uint32(b[0]) << 24) |
(uint32(b[1]) << 16) |
(uint32(b[2]) << 8) |
uint32(b[3])
return n, nil
}
func (d *Decoder) int32() (int32, error) {
n, err := d.uint32()
return int32(n), err
}
func (d *Decoder) uint64() (uint64, error) {
b, err := d.readN(8)
if err != nil {
return 0, err
}
n := (uint64(b[0]) << 56) |
(uint64(b[1]) << 48) |
(uint64(b[2]) << 40) |
(uint64(b[3]) << 32) |
(uint64(b[4]) << 24) |
(uint64(b[5]) << 16) |
(uint64(b[6]) << 8) |
uint64(b[7])
return n, nil
}
func (d *Decoder) int64() (int64, error) {
n, err := d.uint64()
return int64(n), err
}
// DecodeUint64 decodes msgpack int8/16/32/64 and uint8/16/32/64
// into Go uint64.
func (d *Decoder) DecodeUint64() (uint64, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.uint(c)
}
func (d *Decoder) uint(c codes.Code) (uint64, error) {
if c == codes.Nil {
return 0, nil
}
if codes.IsFixedNum(c) {
return uint64(int8(c)), nil
}
switch c {
case codes.Uint8:
n, err := d.uint8()
return uint64(n), err
case codes.Int8:
n, err := d.int8()
return uint64(n), err
case codes.Uint16:
n, err := d.uint16()
return uint64(n), err
case codes.Int16:
n, err := d.int16()
return uint64(n), err
case codes.Uint32:
n, err := d.uint32()
return uint64(n), err
case codes.Int32:
n, err := d.int32()
return uint64(n), err
case codes.Uint64, codes.Int64:
return d.uint64()
}
return 0, fmt.Errorf("msgpack: invalid code=%x decoding uint64", c)
}
// DecodeInt64 decodes msgpack int8/16/32/64 and uint8/16/32/64
// into Go int64.
func (d *Decoder) DecodeInt64() (int64, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.int(c)
}
func (d *Decoder) int(c codes.Code) (int64, error) {
if c == codes.Nil {
return 0, nil
}
if codes.IsFixedNum(c) {
return int64(int8(c)), nil
}
switch c {
case codes.Uint8:
n, err := d.uint8()
return int64(n), err
case codes.Int8:
n, err := d.uint8()
return int64(int8(n)), err
case codes.Uint16:
n, err := d.uint16()
return int64(n), err
case codes.Int16:
n, err := d.uint16()
return int64(int16(n)), err
case codes.Uint32:
n, err := d.uint32()
return int64(n), err
case codes.Int32:
n, err := d.uint32()
return int64(int32(n)), err
case codes.Uint64, codes.Int64:
n, err := d.uint64()
return int64(n), err
}
return 0, fmt.Errorf("msgpack: invalid code=%x decoding int64", c)
}
func (d *Decoder) DecodeFloat32() (float32, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.float32(c)
}
func (d *Decoder) float32(c codes.Code) (float32, error) {
if c == codes.Float {
n, err := d.uint32()
if err != nil {
return 0, err
}
return math.Float32frombits(n), nil
}
n, err := d.int(c)
if err != nil {
return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c)
}
return float32(n), nil
}
// DecodeFloat64 decodes msgpack float32/64 into Go float64.
func (d *Decoder) DecodeFloat64() (float64, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.float64(c)
}
func (d *Decoder) float64(c codes.Code) (float64, error) {
switch c {
case codes.Float:
n, err := d.float32(c)
if err != nil {
return 0, err
}
return float64(n), nil
case codes.Double:
n, err := d.uint64()
if err != nil {
return 0, err
}
return math.Float64frombits(n), nil
}
n, err := d.int(c)
if err != nil {
return 0, fmt.Errorf("msgpack: invalid code=%x decoding float32", c)
}
return float64(n), nil
}
func (d *Decoder) DecodeUint() (uint, error) {
n, err := d.DecodeUint64()
return uint(n), err
}
func (d *Decoder) DecodeUint8() (uint8, error) {
n, err := d.DecodeUint64()
return uint8(n), err
}
func (d *Decoder) DecodeUint16() (uint16, error) {
n, err := d.DecodeUint64()
return uint16(n), err
}
func (d *Decoder) DecodeUint32() (uint32, error) {
n, err := d.DecodeUint64()
return uint32(n), err
}
func (d *Decoder) DecodeInt() (int, error) {
n, err := d.DecodeInt64()
return int(n), err
}
func (d *Decoder) DecodeInt8() (int8, error) {
n, err := d.DecodeInt64()
return int8(n), err
}
func (d *Decoder) DecodeInt16() (int16, error) {
n, err := d.DecodeInt64()
return int16(n), err
}
func (d *Decoder) DecodeInt32() (int32, error) {
n, err := d.DecodeInt64()
return int32(n), err
}
func decodeFloat32Value(d *Decoder, v reflect.Value) error {
f, err := d.DecodeFloat32()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetFloat(float64(f))
return nil
}
func decodeFloat64Value(d *Decoder, v reflect.Value) error {
f, err := d.DecodeFloat64()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetFloat(f)
return nil
}
func decodeInt64Value(d *Decoder, v reflect.Value) error {
n, err := d.DecodeInt64()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetInt(n)
return nil
}
func decodeUint64Value(d *Decoder, v reflect.Value) error {
n, err := d.DecodeUint64()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetUint(n)
return nil
}

158
vendor/github.com/vmihailenco/msgpack/decode_query.go generated vendored Normal file
View file

@ -0,0 +1,158 @@
package msgpack
import (
"fmt"
"strconv"
"strings"
"github.com/vmihailenco/msgpack/codes"
)
type queryResult struct {
query string
key string
hasAsterisk bool
values []interface{}
}
func (q *queryResult) nextKey() {
ind := strings.IndexByte(q.query, '.')
if ind == -1 {
q.key = q.query
q.query = ""
return
}
q.key = q.query[:ind]
q.query = q.query[ind+1:]
}
// Query extracts data specified by the query from the msgpack stream skipping
// any other data. Query consists of map keys and array indexes separated with dot,
// e.g. key1.0.key2.
func (d *Decoder) Query(query string) ([]interface{}, error) {
res := queryResult{
query: query,
}
if err := d.query(&res); err != nil {
return nil, err
}
return res.values, nil
}
func (d *Decoder) query(q *queryResult) error {
q.nextKey()
if q.key == "" {
v, err := d.decodeInterface()
if err != nil {
return err
}
q.values = append(q.values, v)
return nil
}
code, err := d.PeekCode()
if err != nil {
return err
}
switch {
case code == codes.Map16 || code == codes.Map32 || codes.IsFixedMap(code):
err = d.queryMapKey(q)
case code == codes.Array16 || code == codes.Array32 || codes.IsFixedArray(code):
err = d.queryArrayIndex(q)
default:
err = fmt.Errorf("msgpack: unsupported code=%x decoding key=%q", code, q.key)
}
return err
}
func (d *Decoder) queryMapKey(q *queryResult) error {
n, err := d.DecodeMapLen()
if err != nil {
return err
}
if n == -1 {
return nil
}
for i := 0; i < n; i++ {
k, err := d.bytesNoCopy()
if err != nil {
return err
}
if string(k) == q.key {
if err := d.query(q); err != nil {
return err
}
if q.hasAsterisk {
return d.skipNext((n - i - 1) * 2)
}
return nil
}
if err := d.Skip(); err != nil {
return err
}
}
return nil
}
func (d *Decoder) queryArrayIndex(q *queryResult) error {
n, err := d.DecodeArrayLen()
if err != nil {
return err
}
if n == -1 {
return nil
}
if q.key == "*" {
q.hasAsterisk = true
query := q.query
for i := 0; i < n; i++ {
q.query = query
if err := d.query(q); err != nil {
return err
}
}
q.hasAsterisk = false
return nil
}
ind, err := strconv.Atoi(q.key)
if err != nil {
return err
}
for i := 0; i < n; i++ {
if i == ind {
if err := d.query(q); err != nil {
return err
}
if q.hasAsterisk {
return d.skipNext(n - i - 1)
}
return nil
}
if err := d.Skip(); err != nil {
return err
}
}
return nil
}
func (d *Decoder) skipNext(n int) error {
for i := 0; i < n; i++ {
if err := d.Skip(); err != nil {
return err
}
}
return nil
}

192
vendor/github.com/vmihailenco/msgpack/decode_slice.go generated vendored Normal file
View file

@ -0,0 +1,192 @@
package msgpack
import (
"fmt"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
const sliceElemsAllocLimit = 1e4
var sliceStringPtrType = reflect.TypeOf((*[]string)(nil))
func (d *Decoder) DecodeArrayLen() (int, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.arrayLen(c)
}
func (d *Decoder) arrayLen(c codes.Code) (int, error) {
if c == codes.Nil {
return -1, nil
} else if c >= codes.FixedArrayLow && c <= codes.FixedArrayHigh {
return int(c & codes.FixedArrayMask), nil
}
switch c {
case codes.Array16:
n, err := d.uint16()
return int(n), err
case codes.Array32:
n, err := d.uint32()
return int(n), err
}
return 0, fmt.Errorf("msgpack: invalid code=%x decoding array length", c)
}
func decodeStringSliceValue(d *Decoder, v reflect.Value) error {
ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string)
return d.decodeStringSlicePtr(ptr)
}
func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error {
n, err := d.DecodeArrayLen()
if err != nil {
return err
}
if n == -1 {
return nil
}
ss := setStringsCap(*ptr, n)
for i := 0; i < n; i++ {
s, err := d.DecodeString()
if err != nil {
return err
}
ss = append(ss, s)
}
*ptr = ss
return nil
}
func setStringsCap(s []string, n int) []string {
if n > sliceElemsAllocLimit {
n = sliceElemsAllocLimit
}
if s == nil {
return make([]string, 0, n)
}
if cap(s) >= n {
return s[:0]
}
s = s[:cap(s)]
s = append(s, make([]string, n-len(s))...)
return s[:0]
}
func decodeSliceValue(d *Decoder, v reflect.Value) error {
n, err := d.DecodeArrayLen()
if err != nil {
return err
}
if n == -1 {
v.Set(reflect.Zero(v.Type()))
return nil
}
if n == 0 && v.IsNil() {
v.Set(reflect.MakeSlice(v.Type(), 0, 0))
return nil
}
if v.Cap() >= n {
v.Set(v.Slice(0, n))
} else if v.Len() < v.Cap() {
v.Set(v.Slice(0, v.Cap()))
}
for i := 0; i < n; i++ {
if i >= v.Len() {
v.Set(growSliceValue(v, n))
}
sv := v.Index(i)
if err := d.DecodeValue(sv); err != nil {
return err
}
}
return nil
}
func growSliceValue(v reflect.Value, n int) reflect.Value {
diff := n - v.Len()
if diff > sliceElemsAllocLimit {
diff = sliceElemsAllocLimit
}
v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff))
return v
}
func decodeArrayValue(d *Decoder, v reflect.Value) error {
n, err := d.DecodeArrayLen()
if err != nil {
return err
}
if n == -1 {
return nil
}
if n > v.Len() {
return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n)
}
for i := 0; i < n; i++ {
sv := v.Index(i)
if err := d.DecodeValue(sv); err != nil {
return err
}
}
return nil
}
func (d *Decoder) DecodeSlice() ([]interface{}, error) {
c, err := d.readCode()
if err != nil {
return nil, err
}
return d.decodeSlice(c)
}
func (d *Decoder) decodeSlice(c codes.Code) ([]interface{}, error) {
n, err := d.arrayLen(c)
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
s := make([]interface{}, 0, min(n, sliceElemsAllocLimit))
for i := 0; i < n; i++ {
v, err := d.decodeInterface()
if err != nil {
return nil, err
}
s = append(s, v)
}
return s, nil
}
func (d *Decoder) skipSlice(c codes.Code) error {
n, err := d.arrayLen(c)
if err != nil {
return err
}
for i := 0; i < n; i++ {
if err := d.Skip(); err != nil {
return err
}
}
return nil
}

175
vendor/github.com/vmihailenco/msgpack/decode_string.go generated vendored Normal file
View file

@ -0,0 +1,175 @@
package msgpack
import (
"fmt"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
func (d *Decoder) bytesLen(c codes.Code) (int, error) {
if c == codes.Nil {
return -1, nil
} else if codes.IsFixedString(c) {
return int(c & codes.FixedStrMask), nil
}
switch c {
case codes.Str8, codes.Bin8:
n, err := d.uint8()
return int(n), err
case codes.Str16, codes.Bin16:
n, err := d.uint16()
return int(n), err
case codes.Str32, codes.Bin32:
n, err := d.uint32()
return int(n), err
}
return 0, fmt.Errorf("msgpack: invalid code=%x decoding bytes length", c)
}
func (d *Decoder) DecodeString() (string, error) {
c, err := d.readCode()
if err != nil {
return "", err
}
return d.string(c)
}
func (d *Decoder) string(c codes.Code) (string, error) {
n, err := d.bytesLen(c)
if err != nil {
return "", err
}
if n == -1 {
return "", nil
}
b, err := d.readN(n)
return string(b), err
}
func decodeStringValue(d *Decoder, v reflect.Value) error {
s, err := d.DecodeString()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetString(s)
return nil
}
func (d *Decoder) DecodeBytesLen() (int, error) {
c, err := d.readCode()
if err != nil {
return 0, err
}
return d.bytesLen(c)
}
func (d *Decoder) DecodeBytes() ([]byte, error) {
c, err := d.readCode()
if err != nil {
return nil, err
}
return d.bytes(c, nil)
}
func (d *Decoder) bytes(c codes.Code, b []byte) ([]byte, error) {
n, err := d.bytesLen(c)
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
return readN(d.r, b, n)
}
func (d *Decoder) bytesNoCopy() ([]byte, error) {
c, err := d.readCode()
if err != nil {
return nil, err
}
n, err := d.bytesLen(c)
if err != nil {
return nil, err
}
if n == -1 {
return nil, nil
}
return d.readN(n)
}
func (d *Decoder) decodeBytesPtr(ptr *[]byte) error {
c, err := d.readCode()
if err != nil {
return err
}
return d.bytesPtr(c, ptr)
}
func (d *Decoder) bytesPtr(c codes.Code, ptr *[]byte) error {
n, err := d.bytesLen(c)
if err != nil {
return err
}
if n == -1 {
*ptr = nil
return nil
}
*ptr, err = readN(d.r, *ptr, n)
return err
}
func (d *Decoder) skipBytes(c codes.Code) error {
n, err := d.bytesLen(c)
if err != nil {
return err
}
if n == -1 {
return nil
}
return d.skipN(n)
}
func decodeBytesValue(d *Decoder, v reflect.Value) error {
c, err := d.readCode()
if err != nil {
return err
}
b, err := d.bytes(c, v.Bytes())
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetBytes(b)
return nil
}
func decodeByteArrayValue(d *Decoder, v reflect.Value) error {
c, err := d.readCode()
if err != nil {
return err
}
n, err := d.bytesLen(c)
if err != nil {
return err
}
if n == -1 {
return nil
}
if n > v.Len() {
return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n)
}
b := v.Slice(0, n).Bytes()
return d.readFull(b)
}

292
vendor/github.com/vmihailenco/msgpack/decode_value.go generated vendored Normal file
View file

@ -0,0 +1,292 @@
package msgpack
import (
"errors"
"fmt"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
var stringType = reflect.TypeOf((*string)(nil)).Elem()
var valueDecoders []decoderFunc
func init() {
valueDecoders = []decoderFunc{
reflect.Bool: decodeBoolValue,
reflect.Int: decodeInt64Value,
reflect.Int8: decodeInt64Value,
reflect.Int16: decodeInt64Value,
reflect.Int32: decodeInt64Value,
reflect.Int64: decodeInt64Value,
reflect.Uint: decodeUint64Value,
reflect.Uint8: decodeUint64Value,
reflect.Uint16: decodeUint64Value,
reflect.Uint32: decodeUint64Value,
reflect.Uint64: decodeUint64Value,
reflect.Float32: decodeFloat32Value,
reflect.Float64: decodeFloat64Value,
reflect.Complex64: decodeUnsupportedValue,
reflect.Complex128: decodeUnsupportedValue,
reflect.Array: decodeArrayValue,
reflect.Chan: decodeUnsupportedValue,
reflect.Func: decodeUnsupportedValue,
reflect.Interface: decodeInterfaceValue,
reflect.Map: decodeMapValue,
reflect.Ptr: decodeUnsupportedValue,
reflect.Slice: decodeSliceValue,
reflect.String: decodeStringValue,
reflect.Struct: decodeStructValue,
reflect.UnsafePointer: decodeUnsupportedValue,
}
}
func mustSet(v reflect.Value) error {
if !v.CanSet() {
return fmt.Errorf("msgpack: Decode(nonsettable %s)", v.Type())
}
return nil
}
func getDecoder(typ reflect.Type) decoderFunc {
kind := typ.Kind()
if decoder, ok := typDecMap[typ]; ok {
return decoder
}
if typ.Implements(customDecoderType) {
return decodeCustomValue
}
if typ.Implements(unmarshalerType) {
return unmarshalValue
}
// Addressable struct field value.
if kind != reflect.Ptr {
ptr := reflect.PtrTo(typ)
if ptr.Implements(customDecoderType) {
return decodeCustomValueAddr
}
if ptr.Implements(unmarshalerType) {
return unmarshalValueAddr
}
}
switch kind {
case reflect.Ptr:
return ptrDecoderFunc(typ)
case reflect.Slice:
elem := typ.Elem()
switch elem.Kind() {
case reflect.Uint8:
return decodeBytesValue
}
switch elem {
case stringType:
return decodeStringSliceValue
}
case reflect.Array:
if typ.Elem().Kind() == reflect.Uint8 {
return decodeByteArrayValue
}
case reflect.Map:
if typ.Key() == stringType {
switch typ.Elem() {
case stringType:
return decodeMapStringStringValue
case interfaceType:
return decodeMapStringInterfaceValue
}
}
}
return valueDecoders[kind]
}
func ptrDecoderFunc(typ reflect.Type) decoderFunc {
decoder := getDecoder(typ.Elem())
return func(d *Decoder, v reflect.Value) error {
if d.hasNilCode() {
if err := mustSet(v); err != nil {
return err
}
v.Set(reflect.Zero(v.Type()))
return d.DecodeNil()
}
if v.IsNil() {
if err := mustSet(v); err != nil {
return err
}
v.Set(reflect.New(v.Type().Elem()))
}
return decoder(d, v.Elem())
}
}
func decodeCustomValueAddr(d *Decoder, v reflect.Value) error {
if !v.CanAddr() {
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
}
return decodeCustomValue(d, v.Addr())
}
func decodeCustomValue(d *Decoder, v reflect.Value) error {
c, err := d.PeekCode()
if err != nil {
return err
}
if codes.IsExt(c) {
c, err = d.readCode()
if err != nil {
return err
}
extLen, err := d.parseExtLen(c)
if err != nil {
return err
}
_, err = d.readCode()
if err != nil {
return err
}
c, err = d.PeekCode()
if err != nil {
return err
}
d.extLen = extLen
}
if c == codes.Nil {
return d.decodeNilValue(v)
}
if v.IsNil() {
v.Set(reflect.New(v.Type().Elem()))
}
decoder := v.Interface().(CustomDecoder)
return decoder.DecodeMsgpack(d)
}
func unmarshalValueAddr(d *Decoder, v reflect.Value) error {
if !v.CanAddr() {
return fmt.Errorf("msgpack: Decode(nonaddressable %T)", v.Interface())
}
return unmarshalValue(d, v.Addr())
}
func unmarshalValue(d *Decoder, v reflect.Value) error {
c, err := d.PeekCode()
if err != nil {
return err
}
extLen := d.extLen
d.extLen = 0
if extLen == 0 && codes.IsExt(c) {
c, err = d.readCode()
if err != nil {
return err
}
extLen, err = d.parseExtLen(c)
if err != nil {
return err
}
_, err = d.readCode()
if err != nil {
return err
}
c, err = d.PeekCode()
if err != nil {
return err
}
}
if c == codes.Nil {
return d.decodeNilValue(v)
}
if v.IsNil() {
v.Set(reflect.New(v.Type().Elem()))
}
if extLen != 0 {
b, err := d.readN(extLen)
if err != nil {
return err
}
d.rec = b
} else {
d.rec = makeBuffer()
if err := d.Skip(); err != nil {
return err
}
}
unmarshaler := v.Interface().(Unmarshaler)
err = unmarshaler.UnmarshalMsgpack(d.rec)
d.rec = nil
return err
}
func decodeBoolValue(d *Decoder, v reflect.Value) error {
flag, err := d.DecodeBool()
if err != nil {
return err
}
if err = mustSet(v); err != nil {
return err
}
v.SetBool(flag)
return nil
}
func decodeInterfaceValue(d *Decoder, v reflect.Value) error {
if v.IsNil() {
return d.interfaceValue(v)
}
elem := v.Elem()
if !elem.CanAddr() {
if d.hasNilCode() {
v.Set(reflect.Zero(v.Type()))
return d.DecodeNil()
}
}
return d.DecodeValue(elem)
}
func (d *Decoder) interfaceValue(v reflect.Value) error {
vv, err := d.decodeInterface()
if err != nil {
return err
}
if vv != nil {
if v.Type() == errorType {
if vv, ok := vv.(string); ok {
v.Set(reflect.ValueOf(errors.New(vv)))
return nil
}
}
v.Set(reflect.ValueOf(vv))
}
return nil
}
func decodeUnsupportedValue(d *Decoder, v reflect.Value) error {
return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type())
}

162
vendor/github.com/vmihailenco/msgpack/encode.go generated vendored Normal file
View file

@ -0,0 +1,162 @@
package msgpack
import (
"bytes"
"io"
"reflect"
"time"
"github.com/vmihailenco/msgpack/codes"
)
type writer interface {
io.Writer
WriteByte(byte) error
WriteString(string) (int, error)
}
type byteWriter struct {
io.Writer
buf []byte
bootstrap [64]byte
}
func newByteWriter(w io.Writer) *byteWriter {
bw := &byteWriter{
Writer: w,
}
bw.buf = bw.bootstrap[:]
return bw
}
func (w *byteWriter) WriteByte(c byte) error {
w.buf = w.buf[:1]
w.buf[0] = c
_, err := w.Write(w.buf)
return err
}
func (w *byteWriter) WriteString(s string) (int, error) {
w.buf = append(w.buf[:0], s...)
return w.Write(w.buf)
}
// Marshal returns the MessagePack encoding of v.
func Marshal(v ...interface{}) ([]byte, error) {
var buf bytes.Buffer
err := NewEncoder(&buf).Encode(v...)
return buf.Bytes(), err
}
type Encoder struct {
w writer
buf []byte
sortMapKeys bool
structAsArray bool
useJSONTag bool
}
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
bw, ok := w.(writer)
if !ok {
bw = newByteWriter(w)
}
return &Encoder{
w: bw,
buf: make([]byte, 9),
}
}
// SortMapKeys causes the Encoder to encode map keys in increasing order.
// Supported map types are:
// - map[string]string
// - map[string]interface{}
func (e *Encoder) SortMapKeys(v bool) *Encoder {
e.sortMapKeys = v
return e
}
// StructAsArray causes the Encoder to encode Go structs as MessagePack arrays.
func (e *Encoder) StructAsArray(v bool) *Encoder {
e.structAsArray = v
return e
}
// UseJSONTag causes the Encoder to use json struct tag as fallback option
// if there is no msgpack tag.
func (e *Encoder) UseJSONTag(v bool) *Encoder {
e.useJSONTag = v
return e
}
func (e *Encoder) Encode(v ...interface{}) error {
for _, vv := range v {
if err := e.encode(vv); err != nil {
return err
}
}
return nil
}
func (e *Encoder) encode(v interface{}) error {
switch v := v.(type) {
case nil:
return e.EncodeNil()
case string:
return e.EncodeString(v)
case []byte:
return e.EncodeBytes(v)
case int:
return e.EncodeInt(int64(v))
case int64:
return e.EncodeInt(v)
case uint:
return e.EncodeUint(uint64(v))
case uint64:
return e.EncodeUint(v)
case bool:
return e.EncodeBool(v)
case float32:
return e.EncodeFloat32(v)
case float64:
return e.EncodeFloat64(v)
case time.Duration:
return e.EncodeInt(int64(v))
case time.Time:
return e.EncodeTime(v)
}
return e.EncodeValue(reflect.ValueOf(v))
}
func (e *Encoder) EncodeValue(v reflect.Value) error {
encode := getEncoder(v.Type())
return encode(e, v)
}
func (e *Encoder) EncodeNil() error {
return e.writeCode(codes.Nil)
}
func (e *Encoder) EncodeBool(value bool) error {
if value {
return e.writeCode(codes.True)
}
return e.writeCode(codes.False)
}
func (e *Encoder) writeCode(c codes.Code) error {
return e.w.WriteByte(byte(c))
}
func (e *Encoder) write(b []byte) error {
_, err := e.w.Write(b)
return err
}
func (e *Encoder) writeString(s string) error {
_, err := e.w.WriteString(s)
return err
}

172
vendor/github.com/vmihailenco/msgpack/encode_map.go generated vendored Normal file
View file

@ -0,0 +1,172 @@
package msgpack
import (
"reflect"
"sort"
"github.com/vmihailenco/msgpack/codes"
)
func encodeMapValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
if err := e.EncodeMapLen(v.Len()); err != nil {
return err
}
for _, key := range v.MapKeys() {
if err := e.EncodeValue(key); err != nil {
return err
}
if err := e.EncodeValue(v.MapIndex(key)); err != nil {
return err
}
}
return nil
}
func encodeMapStringStringValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
if err := e.EncodeMapLen(v.Len()); err != nil {
return err
}
m := v.Convert(mapStringStringType).Interface().(map[string]string)
if e.sortMapKeys {
return e.encodeSortedMapStringString(m)
}
for mk, mv := range m {
if err := e.EncodeString(mk); err != nil {
return err
}
if err := e.EncodeString(mv); err != nil {
return err
}
}
return nil
}
func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
if err := e.EncodeMapLen(v.Len()); err != nil {
return err
}
m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{})
if e.sortMapKeys {
return e.encodeSortedMapStringInterface(m)
}
for mk, mv := range m {
if err := e.EncodeString(mk); err != nil {
return err
}
if err := e.Encode(mv); err != nil {
return err
}
}
return nil
}
func (e *Encoder) encodeSortedMapStringString(m map[string]string) error {
keys := make([]string, 0, len(m))
for k, _ := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
err := e.EncodeString(k)
if err != nil {
return err
}
if err = e.EncodeString(m[k]); err != nil {
return err
}
}
return nil
}
func (e *Encoder) encodeSortedMapStringInterface(m map[string]interface{}) error {
keys := make([]string, 0, len(m))
for k, _ := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
err := e.EncodeString(k)
if err != nil {
return err
}
if err = e.Encode(m[k]); err != nil {
return err
}
}
return nil
}
func (e *Encoder) EncodeMapLen(l int) error {
if l < 16 {
return e.writeCode(codes.FixedMapLow | codes.Code(l))
}
if l < 65536 {
return e.write2(codes.Map16, uint64(l))
}
return e.write4(codes.Map32, uint32(l))
}
func encodeStructValue(e *Encoder, strct reflect.Value) error {
var structFields *fields
if e.useJSONTag {
structFields = jsonStructs.Fields(strct.Type())
} else {
structFields = structs.Fields(strct.Type())
}
if e.structAsArray || structFields.AsArray {
return encodeStructValueAsArray(e, strct, structFields.List)
}
fields := structFields.OmitEmpty(strct)
if err := e.EncodeMapLen(len(fields)); err != nil {
return err
}
for _, f := range fields {
if err := e.EncodeString(f.name); err != nil {
return err
}
if err := f.EncodeValue(e, strct); err != nil {
return err
}
}
return nil
}
func encodeStructValueAsArray(e *Encoder, strct reflect.Value, fields []*field) error {
if err := e.EncodeArrayLen(len(fields)); err != nil {
return err
}
for _, f := range fields {
if err := f.EncodeValue(e, strct); err != nil {
return err
}
}
return nil
}

108
vendor/github.com/vmihailenco/msgpack/encode_number.go generated vendored Normal file
View file

@ -0,0 +1,108 @@
package msgpack
import (
"math"
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
// EncodeUint encodes an uint64 in 1, 2, 3, 5, or 9 bytes.
func (e *Encoder) EncodeUint(v uint64) error {
if v <= math.MaxInt8 {
return e.w.WriteByte(byte(v))
}
if v <= math.MaxUint8 {
return e.write1(codes.Uint8, v)
}
if v <= math.MaxUint16 {
return e.write2(codes.Uint16, v)
}
if v <= math.MaxUint32 {
return e.write4(codes.Uint32, uint32(v))
}
return e.write8(codes.Uint64, v)
}
// EncodeInt encodes an int64 in 1, 2, 3, 5, or 9 bytes.
func (e *Encoder) EncodeInt(v int64) error {
if v >= 0 {
return e.EncodeUint(uint64(v))
}
if v >= int64(int8(codes.NegFixedNumLow)) {
return e.w.WriteByte(byte(v))
}
if v >= math.MinInt8 {
return e.write1(codes.Int8, uint64(v))
}
if v >= math.MinInt16 {
return e.write2(codes.Int16, uint64(v))
}
if v >= math.MinInt32 {
return e.write4(codes.Int32, uint32(v))
}
return e.write8(codes.Int64, uint64(v))
}
func (e *Encoder) EncodeFloat32(n float32) error {
return e.write4(codes.Float, math.Float32bits(n))
}
func (e *Encoder) EncodeFloat64(n float64) error {
return e.write8(codes.Double, math.Float64bits(n))
}
func (e *Encoder) write1(code codes.Code, n uint64) error {
e.buf = e.buf[:2]
e.buf[0] = byte(code)
e.buf[1] = byte(n)
return e.write(e.buf)
}
func (e *Encoder) write2(code codes.Code, n uint64) error {
e.buf = e.buf[:3]
e.buf[0] = byte(code)
e.buf[1] = byte(n >> 8)
e.buf[2] = byte(n)
return e.write(e.buf)
}
func (e *Encoder) write4(code codes.Code, n uint32) error {
e.buf = e.buf[:5]
e.buf[0] = byte(code)
e.buf[1] = byte(n >> 24)
e.buf[2] = byte(n >> 16)
e.buf[3] = byte(n >> 8)
e.buf[4] = byte(n)
return e.write(e.buf)
}
func (e *Encoder) write8(code codes.Code, n uint64) error {
e.buf = e.buf[:9]
e.buf[0] = byte(code)
e.buf[1] = byte(n >> 56)
e.buf[2] = byte(n >> 48)
e.buf[3] = byte(n >> 40)
e.buf[4] = byte(n >> 32)
e.buf[5] = byte(n >> 24)
e.buf[6] = byte(n >> 16)
e.buf[7] = byte(n >> 8)
e.buf[8] = byte(n)
return e.write(e.buf)
}
func encodeInt64Value(e *Encoder, v reflect.Value) error {
return e.EncodeInt(v.Int())
}
func encodeUint64Value(e *Encoder, v reflect.Value) error {
return e.EncodeUint(v.Uint())
}
func encodeFloat32Value(e *Encoder, v reflect.Value) error {
return e.EncodeFloat32(float32(v.Float()))
}
func encodeFloat64Value(e *Encoder, v reflect.Value) error {
return e.EncodeFloat64(v.Float())
}

124
vendor/github.com/vmihailenco/msgpack/encode_slice.go generated vendored Normal file
View file

@ -0,0 +1,124 @@
package msgpack
import (
"reflect"
"github.com/vmihailenco/msgpack/codes"
)
func encodeStringValue(e *Encoder, v reflect.Value) error {
return e.EncodeString(v.String())
}
func encodeByteSliceValue(e *Encoder, v reflect.Value) error {
return e.EncodeBytes(v.Bytes())
}
func encodeByteArrayValue(e *Encoder, v reflect.Value) error {
if err := e.EncodeBytesLen(v.Len()); err != nil {
return err
}
if v.CanAddr() {
b := v.Slice(0, v.Len()).Bytes()
return e.write(b)
}
e.buf = grow(e.buf, v.Len())
reflect.Copy(reflect.ValueOf(e.buf), v)
return e.write(e.buf)
}
func grow(b []byte, n int) []byte {
if cap(b) >= n {
return b[:n]
}
b = b[:cap(b)]
b = append(b, make([]byte, n-len(b))...)
return b
}
func (e *Encoder) EncodeBytesLen(l int) error {
if l < 256 {
return e.write1(codes.Bin8, uint64(l))
}
if l < 65536 {
return e.write2(codes.Bin16, uint64(l))
}
return e.write4(codes.Bin32, uint32(l))
}
func (e *Encoder) encodeStrLen(l int) error {
if l < 32 {
return e.writeCode(codes.FixedStrLow | codes.Code(l))
}
if l < 256 {
return e.write1(codes.Str8, uint64(l))
}
if l < 65536 {
return e.write2(codes.Str16, uint64(l))
}
return e.write4(codes.Str32, uint32(l))
}
func (e *Encoder) EncodeString(v string) error {
if err := e.encodeStrLen(len(v)); err != nil {
return err
}
return e.writeString(v)
}
func (e *Encoder) EncodeBytes(v []byte) error {
if v == nil {
return e.EncodeNil()
}
if err := e.EncodeBytesLen(len(v)); err != nil {
return err
}
return e.write(v)
}
func (e *Encoder) EncodeArrayLen(l int) error {
if l < 16 {
return e.writeCode(codes.FixedArrayLow | codes.Code(l))
}
if l < 65536 {
return e.write2(codes.Array16, uint64(l))
}
return e.write4(codes.Array32, uint32(l))
}
func (e *Encoder) encodeStringSlice(s []string) error {
if s == nil {
return e.EncodeNil()
}
if err := e.EncodeArrayLen(len(s)); err != nil {
return err
}
for _, v := range s {
if err := e.EncodeString(v); err != nil {
return err
}
}
return nil
}
func encodeSliceValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
return encodeArrayValue(e, v)
}
func encodeArrayValue(e *Encoder, v reflect.Value) error {
l := v.Len()
if err := e.EncodeArrayLen(l); err != nil {
return err
}
for i := 0; i < l; i++ {
if err := e.EncodeValue(v.Index(i)); err != nil {
return err
}
}
return nil
}

167
vendor/github.com/vmihailenco/msgpack/encode_value.go generated vendored Normal file
View file

@ -0,0 +1,167 @@
package msgpack
import (
"fmt"
"reflect"
)
var valueEncoders []encoderFunc
func init() {
valueEncoders = []encoderFunc{
reflect.Bool: encodeBoolValue,
reflect.Int: encodeInt64Value,
reflect.Int8: encodeInt64Value,
reflect.Int16: encodeInt64Value,
reflect.Int32: encodeInt64Value,
reflect.Int64: encodeInt64Value,
reflect.Uint: encodeUint64Value,
reflect.Uint8: encodeUint64Value,
reflect.Uint16: encodeUint64Value,
reflect.Uint32: encodeUint64Value,
reflect.Uint64: encodeUint64Value,
reflect.Float32: encodeFloat32Value,
reflect.Float64: encodeFloat64Value,
reflect.Complex64: encodeUnsupportedValue,
reflect.Complex128: encodeUnsupportedValue,
reflect.Array: encodeArrayValue,
reflect.Chan: encodeUnsupportedValue,
reflect.Func: encodeUnsupportedValue,
reflect.Interface: encodeInterfaceValue,
reflect.Map: encodeMapValue,
reflect.Ptr: encodeUnsupportedValue,
reflect.Slice: encodeSliceValue,
reflect.String: encodeStringValue,
reflect.Struct: encodeStructValue,
reflect.UnsafePointer: encodeUnsupportedValue,
}
}
func getEncoder(typ reflect.Type) encoderFunc {
if encoder, ok := typEncMap[typ]; ok {
return encoder
}
if typ.Implements(customEncoderType) {
return encodeCustomValue
}
if typ.Implements(marshalerType) {
return marshalValue
}
kind := typ.Kind()
// Addressable struct field value.
if kind != reflect.Ptr {
ptr := reflect.PtrTo(typ)
if ptr.Implements(customEncoderType) {
return encodeCustomValuePtr
}
if ptr.Implements(marshalerType) {
return marshalValuePtr
}
}
if typ == errorType {
return encodeErrorValue
}
switch kind {
case reflect.Ptr:
return ptrEncoderFunc(typ)
case reflect.Slice:
if typ.Elem().Kind() == reflect.Uint8 {
return encodeByteSliceValue
}
case reflect.Array:
if typ.Elem().Kind() == reflect.Uint8 {
return encodeByteArrayValue
}
case reflect.Map:
if typ.Key() == stringType {
switch typ.Elem() {
case stringType:
return encodeMapStringStringValue
case interfaceType:
return encodeMapStringInterfaceValue
}
}
}
return valueEncoders[kind]
}
func ptrEncoderFunc(typ reflect.Type) encoderFunc {
encoder := getEncoder(typ.Elem())
return func(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
return encoder(e, v.Elem())
}
}
func encodeCustomValuePtr(e *Encoder, v reflect.Value) error {
if !v.CanAddr() {
return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
}
encoder := v.Addr().Interface().(CustomEncoder)
return encoder.EncodeMsgpack(e)
}
func encodeCustomValue(e *Encoder, v reflect.Value) error {
switch v.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
if v.IsNil() {
return e.EncodeNil()
}
}
encoder := v.Interface().(CustomEncoder)
return encoder.EncodeMsgpack(e)
}
func marshalValuePtr(e *Encoder, v reflect.Value) error {
if !v.CanAddr() {
return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface())
}
return marshalValue(e, v.Addr())
}
func marshalValue(e *Encoder, v reflect.Value) error {
switch v.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
if v.IsNil() {
return e.EncodeNil()
}
}
marshaler := v.Interface().(Marshaler)
b, err := marshaler.MarshalMsgpack()
if err != nil {
return err
}
_, err = e.w.Write(b)
return err
}
func encodeBoolValue(e *Encoder, v reflect.Value) error {
return e.EncodeBool(v.Bool())
}
func encodeInterfaceValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
return e.EncodeValue(v.Elem())
}
func encodeErrorValue(e *Encoder, v reflect.Value) error {
if v.IsNil() {
return e.EncodeNil()
}
return e.EncodeString(v.Interface().(error).Error())
}
func encodeUnsupportedValue(e *Encoder, v reflect.Value) error {
return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type())
}

212
vendor/github.com/vmihailenco/msgpack/ext.go generated vendored Normal file
View file

@ -0,0 +1,212 @@
package msgpack
import (
"bytes"
"fmt"
"reflect"
"sync"
"github.com/vmihailenco/msgpack/codes"
)
var extTypes = make(map[int8]reflect.Type)
var bufferPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
// RegisterExt records a type, identified by a value for that type,
// under the provided id. That id will identify the concrete type of a value
// sent or received as an interface variable. Only types that will be
// transferred as implementations of interface values need to be registered.
// Expecting to be used only during initialization, it panics if the mapping
// between types and ids is not a bijection.
func RegisterExt(id int8, value interface{}) {
typ := reflect.TypeOf(value)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
}
ptr := reflect.PtrTo(typ)
if _, ok := extTypes[id]; ok {
panic(fmt.Errorf("msgpack: ext with id=%d is already registered", id))
}
registerExt(id, ptr, getEncoder(ptr), nil)
registerExt(id, typ, getEncoder(typ), getDecoder(typ))
}
func registerExt(id int8, typ reflect.Type, enc encoderFunc, dec decoderFunc) {
if dec != nil {
extTypes[id] = typ
}
if enc != nil {
typEncMap[typ] = makeExtEncoder(id, enc)
}
if dec != nil {
typDecMap[typ] = dec
}
}
func (e *Encoder) EncodeExtHeader(typeId int8, length int) error {
if err := e.encodeExtLen(length); err != nil {
return err
}
if err := e.w.WriteByte(byte(typeId)); err != nil {
return err
}
return nil
}
func makeExtEncoder(typeId int8, enc encoderFunc) encoderFunc {
return func(e *Encoder, v reflect.Value) error {
buf := bufferPool.Get().(*bytes.Buffer)
defer bufferPool.Put(buf)
buf.Reset()
oldw := e.w
e.w = buf
err := enc(e, v)
e.w = oldw
if err != nil {
return err
}
if err := e.EncodeExtHeader(typeId, buf.Len()); err != nil {
return err
}
return e.write(buf.Bytes())
}
}
func (e *Encoder) encodeExtLen(l int) error {
switch l {
case 1:
return e.writeCode(codes.FixExt1)
case 2:
return e.writeCode(codes.FixExt2)
case 4:
return e.writeCode(codes.FixExt4)
case 8:
return e.writeCode(codes.FixExt8)
case 16:
return e.writeCode(codes.FixExt16)
}
if l < 256 {
return e.write1(codes.Ext8, uint64(l))
}
if l < 65536 {
return e.write2(codes.Ext16, uint64(l))
}
return e.write4(codes.Ext32, uint32(l))
}
func (d *Decoder) parseExtLen(c codes.Code) (int, error) {
switch c {
case codes.FixExt1:
return 1, nil
case codes.FixExt2:
return 2, nil
case codes.FixExt4:
return 4, nil
case codes.FixExt8:
return 8, nil
case codes.FixExt16:
return 16, nil
case codes.Ext8:
n, err := d.uint8()
return int(n), err
case codes.Ext16:
n, err := d.uint16()
return int(n), err
case codes.Ext32:
n, err := d.uint32()
return int(n), err
default:
return 0, fmt.Errorf("msgpack: invalid code=%x decoding ext length", c)
}
}
func (d *Decoder) decodeExtHeader(c codes.Code) (int8, int, error) {
length, err := d.parseExtLen(c)
if err != nil {
return 0, 0, err
}
typeId, err := d.readCode()
if err != nil {
return 0, 0, err
}
return int8(typeId), length, nil
}
func (d *Decoder) DecodeExtHeader() (typeId int8, length int, err error) {
c, err := d.readCode()
if err != nil {
return
}
return d.decodeExtHeader(c)
}
func (d *Decoder) extInterface(c codes.Code) (interface{}, error) {
extId, extLen, err := d.decodeExtHeader(c)
if err != nil {
return nil, err
}
typ, ok := extTypes[extId]
if !ok {
return nil, fmt.Errorf("msgpack: unregistered ext id=%d", extId)
}
v := reflect.New(typ)
d.extLen = extLen
err = d.DecodeValue(v.Elem())
d.extLen = 0
if err != nil {
return nil, err
}
return v.Interface(), nil
}
func (d *Decoder) skipExt(c codes.Code) error {
n, err := d.parseExtLen(c)
if err != nil {
return err
}
return d.skipN(n + 1)
}
func (d *Decoder) skipExtHeader(c codes.Code) error {
// Read ext type.
_, err := d.readCode()
if err != nil {
return err
}
// Read ext body len.
for i := 0; i < extHeaderLen(c); i++ {
_, err := d.readCode()
if err != nil {
return err
}
}
return nil
}
func extHeaderLen(c codes.Code) int {
switch c {
case codes.Ext8:
return 1
case codes.Ext16:
return 2
case codes.Ext32:
return 4
}
return 0
}

17
vendor/github.com/vmihailenco/msgpack/msgpack.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
package msgpack
type Marshaler interface {
MarshalMsgpack() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalMsgpack([]byte) error
}
type CustomEncoder interface {
EncodeMsgpack(*Encoder) error
}
type CustomDecoder interface {
DecodeMsgpack(*Decoder) error
}

42
vendor/github.com/vmihailenco/msgpack/tag.go generated vendored Normal file
View file

@ -0,0 +1,42 @@
package msgpack
import (
"strings"
)
type tagOptions string
func (o tagOptions) Get(name string) (string, bool) {
s := string(o)
for len(s) > 0 {
var next string
idx := strings.IndexByte(s, ',')
if idx >= 0 {
s, next = s[:idx], s[idx+1:]
}
if strings.HasPrefix(s, name) {
return s[len(name):], true
}
s = next
}
return "", false
}
func (o tagOptions) Contains(name string) bool {
_, ok := o.Get(name)
return ok
}
func parseTag(tag string) (string, tagOptions) {
if idx := strings.IndexByte(tag, ','); idx != -1 {
name := tag[:idx]
if strings.IndexByte(name, ':') == -1 {
return name, tagOptions(tag[idx+1:])
}
}
if strings.IndexByte(tag, ':') == -1 {
return tag, ""
}
return "", tagOptions(tag)
}

145
vendor/github.com/vmihailenco/msgpack/time.go generated vendored Normal file
View file

@ -0,0 +1,145 @@
package msgpack
import (
"encoding/binary"
"fmt"
"reflect"
"time"
"github.com/vmihailenco/msgpack/codes"
)
var timeExtId int8 = -1
func init() {
timeType := reflect.TypeOf((*time.Time)(nil)).Elem()
registerExt(timeExtId, timeType, encodeTimeValue, decodeTimeValue)
}
func (e *Encoder) EncodeTime(tm time.Time) error {
b := e.encodeTime(tm)
if err := e.encodeExtLen(len(b)); err != nil {
return err
}
if err := e.w.WriteByte(byte(timeExtId)); err != nil {
return err
}
return e.write(b)
}
func (e *Encoder) encodeTime(tm time.Time) []byte {
secs := uint64(tm.Unix())
if secs>>34 == 0 {
data := uint64(tm.Nanosecond())<<34 | secs
if data&0xffffffff00000000 == 0 {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, uint32(data))
return b
} else {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, data)
return b
}
}
b := make([]byte, 12)
binary.BigEndian.PutUint32(b, uint32(tm.Nanosecond()))
binary.BigEndian.PutUint64(b[4:], uint64(secs))
return b
}
func (d *Decoder) DecodeTime() (time.Time, error) {
tm, err := d.decodeTime()
if err != nil {
return tm, err
}
if tm.IsZero() {
// Assume that zero time does not have timezone information.
return tm.UTC(), nil
}
return tm, nil
}
func (d *Decoder) decodeTime() (time.Time, error) {
extLen := d.extLen
d.extLen = 0
if extLen == 0 {
c, err := d.readCode()
if err != nil {
return time.Time{}, err
}
// Legacy format.
if c == codes.FixedArrayLow|2 {
sec, err := d.DecodeInt64()
if err != nil {
return time.Time{}, err
}
nsec, err := d.DecodeInt64()
if err != nil {
return time.Time{}, err
}
return time.Unix(sec, nsec), nil
}
if codes.IsString(c) {
s, err := d.string(c)
if err != nil {
return time.Time{}, err
}
return time.Parse(time.RFC3339Nano, s)
}
extLen, err = d.parseExtLen(c)
if err != nil {
return time.Time{}, err
}
// Skip ext id.
_, err = d.s.ReadByte()
if err != nil {
return time.Time{}, nil
}
}
b, err := d.readN(extLen)
if err != nil {
return time.Time{}, err
}
switch len(b) {
case 4:
sec := binary.BigEndian.Uint32(b)
return time.Unix(int64(sec), 0), nil
case 8:
sec := binary.BigEndian.Uint64(b)
nsec := int64(sec >> 34)
sec &= 0x00000003ffffffff
return time.Unix(int64(sec), nsec), nil
case 12:
nsec := binary.BigEndian.Uint32(b)
sec := binary.BigEndian.Uint64(b[4:])
return time.Unix(int64(sec), int64(nsec)), nil
default:
err = fmt.Errorf("msgpack: invalid ext len=%d decoding time", extLen)
return time.Time{}, err
}
}
func encodeTimeValue(e *Encoder, v reflect.Value) error {
tm := v.Interface().(time.Time)
b := e.encodeTime(tm)
return e.write(b)
}
func decodeTimeValue(d *Decoder, v reflect.Value) error {
tm, err := d.DecodeTime()
if err != nil {
return err
}
v.Set(reflect.ValueOf(tm))
return nil
}

307
vendor/github.com/vmihailenco/msgpack/types.go generated vendored Normal file
View file

@ -0,0 +1,307 @@
package msgpack
import (
"reflect"
"sync"
)
var errorType = reflect.TypeOf((*error)(nil)).Elem()
var customEncoderType = reflect.TypeOf((*CustomEncoder)(nil)).Elem()
var customDecoderType = reflect.TypeOf((*CustomDecoder)(nil)).Elem()
var marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
var unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
type encoderFunc func(*Encoder, reflect.Value) error
type decoderFunc func(*Decoder, reflect.Value) error
var typEncMap = make(map[reflect.Type]encoderFunc)
var typDecMap = make(map[reflect.Type]decoderFunc)
// Register registers encoder and decoder functions for a value.
// This is low level API and in most cases you should prefer implementing
// Marshaler/CustomEncoder and Unmarshaler/CustomDecoder interfaces.
func Register(value interface{}, enc encoderFunc, dec decoderFunc) {
typ := reflect.TypeOf(value)
if enc != nil {
typEncMap[typ] = enc
}
if dec != nil {
typDecMap[typ] = dec
}
}
//------------------------------------------------------------------------------
var structs = newStructCache(false)
var jsonStructs = newStructCache(true)
type structCache struct {
mu sync.RWMutex
m map[reflect.Type]*fields
useJSONTag bool
}
func newStructCache(useJSONTag bool) *structCache {
return &structCache{
m: make(map[reflect.Type]*fields),
useJSONTag: useJSONTag,
}
}
func (m *structCache) Fields(typ reflect.Type) *fields {
m.mu.RLock()
fs, ok := m.m[typ]
m.mu.RUnlock()
if ok {
return fs
}
m.mu.Lock()
fs, ok = m.m[typ]
if !ok {
fs = getFields(typ, m.useJSONTag)
m.m[typ] = fs
}
m.mu.Unlock()
return fs
}
//------------------------------------------------------------------------------
type field struct {
name string
index []int
omitEmpty bool
encoder encoderFunc
decoder decoderFunc
}
func (f *field) value(v reflect.Value) reflect.Value {
return fieldByIndex(v, f.index)
}
func (f *field) Omit(strct reflect.Value) bool {
return f.omitEmpty && isEmptyValue(f.value(strct))
}
func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error {
return f.encoder(e, f.value(strct))
}
func (f *field) DecodeValue(d *Decoder, strct reflect.Value) error {
return f.decoder(d, f.value(strct))
}
//------------------------------------------------------------------------------
type fields struct {
Table map[string]*field
List []*field
AsArray bool
hasOmitEmpty bool
}
func newFields(numField int) *fields {
return &fields{
Table: make(map[string]*field, numField),
List: make([]*field, 0, numField),
}
}
func (fs *fields) Add(field *field) {
fs.Table[field.name] = field
fs.List = append(fs.List, field)
if field.omitEmpty {
fs.hasOmitEmpty = true
}
}
func (fs *fields) OmitEmpty(strct reflect.Value) []*field {
if !fs.hasOmitEmpty {
return fs.List
}
fields := make([]*field, 0, len(fs.List))
for _, f := range fs.List {
if !f.Omit(strct) {
fields = append(fields, f)
}
}
return fields
}
func getFields(typ reflect.Type, useJSONTag bool) *fields {
numField := typ.NumField()
fs := newFields(numField)
var omitEmpty bool
for i := 0; i < numField; i++ {
f := typ.Field(i)
tag := f.Tag.Get("msgpack")
if useJSONTag && tag == "" {
tag = f.Tag.Get("json")
}
name, opt := parseTag(tag)
if name == "-" {
continue
}
if f.Name == "_msgpack" {
if opt.Contains("asArray") {
fs.AsArray = true
}
if opt.Contains("omitempty") {
omitEmpty = true
}
}
if f.PkgPath != "" && !f.Anonymous {
continue
}
field := &field{
name: name,
index: f.Index,
omitEmpty: omitEmpty || opt.Contains("omitempty"),
encoder: getEncoder(f.Type),
decoder: getDecoder(f.Type),
}
if field.name == "" {
field.name = f.Name
}
if f.Anonymous {
if opt.Contains("inline") {
inlineFields(fs, f.Type, field, useJSONTag)
continue
}
if autoinlineFields(fs, f.Type, field, useJSONTag) {
continue
}
}
fs.Add(field)
}
return fs
}
var encodeStructValuePtr uintptr
var decodeStructValuePtr uintptr
func init() {
encodeStructValuePtr = reflect.ValueOf(encodeStructValue).Pointer()
decodeStructValuePtr = reflect.ValueOf(decodeStructValue).Pointer()
}
func inlineFields(fs *fields, typ reflect.Type, f *field, useJSONTag bool) {
inlinedFields := getFields(typ, useJSONTag).List
for _, field := range inlinedFields {
if _, ok := fs.Table[field.name]; ok {
// Don't inline shadowed fields.
continue
}
field.index = append(f.index, field.index...)
fs.Add(field)
}
}
func autoinlineFields(fs *fields, typ reflect.Type, f *field, useJSONTag bool) bool {
var encoder encoderFunc
var decoder decoderFunc
if typ.Kind() == reflect.Struct {
encoder = f.encoder
decoder = f.decoder
} else {
for typ.Kind() == reflect.Ptr {
typ = typ.Elem()
encoder = getEncoder(typ)
decoder = getDecoder(typ)
}
if typ.Kind() != reflect.Struct {
return false
}
}
if reflect.ValueOf(encoder).Pointer() != encodeStructValuePtr {
return false
}
if reflect.ValueOf(decoder).Pointer() != decodeStructValuePtr {
return false
}
inlinedFields := getFields(typ, useJSONTag).List
for _, field := range inlinedFields {
if _, ok := fs.Table[field.name]; ok {
// Don't inline shadowed fields.
return false
}
}
for _, field := range inlinedFields {
field.index = append(f.index, field.index...)
fs.Add(field)
}
return true
}
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
func fieldByIndex(v reflect.Value, index []int) reflect.Value {
if len(index) == 1 {
return v.Field(index[0])
}
for i, x := range index {
if i > 0 {
var ok bool
v, ok = indirectNew(v)
if !ok {
return v
}
}
v = v.Field(x)
}
return v
}
func indirectNew(v reflect.Value) (reflect.Value, bool) {
if v.Kind() == reflect.Ptr {
if v.IsNil() {
if !v.CanSet() {
return v, false
}
elemType := v.Type().Elem()
if elemType.Kind() != reflect.Struct {
return v, false
}
v.Set(reflect.New(elemType))
}
v = v.Elem()
}
return v, true
}

14
vendor/github.com/zclconf/go-cty/cty/msgpack/doc.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Package msgpack provides functions for serializing cty values in the
// msgpack encoding, and decoding them again.
//
// If the same type information is provided both at encoding and decoding time
// then values can be round-tripped without loss, except for capsule types
// which are not currently supported.
//
// If any unknown values are passed to Marshal then they will be represented
// using a msgpack extension with type code zero, which is understood by
// the Unmarshal function within this package but will not be understood by
// a generic (non-cty-aware) msgpack decoder. Ensure that no unknown values
// are used if interoperability with other msgpack implementations is
// required.
package msgpack

View file

@ -0,0 +1,31 @@
package msgpack
import (
"bytes"
"github.com/vmihailenco/msgpack"
"github.com/zclconf/go-cty/cty"
)
type dynamicVal struct {
Value cty.Value
Path cty.Path
}
func (dv *dynamicVal) MarshalMsgpack() ([]byte, error) {
// Rather than defining a msgpack-specific serialization of types,
// instead we use the existing JSON serialization.
typeJSON, err := dv.Value.Type().MarshalJSON()
if err != nil {
return nil, dv.Path.NewErrorf("failed to serialize type: %s", err)
}
var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf)
enc.EncodeArrayLen(2)
enc.EncodeBytes(typeJSON)
err = marshal(dv.Value, dv.Value.Type(), dv.Path, enc)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}

View file

@ -0,0 +1,8 @@
package msgpack
import (
"math"
)
var negativeInfinity = math.Inf(-1)
var positiveInfinity = math.Inf(1)

207
vendor/github.com/zclconf/go-cty/cty/msgpack/marshal.go generated vendored Normal file
View file

@ -0,0 +1,207 @@
package msgpack
import (
"bytes"
"math/big"
"sort"
"github.com/vmihailenco/msgpack"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/convert"
)
// Marshal produces a msgpack serialization of the given value that
// can be decoded into the given type later using Unmarshal.
//
// The given value must conform to the given type, or an error will
// be returned.
func Marshal(val cty.Value, ty cty.Type) ([]byte, error) {
errs := val.Type().TestConformance(ty)
if errs != nil {
// Attempt a conversion
var err error
val, err = convert.Convert(val, ty)
if err != nil {
return nil, err
}
}
// From this point onward, val can be assumed to be conforming to t.
var path cty.Path
var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf)
err := marshal(val, ty, path, enc)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func marshal(val cty.Value, ty cty.Type, path cty.Path, enc *msgpack.Encoder) error {
// If we're going to decode as DynamicPseudoType then we need to save
// dynamic type information to recover the real type.
if ty == cty.DynamicPseudoType && val.Type() != cty.DynamicPseudoType {
return marshalDynamic(val, path, enc)
}
if !val.IsKnown() {
err := enc.Encode(unknownVal)
if err != nil {
return path.NewError(err)
}
return nil
}
if val.IsNull() {
err := enc.EncodeNil()
if err != nil {
return path.NewError(err)
}
return nil
}
// The caller should've guaranteed that the given val is conformant with
// the given type ty, so we'll proceed under that assumption here.
switch {
case ty.IsPrimitiveType():
switch ty {
case cty.String:
err := enc.EncodeString(val.AsString())
if err != nil {
return path.NewError(err)
}
return nil
case cty.Number:
var err error
switch {
case val.RawEquals(cty.PositiveInfinity):
err = enc.EncodeFloat64(positiveInfinity)
case val.RawEquals(cty.NegativeInfinity):
err = enc.EncodeFloat64(negativeInfinity)
default:
bf := val.AsBigFloat()
if iv, acc := bf.Int64(); acc == big.Exact {
err = enc.EncodeInt(iv)
} else if fv, acc := bf.Float64(); acc == big.Exact {
err = enc.EncodeFloat64(fv)
} else {
err = enc.EncodeString(bf.Text('f', -1))
}
}
if err != nil {
return path.NewError(err)
}
return nil
case cty.Bool:
err := enc.EncodeBool(val.True())
if err != nil {
return path.NewError(err)
}
return nil
default:
panic("unsupported primitive type")
}
case ty.IsListType(), ty.IsSetType():
enc.EncodeArrayLen(val.LengthInt())
ety := ty.ElementType()
it := val.ElementIterator()
path := append(path, nil) // local override of 'path' with extra element
for it.Next() {
ek, ev := it.Element()
path[len(path)-1] = cty.IndexStep{
Key: ek,
}
err := marshal(ev, ety, path, enc)
if err != nil {
return err
}
}
return nil
case ty.IsMapType():
enc.EncodeMapLen(val.LengthInt())
ety := ty.ElementType()
it := val.ElementIterator()
path := append(path, nil) // local override of 'path' with extra element
for it.Next() {
ek, ev := it.Element()
path[len(path)-1] = cty.IndexStep{
Key: ek,
}
var err error
err = marshal(ek, ek.Type(), path, enc)
if err != nil {
return err
}
err = marshal(ev, ety, path, enc)
if err != nil {
return err
}
}
return nil
case ty.IsTupleType():
etys := ty.TupleElementTypes()
it := val.ElementIterator()
path := append(path, nil) // local override of 'path' with extra element
i := 0
enc.EncodeArrayLen(len(etys))
for it.Next() {
ety := etys[i]
ek, ev := it.Element()
path[len(path)-1] = cty.IndexStep{
Key: ek,
}
err := marshal(ev, ety, path, enc)
if err != nil {
return err
}
i++
}
return nil
case ty.IsObjectType():
atys := ty.AttributeTypes()
path := append(path, nil) // local override of 'path' with extra element
names := make([]string, 0, len(atys))
for k := range atys {
names = append(names, k)
}
sort.Strings(names)
enc.EncodeMapLen(len(names))
for _, k := range names {
aty := atys[k]
av := val.GetAttr(k)
path[len(path)-1] = cty.GetAttrStep{
Name: k,
}
var err error
err = marshal(cty.StringVal(k), cty.String, path, enc)
if err != nil {
return err
}
err = marshal(av, aty, path, enc)
if err != nil {
return err
}
}
return nil
case ty.IsCapsuleType():
return path.NewErrorf("capsule types not supported for msgpack encoding")
default:
// should never happen
return path.NewErrorf("cannot msgpack-serialize %s", ty.FriendlyName())
}
}
// marshalDynamic adds an extra wrapping object containing dynamic type
// information for the given value.
func marshalDynamic(val cty.Value, path cty.Path, enc *msgpack.Encoder) error {
dv := dynamicVal{
Value: val,
Path: path,
}
return enc.Encode(&dv)
}

View file

@ -0,0 +1,167 @@
package msgpack
import (
"bytes"
"fmt"
"io"
"github.com/vmihailenco/msgpack"
msgpackcodes "github.com/vmihailenco/msgpack/codes"
"github.com/zclconf/go-cty/cty"
)
// ImpliedType returns the cty Type implied by the structure of the given
// msgpack-compliant buffer. This function implements the default type mapping
// behavior used when decoding arbitrary msgpack without explicit cty Type
// information.
//
// The rules are as follows:
//
// msgpack strings, numbers and bools map to their equivalent primitive type in
// cty.
//
// msgpack maps become cty object types, with the attributes defined by the
// map keys and the types of their values.
//
// msgpack arrays become cty tuple types, with the elements defined by the
// types of the array members.
//
// Any nulls are typed as DynamicPseudoType, so callers of this function
// must be prepared to deal with this. Callers that do not wish to deal with
// dynamic typing should not use this function and should instead describe
// their required types explicitly with a cty.Type instance when decoding.
//
// Any unknown values are similarly typed as DynamicPseudoType, because these
// do not carry type information on the wire.
//
// Any parse errors will be returned as an error, and the type will be the
// invalid value cty.NilType.
func ImpliedType(buf []byte) (cty.Type, error) {
r := bytes.NewReader(buf)
dec := msgpack.NewDecoder(r)
ty, err := impliedType(dec)
if err != nil {
return cty.NilType, err
}
// We must now be at the end of the buffer
err = dec.Skip()
if err != io.EOF {
return ty, fmt.Errorf("extra bytes after msgpack value")
}
return ty, nil
}
func impliedType(dec *msgpack.Decoder) (cty.Type, error) {
// If this function returns with a nil error then it must have already
// consumed the next value from the decoder, since when called recursively
// the caller will be expecting to find a following value here.
code, err := dec.PeekCode()
if err != nil {
return cty.NilType, err
}
switch {
case code == msgpackcodes.Nil || msgpackcodes.IsExt(code):
err := dec.Skip()
return cty.DynamicPseudoType, err
case code == msgpackcodes.True || code == msgpackcodes.False:
_, err := dec.DecodeBool()
return cty.Bool, err
case msgpackcodes.IsFixedNum(code):
_, err := dec.DecodeInt64()
return cty.Number, err
case code == msgpackcodes.Int8 || code == msgpackcodes.Int16 || code == msgpackcodes.Int32 || code == msgpackcodes.Int64:
_, err := dec.DecodeInt64()
return cty.Number, err
case code == msgpackcodes.Uint8 || code == msgpackcodes.Uint16 || code == msgpackcodes.Uint32 || code == msgpackcodes.Uint64:
_, err := dec.DecodeUint64()
return cty.Number, err
case code == msgpackcodes.Float || code == msgpackcodes.Double:
_, err := dec.DecodeFloat64()
return cty.Number, err
case msgpackcodes.IsString(code):
_, err := dec.DecodeString()
return cty.String, err
case msgpackcodes.IsFixedMap(code) || code == msgpackcodes.Map16 || code == msgpackcodes.Map32:
return impliedObjectType(dec)
case msgpackcodes.IsFixedArray(code) || code == msgpackcodes.Array16 || code == msgpackcodes.Array32:
return impliedTupleType(dec)
default:
return cty.NilType, fmt.Errorf("unsupported msgpack code %#v", code)
}
}
func impliedObjectType(dec *msgpack.Decoder) (cty.Type, error) {
// If we get in here then we've already peeked the next code and know
// it's some sort of map.
l, err := dec.DecodeMapLen()
if err != nil {
return cty.DynamicPseudoType, nil
}
var atys map[string]cty.Type
for i := 0; i < l; i++ {
// Read the map key first. We require maps to be strings, but msgpack
// doesn't so we're prepared to error here if not.
k, err := dec.DecodeString()
if err != nil {
return cty.DynamicPseudoType, err
}
aty, err := impliedType(dec)
if err != nil {
return cty.DynamicPseudoType, err
}
if atys == nil {
atys = make(map[string]cty.Type)
}
atys[k] = aty
}
if len(atys) == 0 {
return cty.EmptyObject, nil
}
return cty.Object(atys), nil
}
func impliedTupleType(dec *msgpack.Decoder) (cty.Type, error) {
// If we get in here then we've already peeked the next code and know
// it's some sort of array.
l, err := dec.DecodeArrayLen()
if err != nil {
return cty.DynamicPseudoType, nil
}
if l == 0 {
return cty.EmptyTuple, nil
}
etys := make([]cty.Type, l)
for i := 0; i < l; i++ {
ety, err := impliedType(dec)
if err != nil {
return cty.DynamicPseudoType, err
}
etys[i] = ety
}
return cty.Tuple(etys), nil
}

View file

@ -0,0 +1,16 @@
package msgpack
type unknownType struct{}
var unknownVal = unknownType{}
// unknownValBytes is the raw bytes of the msgpack fixext1 value we
// write to represent an unknown value. It's an extension value of
// type zero whose value is irrelevant. Since it's irrelevant, we
// set it to a single byte whose value is also zero, since that's
// the most compact possible representation.
var unknownValBytes = []byte{0xd4, 0, 0}
func (uv unknownType) MarshalMsgpack() ([]byte, error) {
return unknownValBytes, nil
}

View file

@ -0,0 +1,311 @@
package msgpack
import (
"bytes"
"math/big"
"github.com/vmihailenco/msgpack"
msgpackCodes "github.com/vmihailenco/msgpack/codes"
"github.com/zclconf/go-cty/cty"
)
// Unmarshal interprets the given bytes as a msgpack-encoded cty Value of
// the given type, returning the result.
//
// If an error is returned, the error is written with a hypothetical
// end-user that wrote the msgpack file as its audience, using cty type
// system concepts rather than Go type system concepts.
func Unmarshal(b []byte, ty cty.Type) (cty.Value, error) {
r := bytes.NewReader(b)
dec := msgpack.NewDecoder(r)
var path cty.Path
return unmarshal(dec, ty, path)
}
func unmarshal(dec *msgpack.Decoder, ty cty.Type, path cty.Path) (cty.Value, error) {
peek, err := dec.PeekCode()
if err != nil {
return cty.DynamicVal, path.NewError(err)
}
if msgpackCodes.IsExt(peek) {
// We just assume _all_ extensions are unknown values,
// since we don't have any other extensions.
return cty.UnknownVal(ty), nil
}
if ty == cty.DynamicPseudoType {
return unmarshalDynamic(dec, path)
}
if peek == msgpackCodes.Nil {
return cty.NullVal(ty), nil
}
switch {
case ty.IsPrimitiveType():
val, err := unmarshalPrimitive(dec, ty, path)
if err != nil {
return cty.NilVal, err
}
return val, nil
case ty.IsListType():
return unmarshalList(dec, ty.ElementType(), path)
case ty.IsSetType():
return unmarshalSet(dec, ty.ElementType(), path)
case ty.IsMapType():
return unmarshalMap(dec, ty.ElementType(), path)
case ty.IsTupleType():
return unmarshalTuple(dec, ty.TupleElementTypes(), path)
case ty.IsObjectType():
return unmarshalObject(dec, ty.AttributeTypes(), path)
default:
return cty.NilVal, path.NewErrorf("unsupported type %s", ty.FriendlyName())
}
}
func unmarshalPrimitive(dec *msgpack.Decoder, ty cty.Type, path cty.Path) (cty.Value, error) {
switch ty {
case cty.Bool:
rv, err := dec.DecodeBool()
if err != nil {
return cty.DynamicVal, path.NewErrorf("bool is required")
}
return cty.BoolVal(rv), nil
case cty.Number:
// Marshal will try int and float first, if the value can be
// losslessly represented in these encodings, and then fall
// back on a string if the number is too large or too precise.
peek, err := dec.PeekCode()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
if msgpackCodes.IsFixedNum(peek) {
rv, err := dec.DecodeInt64()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
return cty.NumberIntVal(rv), nil
}
switch peek {
case msgpackCodes.Int8, msgpackCodes.Int16, msgpackCodes.Int32, msgpackCodes.Int64:
rv, err := dec.DecodeInt64()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
return cty.NumberIntVal(rv), nil
case msgpackCodes.Uint8, msgpackCodes.Uint16, msgpackCodes.Uint32, msgpackCodes.Uint64:
rv, err := dec.DecodeUint64()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
return cty.NumberUIntVal(rv), nil
case msgpackCodes.Float, msgpackCodes.Double:
rv, err := dec.DecodeFloat64()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
return cty.NumberFloatVal(rv), nil
default:
rv, err := dec.DecodeString()
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
bf := &big.Float{}
_, _, err = bf.Parse(rv, 10)
if err != nil {
return cty.DynamicVal, path.NewErrorf("number is required")
}
return cty.NumberVal(bf), nil
}
case cty.String:
rv, err := dec.DecodeString()
if err != nil {
return cty.DynamicVal, path.NewErrorf("string is required")
}
return cty.StringVal(rv), nil
default:
// should never happen
panic("unsupported primitive type")
}
}
func unmarshalList(dec *msgpack.Decoder, ety cty.Type, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeArrayLen()
if err != nil {
return cty.DynamicVal, path.NewErrorf("a list is required")
}
if length == 0 {
return cty.ListValEmpty(ety), nil
}
vals := make([]cty.Value, 0, length)
path = append(path, nil)
for i := 0; i < length; i++ {
path[len(path)-1] = cty.IndexStep{
Key: cty.NumberIntVal(int64(i)),
}
val, err := unmarshal(dec, ety, path)
if err != nil {
return cty.DynamicVal, err
}
vals = append(vals, val)
}
return cty.ListVal(vals), nil
}
func unmarshalSet(dec *msgpack.Decoder, ety cty.Type, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeArrayLen()
if err != nil {
return cty.DynamicVal, path.NewErrorf("a set is required")
}
if length == 0 {
return cty.SetValEmpty(ety), nil
}
vals := make([]cty.Value, 0, length)
path = append(path, nil)
for i := 0; i < length; i++ {
path[len(path)-1] = cty.IndexStep{
Key: cty.NumberIntVal(int64(i)),
}
val, err := unmarshal(dec, ety, path)
if err != nil {
return cty.DynamicVal, err
}
vals = append(vals, val)
}
return cty.SetVal(vals), nil
}
func unmarshalMap(dec *msgpack.Decoder, ety cty.Type, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeMapLen()
if err != nil {
return cty.DynamicVal, path.NewErrorf("a map is required")
}
if length == 0 {
return cty.MapValEmpty(ety), nil
}
vals := make(map[string]cty.Value, length)
path = append(path, nil)
for i := 0; i < length; i++ {
key, err := dec.DecodeString()
if err != nil {
path[:len(path)-1].NewErrorf("non-string key in map")
}
path[len(path)-1] = cty.IndexStep{
Key: cty.StringVal(key),
}
val, err := unmarshal(dec, ety, path)
if err != nil {
return cty.DynamicVal, err
}
vals[key] = val
}
return cty.MapVal(vals), nil
}
func unmarshalTuple(dec *msgpack.Decoder, etys []cty.Type, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeArrayLen()
if err != nil {
return cty.DynamicVal, path.NewErrorf("a tuple is required")
}
if length != len(etys) {
return cty.DynamicVal, path.NewErrorf("a tuple of length %d is required", len(etys))
}
vals := make([]cty.Value, 0, length)
path = append(path, nil)
for i := 0; i < length; i++ {
path[len(path)-1] = cty.IndexStep{
Key: cty.NumberIntVal(int64(i)),
}
ety := etys[i]
val, err := unmarshal(dec, ety, path)
if err != nil {
return cty.DynamicVal, err
}
vals = append(vals, val)
}
return cty.TupleVal(vals), nil
}
func unmarshalObject(dec *msgpack.Decoder, atys map[string]cty.Type, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeMapLen()
if err != nil {
return cty.DynamicVal, path.NewErrorf("an object is required")
}
if length != len(atys) {
return cty.DynamicVal, path.NewErrorf("an object with %d attributes is required", len(atys))
}
vals := make(map[string]cty.Value, length)
path = append(path, nil)
for i := 0; i < length; i++ {
key, err := dec.DecodeString()
if err != nil {
return cty.DynamicVal, path[:len(path)-1].NewErrorf("all keys must be strings")
}
path[len(path)-1] = cty.IndexStep{
Key: cty.StringVal(key),
}
aty, exists := atys[key]
if !exists {
return cty.DynamicVal, path.NewErrorf("unsupported attribute")
}
val, err := unmarshal(dec, aty, path)
if err != nil {
return cty.DynamicVal, err
}
vals[key] = val
}
return cty.ObjectVal(vals), nil
}
func unmarshalDynamic(dec *msgpack.Decoder, path cty.Path) (cty.Value, error) {
length, err := dec.DecodeArrayLen()
if err != nil {
return cty.DynamicVal, path.NewError(err)
}
if length != 2 {
return cty.DynamicVal, path.NewErrorf(
"dynamic value array must have exactly two elements",
)
}
typeJSON, err := dec.DecodeBytes()
if err != nil {
return cty.DynamicVal, path.NewError(err)
}
var ty cty.Type
err = (&ty).UnmarshalJSON(typeJSON)
if err != nil {
return cty.DynamicVal, path.NewError(err)
}
return unmarshal(dec, ty, path)
}

3
vendor/vendor.json vendored
View file

@ -312,12 +312,15 @@
{"path":"github.com/ulikunitz/xz/internal/hash","checksumSHA1":"vjnTkzNrMs5Xj6so/fq0mQ6dT1c=","revision":"0c6b41e72360850ca4f98dc341fd999726ea007f","revisionTime":"2017-06-05T21:53:11Z"},
{"path":"github.com/ulikunitz/xz/internal/xlog","checksumSHA1":"m0pm57ASBK/CTdmC0ppRHO17mBs=","revision":"0c6b41e72360850ca4f98dc341fd999726ea007f","revisionTime":"2017-06-05T21:53:11Z"},
{"path":"github.com/ulikunitz/xz/lzma","checksumSHA1":"2vZw6zc8xuNlyVz2QKvdlNSZQ1U=","revision":"0c6b41e72360850ca4f98dc341fd999726ea007f","revisionTime":"2017-06-05T21:53:11Z"},
{"path":"github.com/vmihailenco/msgpack","checksumSHA1":"t9A/EE2GhHFPHzK+ksAKgKW9ZC8=","revision":"b5e691b1eb52a28c05e67ab9df303626c095c23b","revisionTime":"2018-06-13T09:15:15Z"},
{"path":"github.com/vmihailenco/msgpack/codes","checksumSHA1":"OcTSGT2v7/2saIGq06nDhEZwm8I=","revision":"b5e691b1eb52a28c05e67ab9df303626c095c23b","revisionTime":"2018-06-13T09:15:15Z"},
{"path":"github.com/zclconf/go-cty/cty","checksumSHA1":"Ej+3WWvyjn0xg3aujsyT+yvvmdc=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/convert","checksumSHA1":"1WGUPe776lvMMbaRerAbqOx19nQ=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/function","checksumSHA1":"MyyLCGg3RREMllTJyK6ehZl/dHk=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/function/stdlib","checksumSHA1":"kcTJOuL131/stXJ4U9tC3SASQLs=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/gocty","checksumSHA1":"tmCzwfNXOEB1sSO7TKVzilb2vjA=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/json","checksumSHA1":"1ApmO+Q33+Oem/3f6BU6sztJWNc=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/msgpack","checksumSHA1":"8H+2pufGi2Eo3d8cXFfJs31wk+I=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"github.com/zclconf/go-cty/cty/set","checksumSHA1":"y5Sk+n6SOspFj8mlyb8swr4DMIs=","revision":"02bd58e97b5759d478019c5a6333edbfdfed16a0","revisionTime":"2018-07-18T22:05:26Z"},
{"path":"go4.org/errorutil","checksumSHA1":"PMr/a5kcnC4toJtVwWhlU5E4tJY=","revision":"034d17a462f7b2dcd1a4a73553ec5357ff6e6c6e","revisionTime":"2017-05-24T23:16:39Z"},
{"path":"golang.org/x/crypto/blake2b","checksumSHA1":"iBXpCGzDbbbm0sWfaOY3aKDJ31U=","revision":"a49355c7e3f8fe157a85be2f77e6e269a0f89602","revisionTime":"2018-06-20T09:14:27Z"},