Merge pull request #39807 from deads2k/client-02-client-go

Automatic merge from submit-queue

run staging client-go update

Chasing to see what real problems we have in staging-client-go.

@sttts you get similar results?
pull/6/head
Kubernetes Submit Queue 2017-01-13 13:21:19 -08:00 committed by GitHub
commit 212234ab3f
679 changed files with 63088 additions and 51429 deletions

View File

@ -61,7 +61,7 @@ go_test(
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/client-go/pkg/util/diff",
"//vendor:k8s.io/apimachinery/pkg/util/diff",
],
)

View File

@ -54,7 +54,7 @@ go_test(
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/util/intstr:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/client-go/pkg/util/diff",
"//vendor:k8s.io/apimachinery/pkg/util/diff",
],
)

View File

@ -31,7 +31,7 @@ import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/diff"
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
"k8s.io/kubernetes/federation/pkg/kubefed/util"
"k8s.io/kubernetes/pkg/api"

View File

@ -24,7 +24,7 @@ import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/diff"
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
"k8s.io/kubernetes/federation/pkg/kubefed/util"

View File

@ -26,7 +26,7 @@ go_test(
],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//vendor:k8s.io/client-go/pkg/util/sets"],
deps = ["//vendor:k8s.io/apimachinery/pkg/util/sets"],
)
filegroup(

View File

@ -19,7 +19,7 @@ package allocator
import (
"testing"
"k8s.io/client-go/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
)
func TestAllocate(t *testing.T) {

View File

@ -16,7 +16,7 @@ go_test(
deps = [
"//vendor:github.com/golang/glog",
"//vendor:golang.org/x/crypto/ssh",
"//vendor:k8s.io/client-go/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
],
)
@ -28,9 +28,9 @@ go_library(
"//vendor:github.com/golang/glog",
"//vendor:github.com/prometheus/client_golang/prometheus",
"//vendor:golang.org/x/crypto/ssh",
"//vendor:k8s.io/client-go/pkg/util/net",
"//vendor:k8s.io/client-go/pkg/util/runtime",
"//vendor:k8s.io/client-go/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/util/net",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
],
)

View File

@ -40,9 +40,9 @@ import (
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/crypto/ssh"
utilnet "k8s.io/client-go/pkg/util/net"
"k8s.io/client-go/pkg/util/runtime"
"k8s.io/client-go/pkg/util/wait"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
)
var (

View File

@ -26,7 +26,7 @@ import (
"testing"
"time"
"k8s.io/client-go/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/wait"
"github.com/golang/glog"
"golang.org/x/crypto/ssh"

View File

@ -20,7 +20,6 @@ go_library(
"//vendor:github.com/golang/glog",
"//vendor:golang.org/x/net/websocket",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/client-go/pkg/util/runtime",
],
)

View File

@ -25,7 +25,7 @@ import (
"golang.org/x/net/websocket"
"k8s.io/client-go/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/runtime"
)
// The WebSocket subprotocol "binary.k8s.io" will only send messages to the

View File

@ -28,7 +28,6 @@ go_library(
"//vendor:k8s.io/client-go/pkg/api/errors",
"//vendor:k8s.io/client-go/pkg/apis/imagepolicy/install",
"//vendor:k8s.io/client-go/pkg/apis/imagepolicy/v1alpha1",
"//vendor:k8s.io/client-go/pkg/runtime/schema",
"//vendor:k8s.io/client-go/rest",
],
)

View File

@ -28,14 +28,14 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/runtime/schema"
kubeschema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/apiserver/pkg/util/cache"
apierrors "k8s.io/client-go/pkg/api/errors"
"k8s.io/client-go/pkg/apis/imagepolicy/v1alpha1"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/client-go/rest"
kubeschema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/plugin/pkg/webhook"

View File

@ -21,11 +21,11 @@ go_library(
srcs = ["requestheader.go"],
tags = ["automanaged"],
deps = [
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apiserver/pkg/authentication/authenticator",
"//vendor:k8s.io/apiserver/pkg/authentication/request/x509",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
"//vendor:k8s.io/client-go/pkg/util/cert",
"//vendor:k8s.io/client-go/pkg/util/sets",
],
)

View File

@ -23,11 +23,11 @@ import (
"net/http"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator"
x509request "k8s.io/apiserver/pkg/authentication/request/x509"
"k8s.io/apiserver/pkg/authentication/user"
utilcert "k8s.io/client-go/pkg/util/cert"
"k8s.io/client-go/pkg/util/sets"
)
type requestHeaderAuthRequestHandler struct {

View File

@ -15,13 +15,13 @@ go_library(
deps = [
"//pkg/apis/authentication/install:go_default_library",
"//plugin/pkg/webhook:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apiserver/pkg/authentication/authenticator",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
"//vendor:k8s.io/apiserver/pkg/util/cache",
"//vendor:k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
"//vendor:k8s.io/client-go/pkg/apis/authentication/install",
"//vendor:k8s.io/client-go/pkg/apis/authentication/v1beta1",
"//vendor:k8s.io/client-go/pkg/runtime/schema",
],
)

View File

@ -20,12 +20,12 @@ package webhook
import (
"time"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/util/cache"
authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1beta1"
authentication "k8s.io/client-go/pkg/apis/authentication/v1beta1"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/kubernetes/plugin/pkg/webhook"

View File

@ -16,12 +16,12 @@ go_library(
"//pkg/apis/authorization/install:go_default_library",
"//plugin/pkg/webhook:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
"//vendor:k8s.io/apiserver/pkg/util/cache",
"//vendor:k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
"//vendor:k8s.io/client-go/pkg/apis/authorization/install",
"//vendor:k8s.io/client-go/pkg/apis/authorization/v1beta1",
"//vendor:k8s.io/client-go/pkg/runtime/schema",
],
)

View File

@ -23,11 +23,11 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/util/cache"
authorizationclient "k8s.io/client-go/kubernetes/typed/authorization/v1beta1"
authorization "k8s.io/client-go/pkg/apis/authorization/v1beta1"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/kubernetes/plugin/pkg/webhook"

View File

@ -12,15 +12,13 @@ go_library(
srcs = ["webhook.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/pkg/api/errors",
"//vendor:k8s.io/client-go/pkg/apis/authorization/install",
"//vendor:k8s.io/client-go/pkg/runtime",
"//vendor:k8s.io/client-go/pkg/runtime/schema",
"//vendor:k8s.io/client-go/pkg/runtime/serializer",
"//vendor:k8s.io/client-go/pkg/util/wait",
"//vendor:k8s.io/client-go/rest",
"//vendor:k8s.io/client-go/tools/clientcmd",
],

View File

@ -21,18 +21,15 @@ import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/pkg/api"
apierrors "k8s.io/client-go/pkg/api/errors"
"k8s.io/client-go/pkg/runtime"
clientschema "k8s.io/client-go/pkg/runtime/schema"
runtimeserializer "k8s.io/client-go/pkg/runtime/serializer"
"k8s.io/client-go/pkg/util/wait"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
kapi "k8s.io/kubernetes/pkg/api"
_ "k8s.io/client-go/pkg/apis/authorization/install"
)
@ -42,9 +39,9 @@ type GenericWebhook struct {
}
// NewGenericWebhook creates a new GenericWebhook from the provided kubeconfig file.
func NewGenericWebhook(kubeConfigFile string, groupVersions []clientschema.GroupVersion, initialBackoff time.Duration) (*GenericWebhook, error) {
func NewGenericWebhook(kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration) (*GenericWebhook, error) {
for _, groupVersion := range groupVersions {
if !kapi.Registry.IsEnabledVersion(schema.GroupVersion{Group: groupVersion.Group, Version: groupVersion.Version}) {
if !api.Registry.IsEnabledVersion(groupVersion) {
return nil, fmt.Errorf("webhook plugin requires enabling extension resource: %s", groupVersion)
}
}

View File

@ -19,9 +19,9 @@ package union
import (
"net/http"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
utilerrors "k8s.io/client-go/pkg/util/errors"
)
// unionAuthRequestHandler authenticates requests using a chain of authenticator.Requests

View File

@ -25,10 +25,10 @@ import (
"github.com/golang/glog"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
utilerrors "k8s.io/client-go/pkg/util/errors"
"k8s.io/client-go/pkg/util/sets"
)
// UserConversion defines an interface for extracting user info from a client certificate chain

View File

@ -17,24 +17,24 @@ limitations under the License.
package x509
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"io/ioutil"
"net/http"
"reflect"
"sort"
"testing"
"time"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"io/ioutil"
"net/http"
"reflect"
"sort"
"testing"
"time"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
)
const (
rootCACert = `-----BEGIN CERTIFICATE-----
rootCACert = `-----BEGIN CERTIFICATE-----
MIIDOTCCAqKgAwIBAgIJAOoObf5kuGgZMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV
BAYTAlVTMREwDwYDVQQIEwhNeSBTdGF0ZTEQMA4GA1UEBxMHTXkgQ2l0eTEPMA0G
A1UEChMGTXkgT3JnMRAwDgYDVQQLEwdNeSBVbml0MRAwDgYDVQQDEwdST09UIENB
@ -56,7 +56,7 @@ H9oc7u5zhTGXeV8WPg==
-----END CERTIFICATE-----
`
selfSignedCert = `-----BEGIN CERTIFICATE-----
selfSignedCert = `-----BEGIN CERTIFICATE-----
MIIDEzCCAnygAwIBAgIJAMaPaFbGgJN+MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV
BAYTAlVTMREwDwYDVQQIEwhNeSBTdGF0ZTEQMA4GA1UEBxMHTXkgQ2l0eTEPMA0G
A1UEChMGTXkgT3JnMRAwDgYDVQQLEwdNeSBVbml0MQ4wDAYDVQQDEwVzZWxmMTAe
@ -77,7 +77,7 @@ ze3kOoP+iWSmTySHMSKVMppp0Xnls6t38mrsXtPuY8fGD2GS6VllaizMqc3wShNK
-----END CERTIFICATE-----
`
clientCNCert = `Certificate:
clientCNCert = `Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
@ -151,7 +151,7 @@ AjARBglghkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQELBQADgYEACLy0gKU7vpp4
i5fmaPPBNzzBFCaQoN3TAjrpwp5Z0kQ=
-----END CERTIFICATE-----`
clientDNSCert = `Certificate:
clientDNSCert = `Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4 (0x4)
@ -224,7 +224,7 @@ gGolrD3igQXkiStVY5otSto7xJdeGulvg7gFSty9q7CgddAetcWN8/aS8VLSgWf8
b3TuSTdzCLz1JoZn9YIE/9tan/lr3y/1dWHypZELBVZb6NE211Z67X3lXyoIh8JI
-----END CERTIFICATE-----`
clientEmailCert = `Certificate:
clientEmailCert = `Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
@ -299,7 +299,7 @@ BIaMiQ==
-----END CERTIFICATE-----
`
serverCert = `Certificate:
serverCert = `Certificate:
Data:
Version: 3 (0x2)
Serial Number: 7 (0x7)
@ -374,17 +374,17 @@ mFlG6tStAWz3TmydciZNdiEbeqHw5uaIYWj1zC5AdvFXBFue0ojIrJ5JtbTWccH9
-----END CERTIFICATE-----
`
/*
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 36500 \
-sha256 -key ca.key -extensions v3_ca \
-out ca.crt \
-subj "/C=US/ST=My State/L=My City/O=My Org/O=My Org 1/O=My Org 2/CN=ROOT CA WITH GROUPS"
openssl x509 -in ca.crt -text
*/
/*
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 36500 \
-sha256 -key ca.key -extensions v3_ca \
-out ca.crt \
-subj "/C=US/ST=My State/L=My City/O=My Org/O=My Org 1/O=My Org 2/CN=ROOT CA WITH GROUPS"
openssl x509 -in ca.crt -text
*/
// A certificate with multiple organizations.
caWithGroups = `Certificate:
// A certificate with multiple organizations.
caWithGroups = `Certificate:
Data:
Version: 3 (0x2)
Serial Number:
@ -510,424 +510,424 @@ PKJQCs0CM0zkesktuLi/gFpuB0nEwyOgLg==
)
func TestX509(t *testing.T) {
multilevelOpts := DefaultVerifyOptions()
multilevelOpts.Roots = x509.NewCertPool()
multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0])
multilevelOpts := DefaultVerifyOptions()
multilevelOpts.Roots = x509.NewCertPool()
multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0])
testCases := map[string]struct {
Insecure bool
Certs []*x509.Certificate
testCases := map[string]struct {
Insecure bool
Certs []*x509.Certificate
Opts x509.VerifyOptions
User UserConversion
Opts x509.VerifyOptions
User UserConversion
ExpectUserName string
ExpectGroups []string
ExpectOK bool
ExpectErr bool
}{
"non-tls": {
Insecure: true,
ExpectUserName string
ExpectGroups []string
ExpectOK bool
ExpectErr bool
}{
"non-tls": {
Insecure: true,
ExpectOK: false,
ExpectErr: false,
},
ExpectOK: false,
ExpectErr: false,
},
"tls, no certs": {
ExpectOK: false,
ExpectErr: false,
},
"tls, no certs": {
ExpectOK: false,
ExpectErr: false,
},
"self signed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, selfSignedCert),
User: CommonNameUserConversion,
"self signed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, selfSignedCert),
User: CommonNameUserConversion,
ExpectErr: true,
},
ExpectErr: true,
},
"server cert": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, serverCert),
User: CommonNameUserConversion,
"server cert": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, serverCert),
User: CommonNameUserConversion,
ExpectErr: true,
},
"server cert allowing non-client cert usages": {
Opts: x509.VerifyOptions{Roots: getRootCertPool(t)},
Certs: getCerts(t, serverCert),
User: CommonNameUserConversion,
ExpectErr: true,
},
"server cert allowing non-client cert usages": {
Opts: x509.VerifyOptions{Roots: getRootCertPool(t)},
Certs: getCerts(t, serverCert),
User: CommonNameUserConversion,
ExpectUserName: "127.0.0.1",
ExpectGroups: []string{"My Org"},
ExpectOK: true,
ExpectErr: false,
},
ExpectUserName: "127.0.0.1",
ExpectGroups: []string{"My Org"},
ExpectOK: true,
ExpectErr: false,
},
"common name": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
"common name": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
ExpectUserName: "client_cn",
ExpectGroups: []string{"My Org"},
ExpectOK: true,
ExpectErr: false,
},
"ca with multiple organizations": {
Opts: x509.VerifyOptions{
Roots: getRootCertPoolFor(t, caWithGroups),
},
Certs: getCerts(t, caWithGroups),
User: CommonNameUserConversion,
ExpectUserName: "client_cn",
ExpectGroups: []string{"My Org"},
ExpectOK: true,
ExpectErr: false,
},
"ca with multiple organizations": {
Opts: x509.VerifyOptions{
Roots: getRootCertPoolFor(t, caWithGroups),
},
Certs: getCerts(t, caWithGroups),
User: CommonNameUserConversion,
ExpectUserName: "ROOT CA WITH GROUPS",
ExpectGroups: []string{"My Org", "My Org 1", "My Org 2"},
ExpectOK: true,
ExpectErr: false,
},
"empty dns": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: DNSNameUserConversion,
ExpectUserName: "ROOT CA WITH GROUPS",
ExpectGroups: []string{"My Org", "My Org 1", "My Org 2"},
ExpectOK: true,
ExpectErr: false,
},
"empty dns": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: DNSNameUserConversion,
ExpectOK: false,
ExpectErr: false,
},
"dns": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientDNSCert),
User: DNSNameUserConversion,
ExpectOK: false,
ExpectErr: false,
},
"dns": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientDNSCert),
User: DNSNameUserConversion,
ExpectUserName: "client_dns.example.com",
ExpectOK: true,
ExpectErr: false,
},
ExpectUserName: "client_dns.example.com",
ExpectOK: true,
ExpectErr: false,
},
"empty email": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: EmailAddressUserConversion,
"empty email": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: EmailAddressUserConversion,
ExpectOK: false,
ExpectErr: false,
},
"email": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientEmailCert),
User: EmailAddressUserConversion,
ExpectOK: false,
ExpectErr: false,
},
"email": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientEmailCert),
User: EmailAddressUserConversion,
ExpectUserName: "client_email@example.com",
ExpectOK: true,
ExpectErr: false,
},
ExpectUserName: "client_email@example.com",
ExpectOK: true,
ExpectErr: false,
},
"custom conversion error": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
return nil, false, errors.New("custom error")
}),
"custom conversion error": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
return nil, false, errors.New("custom error")
}),
ExpectOK: false,
ExpectErr: true,
},
"custom conversion success": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
return &user.DefaultInfo{Name: "custom"}, true, nil
}),
ExpectOK: false,
ExpectErr: true,
},
"custom conversion success": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
return &user.DefaultInfo{Name: "custom"}, true, nil
}),
ExpectUserName: "custom",
ExpectOK: true,
ExpectErr: false,
},
ExpectUserName: "custom",
ExpectOK: true,
ExpectErr: false,
},
"future cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(time.Duration(-100 * time.Hour * 24 * 365)),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
"future cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(time.Duration(-100 * time.Hour * 24 * 365)),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
ExpectOK: false,
ExpectErr: true,
},
"expired cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(time.Duration(100 * time.Hour * 24 * 365)),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
ExpectOK: false,
ExpectErr: true,
},
"expired cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(time.Duration(100 * time.Hour * 24 * 365)),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
User: CommonNameUserConversion,
ExpectOK: false,
ExpectErr: true,
},
ExpectOK: false,
ExpectErr: true,
},
"multi-level, valid": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-valid", "intermediate"),
User: CommonNameUserConversion,
"multi-level, valid": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-valid", "intermediate"),
User: CommonNameUserConversion,
ExpectUserName: "My Client",
ExpectOK: true,
ExpectErr: false,
},
"multi-level, expired": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-expired", "intermediate"),
User: CommonNameUserConversion,
ExpectUserName: "My Client",
ExpectOK: true,
ExpectErr: false,
},
"multi-level, expired": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-expired", "intermediate"),
User: CommonNameUserConversion,
ExpectOK: false,
ExpectErr: true,
},
}
ExpectOK: false,
ExpectErr: true,
},
}
for k, testCase := range testCases {
req, _ := http.NewRequest("GET", "/", nil)
if !testCase.Insecure {
req.TLS = &tls.ConnectionState{PeerCertificates: testCase.Certs}
}
for k, testCase := range testCases {
req, _ := http.NewRequest("GET", "/", nil)
if !testCase.Insecure {
req.TLS = &tls.ConnectionState{PeerCertificates: testCase.Certs}
}
a := New(testCase.Opts, testCase.User)
a := New(testCase.Opts, testCase.User)
user, ok, err := a.AuthenticateRequest(req)
user, ok, err := a.AuthenticateRequest(req)
if testCase.ExpectErr && err == nil {
t.Errorf("%s: Expected error, got none", k)
continue
}
if !testCase.ExpectErr && err != nil {
t.Errorf("%s: Got unexpected error: %v", k, err)
continue
}
if testCase.ExpectErr && err == nil {
t.Errorf("%s: Expected error, got none", k)
continue
}
if !testCase.ExpectErr && err != nil {
t.Errorf("%s: Got unexpected error: %v", k, err)
continue
}
if testCase.ExpectOK != ok {
t.Errorf("%s: Expected ok=%v, got %v", k, testCase.ExpectOK, ok)
continue
}
if testCase.ExpectOK != ok {
t.Errorf("%s: Expected ok=%v, got %v", k, testCase.ExpectOK, ok)
continue
}
if testCase.ExpectOK {
if testCase.ExpectUserName != user.GetName() {
t.Errorf("%s: Expected user.name=%v, got %v", k, testCase.ExpectUserName, user.GetName())
}
if testCase.ExpectOK {
if testCase.ExpectUserName != user.GetName() {
t.Errorf("%s: Expected user.name=%v, got %v", k, testCase.ExpectUserName, user.GetName())
}
groups := user.GetGroups()
sort.Strings(testCase.ExpectGroups)
sort.Strings(groups)
if !reflect.DeepEqual(testCase.ExpectGroups, groups) {
t.Errorf("%s: Expected user.groups=%v, got %v", k, testCase.ExpectGroups, groups)
}
}
}
groups := user.GetGroups()
sort.Strings(testCase.ExpectGroups)
sort.Strings(groups)
if !reflect.DeepEqual(testCase.ExpectGroups, groups) {
t.Errorf("%s: Expected user.groups=%v, got %v", k, testCase.ExpectGroups, groups)
}
}
}
}
func TestX509Verifier(t *testing.T) {
multilevelOpts := DefaultVerifyOptions()
multilevelOpts.Roots = x509.NewCertPool()
multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0])
multilevelOpts := DefaultVerifyOptions()
multilevelOpts.Roots = x509.NewCertPool()
multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0])
testCases := map[string]struct {
Insecure bool
Certs []*x509.Certificate
testCases := map[string]struct {
Insecure bool
Certs []*x509.Certificate
Opts x509.VerifyOptions
Opts x509.VerifyOptions
AllowedCNs sets.String
AllowedCNs sets.String
ExpectOK bool
ExpectErr bool
}{
"non-tls": {
Insecure: true,
ExpectOK bool
ExpectErr bool
}{
"non-tls": {
Insecure: true,
ExpectOK: false,
ExpectErr: false,
},
ExpectOK: false,
ExpectErr: false,
},
"tls, no certs": {
ExpectOK: false,
ExpectErr: false,
},
"tls, no certs": {
ExpectOK: false,
ExpectErr: false,
},
"self signed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, selfSignedCert),
"self signed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, selfSignedCert),
ExpectErr: true,
},
ExpectErr: true,
},
"server cert disallowed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, serverCert),
"server cert disallowed": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, serverCert),
ExpectErr: true,
},
"server cert allowing non-client cert usages": {
Opts: x509.VerifyOptions{Roots: getRootCertPool(t)},
Certs: getCerts(t, serverCert),
ExpectErr: true,
},
"server cert allowing non-client cert usages": {
Opts: x509.VerifyOptions{Roots: getRootCertPool(t)},
Certs: getCerts(t, serverCert),
ExpectOK: true,
ExpectErr: false,
},
ExpectOK: true,
ExpectErr: false,
},
"valid client cert": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
"valid client cert": {
Opts: getDefaultVerifyOptions(t),
Certs: getCerts(t, clientCNCert),
ExpectOK: true,
ExpectErr: false,
},
"valid client cert with wrong CN": {
Opts: getDefaultVerifyOptions(t),
AllowedCNs: sets.NewString("foo", "bar"),
Certs: getCerts(t, clientCNCert),
ExpectOK: true,
ExpectErr: false,
},
"valid client cert with wrong CN": {
Opts: getDefaultVerifyOptions(t),
AllowedCNs: sets.NewString("foo", "bar"),
Certs: getCerts(t, clientCNCert),
ExpectOK: false,
ExpectErr: true,
},
"valid client cert with right CN": {
Opts: getDefaultVerifyOptions(t),
AllowedCNs: sets.NewString("client_cn"),
Certs: getCerts(t, clientCNCert),
ExpectOK: false,
ExpectErr: true,
},
"valid client cert with right CN": {
Opts: getDefaultVerifyOptions(t),
AllowedCNs: sets.NewString("client_cn"),
Certs: getCerts(t, clientCNCert),
ExpectOK: true,
ExpectErr: false,
},
ExpectOK: true,
ExpectErr: false,
},
"future cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(-100 * time.Hour * 24 * 365),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
"future cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(-100 * time.Hour * 24 * 365),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
ExpectOK: false,
ExpectErr: true,
},
"expired cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(100 * time.Hour * 24 * 365),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
ExpectOK: false,
ExpectErr: true,
},
"expired cert": {
Opts: x509.VerifyOptions{
CurrentTime: time.Now().Add(100 * time.Hour * 24 * 365),
Roots: getRootCertPool(t),
},
Certs: getCerts(t, clientCNCert),
ExpectOK: false,
ExpectErr: true,
},
ExpectOK: false,
ExpectErr: true,
},
"multi-level, valid": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-valid", "intermediate"),
"multi-level, valid": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-valid", "intermediate"),
ExpectOK: true,
ExpectErr: false,
},
"multi-level, expired": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-expired", "intermediate"),
ExpectOK: true,
ExpectErr: false,
},
"multi-level, expired": {
Opts: multilevelOpts,
Certs: getCertsFromFile(t, "client-expired", "intermediate"),
ExpectOK: false,
ExpectErr: true,
},
}
ExpectOK: false,
ExpectErr: true,
},
}
for k, testCase := range testCases {
req, _ := http.NewRequest("GET", "/", nil)
if !testCase.Insecure {
req.TLS = &tls.ConnectionState{PeerCertificates: testCase.Certs}
}
for k, testCase := range testCases {
req, _ := http.NewRequest("GET", "/", nil)
if !testCase.Insecure {
req.TLS = &tls.ConnectionState{PeerCertificates: testCase.Certs}
}
authCall := false
auth := authenticator.RequestFunc(func(req *http.Request) (user.Info, bool, error) {
authCall = true
return &user.DefaultInfo{Name: "innerauth"}, true, nil
})
authCall := false
auth := authenticator.RequestFunc(func(req *http.Request) (user.Info, bool, error) {
authCall = true
return &user.DefaultInfo{Name: "innerauth"}, true, nil
})
a := NewVerifier(testCase.Opts, auth, testCase.AllowedCNs)
a := NewVerifier(testCase.Opts, auth, testCase.AllowedCNs)
user, ok, err := a.AuthenticateRequest(req)
user, ok, err := a.AuthenticateRequest(req)
if testCase.ExpectErr && err == nil {
t.Errorf("%s: Expected error, got none", k)
continue
}
if !testCase.ExpectErr && err != nil {
t.Errorf("%s: Got unexpected error: %v", k, err)
continue
}
if testCase.ExpectErr && err == nil {
t.Errorf("%s: Expected error, got none", k)
continue
}
if !testCase.ExpectErr && err != nil {
t.Errorf("%s: Got unexpected error: %v", k, err)
continue
}
if testCase.ExpectOK != ok {
t.Errorf("%s: Expected ok=%v, got %v", k, testCase.ExpectOK, ok)
continue
}
if testCase.ExpectOK != ok {
t.Errorf("%s: Expected ok=%v, got %v", k, testCase.ExpectOK, ok)
continue
}
if testCase.ExpectOK {
if !authCall {
t.Errorf("%s: Expected inner auth called, wasn't", k)
continue
}
if "innerauth" != user.GetName() {
t.Errorf("%s: Expected user.name=%v, got %v", k, "innerauth", user.GetName())
continue
}
} else {
if authCall {
t.Errorf("%s: Expected inner auth not to be called, was", k)
continue
}
}
}
if testCase.ExpectOK {
if !authCall {
t.Errorf("%s: Expected inner auth called, wasn't", k)
continue
}
if "innerauth" != user.GetName() {
t.Errorf("%s: Expected user.name=%v, got %v", k, "innerauth", user.GetName())
continue
}
} else {
if authCall {
t.Errorf("%s: Expected inner auth not to be called, was", k)
continue
}
}
}
}
func getDefaultVerifyOptions(t *testing.T) x509.VerifyOptions {
options := DefaultVerifyOptions()
options.Roots = getRootCertPool(t)
return options
options := DefaultVerifyOptions()
options.Roots = getRootCertPool(t)
return options
}
func getRootCertPool(t *testing.T) *x509.CertPool {
return getRootCertPoolFor(t, rootCACert)
return getRootCertPoolFor(t, rootCACert)
}
func getRootCertPoolFor(t *testing.T, certs ...string) *x509.CertPool {
pool := x509.NewCertPool()
for _, cert := range certs {
pool.AddCert(getCert(t, cert))
}
return pool
pool := x509.NewCertPool()
for _, cert := range certs {
pool.AddCert(getCert(t, cert))
}
return pool
}
func getCertsFromFile(t *testing.T, names ...string) []*x509.Certificate {
certs := []*x509.Certificate{}
for _, name := range names {
filename := "testdata/" + name + ".pem"
data, err := ioutil.ReadFile(filename)
if err != nil {
t.Fatalf("error reading %s: %v", filename, err)
}
certs = append(certs, getCert(t, string(data)))
}
return certs
certs := []*x509.Certificate{}
for _, name := range names {
filename := "testdata/" + name + ".pem"
data, err := ioutil.ReadFile(filename)
if err != nil {
t.Fatalf("error reading %s: %v", filename, err)
}
certs = append(certs, getCert(t, string(data)))
}
return certs
}
func getCert(t *testing.T, pemData string) *x509.Certificate {
pemBlock, _ := pem.Decode([]byte(pemData))
cert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
t.Fatalf("Error parsing cert: %v", err)
return nil
}
return cert
pemBlock, _ := pem.Decode([]byte(pemData))
cert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
t.Fatalf("Error parsing cert: %v", err)
return nil
}
return cert
}
func getCerts(t *testing.T, pemData ...string) []*x509.Certificate {
certs := []*x509.Certificate{}
for _, pemData := range pemData {
certs = append(certs, getCert(t, pemData))
}
return certs
certs := []*x509.Certificate{}
for _, pemData := range pemData {
certs = append(certs, getCert(t, pemData))
}
return certs
}

View File

@ -19,8 +19,8 @@ package union
import (
"strings"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/authorization/authorizer"
utilerrors "k8s.io/client-go/pkg/util/errors"
)
// unionAuthzHandler authorizer against a chain of authorizer.Authorizer

View File

@ -172,10 +172,6 @@
"ImportPath": "github.com/mailru/easyjson/jwriter",
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
},
{
"ImportPath": "github.com/pborman/uuid",
"Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4"
},
{
"ImportPath": "github.com/pmezard/go-difflib/difflib",
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
@ -191,11 +187,11 @@
},
{
"ImportPath": "github.com/ugorji/go/codec",
"Rev": "f1f1a805ed361a0e078bb537e4ea78cd37dcf065"
"Rev": "ded73eae5db7e7a0ef6f55aace87a2873c5d2b74"
},
{
"ImportPath": "golang.org/x/crypto/ssh/terminal",
"Rev": "1f22c0103821b9390939b6776727195525381532"
"Rev": "d172538b2cfce0c13cee31e647d0367aa8cd2486"
},
{
"ImportPath": "golang.org/x/net/context",
@ -325,6 +321,134 @@
{
"ImportPath": "gopkg.in/yaml.v2",
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/genericapiserver/openapi/common",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/labels",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/selection",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/types",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/watch",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
"Rev": "66b1ba666d4dbb77b323da06b1cbe86f83414878"
}
]
}

View File

@ -1 +0,0 @@
Paul Borman <borman@google.com>

View File

@ -1,27 +0,0 @@
Copyright (c) 2009,2014 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
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.

View File

@ -1,84 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"fmt"
"os"
)
// A Domain represents a Version 2 domain
type Domain byte
// Domain constants for DCE Security (Version 2) UUIDs.
const (
Person = Domain(0)
Group = Domain(1)
Org = Domain(2)
)
// NewDCESecurity returns a DCE Security (Version 2) UUID.
//
// The domain should be one of Person, Group or Org.
// On a POSIX system the id should be the users UID for the Person
// domain and the users GID for the Group. The meaning of id for
// the domain Org or on non-POSIX systems is site defined.
//
// For a given domain/id pair the same token may be returned for up to
// 7 minutes and 10 seconds.
func NewDCESecurity(domain Domain, id uint32) UUID {
uuid := NewUUID()
if uuid != nil {
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
uuid[9] = byte(domain)
binary.BigEndian.PutUint32(uuid[0:], id)
}
return uuid
}
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
// NewDCEPerson(Person, uint32(os.Getuid()))
func NewDCEPerson() UUID {
return NewDCESecurity(Person, uint32(os.Getuid()))
}
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
// domain with the id returned by os.Getgid.
//
// NewDCEGroup(Group, uint32(os.Getgid()))
func NewDCEGroup() UUID {
return NewDCESecurity(Group, uint32(os.Getgid()))
}
// Domain returns the domain for a Version 2 UUID or false.
func (uuid UUID) Domain() (Domain, bool) {
if v, _ := uuid.Version(); v != 2 {
return 0, false
}
return Domain(uuid[9]), true
}
// Id returns the id for a Version 2 UUID or false.
func (uuid UUID) Id() (uint32, bool) {
if v, _ := uuid.Version(); v != 2 {
return 0, false
}
return binary.BigEndian.Uint32(uuid[0:4]), true
}
func (d Domain) String() string {
switch d {
case Person:
return "Person"
case Group:
return "Group"
case Org:
return "Org"
}
return fmt.Sprintf("Domain%d", int(d))
}

View File

@ -1,8 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The uuid package generates and inspects UUIDs.
//
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
package uuid

View File

@ -1,53 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"crypto/md5"
"crypto/sha1"
"hash"
)
// Well known Name Space IDs and UUIDs
var (
NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
NIL = Parse("00000000-0000-0000-0000-000000000000")
)
// NewHash returns a new UUID dervied from the hash of space concatenated with
// data generated by h. The hash should be at least 16 byte in length. The
// first 16 bytes of the hash are used to form the UUID. The version of the
// UUID will be the lower 4 bits of version. NewHash is used to implement
// NewMD5 and NewSHA1.
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
h.Reset()
h.Write(space)
h.Write([]byte(data))
s := h.Sum(nil)
uuid := make([]byte, 16)
copy(uuid, s)
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
return uuid
}
// NewMD5 returns a new MD5 (Version 3) UUID based on the
// supplied name space and data.
//
// NewHash(md5.New(), space, data, 3)
func NewMD5(space UUID, data []byte) UUID {
return NewHash(md5.New(), space, data, 3)
}
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
// supplied name space and data.
//
// NewHash(sha1.New(), space, data, 5)
func NewSHA1(space UUID, data []byte) UUID {
return NewHash(sha1.New(), space, data, 5)
}

View File

@ -1,30 +0,0 @@
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "errors"
func (u UUID) MarshalJSON() ([]byte, error) {
if len(u) == 0 {
return []byte(`""`), nil
}
return []byte(`"` + u.String() + `"`), nil
}
func (u *UUID) UnmarshalJSON(data []byte) error {
if len(data) == 0 || string(data) == `""` {
return nil
}
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
return errors.New("invalid UUID format")
}
data = data[1 : len(data)-1]
uu := Parse(string(data))
if uu == nil {
return errors.New("invalid UUID format")
}
*u = uu
return nil
}

View File

@ -1,101 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "net"
var (
interfaces []net.Interface // cached list of interfaces
ifname string // name of interface being used
nodeID []byte // hardware for version 1 UUIDs
)
// NodeInterface returns the name of the interface from which the NodeID was
// derived. The interface "user" is returned if the NodeID was set by
// SetNodeID.
func NodeInterface() string {
return ifname
}
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
// If name is "" then the first usable interface found will be used or a random
// Node ID will be generated. If a named interface cannot be found then false
// is returned.
//
// SetNodeInterface never fails when name is "".
func SetNodeInterface(name string) bool {
if interfaces == nil {
var err error
interfaces, err = net.Interfaces()
if err != nil && name != "" {
return false
}
}
for _, ifs := range interfaces {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
if setNodeID(ifs.HardwareAddr) {
ifname = ifs.Name
return true
}
}
}
// We found no interfaces with a valid hardware address. If name
// does not specify a specific interface generate a random Node ID
// (section 4.1.6)
if name == "" {
if nodeID == nil {
nodeID = make([]byte, 6)
}
randomBits(nodeID)
return true
}
return false
}
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
// if not already set.
func NodeID() []byte {
if nodeID == nil {
SetNodeInterface("")
}
nid := make([]byte, 6)
copy(nid, nodeID)
return nid
}
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
// of id are used. If id is less than 6 bytes then false is returned and the
// Node ID is not set.
func SetNodeID(id []byte) bool {
if setNodeID(id) {
ifname = "user"
return true
}
return false
}
func setNodeID(id []byte) bool {
if len(id) < 6 {
return false
}
if nodeID == nil {
nodeID = make([]byte, 6)
}
copy(nodeID, id)
return true
}
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) NodeID() []byte {
if len(uuid) != 16 {
return nil
}
node := make([]byte, 6)
copy(node, uuid[10:])
return node
}

View File

@ -1,132 +0,0 @@
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"sync"
"time"
)
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
// 1582.
type Time int64
const (
lillian = 2299160 // Julian day of 15 Oct 1582
unix = 2440587 // Julian day of 1 Jan 1970
epoch = unix - lillian // Days between epochs
g1582 = epoch * 86400 // seconds between epochs
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
)
var (
mu sync.Mutex
lasttime uint64 // last time we returned
clock_seq uint16 // clock sequence for this run
timeNow = time.Now // for testing
)
// UnixTime converts t the number of seconds and nanoseconds using the Unix
// epoch of 1 Jan 1970.
func (t Time) UnixTime() (sec, nsec int64) {
sec = int64(t - g1582ns100)
nsec = (sec % 10000000) * 100
sec /= 10000000
return sec, nsec
}
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
// clock sequence as well as adjusting the clock sequence as needed. An error
// is returned if the current time cannot be determined.
func GetTime() (Time, uint16, error) {
defer mu.Unlock()
mu.Lock()
return getTime()
}
func getTime() (Time, uint16, error) {
t := timeNow()
// If we don't have a clock sequence already, set one.
if clock_seq == 0 {
setClockSequence(-1)
}
now := uint64(t.UnixNano()/100) + g1582ns100
// If time has gone backwards with this clock sequence then we
// increment the clock sequence
if now <= lasttime {
clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
}
lasttime = now
return Time(now), clock_seq, nil
}
// ClockSequence returns the current clock sequence, generating one if not
// already set. The clock sequence is only used for Version 1 UUIDs.
//
// The uuid package does not use global static storage for the clock sequence or
// the last time a UUID was generated. Unless SetClockSequence a new random
// clock sequence is generated the first time a clock sequence is requested by
// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
// for
func ClockSequence() int {
defer mu.Unlock()
mu.Lock()
return clockSequence()
}
func clockSequence() int {
if clock_seq == 0 {
setClockSequence(-1)
}
return int(clock_seq & 0x3fff)
}
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
// -1 causes a new sequence to be generated.
func SetClockSequence(seq int) {
defer mu.Unlock()
mu.Lock()
setClockSequence(seq)
}
func setClockSequence(seq int) {
if seq == -1 {
var b [2]byte
randomBits(b[:]) // clock sequence
seq = int(b[0])<<8 | int(b[1])
}
old_seq := clock_seq
clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
if old_seq != clock_seq {
lasttime = 0
}
}
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
// uuid. It returns false if uuid is not valid. The time is only well defined
// for version 1 and 2 UUIDs.
func (uuid UUID) Time() (Time, bool) {
if len(uuid) != 16 {
return 0, false
}
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
return Time(time), true
}
// ClockSequence returns the clock sequence encoded in uuid. It returns false
// if uuid is not valid. The clock sequence is only well defined for version 1
// and 2 UUIDs.
func (uuid UUID) ClockSequence() (int, bool) {
if len(uuid) != 16 {
return 0, false
}
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true
}

View File

@ -1,43 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"io"
)
// randomBits completely fills slice b with random data.
func randomBits(b []byte) {
if _, err := io.ReadFull(rander, b); err != nil {
panic(err.Error()) // rand should never fail
}
}
// xvalues returns the value of a byte as a hexadecimal digit or 255.
var xvalues = []byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}
// xtob converts the the first two hex bytes of x into a byte.
func xtob(x string) (byte, bool) {
b1 := xvalues[x[0]]
b2 := xvalues[x[1]]
return (b1 << 4) | b2, b1 != 255 && b2 != 255
}

View File

@ -1,163 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"bytes"
"crypto/rand"
"fmt"
"io"
"strings"
)
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
// 4122.
type UUID []byte
// A Version represents a UUIDs version.
type Version byte
// A Variant represents a UUIDs variant.
type Variant byte
// Constants returned by Variant.
const (
Invalid = Variant(iota) // Invalid UUID
RFC4122 // The variant specified in RFC4122
Reserved // Reserved, NCS backward compatibility.
Microsoft // Reserved, Microsoft Corporation backward compatibility.
Future // Reserved for future definition.
)
var rander = rand.Reader // random function
// New returns a new random (version 4) UUID as a string. It is a convenience
// function for NewRandom().String().
func New() string {
return NewRandom().String()
}
// Parse decodes s into a UUID or returns nil. Both the UUID form of
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
func Parse(s string) UUID {
if len(s) == 36+9 {
if strings.ToLower(s[:9]) != "urn:uuid:" {
return nil
}
s = s[9:]
} else if len(s) != 36 {
return nil
}
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
return nil
}
uuid := make([]byte, 16)
for i, x := range []int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
if v, ok := xtob(s[x:]); !ok {
return nil
} else {
uuid[i] = v
}
}
return uuid
}
// Equal returns true if uuid1 and uuid2 are equal.
func Equal(uuid1, uuid2 UUID) bool {
return bytes.Equal(uuid1, uuid2)
}
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// , or "" if uuid is invalid.
func (uuid UUID) String() string {
if uuid == nil || len(uuid) != 16 {
return ""
}
b := []byte(uuid)
return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x",
b[:4], b[4:6], b[6:8], b[8:10], b[10:])
}
// URN returns the RFC 2141 URN form of uuid,
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
func (uuid UUID) URN() string {
if uuid == nil || len(uuid) != 16 {
return ""
}
b := []byte(uuid)
return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x",
b[:4], b[4:6], b[6:8], b[8:10], b[10:])
}
// Variant returns the variant encoded in uuid. It returns Invalid if
// uuid is invalid.
func (uuid UUID) Variant() Variant {
if len(uuid) != 16 {
return Invalid
}
switch {
case (uuid[8] & 0xc0) == 0x80:
return RFC4122
case (uuid[8] & 0xe0) == 0xc0:
return Microsoft
case (uuid[8] & 0xe0) == 0xe0:
return Future
default:
return Reserved
}
panic("unreachable")
}
// Version returns the verison of uuid. It returns false if uuid is not
// valid.
func (uuid UUID) Version() (Version, bool) {
if len(uuid) != 16 {
return 0, false
}
return Version(uuid[6] >> 4), true
}
func (v Version) String() string {
if v > 15 {
return fmt.Sprintf("BAD_VERSION_%d", v)
}
return fmt.Sprintf("VERSION_%d", v)
}
func (v Variant) String() string {
switch v {
case RFC4122:
return "RFC4122"
case Reserved:
return "Reserved"
case Microsoft:
return "Microsoft"
case Future:
return "Future"
case Invalid:
return "Invalid"
}
return fmt.Sprintf("BadVariant%d", int(v))
}
// SetRand sets the random number generator to r, which implents io.Reader.
// If r.Read returns an error when the package requests random data then
// a panic will be issued.
//
// Calling SetRand with nil sets the random number generator to the default
// generator.
func SetRand(r io.Reader) {
if r == nil {
rander = rand.Reader
return
}
rander = r
}

View File

@ -1,41 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
)
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
// sequence, and the current time. If the NodeID has not been set by SetNodeID
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
// be set NewUUID returns nil. If clock sequence has not been set by
// SetClockSequence then it will be set automatically. If GetTime fails to
// return the current NewUUID returns nil.
func NewUUID() UUID {
if nodeID == nil {
SetNodeInterface("")
}
now, seq, err := GetTime()
if err != nil {
return nil
}
uuid := make([]byte, 16)
time_low := uint32(now & 0xffffffff)
time_mid := uint16((now >> 32) & 0xffff)
time_hi := uint16((now >> 48) & 0x0fff)
time_hi |= 0x1000 // Version 1
binary.BigEndian.PutUint32(uuid[0:], time_low)
binary.BigEndian.PutUint16(uuid[4:], time_mid)
binary.BigEndian.PutUint16(uuid[6:], time_hi)
binary.BigEndian.PutUint16(uuid[8:], seq)
copy(uuid[10:], nodeID)
return uuid
}

View File

@ -1,25 +0,0 @@
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
// Random returns a Random (Version 4) UUID or panics.
//
// The strength of the UUIDs is based on the strength of the crypto/rand
// package.
//
// A note about uniqueness derived from from the UUID Wikipedia entry:
//
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
// hit by a meteorite is estimated to be one chance in 17 billion, that
// means the probability is about 0.00000000006 (6 × 1011),
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate.
func NewRandom() UUID {
uuid := make([]byte, 16)
randomBits([]byte(uuid))
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
return uuid
}

View File

@ -64,10 +64,11 @@ Rich Feature Set includes:
- Never silently skip data when decoding.
User decides whether to return an error or silently skip data when keys or indexes
in the data stream do not map to fields in the struct.
- Detect and error when encoding a cyclic reference (instead of stack overflow shutdown)
- Encode/Decode from/to chan types (for iterative streaming support)
- Drop-in replacement for encoding/json. `json:` key in struct tag supported.
- Provides a RPC Server and Client Codec for net/rpc communication protocol.
- Handle unique idiosynchracies of codecs e.g.
- Handle unique idiosyncrasies of codecs e.g.
- For messagepack, configure how ambiguities in handling raw bytes are resolved
- For messagepack, provide rpc server/client codec to support
msgpack-rpc protocol defined at:
@ -171,6 +172,8 @@ package codec
// TODO:
//
// - optimization for codecgen:
// if len of entity is <= 3 words, then support a value receiver for encode.
// - (En|De)coder should store an error when it occurs.
// Until reset, subsequent calls return that error that was stored.
// This means that free panics must go away.
@ -178,16 +181,19 @@ package codec
// - Decoding using a chan is good, but incurs concurrency costs.
// This is because there's no fast way to use a channel without it
// having to switch goroutines constantly.
// Callback pattern is still the best. Maybe cnsider supporting something like:
// Callback pattern is still the best. Maybe consider supporting something like:
// type X struct {
// Name string
// Ys []Y
// Ys chan <- Y
// Ys func(interface{}) -> call this interface for each entry in there.
// Ys func(Y) -> call this function for each entry
// }
// - Consider adding a isZeroer interface { isZero() bool }
// It is used within isEmpty, for omitEmpty support.
// - Consider making Handle used AS-IS within the encoding/decoding session.
// This means that we don't cache Handle information within the (En|De)coder,
// except we really need it at Reset(...)
// - Handle recursive types during encoding/decoding?
// - Consider adding math/big support
// - Consider reducing the size of the generated functions:
// Maybe use one loop, and put the conditionals in the loop.
// for ... { if cLen > 0 { if j == cLen { break } } else if dd.CheckBreak() { break } }

View File

@ -68,7 +68,7 @@ Rich Feature Set includes:
- Encode/Decode from/to chan types (for iterative streaming support)
- Drop-in replacement for encoding/json. `json:` key in struct tag supported.
- Provides a RPC Server and Client Codec for net/rpc communication protocol.
- Handle unique idiosynchracies of codecs e.g.
- Handle unique idiosyncrasies of codecs e.g.
- For messagepack, configure how ambiguities in handling raw bytes are resolved
- For messagepack, provide rpc server/client codec to support
msgpack-rpc protocol defined at:

View File

@ -348,6 +348,13 @@ func (d *bincDecDriver) readNextBd() {
d.bdRead = true
}
func (d *bincDecDriver) uncacheRead() {
if d.bdRead {
d.r.unreadn1()
d.bdRead = false
}
}
func (d *bincDecDriver) ContainerType() (vt valueType) {
if d.vd == bincVdSpecial && d.vs == bincSpNil {
return valueTypeNil
@ -705,7 +712,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
}
func (d *bincDecDriver) DecodeString() (s string) {
// DecodeBytes does not accomodate symbols, whose impl stores string version in map.
// DecodeBytes does not accommodate symbols, whose impl stores string version in map.
// Use decStringAndBytes directly.
// return string(d.DecodeBytes(d.b[:], true, true))
_, s = d.decStringAndBytes(d.b[:], true, true)
@ -908,10 +915,14 @@ func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
func (e *bincEncDriver) reset() {
e.w = e.e.w
e.s = 0
e.m = nil
}
func (d *bincDecDriver) reset() {
d.r = d.d.r
d.s = nil
d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
}
var _ decDriver = (*bincDecDriver)(nil)

View File

@ -188,6 +188,13 @@ func (d *cborDecDriver) readNextBd() {
d.bdRead = true
}
func (d *cborDecDriver) uncacheRead() {
if d.bdRead {
d.r.unreadn1()
d.bdRead = false
}
}
func (d *cborDecDriver) ContainerType() (vt valueType) {
if d.bd == cborBdNil {
return valueTypeNil
@ -508,7 +515,7 @@ func (d *cborDecDriver) DecodeNaked() {
n.v = valueTypeExt
n.u = d.decUint()
n.l = nil
d.bdRead = false
// d.bdRead = false
// d.d.decode(&re.Value) // handled by decode itself.
// decodeFurther = true
default:
@ -578,6 +585,7 @@ func (e *cborEncDriver) reset() {
func (d *cborDecDriver) reset() {
d.r = d.d.r
d.bd, d.bdRead = 0, false
}
var _ decDriver = (*cborDecDriver)(nil)

View File

@ -91,10 +91,12 @@ type decDriver interface {
uncacheRead()
}
type decNoSeparator struct{}
type decNoSeparator struct {
}
func (_ decNoSeparator) ReadEnd() {}
func (_ decNoSeparator) uncacheRead() {}
func (_ decNoSeparator) ReadEnd() {}
// func (_ decNoSeparator) uncacheRead() {}
type DecodeOptions struct {
// MapType specifies type to use during schema-less decoding of a map in the stream.
@ -161,6 +163,15 @@ type DecodeOptions struct {
// Note: Handles will be smart when using the intern functionality.
// So everything will not be interned.
InternString bool
// PreferArrayOverSlice controls whether to decode to an array or a slice.
//
// This only impacts decoding into a nil interface{}.
// Consequently, it has no effect on codecgen.
//
// *Note*: This only applies if using go1.5 and above,
// as it requires reflect.ArrayOf support which was absent before go1.5.
PreferArrayOverSlice bool
}
// ------------------------------------
@ -433,6 +444,10 @@ func (f *decFnInfo) rawExt(rv reflect.Value) {
f.d.d.DecodeExt(rv.Addr().Interface(), 0, nil)
}
func (f *decFnInfo) raw(rv reflect.Value) {
rv.SetBytes(f.d.raw())
}
func (f *decFnInfo) ext(rv reflect.Value) {
f.d.d.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn)
}
@ -583,14 +598,16 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
if d.mtid == 0 || d.mtid == mapIntfIntfTypId {
l := len(n.ms)
n.ms = append(n.ms, nil)
d.decode(&n.ms[l])
rvn = reflect.ValueOf(&n.ms[l]).Elem()
var v2 interface{} = &n.ms[l]
d.decode(v2)
rvn = reflect.ValueOf(v2).Elem()
n.ms = n.ms[:l]
} else if d.mtid == mapStrIntfTypId { // for json performance
l := len(n.ns)
n.ns = append(n.ns, nil)
d.decode(&n.ns[l])
rvn = reflect.ValueOf(&n.ns[l]).Elem()
var v2 interface{} = &n.ns[l]
d.decode(v2)
rvn = reflect.ValueOf(v2).Elem()
n.ns = n.ns[:l]
} else {
rvn = reflect.New(d.h.MapType).Elem()
@ -601,9 +618,13 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
if d.stid == 0 || d.stid == intfSliceTypId {
l := len(n.ss)
n.ss = append(n.ss, nil)
d.decode(&n.ss[l])
rvn = reflect.ValueOf(&n.ss[l]).Elem()
var v2 interface{} = &n.ss[l]
d.decode(v2)
n.ss = n.ss[:l]
rvn = reflect.ValueOf(v2).Elem()
if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
rvn = reflectArrayOf(rvn)
}
} else {
rvn = reflect.New(d.h.SliceType).Elem()
d.decodeValue(rvn, nil)
@ -615,9 +636,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
l := len(n.is)
n.is = append(n.is, nil)
v2 := &n.is[l]
n.is = n.is[:l]
d.decode(v2)
v = *v2
n.is = n.is[:l]
}
bfn := d.h.getExtForTag(tag)
if bfn == nil {
@ -1166,7 +1187,7 @@ type decRtidFn struct {
// primitives are being decoded.
//
// maps and arrays are not handled by this mechanism.
// However, RawExt is, and we accomodate for extensions that decode
// However, RawExt is, and we accommodate for extensions that decode
// RawExt from DecodeNaked, but need to decode the value subsequently.
// kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat.
//
@ -1453,8 +1474,8 @@ func (d *Decoder) swallow() {
l := len(n.is)
n.is = append(n.is, nil)
v2 := &n.is[l]
n.is = n.is[:l]
d.decode(v2)
n.is = n.is[:l]
}
}
}
@ -1504,6 +1525,8 @@ func (d *Decoder) decode(iv interface{}) {
*v = 0
case *[]uint8:
*v = nil
case *Raw:
*v = nil
case reflect.Value:
if v.Kind() != reflect.Ptr || v.IsNil() {
d.errNotValidPtrValue(v)
@ -1543,7 +1566,6 @@ func (d *Decoder) decode(iv interface{}) {
d.decodeValueNotNil(v.Elem(), nil)
case *string:
*v = d.d.DecodeString()
case *bool:
*v = d.d.DecodeBool()
@ -1574,6 +1596,9 @@ func (d *Decoder) decode(iv interface{}) {
case *[]uint8:
*v = d.d.DecodeBytes(*v, false, false)
case *Raw:
*v = d.raw()
case *interface{}:
d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), nil)
@ -1695,6 +1720,8 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool
fn.f = (*decFnInfo).selferUnmarshal
} else if rtid == rawExtTypId {
fn.f = (*decFnInfo).rawExt
} else if rtid == rawTypId {
fn.f = (*decFnInfo).raw
} else if d.d.IsBuiltinType(rtid) {
fn.f = (*decFnInfo).builtin
} else if xfFn := d.h.getExt(rtid); xfFn != nil {
@ -1793,12 +1820,13 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool
}
func (d *Decoder) structFieldNotFound(index int, rvkencname string) {
// NOTE: rvkencname may be a stringView, so don't pass it to another function.
if d.h.ErrorIfNoField {
if index >= 0 {
d.errorf("no matching struct field found when decoding stream array at index %v", index)
return
} else if rvkencname != "" {
d.errorf("no matching struct field found when decoding stream map with key %s", rvkencname)
d.errorf("no matching struct field found when decoding stream map with key " + rvkencname)
return
}
}
@ -1862,6 +1890,7 @@ func (d *Decoder) intern(s string) {
}
}
// nextValueBytes returns the next value in the stream as a set of bytes.
func (d *Decoder) nextValueBytes() []byte {
d.d.uncacheRead()
d.r.track()
@ -1869,6 +1898,15 @@ func (d *Decoder) nextValueBytes() []byte {
return d.r.stopTrack()
}
func (d *Decoder) raw() []byte {
// ensure that this is not a view into the bytes
// i.e. make new copy always.
bs := d.nextValueBytes()
bs2 := make([]byte, len(bs))
copy(bs2, bs)
return bs2
}
// --------------------------------------------------
// decSliceHelper assists when decoding into a slice, from a map or an array in the stream.

View File

@ -0,0 +1,16 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.5
package codec
import "reflect"
const reflectArrayOfSupported = true
func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
rvn2 = reflect.New(reflect.ArrayOf(rvn.Len(), intfTyp)).Elem()
reflect.Copy(rvn2, rvn)
return
}

View File

@ -0,0 +1,14 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build !go1.5
package codec
import "reflect"
const reflectArrayOfSupported = false
func reflectArrayOf(rvn reflect.Value) (rvn2 reflect.Value) {
panic("reflect.ArrayOf unsupported")
}

View File

@ -110,6 +110,28 @@ type EncodeOptions struct {
//
Canonical bool
// CheckCircularRef controls whether we check for circular references
// and error fast during an encode.
//
// If enabled, an error is received if a pointer to a struct
// references itself either directly or through one of its fields (iteratively).
//
// This is opt-in, as there may be a performance hit to checking circular references.
CheckCircularRef bool
// RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
// when checking if a value is empty.
//
// Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
RecursiveEmptyCheck bool
// Raw controls whether we encode Raw values.
// This is a "dangerous" option and must be explicitly set.
// If set, we blindly encode Raw values as-is, without checking
// if they are a correct representation of a value in that format.
// If unset, we error out.
Raw bool
// AsSymbols defines what should be encoded as symbols.
//
// Encoding as symbols can reduce the encoded size significantly.
@ -132,13 +154,16 @@ type simpleIoEncWriterWriter struct {
w io.Writer
bw io.ByteWriter
sw ioEncStringWriter
bs [1]byte
}
func (o *simpleIoEncWriterWriter) WriteByte(c byte) (err error) {
if o.bw != nil {
return o.bw.WriteByte(c)
}
_, err = o.w.Write([]byte{c})
// _, err = o.w.Write([]byte{c})
o.bs[0] = c
_, err = o.w.Write(o.bs[:])
return
}
@ -210,45 +235,57 @@ type bytesEncWriter struct {
}
func (z *bytesEncWriter) writeb(s []byte) {
if len(s) > 0 {
c := z.grow(len(s))
copy(z.b[c:], s)
if len(s) == 0 {
return
}
oc, a := z.growNoAlloc(len(s))
if a {
z.growAlloc(len(s), oc)
}
copy(z.b[oc:], s)
}
func (z *bytesEncWriter) writestr(s string) {
if len(s) > 0 {
c := z.grow(len(s))
copy(z.b[c:], s)
if len(s) == 0 {
return
}
oc, a := z.growNoAlloc(len(s))
if a {
z.growAlloc(len(s), oc)
}
copy(z.b[oc:], s)
}
func (z *bytesEncWriter) writen1(b1 byte) {
c := z.grow(1)
z.b[c] = b1
oc, a := z.growNoAlloc(1)
if a {
z.growAlloc(1, oc)
}
z.b[oc] = b1
}
func (z *bytesEncWriter) writen2(b1 byte, b2 byte) {
c := z.grow(2)
z.b[c] = b1
z.b[c+1] = b2
oc, a := z.growNoAlloc(2)
if a {
z.growAlloc(2, oc)
}
z.b[oc+1] = b2
z.b[oc] = b1
}
func (z *bytesEncWriter) atEndOfEncode() {
*(z.out) = z.b[:z.c]
}
func (z *bytesEncWriter) grow(n int) (oldcursor int) {
// have a growNoalloc(n int), which can be inlined.
// if allocation is needed, then call growAlloc(n int)
func (z *bytesEncWriter) growNoAlloc(n int) (oldcursor int, allocNeeded bool) {
oldcursor = z.c
z.c = oldcursor + n
z.c = z.c + n
if z.c > len(z.b) {
if z.c > cap(z.b) {
// appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls.
// bytes.Buffer model (2*cap + n): much better
// bs := make([]byte, 2*cap(z.b)+n)
bs := make([]byte, growCap(cap(z.b), 1, n))
copy(bs, z.b[:oldcursor])
z.b = bs
allocNeeded = true
} else {
z.b = z.b[:cap(z.b)]
}
@ -256,6 +293,15 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) {
return
}
func (z *bytesEncWriter) growAlloc(n int, oldcursor int) {
// appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls.
// bytes.Buffer model (2*cap + n): much better
// bs := make([]byte, 2*cap(z.b)+n)
bs := make([]byte, growCap(cap(z.b), 1, n))
copy(bs, z.b[:oldcursor])
z.b = bs
}
// ---------------------------------------------
type encFnInfo struct {
@ -270,6 +316,10 @@ func (f *encFnInfo) builtin(rv reflect.Value) {
f.e.e.EncodeBuiltin(f.ti.rtid, rv.Interface())
}
func (f *encFnInfo) raw(rv reflect.Value) {
f.e.raw(rv.Interface().(Raw))
}
func (f *encFnInfo) rawExt(rv reflect.Value) {
// rev := rv.Interface().(RawExt)
// f.e.e.EncodeRawExt(&rev, f.e)
@ -296,7 +346,7 @@ func (f *encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v
v = rv.Interface()
} else if indir == -1 {
// If a non-pointer was passed to Encode(), then that value is not addressable.
// Take addr if addresable, else copy value to an addressable value.
// Take addr if addressable, else copy value to an addressable value.
if rv.CanAddr() {
v = rv.Addr().Interface()
} else {
@ -464,7 +514,7 @@ func (f *encFnInfo) kSlice(rv reflect.Value) {
for j := 0; j < l; j++ {
if cr != nil {
if ti.mbs {
if l%2 == 0 {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
@ -503,7 +553,7 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
newlen := len(fti.sfi)
// Use sync.Pool to reduce allocating slices unnecessarily.
// The cost of the occasional locking is less than the cost of new allocation.
// The cost of sync.Pool is less than the cost of new allocation.
pool, poolv, fkvs := encStructPoolGet(newlen)
// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
@ -512,25 +562,20 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
}
newlen = 0
var kv stringRv
recur := e.h.RecursiveEmptyCheck
for _, si := range tisfi {
kv.r = si.field(rv, false)
// if si.i != -1 {
// rvals[newlen] = rv.Field(int(si.i))
// } else {
// rvals[newlen] = rv.FieldByIndex(si.is)
// }
if toMap {
if si.omitEmpty && isEmptyValue(kv.r) {
if si.omitEmpty && isEmptyValue(kv.r, recur, recur) {
continue
}
kv.v = si.encName
} else {
// use the zero value.
// if a reference or struct, set to nil (so you do not output too much)
if si.omitEmpty && isEmptyValue(kv.r) {
if si.omitEmpty && isEmptyValue(kv.r, recur, recur) {
switch kv.r.Kind() {
case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array,
reflect.Map, reflect.Slice:
case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
kv.r = reflect.Value{} //encode as nil
}
}
@ -541,7 +586,7 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
// debugf(">>>> kStruct: newlen: %v", newlen)
// sep := !e.be
ee := e.e //don't dereference everytime
ee := e.e //don't dereference every time
if toMap {
ee.EncodeMapStart(newlen)
@ -596,13 +641,15 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
// f.e.encodeValue(rv.Elem())
// }
func (f *encFnInfo) kInterface(rv reflect.Value) {
if rv.IsNil() {
f.e.e.EncodeNil()
return
}
f.e.encodeValue(rv.Elem(), nil)
}
// func (f *encFnInfo) kInterface(rv reflect.Value) {
// println("kInterface called")
// debug.PrintStack()
// if rv.IsNil() {
// f.e.e.EncodeNil()
// return
// }
// f.e.encodeValue(rv.Elem(), nil)
// }
func (f *encFnInfo) kMap(rv reflect.Value) {
ee := f.e.e
@ -877,6 +924,7 @@ type Encoder struct {
// as the handler MAY need to do some coordination.
w encWriter
s []encRtidFn
ci set
be bool // is binary encoding
js bool // is json handle
@ -925,7 +973,7 @@ func newEncoder(h Handle) *Encoder {
// Reset the Encoder with a new output stream.
//
// This accomodates using the state of the Encoder,
// This accommodates using the state of the Encoder,
// where it has "cached" information about sub-engines.
func (e *Encoder) Reset(w io.Writer) {
ww, ok := w.(ioEncWriterWriter)
@ -1032,20 +1080,6 @@ func (e *Encoder) MustEncode(v interface{}) {
e.w.atEndOfEncode()
}
// comment out these (Must)Write methods. They were only put there to support cbor.
// However, users already have access to the streams, and can write directly.
//
// // Write allows users write to the Encoder stream directly.
// func (e *Encoder) Write(bs []byte) (err error) {
// defer panicToErr(&err)
// e.w.writeb(bs)
// return
// }
// // MustWrite is like write, but panics if unable to Write.
// func (e *Encoder) MustWrite(bs []byte) {
// e.w.writeb(bs)
// }
func (e *Encoder) encode(iv interface{}) {
// if ics, ok := iv.(Selfer); ok {
// ics.CodecEncodeSelf(e)
@ -1057,7 +1091,8 @@ func (e *Encoder) encode(iv interface{}) {
e.e.EncodeNil()
case Selfer:
v.CodecEncodeSelf(e)
case Raw:
e.raw(v)
case reflect.Value:
e.encodeValue(v, nil)
@ -1133,20 +1168,23 @@ func (e *Encoder) encode(iv interface{}) {
}
}
func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) {
if rv, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed {
rt := rv.Type()
rtid := reflect.ValueOf(rt).Pointer()
fn := e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer)
fn.f(&fn.i, rv)
}
}
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) {
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) {
// use a goto statement instead of a recursive function for ptr/interface.
TOP:
switch rv.Kind() {
case reflect.Ptr, reflect.Interface:
case reflect.Ptr:
if rv.IsNil() {
e.e.EncodeNil()
return
}
rv = rv.Elem()
if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
// TODO: Movable pointers will be an issue here. Future problem.
sptr = rv.UnsafeAddr()
break TOP
}
goto TOP
case reflect.Interface:
if rv.IsNil() {
e.e.EncodeNil()
return
@ -1163,18 +1201,40 @@ TOP:
return
}
return rv, true
proceed = true
rv2 = rv
return
}
func (e *Encoder) doEncodeValue(rv reflect.Value, fn *encFn, sptr uintptr,
checkFastpath, checkCodecSelfer bool) {
if sptr != 0 {
if (&e.ci).add(sptr) {
e.errorf("circular reference found: # %d", sptr)
}
}
if fn == nil {
rt := rv.Type()
rtid := reflect.ValueOf(rt).Pointer()
// fn = e.getEncFn(rtid, rt, true, true)
fn = e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer)
}
fn.f(&fn.i, rv)
if sptr != 0 {
(&e.ci).remove(sptr)
}
}
func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) {
if rv, sptr, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed {
e.doEncodeValue(rv, nil, sptr, checkFastpath, checkCodecSelfer)
}
}
func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) {
// if a valid fn is passed, it MUST BE for the dereferenced type of rv
if rv, proceed := e.preEncodeValue(rv); proceed {
if fn == nil {
rt := rv.Type()
rtid := reflect.ValueOf(rt).Pointer()
fn = e.getEncFn(rtid, rt, true, true)
}
fn.f(&fn.i, rv)
if rv, sptr, proceed := e.preEncodeValue(rv); proceed {
e.doEncodeValue(rv, fn, sptr, true, true)
}
}
@ -1217,6 +1277,8 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo
if checkCodecSelfer && ti.cs {
fn.f = (*encFnInfo).selferMarshal
} else if rtid == rawTypId {
fn.f = (*encFnInfo).raw
} else if rtid == rawExtTypId {
fn.f = (*encFnInfo).rawExt
} else if e.e.IsBuiltinType(rtid) {
@ -1234,7 +1296,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo
} else {
rk := rt.Kind()
if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
if rt.PkgPath() == "" {
if rt.PkgPath() == "" { // un-named slice or map
if idx := fastpathAV.index(rtid); idx != -1 {
fn.f = fastpathAV[idx].encfn
}
@ -1284,10 +1346,11 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo
fn.f = (*encFnInfo).kSlice
case reflect.Struct:
fn.f = (*encFnInfo).kStruct
// reflect.Ptr and reflect.Interface are handled already by preEncodeValue
// case reflect.Ptr:
// fn.f = (*encFnInfo).kPtr
case reflect.Interface:
fn.f = (*encFnInfo).kInterface
// case reflect.Interface:
// fn.f = (*encFnInfo).kInterface
case reflect.Map:
fn.f = (*encFnInfo).kMap
default:
@ -1320,6 +1383,18 @@ func (e *Encoder) asis(v []byte) {
}
}
func (e *Encoder) raw(vv Raw) {
v := []byte(vv)
if !e.h.Raw {
e.errorf("Raw values cannot be encoded: %v", v)
}
if e.as == nil {
e.w.writeb(v)
} else {
e.as.EncodeAsis(v)
}
}
func (e *Encoder) errorf(format string, params ...interface{}) {
err := fmt.Errorf(format, params...)
panic(err)
@ -1353,25 +1428,6 @@ func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) {
// panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed
// }
// idxpool := newlen / 8
// if pool == nil {
// fkvs = make([]stringRv, newlen)
// } else {
// poolv = pool.Get()
// switch vv := poolv.(type) {
// case *[8]stringRv:
// fkvs = vv[:newlen]
// case *[16]stringRv:
// fkvs = vv[:newlen]
// case *[32]stringRv:
// fkvs = vv[:newlen]
// case *[64]stringRv:
// fkvs = vv[:newlen]
// case *[128]stringRv:
// fkvs = vv[:newlen]
// }
// }
if newlen <= 8 {
p = &encStructPool[0]
v = p.Get()

View File

@ -23,7 +23,7 @@ package codec
// Currently support
// - slice of all builtin types,
// - map of all builtin types to string or interface value
// - symetrical maps of all builtin types (e.g. str-str, uint8-uint8)
// - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
// This should provide adequate "typical" implementations.
//
// Note that fast track decode functions must handle values for which an address cannot be obtained.
@ -38,6 +38,8 @@ import (
"sort"
)
const fastpathEnabled = true
const fastpathCheckNilFalse = false // for reflect
const fastpathCheckNilTrue = true // for type switch
@ -81,9 +83,6 @@ var fastpathAV fastpathA
// due to possible initialization loop error, make fastpath in an init()
func init() {
if !fastpathEnabled {
return
}
i := 0
fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) {
xrt := reflect.TypeOf(v)
@ -373,9 +372,6 @@ func init() {
// -- -- fast path type switch
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
case []interface{}:
@ -1741,9 +1737,6 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
}
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
case []interface{}:
@ -1829,9 +1822,6 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
}
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
case map[interface{}]interface{}:
@ -3124,7 +3114,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
// -- -- fast path functions
func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) {
fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) {
ee := e.e
@ -3145,8 +3139,39 @@ func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
e.encode(v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) {
fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) {
ee := e.e
@ -3167,8 +3192,39 @@ func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceStringV(v []string, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeString(c_UTF8, v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) {
fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) {
ee := e.e
@ -3189,8 +3245,39 @@ func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeFloat32(v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) {
fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) {
ee := e.e
@ -3211,8 +3298,39 @@ func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeFloat64(v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) {
fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) {
ee := e.e
@ -3233,8 +3351,39 @@ func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceUintV(v []uint, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeUint(uint64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) {
fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) {
ee := e.e
@ -3255,8 +3404,39 @@ func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeUint(uint64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) {
fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) {
ee := e.e
@ -3277,8 +3457,39 @@ func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeUint(uint64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) {
fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) {
ee := e.e
@ -3299,8 +3510,39 @@ func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeUint(uint64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceUintptrR(rv reflect.Value) {
fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) {
ee := e.e
@ -3321,8 +3563,39 @@ func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
e.encode(v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) {
fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) {
ee := e.e
@ -3343,8 +3616,39 @@ func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceIntV(v []int, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeInt(int64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) {
fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) {
ee := e.e
@ -3365,8 +3669,39 @@ func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceInt8V(v []int8, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeInt(int64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) {
fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) {
ee := e.e
@ -3387,8 +3722,39 @@ func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceInt16V(v []int16, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeInt(int64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) {
fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) {
ee := e.e
@ -3409,8 +3775,39 @@ func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceInt32V(v []int32, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeInt(int64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) {
fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) {
ee := e.e
@ -3431,8 +3828,39 @@ func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceInt64V(v []int64, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeInt(int64(v2))
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) {
fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.EncAsMapSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) {
ee := e.e
@ -3453,6 +3881,33 @@ func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) {
}
}
func (_ fastpathT) EncAsMapSliceBoolV(v []bool, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
ee.EncodeBool(v2)
}
if cr != nil {
cr.sendContainerState(containerMapEnd)
}
}
func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) {
fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e)
}
@ -15489,9 +15944,6 @@ func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) {
// -- -- fast path type switch
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
case []interface{}:
@ -17712,7 +18164,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -17771,7 +18223,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]interface{}, 1, 4)
@ -17846,7 +18298,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -17905,7 +18357,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]string, 1, 4)
@ -17979,7 +18431,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18038,7 +18490,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]float32, 1, 4)
@ -18112,7 +18564,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18171,7 +18623,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]float64, 1, 4)
@ -18245,7 +18697,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18304,7 +18756,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]uint, 1, 4)
@ -18378,7 +18830,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18437,7 +18889,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]uint16, 1, 4)
@ -18511,7 +18963,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18570,7 +19022,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]uint32, 1, 4)
@ -18644,7 +19096,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18703,7 +19155,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]uint64, 1, 4)
@ -18777,7 +19229,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18836,7 +19288,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool,
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]uintptr, 1, 4)
@ -18910,7 +19362,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -18969,7 +19421,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]int, 1, 4)
@ -19043,7 +19495,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -19102,7 +19554,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]int8, 1, 4)
@ -19176,7 +19628,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -19235,7 +19687,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]int16, 1, 4)
@ -19309,7 +19761,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -19368,7 +19820,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]int32, 1, 4)
@ -19442,7 +19894,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -19501,7 +19953,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]int64, 1, 4)
@ -19575,7 +20027,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -19634,7 +20086,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]bool, 1, 4)

View File

@ -23,7 +23,7 @@ package codec
// Currently support
// - slice of all builtin types,
// - map of all builtin types to string or interface value
// - symetrical maps of all builtin types (e.g. str-str, uint8-uint8)
// - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
// This should provide adequate "typical" implementations.
//
// Note that fast track decode functions must handle values for which an address cannot be obtained.
@ -38,6 +38,8 @@ import (
"sort"
)
const fastpathEnabled = true
const fastpathCheckNilFalse = false // for reflect
const fastpathCheckNilTrue = true // for type switch
@ -81,9 +83,6 @@ var fastpathAV fastpathA
// due to possible initialization loop error, make fastpath in an init()
func init() {
if !fastpathEnabled {
return
}
i := 0
fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) {
xrt := reflect.TypeOf(v)
@ -106,9 +105,6 @@ func init() {
// -- -- fast path type switch
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case []{{ .Elem }}:{{else}}
@ -126,9 +122,6 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
}
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case []{{ .Elem }}:
@ -144,9 +137,6 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
}
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
case map[{{ .MapKey }}]{{ .Elem }}:
@ -165,7 +155,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e)
if f.ti.mbs {
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e)
} else {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e)
}
}
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) {
ee := e.e
@ -182,6 +176,31 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil b
if cr != nil { cr.sendContainerState(containerArrayEnd) }{{/* ee.EncodeEnd() */}}
}
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) {
ee := e.e
cr := e.cr
if checkNil && v == nil {
ee.EncodeNil()
return
}
if len(v)%2 == 1 {
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
return
}
ee.EncodeMapStart(len(v) / 2)
for j, v2 := range v {
if cr != nil {
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
}
{{ encmd .Elem "v2"}}
}
if cr != nil { cr.sendContainerState(containerMapEnd) }
}
{{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
@ -257,9 +276,6 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele
// -- -- fast path type switch
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case []{{ .Elem }}:{{else}}
@ -328,7 +344,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b
changed = true
}
slh.End()
return
return v, changed
}
if containerLenS > 0 {
@ -391,7 +407,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b
changed = true
}
slh.End()
return
return v, changed
}
if cap(v) == 0 {
v = make([]{{ .Elem }}, 1, 4)

View File

@ -4,6 +4,8 @@ package codec
import "reflect"
const fastpathEnabled = false
// The generated fast-path code is very large, and adds a few seconds to the build time.
// This causes test execution, execution of small tools which use codec, etc
// to take a long time.

View File

@ -1,6 +1,7 @@
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
var {{var "c"}} bool {{/* // changed */}}
_ = {{var "c"}}{{end}}
if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{}
@ -26,6 +27,8 @@ if {{var "l"}} == 0 {
}
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
_, _ = {{var "rl"}}, {{var "rt"}}
{{var "rr"}} = {{var "l"}} // len({{var "v"}})
if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
{{ else }}{{if not .Immutable }}

View File

@ -1,4 +1,4 @@
// //+build ignore
/* // +build ignore */
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
@ -17,7 +17,7 @@ import (
// This file is used to generate helper code for codecgen.
// The values here i.e. genHelper(En|De)coder are not to be used directly by
// library users. They WILL change continously and without notice.
// library users. They WILL change continuously and without notice.
//
// To help enforce this, we create an unexported type with exported members.
// The only way to get the type is via the one exported type that we control (somewhat).
@ -83,6 +83,11 @@ func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
f.e.marshal(bs, fnerr, false, c_RAW)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncRaw(iv Raw) {
f.e.raw(iv)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
if _, ok := f.e.hh.(*BincHandle); ok {
@ -191,6 +196,11 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
}
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecRaw() []byte {
return f.d.raw()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
if _, ok := f.d.hh.(*BincHandle); ok {

View File

@ -1,4 +1,4 @@
// //+build ignore
/* // +build ignore */
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
@ -17,7 +17,7 @@ import (
// This file is used to generate helper code for codecgen.
// The values here i.e. genHelper(En|De)coder are not to be used directly by
// library users. They WILL change continously and without notice.
// library users. They WILL change continuously and without notice.
//
// To help enforce this, we create an unexported type with exported members.
// The only way to get the type is via the one exported type that we control (somewhat).
@ -79,6 +79,10 @@ func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
f.e.marshal(bs, fnerr, false, c_RAW)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncRaw(iv Raw) {
f.e.raw(iv)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
if _, ok := f.e.hh.(*BincHandle); ok {
return timeTypId
@ -172,6 +176,10 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
}
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecRaw() []byte {
return f.d.raw()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
if _, ok := f.d.hh.(*BincHandle); ok {
return timeTypId

View File

@ -68,8 +68,9 @@ z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
const genDecListTmpl = `
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
var {{var "c"}} bool {{/* // changed */}}
_ = {{var "c"}}{{end}}
if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{}
@ -95,6 +96,8 @@ if {{var "l"}} == 0 {
}
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
_, _ = {{var "rl"}}, {{var "rt"}}
{{var "rr"}} = {{var "l"}} // len({{var "v"}})
if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
{{ else }}{{if not .Immutable }}

View File

@ -12,7 +12,6 @@ import (
"io"
"io/ioutil"
"math/rand"
"os"
"reflect"
"regexp"
"sort"
@ -21,11 +20,14 @@ import (
"sync"
"text/template"
"time"
"unicode"
"unicode/utf8"
)
// ---------------------------------------------------
// codecgen supports the full cycle of reflection-based codec:
// - RawExt
// - Raw
// - Builtins
// - Extensions
// - (Binary|Text|JSON)(Unm|M)arshal
@ -76,7 +78,7 @@ import (
// codecgen will panic if the file was generated with an old version of the library in use.
//
// Note:
// It was a concious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
// It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
// This way, there isn't a function call overhead just to see that we should not enter a block of code.
// GenVersion is the current version of codecgen.
@ -124,6 +126,7 @@ var (
genExpectArrayOrMapErr = errors.New("unexpected type. Expecting array/map/slice")
genBase64enc = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
genCheckVendor bool
)
// genRunner holds some state used during a Gen run.
@ -162,6 +165,10 @@ type genRunner struct {
//
// Library users: *DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.*
func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeInfos, typ ...reflect.Type) {
// All types passed to this method do not have a codec.Selfer method implemented directly.
// codecgen already checks the AST and skips any types that define the codec.Selfer methods.
// Consequently, there's no need to check and trim them if they implement codec.Selfer
if len(typ) == 0 {
return
}
@ -199,7 +206,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
x.genRefPkgs(t)
}
if buildTags != "" {
x.line("//+build " + buildTags)
x.line("// +build " + buildTags)
x.line("")
}
x.line(`
@ -266,6 +273,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
x.line("type " + x.hn + " struct{}")
x.line("")
x.varsfxreset()
x.line("func init() {")
x.linef("if %sGenVersion != %v {", x.cpfx, GenVersion)
x.line("_, file, _, _ := runtime.Caller(0)")
@ -309,6 +317,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
for _, t := range x.ts {
rtid := reflect.ValueOf(t).Pointer()
// generate enc functions for all these slice/map types.
x.varsfxreset()
x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
x.genRequiredMethodVars(true)
switch t.Kind() {
@ -323,6 +332,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
x.line("")
// generate dec functions for all these slice/map types.
x.varsfxreset()
x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx)
x.genRequiredMethodVars(false)
switch t.Kind() {
@ -377,7 +387,7 @@ func (x *genRunner) genRefPkgs(t reflect.Type) {
x.imn[tpkg] = tpkg
} else {
x.imc++
x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + tpkg[idx+1:]
x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
}
}
}
@ -408,6 +418,10 @@ func (x *genRunner) varsfx() string {
return strconv.FormatUint(x.c, 10)
}
func (x *genRunner) varsfxreset() {
x.c = 0
}
func (x *genRunner) out(s string) {
if _, err := io.WriteString(x.w, s); err != nil {
panic(err)
@ -494,6 +508,7 @@ func (x *genRunner) selfer(encode bool) {
// always make decode use a pointer receiver,
// and structs always use a ptr receiver (encode|decode)
isptr := !encode || t.Kind() == reflect.Struct
x.varsfxreset()
fnSigPfx := "func (x "
if isptr {
fnSigPfx += "*"
@ -566,9 +581,28 @@ func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) {
} else {
x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname)
}
if _, ok := x.tm[t]; !ok {
x.tm[t] = struct{}{}
x.ts = append(x.ts, t)
x.registerXtraT(t)
}
func (x *genRunner) registerXtraT(t reflect.Type) {
// recursively register the types
if _, ok := x.tm[t]; ok {
return
}
var tkey reflect.Type
switch t.Kind() {
case reflect.Chan, reflect.Slice, reflect.Array:
case reflect.Map:
tkey = t.Key()
default:
return
}
x.tm[t] = struct{}{}
x.ts = append(x.ts, t)
// check if this refers to any xtra types eg. a slice of array: add the array
x.registerXtraT(t.Elem())
if tkey != nil {
x.registerXtraT(tkey)
}
}
@ -608,22 +642,33 @@ func (x *genRunner) encVar(varname string, t reflect.Type) {
}
// enc will encode a variable (varname) of type T,
// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying)
// enc will encode a variable (varname) of type t,
// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying)
func (x *genRunner) enc(varname string, t reflect.Type) {
// varName here must be to a pointer to a struct/array, or to a value directly.
rtid := reflect.ValueOf(t).Pointer()
// We call CodecEncodeSelf if one of the following are honored:
// - the type already implements Selfer, call that
// - the type has a Selfer implementation just created, use that
// - the type is in the list of the ones we will generate for, but it is not currently being generated
mi := x.varsfx()
tptr := reflect.PtrTo(t)
tk := t.Kind()
if x.checkForSelfer(t, varname) {
if t.Implements(selferTyp) || (tptr.Implements(selferTyp) && (tk == reflect.Array || tk == reflect.Struct)) {
x.line(varname + ".CodecEncodeSelf(e)")
return
if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
x.line(varname + ".CodecEncodeSelf(e)")
return
}
} else { // varname is of type T
if t.Implements(selferTyp) {
x.line(varname + ".CodecEncodeSelf(e)")
return
} else if tptr.Implements(selferTyp) {
x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname)
x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
return
}
}
if _, ok := x.te[rtid]; ok {
@ -651,14 +696,17 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
}
// check if
// - type is RawExt
// - type is RawExt, Raw
// - the type implements (Text|JSON|Binary)(Unm|M)arshal
mi := x.varsfx()
x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi)
x.linef("_ = %sm%s", genTempVarPfx, mi)
x.line("if false {") //start if block
defer func() { x.line("}") }() //end if block
if t == rawTyp {
x.linef("} else { z.EncRaw(%v)", varname)
return
}
if t == rawExtTyp {
x.linef("} else { r.EncodeRawExt(%v, e)", varname)
return
@ -676,15 +724,31 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
// first check if extensions are configued, before doing the interface conversion
x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname)
}
if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T
if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
}
if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
} else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
}
} else { // varname is of type T
if t.Implements(binaryMarshalerTyp) {
x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname)
} else if tptr.Implements(binaryMarshalerTyp) {
x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname)
}
if t.Implements(jsonMarshalerTyp) {
x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
} else if tptr.Implements(jsonMarshalerTyp) {
x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname)
} else if t.Implements(textMarshalerTyp) {
x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
} else if tptr.Implements(textMarshalerTyp) {
x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname)
}
}
if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname)
} else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname)
}
x.line("} else {")
switch t.Kind() {
@ -922,6 +986,14 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
}
func (x *genRunner) encListFallback(varname string, t reflect.Type) {
if t.AssignableTo(uint8SliceTyp) {
x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, []byte(%s))", x.xs, varname)
return
}
if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
x.linef("r.EncodeStringBytes(codecSelferC_RAW%s, ([%v]byte(%s))[:])", x.xs, t.Len(), varname)
return
}
i := x.varsfx()
g := genTempVarPfx
x.line("r.EncodeArrayStart(len(" + varname + "))")
@ -1020,6 +1092,8 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) {
}
}
// dec will decode a variable (varname) of type ptrTo(t).
// t is always a basetype (i.e. not of kind reflect.Ptr).
func (x *genRunner) dec(varname string, t reflect.Type) {
// assumptions:
// - the varname is to a pointer already. No need to take address of it
@ -1056,7 +1130,7 @@ func (x *genRunner) dec(varname string, t reflect.Type) {
}
// check if
// - type is RawExt
// - type is Raw, RawExt
// - the type implements (Text|JSON|Binary)(Unm|M)arshal
mi := x.varsfx()
x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi)
@ -1064,6 +1138,10 @@ func (x *genRunner) dec(varname string, t reflect.Type) {
x.line("if false {") //start if block
defer func() { x.line("}") }() //end if block
if t == rawTyp {
x.linef("} else { *%v = z.DecRaw()", varname)
return
}
if t == rawExtTyp {
x.linef("} else { r.DecodeExt(%v, 0, nil)", varname)
return
@ -1189,59 +1267,49 @@ func (x *genRunner) dec(varname string, t reflect.Type) {
}
func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAsPtr bool) {
// We have to use the actual type name when doing a direct assignment.
// We don't have the luxury of casting the pointer to the underlying type.
//
// Consequently, in the situation of a
// type Message int32
// var x Message
// var i int32 = 32
// x = i // this will bomb
// x = Message(i) // this will work
// *((*int32)(&x)) = i // this will work
//
// Consequently, we replace:
// case reflect.Uint32: x.line(varname + " = uint32(r.DecodeUint(32))")
// with:
// case reflect.Uint32: x.line(varname + " = " + genTypeNamePrim(t, x.tc) + "(r.DecodeUint(32))")
// This should only be used for exact primitives (ie un-named types).
// Named types may be implementations of Selfer, Unmarshaler, etc.
// They should be handled by dec(...)
xfn := func(t reflect.Type) string {
return x.genTypeNamePrim(t)
if t.Name() != "" {
tryAsPtr = true
return
}
switch t.Kind() {
case reflect.Int:
x.linef("%s = %s(r.DecodeInt(codecSelferBitsize%s))", varname, xfn(t), x.xs)
x.linef("%s = r.DecodeInt(codecSelferBitsize%s)", varname, x.xs)
case reflect.Int8:
x.linef("%s = %s(r.DecodeInt(8))", varname, xfn(t))
x.linef("%s = r.DecodeInt(8)", varname)
case reflect.Int16:
x.linef("%s = %s(r.DecodeInt(16))", varname, xfn(t))
x.linef("%s = r.DecodeInt(16)", varname)
case reflect.Int32:
x.linef("%s = %s(r.DecodeInt(32))", varname, xfn(t))
x.linef("%s = r.DecodeInt(32)", varname)
case reflect.Int64:
x.linef("%s = %s(r.DecodeInt(64))", varname, xfn(t))
x.linef("%s = r.DecodeInt(64)", varname)
case reflect.Uint:
x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs)
x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs)
case reflect.Uint8:
x.linef("%s = %s(r.DecodeUint(8))", varname, xfn(t))
x.linef("%s = r.DecodeUint(8)", varname)
case reflect.Uint16:
x.linef("%s = %s(r.DecodeUint(16))", varname, xfn(t))
x.linef("%s = r.DecodeUint(16)", varname)
case reflect.Uint32:
x.linef("%s = %s(r.DecodeUint(32))", varname, xfn(t))
x.linef("%s = r.DecodeUint(32)", varname)
case reflect.Uint64:
x.linef("%s = %s(r.DecodeUint(64))", varname, xfn(t))
x.linef("%s = r.DecodeUint(64)", varname)
case reflect.Uintptr:
x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs)
x.linef("%s = r.DecodeUint(codecSelferBitsize%s)", varname, x.xs)
case reflect.Float32:
x.linef("%s = %s(r.DecodeFloat(true))", varname, xfn(t))
x.linef("%s = r.DecodeFloat(true)", varname)
case reflect.Float64:
x.linef("%s = %s(r.DecodeFloat(false))", varname, xfn(t))
x.linef("%s = r.DecodeFloat(false)", varname)
case reflect.Bool:
x.linef("%s = %s(r.DecodeBool())", varname, xfn(t))
x.linef("%s = r.DecodeBool()", varname)
case reflect.String:
x.linef("%s = %s(r.DecodeString())", varname, xfn(t))
x.linef("%s = r.DecodeString()", varname)
default:
tryAsPtr = true
}
@ -1249,6 +1317,14 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs
}
func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
if t.AssignableTo(uint8SliceTyp) {
x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false, false)")
return
}
if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
x.linef("r.DecodeBytes( ((*[%s]byte)(%s))[:], false, true)", t.Len(), varname)
return
}
type tstruc struct {
TempVar string
Rand string
@ -1364,7 +1440,7 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt
if si.i != -1 {
t2 = t.Field(int(si.i))
} else {
//we must accomodate anonymous fields, where the embedded field is a nil pointer in the value.
//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
// t2 = t.FieldByIndex(si.is)
t2typ := t
varname3 := varname
@ -1452,7 +1528,7 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid
if si.i != -1 {
t2 = t.Field(int(si.i))
} else {
//we must accomodate anonymous fields, where the embedded field is a nil pointer in the value.
//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
// t2 = t.FieldByIndex(si.is)
t2typ := t
varname3 := varname
@ -1569,8 +1645,6 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string {
}
var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise.
//
// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled,
@ -1592,6 +1666,26 @@ func genImportPath(t reflect.Type) (s string) {
return
}
// A go identifier is (letter|_)[letter|number|_]*
func genGoIdentifier(s string, checkFirstChar bool) string {
b := make([]byte, 0, len(s))
t := make([]byte, 4)
var n int
for i, r := range s {
if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
b = append(b, '_')
}
// r must be unicode_letter, unicode_digit or _
if unicode.IsLetter(r) || unicode.IsDigit(r) {
n = utf8.EncodeRune(t, r)
b = append(b, t[:n]...)
} else {
b = append(b, '_')
}
}
return string(b)
}
func genNonPtr(t reflect.Type) reflect.Type {
for t.Kind() == reflect.Ptr {
t = t.Elem()
@ -1601,7 +1695,7 @@ func genNonPtr(t reflect.Type) reflect.Type {
func genTitleCaseName(s string) string {
switch s {
case "interface{}":
case "interface{}", "interface {}":
return "Intf"
default:
return strings.ToUpper(s[0:1]) + s[1:]
@ -1704,7 +1798,7 @@ func (x genInternal) FastpathLen() (l int) {
func genInternalZeroValue(s string) string {
switch s {
case "interface{}":
case "interface{}", "interface {}":
return "nil"
case "bool":
return "false"
@ -1856,7 +1950,7 @@ func genInternalInit() {
}
var gt genInternal
// For each slice or map type, there must be a (symetrical) Encode and Decode fast-path function
// For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function
for _, s := range types {
gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]})
if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.

View File

@ -0,0 +1,12 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.5,!go1.6
package codec
import "os"
func init() {
genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
}

View File

@ -0,0 +1,12 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.6
package codec
import "os"
func init() {
genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
}

View File

@ -0,0 +1,10 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.7
package codec
func init() {
genCheckVendor = true
}

View File

@ -38,10 +38,6 @@ package codec
// a length prefix, or if it used explicit breaks. If length-prefixed, we assume that
// it has to be binary, and we do not even try to read separators.
//
// The only codec that may suffer (slightly) is cbor, and only when decoding indefinite-length.
// It may suffer because we treat it like a text-based codec, and read separators.
// However, this read is a no-op and the cost is insignificant.
//
// Philosophy
// ------------
// On decode, this codec will update containers appropriately:
@ -137,17 +133,6 @@ const (
// Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic.
recoverPanicToErr = true
// Fast path functions try to create a fast path encode or decode implementation
// for common maps and slices, by by-passing reflection altogether.
fastpathEnabled = true
// if checkStructForEmptyValue, check structs fields to see if an empty value.
// This could be an expensive call, so possibly disable it.
checkStructForEmptyValue = false
// if derefForIsEmptyValue, deref pointers and interfaces when checking isEmptyValue
derefForIsEmptyValue = false
// if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first.
// Only concern is that, if the slice already contained some garbage, we will decode into that garbage.
// The chances of this are slim, so leave this "optimization".
@ -155,8 +140,10 @@ const (
resetSliceElemToZeroValue bool = false
)
var oneByteArr = [1]byte{0}
var zeroByteSlice = oneByteArr[:0:0]
var (
oneByteArr = [1]byte{0}
zeroByteSlice = oneByteArr[:0:0]
)
type charEncoding uint8
@ -215,6 +202,41 @@ const (
containerArrayEnd
)
// sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo
type sfiIdx struct {
name string
index int
}
// do not recurse if a containing type refers to an embedded type
// which refers back to its containing type (via a pointer).
// The second time this back-reference happens, break out,
// so as not to cause an infinite loop.
const rgetMaxRecursion = 2
// Anecdotally, we believe most types have <= 12 fields.
// Java's PMD rules set TooManyFields threshold to 15.
const rgetPoolTArrayLen = 12
type rgetT struct {
fNames []string
encNames []string
etypes []uintptr
sfis []*structFieldInfo
}
type rgetPoolT struct {
fNames [rgetPoolTArrayLen]string
encNames [rgetPoolTArrayLen]string
etypes [rgetPoolTArrayLen]uintptr
sfis [rgetPoolTArrayLen]*structFieldInfo
sfiidx [rgetPoolTArrayLen]sfiIdx
}
var rgetPool = sync.Pool{
New: func() interface{} { return new(rgetPoolT) },
}
type containerStateRecv interface {
sendContainerState(containerState)
}
@ -240,6 +262,7 @@ var (
stringTyp = reflect.TypeOf("")
timeTyp = reflect.TypeOf(time.Time{})
rawExtTyp = reflect.TypeOf(RawExt{})
rawTyp = reflect.TypeOf(Raw{})
uint8SliceTyp = reflect.TypeOf([]uint8(nil))
mapBySliceTyp = reflect.TypeOf((*MapBySlice)(nil)).Elem()
@ -257,6 +280,7 @@ var (
uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer()
rawExtTypId = reflect.ValueOf(rawExtTyp).Pointer()
rawTypId = reflect.ValueOf(rawTyp).Pointer()
intfTypId = reflect.ValueOf(intfTyp).Pointer()
timeTypId = reflect.ValueOf(timeTyp).Pointer()
stringTypId = reflect.ValueOf(stringTyp).Pointer()
@ -337,6 +361,11 @@ type Handle interface {
isBinary() bool
}
// Raw represents raw formatted bytes.
// We "blindly" store it during encode and store the raw bytes during decode.
// Note: it is dangerous during encode, so we may gate the behaviour behind an Encode flag which must be explicitly set.
type Raw []byte
// RawExt represents raw unprocessed extension data.
// Some codecs will decode extension data as a *RawExt if there is no registered extension for the tag.
//
@ -347,7 +376,7 @@ type RawExt struct {
// Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types
Data []byte
// Value represents the extension, if Data is nil.
// Value is used by codecs (e.g. cbor) which use the format to do custom serialization of the types.
// Value is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types.
Value interface{}
}
@ -525,7 +554,7 @@ func (o *extHandle) AddExt(
func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) {
// o is a pointer, because we may need to initialize it
if rt.PkgPath() == "" || rt.Kind() == reflect.Interface {
err = fmt.Errorf("codec.Handle.AddExt: Takes named type, especially not a pointer or interface: %T",
err = fmt.Errorf("codec.Handle.AddExt: Takes named type, not a pointer or interface: %T",
reflect.Zero(rt).Interface())
return
}
@ -568,7 +597,8 @@ func (o extHandle) getExtForTag(tag uint64) *extTypeTagFn {
}
type structFieldInfo struct {
encName string // encode name
encName string // encode name
fieldName string // field name
// only one of 'i' or 'is' can be set. If 'i' is -1, then 'is' has been set.
@ -714,6 +744,7 @@ type typeInfo struct {
}
func (ti *typeInfo) indexForEncName(name string) int {
// NOTE: name may be a stringView, so don't pass it to another function.
//tisfi := ti.sfi
const binarySearchThreshold = 16
if sfilen := len(ti.sfi); sfilen < binarySearchThreshold {
@ -828,19 +859,19 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
}
if rt.Kind() == reflect.Struct {
var siInfo *structFieldInfo
var omitEmpty bool
if f, ok := rt.FieldByName(structInfoFieldName); ok {
siInfo = parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag))
siInfo := parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag))
ti.toArray = siInfo.toArray
omitEmpty = siInfo.omitEmpty
}
sfip := make([]*structFieldInfo, 0, rt.NumField())
x.rget(rt, nil, make(map[string]bool, 16), &sfip, siInfo)
ti.sfip = make([]*structFieldInfo, len(sfip))
ti.sfi = make([]*structFieldInfo, len(sfip))
copy(ti.sfip, sfip)
sort.Sort(sfiSortedByEncName(sfip))
copy(ti.sfi, sfip)
pi := rgetPool.Get()
pv := pi.(*rgetPoolT)
pv.etypes[0] = ti.baseId
vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
x.rget(rt, rtid, omitEmpty, nil, &vv)
ti.sfip, ti.sfi = rgetResolveSFI(vv.sfis, pv.sfiidx[:0])
rgetPool.Put(pi)
}
// sfi = sfip
@ -853,17 +884,30 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
return
}
func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool,
sfi *[]*structFieldInfo, siInfo *structFieldInfo,
func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool,
indexstack []int, pv *rgetT,
) {
for j := 0; j < rt.NumField(); j++ {
// Read up fields and store how to access the value.
//
// It uses go's rules for message selectors,
// which say that the field with the shallowest depth is selected.
//
// Note: we consciously use slices, not a map, to simulate a set.
// Typically, types have < 16 fields,
// and iteration using equals is faster than maps there
LOOP:
for j, jlen := 0, rt.NumField(); j < jlen; j++ {
f := rt.Field(j)
fkind := f.Type.Kind()
// skip if a func type, or is unexported, or structTag value == "-"
if fkind == reflect.Func {
continue
switch fkind {
case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:
continue LOOP
}
// if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) {
// if r1, _ := utf8.DecodeRuneInString(f.Name);
// r1 == utf8.RuneError || !unicode.IsUpper(r1) {
if f.PkgPath != "" && !f.Anonymous { // unexported, not embedded
continue
}
@ -872,7 +916,8 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st
continue
}
var si *structFieldInfo
// if anonymous and no struct tag (or it's blank), and a struct (or pointer to struct), inline it.
// if anonymous and no struct tag (or it's blank),
// and a struct (or pointer to struct), inline it.
if f.Anonymous && fkind != reflect.Interface {
doInline := stag == ""
if !doInline {
@ -886,11 +931,31 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st
ft = ft.Elem()
}
if ft.Kind() == reflect.Struct {
indexstack2 := make([]int, len(indexstack)+1, len(indexstack)+4)
copy(indexstack2, indexstack)
indexstack2[len(indexstack)] = j
// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
x.rget(ft, indexstack2, fnameToHastag, sfi, siInfo)
// if etypes contains this, don't call rget again (as fields are already seen here)
ftid := reflect.ValueOf(ft).Pointer()
// We cannot recurse forever, but we need to track other field depths.
// So - we break if we see a type twice (not the first time).
// This should be sufficient to handle an embedded type that refers to its
// owning type, which then refers to its embedded type.
processIt := true
numk := 0
for _, k := range pv.etypes {
if k == ftid {
numk++
if numk == rgetMaxRecursion {
processIt = false
break
}
}
}
if processIt {
pv.etypes = append(pv.etypes, ftid)
indexstack2 := make([]int, len(indexstack)+1)
copy(indexstack2, indexstack)
indexstack2[len(indexstack)] = j
// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
x.rget(ft, ftid, omitEmpty, indexstack2, pv)
}
continue
}
}
@ -901,36 +966,86 @@ func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[st
continue
}
// do not let fields with same name in embedded structs override field at higher level.
// this must be done after anonymous check, to allow anonymous field
// still include their child fields
if _, ok := fnameToHastag[f.Name]; ok {
continue
}
if f.Name == "" {
panic(noFieldNameToStructFieldInfoErr)
}
pv.fNames = append(pv.fNames, f.Name)
if si == nil {
si = parseStructFieldInfo(f.Name, stag)
} else if si.encName == "" {
si.encName = f.Name
}
si.fieldName = f.Name
pv.encNames = append(pv.encNames, si.encName)
// si.ikind = int(f.Type.Kind())
if len(indexstack) == 0 {
si.i = int16(j)
} else {
si.i = -1
si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
si.is = make([]int, len(indexstack)+1)
copy(si.is, indexstack)
si.is[len(indexstack)] = j
// si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
}
if siInfo != nil {
if siInfo.omitEmpty {
si.omitEmpty = true
if omitEmpty {
si.omitEmpty = true
}
pv.sfis = append(pv.sfis, si)
}
}
// resolves the struct field info got from a call to rget.
// Returns a trimmed, unsorted and sorted []*structFieldInfo.
func rgetResolveSFI(x []*structFieldInfo, pv []sfiIdx) (y, z []*structFieldInfo) {
var n int
for i, v := range x {
xn := v.encName //TODO: fieldName or encName? use encName for now.
var found bool
for j, k := range pv {
if k.name == xn {
// one of them must be reset to nil, and the index updated appropriately to the other one
if len(v.is) == len(x[k.index].is) {
} else if len(v.is) < len(x[k.index].is) {
pv[j].index = i
if x[k.index] != nil {
x[k.index] = nil
n++
}
} else {
if x[i] != nil {
x[i] = nil
n++
}
}
found = true
break
}
}
*sfi = append(*sfi, si)
fnameToHastag[f.Name] = stag != ""
if !found {
pv = append(pv, sfiIdx{xn, i})
}
}
// remove all the nils
y = make([]*structFieldInfo, len(x)-n)
n = 0
for _, v := range x {
if v == nil {
continue
}
y[n] = v
n++
}
z = make([]*structFieldInfo, len(y))
copy(z, y)
sort.Sort(sfiSortedByEncName(z))
return
}
func panicToErr(err *error) {
@ -1127,3 +1242,73 @@ type bytesISlice []bytesI
func (p bytesISlice) Len() int { return len(p) }
func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
func (p bytesISlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// -----------------
type set []uintptr
func (s *set) add(v uintptr) (exists bool) {
// e.ci is always nil, or len >= 1
// defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Add: %v, exists: %v\n", v, exists) }()
x := *s
if x == nil {
x = make([]uintptr, 1, 8)
x[0] = v
*s = x
return
}
// typically, length will be 1. make this perform.
if len(x) == 1 {
if j := x[0]; j == 0 {
x[0] = v
} else if j == v {
exists = true
} else {
x = append(x, v)
*s = x
}
return
}
// check if it exists
for _, j := range x {
if j == v {
exists = true
return
}
}
// try to replace a "deleted" slot
for i, j := range x {
if j == 0 {
x[i] = v
return
}
}
// if unable to replace deleted slot, just append it.
x = append(x, v)
*s = x
return
}
func (s *set) remove(v uintptr) (exists bool) {
// defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Rm: %v, exists: %v\n", v, exists) }()
x := *s
if len(x) == 0 {
return
}
if len(x) == 1 {
if x[0] == v {
x[0] = 0
}
return
}
for i, j := range x {
if j == v {
exists = true
x[i] = 0 // set it to 0, as way to delete it.
// copy(x[i:], x[i+1:])
// x = x[:len(x)-1]
return
}
}
return
}

View File

@ -70,8 +70,8 @@ func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
return false
}
func isEmptyValue(v reflect.Value) bool {
return hIsEmptyValue(v, derefForIsEmptyValue, checkStructForEmptyValue)
func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
return hIsEmptyValue(v, deref, checkStruct)
}
func pruneSignExt(v []byte, pos bool) (n int) {

View File

@ -1,4 +1,4 @@
//+build !unsafe
// +build !unsafe
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.

View File

@ -1,4 +1,4 @@
//+build unsafe
// +build unsafe
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
@ -16,7 +16,7 @@ type unsafeString struct {
Len int
}
type unsafeBytes struct {
type unsafeSlice struct {
Data uintptr
Len int
Cap int
@ -29,8 +29,10 @@ func stringView(v []byte) string {
if len(v) == 0 {
return ""
}
x := unsafeString{uintptr(unsafe.Pointer(&v[0])), len(v)}
return *(*string)(unsafe.Pointer(&x))
bx := (*unsafeSlice)(unsafe.Pointer(&v))
sx := unsafeString{bx.Data, bx.Len}
return *(*string)(unsafe.Pointer(&sx))
}
// bytesView returns a view of the string as a []byte.
@ -40,6 +42,8 @@ func bytesView(v string) []byte {
if len(v) == 0 {
return zeroByteSlice
}
x := unsafeBytes{uintptr(unsafe.Pointer(&v)), len(v), len(v)}
return *(*[]byte)(unsafe.Pointer(&x))
sx := (*unsafeString)(unsafe.Pointer(&v))
bx := unsafeSlice{sx.Data, sx.Len, sx.Len}
return *(*[]byte)(unsafe.Pointer(&bx))
}

View File

@ -43,18 +43,23 @@ import (
//--------------------------------
var jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'}
var (
jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'}
var jsonFloat64Pow10 = [...]float64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22,
}
jsonFloat64Pow10 = [...]float64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22,
}
var jsonUint64Pow10 = [...]uint64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
}
jsonUint64Pow10 = [...]uint64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
}
// jsonTabs and jsonSpaces are used as caches for indents
jsonTabs, jsonSpaces string
)
const (
// jsonUnreadAfterDecNum controls whether we unread after decoding a number.
@ -85,8 +90,23 @@ const (
jsonNumUintMaxVal = 1<<uint64(64) - 1
// jsonNumDigitsUint64Largest = 19
jsonSpacesOrTabsLen = 128
)
func init() {
var bs [jsonSpacesOrTabsLen]byte
for i := 0; i < jsonSpacesOrTabsLen; i++ {
bs[i] = ' '
}
jsonSpaces = string(bs[:])
for i := 0; i < jsonSpacesOrTabsLen; i++ {
bs[i] = '\t'
}
jsonTabs = string(bs[:])
}
type jsonEncDriver struct {
e *Encoder
w encWriter
@ -94,30 +114,76 @@ type jsonEncDriver struct {
b [64]byte // scratch
bs []byte // scratch
se setExtWrapper
ds string // indent string
dl uint16 // indent level
dt bool // indent using tabs
d bool // indent
c containerState
noBuiltInTypes
}
// indent is done as below:
// - newline and indent are added before each mapKey or arrayElem
// - newline and indent are added before each ending,
// except there was no entry (so we can have {} or [])
func (e *jsonEncDriver) sendContainerState(c containerState) {
// determine whether to output separators
if c == containerMapKey {
if e.c != containerMapStart {
e.w.writen1(',')
}
if e.d {
e.writeIndent()
}
} else if c == containerMapValue {
e.w.writen1(':')
if e.d {
e.w.writen2(':', ' ')
} else {
e.w.writen1(':')
}
} else if c == containerMapEnd {
if e.d {
e.dl--
if e.c != containerMapStart {
e.writeIndent()
}
}
e.w.writen1('}')
} else if c == containerArrayElem {
if e.c != containerArrayStart {
e.w.writen1(',')
}
if e.d {
e.writeIndent()
}
} else if c == containerArrayEnd {
if e.d {
e.dl--
if e.c != containerArrayStart {
e.writeIndent()
}
}
e.w.writen1(']')
}
e.c = c
}
func (e *jsonEncDriver) writeIndent() {
e.w.writen1('\n')
if x := len(e.ds) * int(e.dl); x <= jsonSpacesOrTabsLen {
if e.dt {
e.w.writestr(jsonTabs[:x])
} else {
e.w.writestr(jsonSpaces[:x])
}
} else {
for i := uint16(0); i < e.dl; i++ {
e.w.writestr(e.ds)
}
}
}
func (e *jsonEncDriver) EncodeNil() {
e.w.writeb(jsonLiterals[9:13]) // null
}
@ -131,19 +197,39 @@ func (e *jsonEncDriver) EncodeBool(b bool) {
}
func (e *jsonEncDriver) EncodeFloat32(f float32) {
e.w.writeb(strconv.AppendFloat(e.b[:0], float64(f), 'E', -1, 32))
e.encodeFloat(float64(f), 32)
}
func (e *jsonEncDriver) EncodeFloat64(f float64) {
// e.w.writestr(strconv.FormatFloat(f, 'E', -1, 64))
e.w.writeb(strconv.AppendFloat(e.b[:0], f, 'E', -1, 64))
e.encodeFloat(f, 64)
}
func (e *jsonEncDriver) encodeFloat(f float64, numbits int) {
x := strconv.AppendFloat(e.b[:0], f, 'G', -1, numbits)
e.w.writeb(x)
if bytes.IndexByte(x, 'E') == -1 && bytes.IndexByte(x, '.') == -1 {
e.w.writen2('.', '0')
}
}
func (e *jsonEncDriver) EncodeInt(v int64) {
if x := e.h.IntegerAsString; x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) {
e.w.writen1('"')
e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
e.w.writen1('"')
return
}
e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
}
func (e *jsonEncDriver) EncodeUint(v uint64) {
if x := e.h.IntegerAsString; x == 'A' || x == 'L' && v > 1<<53 {
e.w.writen1('"')
e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
e.w.writen1('"')
return
}
e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
}
@ -165,11 +251,17 @@ func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
}
func (e *jsonEncDriver) EncodeArrayStart(length int) {
if e.d {
e.dl++
}
e.w.writen1('[')
e.c = containerArrayStart
}
func (e *jsonEncDriver) EncodeMapStart(length int) {
if e.d {
e.dl++
}
e.w.writen1('{')
e.c = containerMapStart
}
@ -564,6 +656,11 @@ func (d *jsonDecDriver) decNum(storeBytes bool) {
d.tok = b
}
b := d.tok
var str bool
if b == '"' {
str = true
b = d.r.readn1()
}
if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) {
d.d.errorf("json: decNum: got first char '%c'", b)
return
@ -578,6 +675,10 @@ func (d *jsonDecDriver) decNum(storeBytes bool) {
n.reset()
d.bs = d.bs[:0]
if str && storeBytes {
d.bs = append(d.bs, '"')
}
// The format of a number is as below:
// parsing: sign? digit* dot? digit* e? sign? digit*
// states: 0 1* 2 3* 4 5* 6 7
@ -668,6 +769,14 @@ LOOP:
default:
break LOOP
}
case '"':
if str {
if storeBytes {
d.bs = append(d.bs, '"')
}
b, eof = r.readn1eof()
}
break LOOP
default:
break LOOP
}
@ -822,6 +931,11 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [
if isstring {
return d.bs
}
// if appendStringAsBytes returned a zero-len slice, then treat as nil.
// This should only happen for null, and "".
if len(d.bs) == 0 {
return nil
}
bs0 := d.bs
slen := base64.StdEncoding.DecodedLen(len(bs0))
if slen <= cap(bs) {
@ -859,6 +973,14 @@ func (d *jsonDecDriver) appendStringAsBytes() {
}
d.tok = b
}
// handle null as a string
if d.tok == 'n' {
d.readStrIdx(10, 13) // ull
d.bs = d.bs[:0]
return
}
if d.tok != '"' {
d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok)
}
@ -1033,6 +1155,24 @@ type JsonHandle struct {
// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
// If not configured, raw bytes are encoded to/from base64 text.
RawBytesExt InterfaceExt
// Indent indicates how a value is encoded.
// - If positive, indent by that number of spaces.
// - If negative, indent by that number of tabs.
Indent int8
// IntegerAsString controls how integers (signed and unsigned) are encoded.
//
// Per the JSON Spec, JSON numbers are 64-bit floating point numbers.
// Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision.
// This can be mitigated by configuring how to encode integers.
//
// IntegerAsString interpretes the following values:
// - if 'L', then encode integers > 2^53 as a json string.
// - if 'A', then encode all integers as a json string
// containing the exact integer representation as a decimal.
// - else encode all integers as a json number (default)
IntegerAsString uint8
}
func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
@ -1040,26 +1180,48 @@ func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceE
}
func (h *JsonHandle) newEncDriver(e *Encoder) encDriver {
hd := jsonEncDriver{e: e, w: e.w, h: h}
hd := jsonEncDriver{e: e, h: h}
hd.bs = hd.b[:0]
hd.se.i = h.RawBytesExt
hd.reset()
return &hd
}
func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
// d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
hd := jsonDecDriver{d: d, r: d.r, h: h}
hd := jsonDecDriver{d: d, h: h}
hd.bs = hd.b[:0]
hd.se.i = h.RawBytesExt
hd.reset()
return &hd
}
func (e *jsonEncDriver) reset() {
e.w = e.e.w
e.se.i = e.h.RawBytesExt
if e.bs != nil {
e.bs = e.bs[:0]
}
e.d, e.dt, e.dl, e.ds = false, false, 0, ""
e.c = 0
if e.h.Indent > 0 {
e.d = true
e.ds = jsonSpaces[:e.h.Indent]
} else if e.h.Indent < 0 {
e.d = true
e.dt = true
e.ds = jsonTabs[:-(e.h.Indent)]
}
}
func (d *jsonDecDriver) reset() {
d.r = d.d.r
d.se.i = d.h.RawBytesExt
if d.bs != nil {
d.bs = d.bs[:0]
}
d.c, d.tok = 0, 0
d.n.reset()
}
var jsonEncodeTerminate = []byte{' '}

View File

@ -374,7 +374,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
}
if n.v == valueTypeUint && d.h.SignedInteger {
n.v = valueTypeInt
n.i = int64(n.v)
n.i = int64(n.u)
}
return
}
@ -561,6 +561,13 @@ func (d *msgpackDecDriver) readNextBd() {
d.bdRead = true
}
func (d *msgpackDecDriver) uncacheRead() {
if d.bdRead {
d.r.unreadn1()
d.bdRead = false
}
}
func (d *msgpackDecDriver) ContainerType() (vt valueType) {
bd := d.bd
if bd == mpNil {
@ -729,6 +736,7 @@ func (e *msgpackEncDriver) reset() {
func (d *msgpackDecDriver) reset() {
d.r = d.d.r
d.bd, d.bdRead = 0, false
}
//--------------------------------------------------

View File

@ -25,7 +25,7 @@ type Rpc interface {
}
// RpcCodecBuffered allows access to the underlying bufio.Reader/Writer
// used by the rpc connection. It accomodates use-cases where the connection
// used by the rpc connection. It accommodates use-cases where the connection
// should be used by rpc and non-rpc functions, e.g. streaming a file after
// sending an rpc response.
type RpcCodecBuffered interface {

View File

@ -166,6 +166,13 @@ func (d *simpleDecDriver) readNextBd() {
d.bdRead = true
}
func (d *simpleDecDriver) uncacheRead() {
if d.bdRead {
d.r.unreadn1()
d.bdRead = false
}
}
func (d *simpleDecDriver) ContainerType() (vt valueType) {
if d.bd == simpleVdNil {
return valueTypeNil
@ -340,7 +347,7 @@ func (d *simpleDecDriver) decLen() int {
}
return int(ui)
}
d.d.errorf("decLen: Cannot read length: bd%8 must be in range 0..4. Got: %d", d.bd%8)
d.d.errorf("decLen: Cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
return -1
}
@ -474,7 +481,7 @@ func (d *simpleDecDriver) DecodeNaked() {
// SimpleHandle is a Handle for a very simple encoding format.
//
// simple is a simplistic codec similar to binc, but not as compact.
// - Encoding of a value is always preceeded by the descriptor byte (bd)
// - Encoding of a value is always preceded by the descriptor byte (bd)
// - True, false, nil are encoded fully in 1 byte (the descriptor)
// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
@ -512,6 +519,7 @@ func (e *simpleEncDriver) reset() {
func (d *simpleDecDriver) reset() {
d.r = d.d.r
d.bd, d.bdRead = 0, false
}
var _ decDriver = (*simpleDecDriver)(nil)

View File

@ -9,6 +9,8 @@
# sudo apt-get install python-pip
# pip install --user msgpack-python msgpack-rpc-python cbor
# Ensure all "string" keys are utf strings (else encoded as bytes)
import cbor, msgpack, msgpackrpc, sys, os, threading
def get_test_data_list():
@ -26,35 +28,39 @@ def get_test_data_list():
-3232.0,
-6464646464.0,
3232.0,
6464.0,
6464646464.0,
False,
True,
u"null",
None,
u"someday",
u"",
u"bytestring",
1328176922000002000,
u"",
-2206187877999998000,
u"bytestring",
270,
u"none",
-2013855847999995777,
#-6795364578871345152,
]
l1 = [
{ "true": True,
"false": False },
{ "true": "True",
{ "true": u"True",
"false": False,
"uint16(1616)": 1616 },
{ "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ],
"int32":32323232, "bool": True,
"LONG STRING": "123456789012345678901234567890123456789012345678901234567890",
"SHORT STRING": "1234567890" },
{ True: "true", 8: False, "false": 0 }
"LONG STRING": u"123456789012345678901234567890123456789012345678901234567890",
"SHORT STRING": u"1234567890" },
{ True: "true", 138: False, "false": 200 }
]
l = []
l.extend(l0)
l.append(l0)
l.append(1)
l.extend(l1)
return l

View File

@ -5,11 +5,22 @@ package codec
import (
"fmt"
"reflect"
"time"
)
var (
timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) {
defer panicToErr(&err)
bs = timeExt{}.WriteExt(rv.Interface())
return
}
timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) {
defer panicToErr(&err)
timeExt{}.ReadExt(rv.Interface(), bs)
return
}
)
type timeExt struct{}

View File

@ -44,8 +44,13 @@ func MakeRaw(fd int) (*State, error) {
}
newState := oldState.termios
newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
// This attempts to replicate the behaviour documented for cfmakeraw in
// the termios(3) manpage.
newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
newState.Oflag &^= syscall.OPOST
newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
newState.Cflag &^= syscall.CSIZE | syscall.PARENB
newState.Cflag |= syscall.CS8
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}

View File

@ -0,0 +1,58 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// oldState, err := terminal.MakeRaw(0)
// if err != nil {
// panic(err)
// }
// defer terminal.Restore(0, oldState)
package terminal
import (
"fmt"
"runtime"
)
type State struct{}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
return false
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}

View File

@ -0,0 +1,73 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build solaris
package terminal
import (
"golang.org/x/sys/unix"
"io"
"syscall"
)
// State contains the state of a terminal.
type State struct {
termios syscall.Termios
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
var termio unix.Termio
err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio)
return err == nil
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
oldState := *val
newState := oldState
newState.Lflag &^= syscall.ECHO
newState.Lflag |= syscall.ICANON | syscall.ISIG
newState.Iflag |= syscall.ICRNL
err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
if err != nil {
return nil, err
}
defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
var buf [16]byte
var ret []byte
for {
n, err := syscall.Read(fd, buf[:])
if err != nil {
return nil, err
}
if n == 0 {
if len(ret) == 0 {
return nil, io.EOF
}
break
}
if buf[n-1] == '\n' {
n--
}
ret = append(ret, buf[:n]...)
if n < len(buf) {
break
}
}
return ret, nil
}

View File

@ -87,8 +87,8 @@ func MakeRaw(fd int) (*State, error) {
if e != 0 {
return nil, error(e)
}
st &^= (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0)
if e != 0 {
return nil, error(e)
}

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -19,7 +19,7 @@ package meta
import (
"fmt"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource

View File

@ -19,8 +19,8 @@ package meta
import (
"fmt"
"k8s.io/client-go/pkg/runtime/schema"
utilerrors "k8s.io/client-go/pkg/util/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
)
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the

View File

@ -20,8 +20,8 @@ import (
"fmt"
"reflect"
"k8s.io/client-go/pkg/conversion"
"k8s.io/client-go/pkg/runtime"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
)
// IsListType returns true if the provided Object has a slice called Items

View File

@ -17,11 +17,11 @@ limitations under the License.
package meta
import (
metav1 "k8s.io/client-go/pkg/apis/meta/v1"
"k8s.io/client-go/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/client-go/pkg/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.

View File

@ -20,11 +20,11 @@ import (
"fmt"
"reflect"
metav1 "k8s.io/client-go/pkg/apis/meta/v1"
"k8s.io/client-go/pkg/conversion"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/client-go/pkg/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"github.com/golang/glog"
)

View File

@ -20,9 +20,9 @@ import (
"fmt"
"strings"
"k8s.io/client-go/pkg/runtime/schema"
utilerrors "k8s.io/client-go/pkg/util/errors"
"k8s.io/client-go/pkg/util/sets"
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
)
// MultiRESTMapper is a wrapper for multiple RESTMappers.

View File

@ -19,7 +19,7 @@ package meta
import (
"fmt"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
)
const (

View File

@ -22,8 +22,8 @@ import (
"sort"
"strings"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Implements RESTScope interface

View File

@ -17,8 +17,8 @@ limitations under the License.
package meta
import (
"k8s.io/client-go/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// InterfacesForUnstructured returns VersionInterfaces suitable for

View File

@ -25,10 +25,10 @@ import (
"github.com/golang/glog"
"k8s.io/client-go/pkg/api/meta"
"k8s.io/client-go/pkg/apimachinery"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/client-go/pkg/util/sets"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
var (

View File

@ -19,9 +19,9 @@ package apimachinery
import (
"fmt"
"k8s.io/client-go/pkg/api/meta"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupMeta stores the metadata of a group.

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -15,14 +15,14 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo.
// source: k8s.io/kubernetes/pkg/apis/meta/v1/generated.proto
// source: k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
// DO NOT EDIT!
/*
Package v1 is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/pkg/apis/meta/v1/generated.proto
k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
It has these top-level messages:
APIGroup
@ -52,6 +52,7 @@ limitations under the License.
Timestamp
TypeMeta
Verbs
WatchEvent
*/
package v1
@ -60,7 +61,7 @@ import fmt "fmt"
import math "math"
import time "time"
import k8s_io_kubernetes_pkg_types "k8s.io/client-go/pkg/types"
import k8s_io_kubernetes_pkg_types "k8s.io/apimachinery/pkg/types"
import strings "strings"
import reflect "reflect"
@ -191,6 +192,10 @@ func (m *Verbs) Reset() { *m = Verbs{} }
func (*Verbs) ProtoMessage() {}
func (*Verbs) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{26} }
func (m *WatchEvent) Reset() { *m = WatchEvent{} }
func (*WatchEvent) ProtoMessage() {}
func (*WatchEvent) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{27} }
func init() {
proto.RegisterType((*APIGroup)(nil), "k8s.io.client-go.pkg.apis.meta.v1.APIGroup")
proto.RegisterType((*APIGroupList)(nil), "k8s.io.client-go.pkg.apis.meta.v1.APIGroupList")
@ -219,6 +224,7 @@ func init() {
proto.RegisterType((*Timestamp)(nil), "k8s.io.client-go.pkg.apis.meta.v1.Timestamp")
proto.RegisterType((*TypeMeta)(nil), "k8s.io.client-go.pkg.apis.meta.v1.TypeMeta")
proto.RegisterType((*Verbs)(nil), "k8s.io.client-go.pkg.apis.meta.v1.Verbs")
proto.RegisterType((*WatchEvent)(nil), "k8s.io.client-go.pkg.apis.meta.v1.WatchEvent")
}
func (m *APIGroup) Marshal() (data []byte, err error) {
size := m.Size()
@ -1094,6 +1100,36 @@ func (m Verbs) MarshalTo(data []byte) (int, error) {
return i, nil
}
func (m *WatchEvent) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
n, err := m.MarshalTo(data)
if err != nil {
return nil, err
}
return data[:n], nil
}
func (m *WatchEvent) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(len(m.Type)))
i += copy(data[i:], m.Type)
data[i] = 0x12
i++
i = encodeVarintGenerated(data, i, uint64(m.Object.Size()))
n5, err := m.Object.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n5
return i, nil
}
func encodeFixed64Generated(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
@ -1454,6 +1490,16 @@ func (m Verbs) Size() (n int) {
return n
}
func (m *WatchEvent) Size() (n int) {
var l int
_ = l
l = len(m.Type)
n += 1 + l + sovGenerated(uint64(l))
l = m.Object.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
func sovGenerated(x uint64) (n int) {
for {
n++
@ -1698,6 +1744,17 @@ func (this *TypeMeta) String() string {
}, "")
return s
}
func (this *WatchEvent) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&WatchEvent{`,
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
`Object:` + strings.Replace(strings.Replace(this.Object.String(), "RawExtension", "k8s_io_kubernetes_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func valueToStringGenerated(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@ -4912,6 +4969,115 @@ func (m *Verbs) Unmarshal(data []byte) error {
}
return nil
}
func (m *WatchEvent) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: WatchEvent: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: WatchEvent: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Type = string(data[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Object.Unmarshal(data[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenerated(data []byte) (n int, err error) {
l := len(data)
iNdEx := 0
@ -5018,102 +5184,105 @@ var (
)
var fileDescriptorGenerated = []byte{
// 1543 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5,
0x17, 0xf7, 0xda, 0xb1, 0x6b, 0x3f, 0xc7, 0x4d, 0xba, 0xdf, 0x54, 0x5f, 0x37, 0x12, 0x76, 0xd8,
0x22, 0x94, 0x4a, 0xed, 0x5a, 0x89, 0x10, 0xaa, 0x0a, 0x45, 0x64, 0x93, 0xb4, 0x0a, 0x6d, 0x9a,
0x68, 0xd2, 0x16, 0x54, 0x7a, 0x60, 0xe3, 0x9d, 0x38, 0x4b, 0xec, 0xdd, 0x65, 0x66, 0x6c, 0x6a,
0x71, 0xa0, 0xe2, 0xc4, 0x01, 0xa1, 0x1e, 0x11, 0x07, 0xd4, 0x48, 0xfc, 0x01, 0xfc, 0x0b, 0xdc,
0x7a, 0xa3, 0xdc, 0x38, 0x20, 0x8b, 0x06, 0x71, 0xe2, 0x3f, 0xc8, 0x09, 0xcd, 0xec, 0xcc, 0x7a,
0xd7, 0x89, 0x9b, 0x8d, 0xca, 0x81, 0x93, 0x77, 0xde, 0x8f, 0xcf, 0x7b, 0xf3, 0xe6, 0x33, 0x6f,
0x9e, 0x61, 0x71, 0xef, 0x2a, 0x35, 0x5d, 0xbf, 0xb1, 0xd7, 0xdd, 0xc6, 0xc4, 0xc3, 0x0c, 0xd3,
0x46, 0xb0, 0xd7, 0x6a, 0xd8, 0x81, 0x4b, 0x1b, 0x1d, 0xcc, 0xec, 0x46, 0x6f, 0xa1, 0xd1, 0xc2,
0x1e, 0x26, 0x36, 0xc3, 0x8e, 0x19, 0x10, 0x9f, 0xf9, 0xba, 0x11, 0xfa, 0x98, 0x43, 0x1f, 0x33,
0xd8, 0x6b, 0x99, 0xdc, 0xc7, 0xe4, 0x3e, 0x66, 0x6f, 0x61, 0xf6, 0x4a, 0xcb, 0x65, 0xbb, 0xdd,
0x6d, 0xb3, 0xe9, 0x77, 0x1a, 0x2d, 0xbf, 0xe5, 0x37, 0x84, 0xeb, 0x76, 0x77, 0x47, 0xac, 0xc4,
0x42, 0x7c, 0x85, 0x90, 0xb3, 0x57, 0x8e, 0x4f, 0x83, 0x74, 0x3d, 0xe6, 0x76, 0xf0, 0x68, 0x06,
0xb3, 0x6f, 0xbd, 0xdc, 0x9c, 0x36, 0x77, 0x71, 0xc7, 0x3e, 0xe2, 0xb5, 0x70, 0xbc, 0x57, 0x97,
0xb9, 0xed, 0x86, 0xeb, 0x31, 0xca, 0xc8, 0xa8, 0x8b, 0xf1, 0x73, 0x0e, 0x8a, 0x4b, 0x9b, 0x6b,
0x37, 0x89, 0xdf, 0x0d, 0xf4, 0x39, 0x98, 0xf0, 0xec, 0x0e, 0xae, 0x6a, 0x73, 0xda, 0x7c, 0xc9,
0x9a, 0x7c, 0x36, 0xa8, 0x67, 0x0e, 0x06, 0xf5, 0x89, 0x3b, 0x76, 0x07, 0x23, 0xa1, 0xd1, 0x3f,
0x85, 0x62, 0x0f, 0x13, 0xea, 0xfa, 0x1e, 0xad, 0x66, 0xe7, 0x72, 0xf3, 0xe5, 0xc5, 0x77, 0xcd,
0x93, 0x8b, 0x65, 0x0a, 0xf8, 0xfb, 0xa1, 0xe3, 0x0d, 0x9f, 0xac, 0xb8, 0xb4, 0xe9, 0xf7, 0x30,
0xe9, 0x5b, 0xd3, 0x32, 0x46, 0x51, 0x2a, 0x29, 0x8a, 0xf0, 0xf5, 0xaf, 0x34, 0x98, 0x0e, 0x08,
0xde, 0xc1, 0x84, 0x60, 0x47, 0xea, 0xab, 0xb9, 0x39, 0xed, 0x95, 0x83, 0x56, 0x65, 0xd0, 0xe9,
0xcd, 0x11, 0x74, 0x74, 0x24, 0x9e, 0xbe, 0xaf, 0xc1, 0x2c, 0xc5, 0xa4, 0x87, 0xc9, 0x92, 0xe3,
0x10, 0x4c, 0xa9, 0xd5, 0x5f, 0x6e, 0xbb, 0xd8, 0x63, 0xcb, 0x6b, 0x2b, 0x88, 0x56, 0x27, 0x44,
0x0d, 0xae, 0xa7, 0x49, 0x67, 0x6b, 0x1c, 0x8a, 0x65, 0xc8, 0x7c, 0x66, 0xc7, 0x9a, 0x50, 0xf4,
0x92, 0x24, 0x0c, 0x07, 0x26, 0xd5, 0x11, 0xde, 0x76, 0x29, 0xd3, 0xef, 0x42, 0xa1, 0xc5, 0x17,
0xb4, 0xaa, 0x89, 0xf4, 0x2e, 0xa7, 0x49, 0x4f, 0x21, 0x58, 0x67, 0x65, 0x36, 0x05, 0xb1, 0xa4,
0x48, 0x62, 0x19, 0xbf, 0x6a, 0x50, 0x5e, 0xda, 0x5c, 0x43, 0x98, 0xfa, 0x5d, 0xd2, 0xc4, 0x29,
0xc8, 0xb2, 0x08, 0xc0, 0x7f, 0x69, 0x60, 0x37, 0xb1, 0x53, 0xcd, 0xce, 0x69, 0xf3, 0x45, 0x4b,
0x97, 0x76, 0x70, 0x27, 0xd2, 0xa0, 0x98, 0x15, 0x47, 0xdd, 0x73, 0x3d, 0x47, 0x9c, 0x73, 0x0c,
0xf5, 0x96, 0xeb, 0x39, 0x48, 0x68, 0xf4, 0x0f, 0x20, 0xdf, 0xc3, 0x64, 0x9b, 0xd7, 0x9e, 0x53,
0xe1, 0x52, 0x9a, 0xcd, 0xdd, 0xe7, 0x0e, 0x56, 0xe9, 0x60, 0x50, 0xcf, 0x8b, 0x4f, 0x14, 0x42,
0x18, 0x3f, 0x69, 0x30, 0x15, 0xdb, 0x93, 0xa8, 0xde, 0x55, 0x98, 0x6c, 0xc5, 0x98, 0x23, 0xf7,
0x37, 0x23, 0x33, 0x99, 0x8c, 0xb3, 0x0a, 0x25, 0x2c, 0xf5, 0x26, 0x94, 0x88, 0x44, 0x52, 0xb7,
0xa3, 0x91, 0xb2, 0xf4, 0x2a, 0x83, 0x61, 0x9c, 0x98, 0x90, 0xa2, 0x21, 0xae, 0xf1, 0x57, 0x78,
0x0c, 0xea, 0xbe, 0xe8, 0xf3, 0xb1, 0x1b, 0xc9, 0x8f, 0xbb, 0x64, 0x4d, 0x8e, 0xb9, 0x4f, 0x27,
0x50, 0x39, 0xfb, 0x1f, 0xa0, 0xf2, 0xb5, 0xe2, 0x77, 0x4f, 0xeb, 0x99, 0xc7, 0xbf, 0xcf, 0x65,
0x8c, 0x35, 0x28, 0xae, 0x74, 0x89, 0xcd, 0x78, 0x61, 0xaf, 0x43, 0xd1, 0x91, 0xdf, 0xe2, 0x38,
0x72, 0xd6, 0xeb, 0xaa, 0x6f, 0x28, 0x9b, 0xc3, 0x41, 0xbd, 0xc2, 0x5b, 0xa3, 0xa9, 0x04, 0x28,
0x72, 0x31, 0x1e, 0x42, 0x65, 0xf5, 0x51, 0xe0, 0x13, 0xb6, 0x11, 0x30, 0x51, 0x89, 0x37, 0xa1,
0x80, 0x85, 0x40, 0xa0, 0x15, 0x87, 0x94, 0x0f, 0xcd, 0x90, 0xd4, 0xea, 0x17, 0x21, 0x8f, 0x1f,
0xd9, 0x4d, 0x26, 0xb9, 0x5b, 0x91, 0x66, 0xf9, 0x55, 0x2e, 0x44, 0xa1, 0xce, 0xd8, 0x00, 0xb8,
0x89, 0x23, 0xe8, 0x25, 0x98, 0x52, 0x67, 0x95, 0x24, 0xd0, 0xff, 0xa5, 0xf3, 0x14, 0x4a, 0xaa,
0xd1, 0xa8, 0xbd, 0xf1, 0x10, 0x4a, 0x82, 0x64, 0x9c, 0xf3, 0x3c, 0x05, 0xc1, 0x31, 0x89, 0x12,
0xa5, 0x20, 0x2c, 0x50, 0xa8, 0x8b, 0x2e, 0x4d, 0x76, 0xdc, 0xa5, 0x89, 0xd5, 0xb5, 0x0d, 0x95,
0xd0, 0x57, 0xdd, 0xe3, 0x54, 0x11, 0x2e, 0x43, 0x51, 0xa5, 0x29, 0xa3, 0x44, 0x9d, 0x5b, 0x01,
0xa1, 0xc8, 0x22, 0x16, 0x6d, 0x17, 0x12, 0x17, 0x26, 0x5d, 0xb0, 0x4b, 0x70, 0x46, 0x92, 0x56,
0xc6, 0x9a, 0x92, 0x66, 0x67, 0x54, 0xcd, 0x94, 0x3e, 0x16, 0xe9, 0x4b, 0xa8, 0x8e, 0x6b, 0xf8,
0xaf, 0x70, 0xa5, 0xd3, 0xa7, 0x62, 0x7c, 0xab, 0xc1, 0x74, 0x1c, 0x29, 0xfd, 0xf1, 0xa5, 0x0f,
0x72, 0x72, 0x7b, 0x8c, 0x55, 0xe4, 0x07, 0x0d, 0x66, 0x12, 0x5b, 0x3b, 0xd5, 0x89, 0x9f, 0x22,
0xa9, 0x38, 0x39, 0x72, 0xa7, 0x20, 0xc7, 0x2f, 0x59, 0xa8, 0xdc, 0xb6, 0xb7, 0x71, 0x7b, 0x0b,
0xb7, 0x71, 0x93, 0xf9, 0x44, 0xef, 0x43, 0xb9, 0x63, 0xb3, 0xe6, 0xae, 0x90, 0xaa, 0xe7, 0xcb,
0x4a, 0xd3, 0x92, 0x12, 0x38, 0xe6, 0xfa, 0x10, 0x64, 0xd5, 0x63, 0xa4, 0x6f, 0xfd, 0x4f, 0x26,
0x54, 0x8e, 0x69, 0x50, 0x3c, 0x96, 0x98, 0x36, 0xc4, 0x7a, 0xf5, 0x51, 0xc0, 0xfb, 0xd2, 0x69,
0x47, 0x9c, 0x44, 0x02, 0x08, 0x7f, 0xd6, 0x75, 0x09, 0xee, 0x60, 0x8f, 0x0d, 0xa7, 0x8d, 0xf5,
0x11, 0x74, 0x74, 0x24, 0xde, 0xec, 0x7b, 0x30, 0x3d, 0x9a, 0xba, 0x3e, 0x0d, 0xb9, 0x3d, 0xdc,
0x0f, 0xcf, 0x0a, 0xf1, 0x4f, 0x7d, 0x06, 0xf2, 0x3d, 0xbb, 0xdd, 0x95, 0x37, 0x11, 0x85, 0x8b,
0x6b, 0xd9, 0xab, 0x9a, 0xf1, 0xa3, 0x06, 0xd5, 0x71, 0x89, 0xe8, 0xaf, 0xc5, 0x80, 0xac, 0xb2,
0xcc, 0x2a, 0x77, 0x0b, 0xf7, 0x43, 0xd4, 0x55, 0x28, 0xfa, 0x01, 0x9f, 0x0d, 0x7d, 0x22, 0x4f,
0xfc, 0x92, 0x3a, 0xc5, 0x0d, 0x29, 0x3f, 0x1c, 0xd4, 0xcf, 0x27, 0xe0, 0x95, 0x02, 0x45, 0xae,
0xba, 0x01, 0x05, 0x91, 0x0f, 0xad, 0xe6, 0xc4, 0x6b, 0x04, 0xbc, 0xaf, 0xde, 0x17, 0x12, 0x24,
0x35, 0xc6, 0x17, 0x50, 0xe4, 0x4f, 0xed, 0x3a, 0x66, 0x36, 0x27, 0x0f, 0xc5, 0xed, 0x9d, 0xdb,
0xae, 0xb7, 0x27, 0x53, 0x8b, 0xc8, 0xb3, 0x25, 0xe5, 0x28, 0xb2, 0x38, 0xae, 0xbd, 0x66, 0x4f,
0xd9, 0x5e, 0x0f, 0x35, 0x38, 0xbb, 0xf1, 0xb9, 0x87, 0x09, 0xe2, 0xa3, 0x1e, 0xf6, 0xc2, 0x51,
0x46, 0xdc, 0x2a, 0x6d, 0xec, 0xd0, 0xa1, 0x86, 0x9d, 0xdc, 0xd8, 0x61, 0xe7, 0x7d, 0xc8, 0x75,
0x5d, 0x47, 0x0c, 0x25, 0x25, 0xcb, 0x54, 0xd5, 0xbd, 0xb7, 0xb6, 0x72, 0x38, 0xa8, 0xd7, 0x8f,
0x9f, 0xcb, 0x59, 0x3f, 0xc0, 0xd4, 0xbc, 0xb7, 0xb6, 0x82, 0xb8, 0x2b, 0x1f, 0x97, 0xec, 0xc0,
0x55, 0xdb, 0xca, 0x0b, 0xa0, 0x68, 0x5c, 0x1a, 0x3e, 0xf9, 0x28, 0x66, 0xa5, 0x9b, 0x00, 0x4d,
0xdf, 0x63, 0xc4, 0x6f, 0xb7, 0x31, 0xa9, 0x16, 0xc2, 0xd7, 0x8c, 0xdb, 0x2f, 0x47, 0x52, 0x14,
0xb3, 0x30, 0x2e, 0x43, 0x09, 0xf9, 0x3e, 0xdb, 0xb4, 0xd9, 0x2e, 0xd5, 0xeb, 0x90, 0x0f, 0xf8,
0x87, 0x9c, 0x1b, 0xc4, 0x78, 0x24, 0x34, 0x28, 0x94, 0x1b, 0xdf, 0x68, 0x70, 0x61, 0xec, 0x43,
0xce, 0xf3, 0x6d, 0x46, 0x2b, 0x59, 0xbb, 0x28, 0xdf, 0xa1, 0x1d, 0x8a, 0x59, 0xe9, 0xef, 0x40,
0x25, 0xf1, 0xfa, 0xcb, 0xd3, 0x3b, 0x2f, 0xdd, 0x2a, 0x89, 0x68, 0x28, 0x69, 0x6b, 0xfc, 0x9d,
0x85, 0xc2, 0x16, 0xb3, 0x59, 0x97, 0xea, 0x0f, 0xa0, 0xc8, 0x2f, 0x9e, 0x63, 0x33, 0x5b, 0x44,
0x4e, 0x39, 0xe4, 0x2a, 0xd6, 0x0d, 0x39, 0xa6, 0x24, 0x28, 0xc2, 0xe3, 0xd3, 0x01, 0x15, 0x51,
0x64, 0x72, 0xd1, 0x74, 0x10, 0xc6, 0x46, 0x52, 0xcb, 0x3b, 0x64, 0x07, 0x53, 0x6a, 0xb7, 0x14,
0x2d, 0xa2, 0x0e, 0xb9, 0x1e, 0x8a, 0x91, 0xd2, 0xeb, 0x6f, 0x43, 0x81, 0x60, 0x9b, 0xfa, 0x9e,
0xe4, 0x47, 0x4d, 0x41, 0x22, 0x21, 0x3d, 0x1c, 0xd4, 0x27, 0x25, 0xb8, 0x58, 0x23, 0x69, 0xad,
0x7f, 0x04, 0x67, 0x1c, 0xcc, 0x6c, 0xb7, 0x4d, 0x05, 0x1f, 0xca, 0x8b, 0x0b, 0xa9, 0xc6, 0x33,
0x01, 0xb5, 0x12, 0x3a, 0x5a, 0x65, 0x9e, 0x91, 0x5c, 0x20, 0x05, 0xc7, 0x09, 0xdd, 0xf4, 0x1d,
0x2c, 0x28, 0x93, 0x1f, 0x12, 0x7a, 0xd9, 0x77, 0x30, 0x12, 0x1a, 0xe3, 0x89, 0x06, 0xe5, 0x10,
0x69, 0xd9, 0xee, 0x52, 0xac, 0x2f, 0x44, 0x7b, 0x08, 0x8f, 0xfa, 0x82, 0xf2, 0xb9, 0xdb, 0x0f,
0xf0, 0xe1, 0xa0, 0x5e, 0x12, 0x66, 0x7c, 0x11, 0xa5, 0x1f, 0xab, 0x50, 0xf6, 0x84, 0x0a, 0x5d,
0x84, 0xfc, 0x8e, 0x8b, 0xdb, 0xea, 0x65, 0x8b, 0xde, 0xa4, 0x1b, 0x5c, 0x88, 0x42, 0x9d, 0xf1,
0x7d, 0x16, 0x2a, 0x89, 0xcd, 0xa5, 0xf8, 0x13, 0x12, 0x3d, 0x76, 0xd9, 0x14, 0x03, 0xd4, 0xf8,
0x7f, 0x1d, 0x1f, 0x42, 0xa1, 0xc9, 0xf7, 0xa7, 0xfe, 0xf2, 0x35, 0xd2, 0x1f, 0x84, 0xa8, 0xcb,
0x90, 0x45, 0x62, 0x49, 0x91, 0x84, 0xd3, 0x6f, 0xc2, 0x39, 0x82, 0x19, 0xe9, 0x2f, 0xed, 0x30,
0x4c, 0xb6, 0x70, 0xd3, 0xf7, 0x9c, 0xf0, 0xb0, 0xf3, 0x51, 0x85, 0xcf, 0xa1, 0x51, 0x03, 0x74,
0xd4, 0xc7, 0x68, 0xc3, 0xc4, 0x5d, 0xb7, 0x83, 0x79, 0xd1, 0xa9, 0x84, 0x09, 0x67, 0xe5, 0xa8,
0xe8, 0xca, 0x59, 0xe9, 0x79, 0x6d, 0x3c, 0xdb, 0xf3, 0x43, 0xa2, 0xe7, 0x87, 0xb5, 0xb9, 0xc3,
0x85, 0x28, 0xd4, 0x5d, 0x9b, 0xe1, 0xef, 0xf5, 0xd7, 0xfb, 0xf5, 0xcc, 0x93, 0xfd, 0x7a, 0xe6,
0xe9, 0xbe, 0x7c, 0xbb, 0x3f, 0x86, 0x12, 0x8f, 0x46, 0x99, 0xdd, 0x09, 0xfe, 0xed, 0x90, 0xc6,
0x27, 0x50, 0xe4, 0x3c, 0x12, 0xef, 0xc3, 0xc9, 0xbd, 0x39, 0xd9, 0x37, 0xb3, 0x69, 0xfa, 0xa6,
0xb1, 0x08, 0xe1, 0x1f, 0x41, 0xde, 0x03, 0x5d, 0x86, 0x3b, 0x89, 0x1e, 0xb8, 0xc6, 0x05, 0x28,
0x94, 0x0f, 0xc7, 0x15, 0xeb, 0x8d, 0x67, 0x2f, 0x6a, 0x99, 0xe7, 0x2f, 0x6a, 0x99, 0xdf, 0x5e,
0xd4, 0x32, 0x8f, 0x0f, 0x6a, 0xda, 0xb3, 0x83, 0x9a, 0xf6, 0xfc, 0xa0, 0xa6, 0xfd, 0x71, 0x50,
0xd3, 0x9e, 0xfc, 0x59, 0xcb, 0x3c, 0xc8, 0xf6, 0x16, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x9c,
0xf8, 0xe2, 0x2b, 0x70, 0x12, 0x00, 0x00,
// 1598 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xf7, 0xda, 0xb1, 0x6b, 0x3f, 0xc7, 0x4d, 0xba, 0xa4, 0xc2, 0x8d, 0x84, 0x1d, 0xb6, 0x08,
0xa5, 0xa2, 0x5d, 0x2b, 0x11, 0x42, 0x55, 0xa1, 0x88, 0x6c, 0x92, 0x56, 0xa1, 0x4d, 0x13, 0x4d,
0xfa, 0x07, 0x95, 0x1e, 0xd8, 0x78, 0x27, 0xce, 0x36, 0xf6, 0xee, 0x32, 0x33, 0x76, 0x63, 0x71,
0xa0, 0x82, 0x0b, 0x07, 0x84, 0x7a, 0x44, 0x1c, 0x50, 0x23, 0xf1, 0x01, 0xf8, 0x0a, 0xdc, 0x7a,
0xa3, 0xdc, 0x38, 0x20, 0x8b, 0x06, 0x71, 0xe2, 0x1b, 0xe4, 0x84, 0x66, 0x76, 0x66, 0xbd, 0x76,
0xe2, 0x66, 0xa3, 0x72, 0xe0, 0x14, 0xcf, 0xfb, 0xf3, 0x7b, 0x6f, 0xde, 0xfc, 0xe6, 0xcd, 0xdb,
0xc0, 0xfc, 0xce, 0x65, 0x6a, 0xba, 0x7e, 0x6d, 0xa7, 0xbd, 0x89, 0x89, 0x87, 0x19, 0xa6, 0xb5,
0x60, 0xa7, 0x51, 0xb3, 0x03, 0x97, 0xd6, 0x5a, 0x98, 0xd9, 0xb5, 0xce, 0x5c, 0xad, 0x81, 0x3d,
0x4c, 0x6c, 0x86, 0x1d, 0x33, 0x20, 0x3e, 0xf3, 0x75, 0x23, 0xf4, 0x31, 0xfb, 0x3e, 0x66, 0xb0,
0xd3, 0x30, 0xb9, 0x8f, 0xc9, 0x7d, 0xcc, 0xce, 0xdc, 0xf4, 0xa5, 0x86, 0xcb, 0xb6, 0xdb, 0x9b,
0x66, 0xdd, 0x6f, 0xd5, 0x1a, 0x7e, 0xc3, 0xaf, 0x09, 0xd7, 0xcd, 0xf6, 0x96, 0x58, 0x89, 0x85,
0xf8, 0x15, 0x42, 0x4e, 0x5f, 0x3a, 0x3a, 0x0d, 0xd2, 0xf6, 0x98, 0xdb, 0xc2, 0xc3, 0x19, 0x4c,
0xbf, 0xfb, 0x72, 0x73, 0x5a, 0xdf, 0xc6, 0x2d, 0xfb, 0x90, 0xd7, 0xdc, 0xd1, 0x5e, 0x6d, 0xe6,
0x36, 0x6b, 0xae, 0xc7, 0x28, 0x23, 0xc3, 0x2e, 0xc6, 0x2f, 0x19, 0xc8, 0x2f, 0xac, 0xaf, 0x5c,
0x27, 0x7e, 0x3b, 0xd0, 0x67, 0x60, 0xcc, 0xb3, 0x5b, 0xb8, 0xac, 0xcd, 0x68, 0xb3, 0x05, 0x6b,
0xfc, 0x59, 0xaf, 0x9a, 0xda, 0xef, 0x55, 0xc7, 0x6e, 0xd9, 0x2d, 0x8c, 0x84, 0x46, 0x7f, 0x08,
0xf9, 0x0e, 0x26, 0xd4, 0xf5, 0x3d, 0x5a, 0x4e, 0xcf, 0x64, 0x66, 0x8b, 0xf3, 0x1f, 0x98, 0xc7,
0x17, 0xcb, 0x14, 0xf0, 0x77, 0x43, 0xc7, 0x6b, 0x3e, 0x59, 0x72, 0x69, 0xdd, 0xef, 0x60, 0xd2,
0xb5, 0x26, 0x65, 0x8c, 0xbc, 0x54, 0x52, 0x14, 0xe1, 0xeb, 0x5f, 0x69, 0x30, 0x19, 0x10, 0xbc,
0x85, 0x09, 0xc1, 0x8e, 0xd4, 0x97, 0x33, 0x33, 0xda, 0x2b, 0x07, 0x2d, 0xcb, 0xa0, 0x93, 0xeb,
0x43, 0xe8, 0xe8, 0x50, 0x3c, 0x7d, 0x4f, 0x83, 0x69, 0x8a, 0x49, 0x07, 0x93, 0x05, 0xc7, 0x21,
0x98, 0x52, 0xab, 0xbb, 0xd8, 0x74, 0xb1, 0xc7, 0x16, 0x57, 0x96, 0x10, 0x2d, 0x8f, 0x89, 0x1a,
0x5c, 0x4d, 0x92, 0xce, 0xc6, 0x28, 0x14, 0xcb, 0x90, 0xf9, 0x4c, 0x8f, 0x34, 0xa1, 0xe8, 0x25,
0x49, 0x18, 0x0e, 0x8c, 0xab, 0x23, 0xbc, 0xe9, 0x52, 0xa6, 0xdf, 0x86, 0x5c, 0x83, 0x2f, 0x68,
0x59, 0x13, 0xe9, 0x5d, 0x4c, 0x92, 0x9e, 0x42, 0xb0, 0x4e, 0xcb, 0x6c, 0x72, 0x62, 0x49, 0x91,
0xc4, 0x32, 0x7e, 0xd3, 0xa0, 0xb8, 0xb0, 0xbe, 0x82, 0x30, 0xf5, 0xdb, 0xa4, 0x8e, 0x13, 0x90,
0x65, 0x1e, 0x80, 0xff, 0xa5, 0x81, 0x5d, 0xc7, 0x4e, 0x39, 0x3d, 0xa3, 0xcd, 0xe6, 0x2d, 0x5d,
0xda, 0xc1, 0xad, 0x48, 0x83, 0x62, 0x56, 0x1c, 0x75, 0xc7, 0xf5, 0x1c, 0x71, 0xce, 0x31, 0xd4,
0x1b, 0xae, 0xe7, 0x20, 0xa1, 0xd1, 0x3f, 0x86, 0x6c, 0x07, 0x93, 0x4d, 0x5e, 0x7b, 0x4e, 0x85,
0x0b, 0x49, 0x36, 0x77, 0x97, 0x3b, 0x58, 0x85, 0xfd, 0x5e, 0x35, 0x2b, 0x7e, 0xa2, 0x10, 0xc2,
0xf8, 0x59, 0x83, 0x89, 0xd8, 0x9e, 0x44, 0xf5, 0x2e, 0xc3, 0x78, 0x23, 0xc6, 0x1c, 0xb9, 0xbf,
0x29, 0x99, 0xc9, 0x78, 0x9c, 0x55, 0x68, 0xc0, 0x52, 0xaf, 0x43, 0x81, 0x48, 0x24, 0x75, 0x3b,
0x6a, 0x09, 0x4b, 0xaf, 0x32, 0xe8, 0xc7, 0x89, 0x09, 0x29, 0xea, 0xe3, 0x1a, 0x7f, 0x87, 0xc7,
0xa0, 0xee, 0x8b, 0x3e, 0x1b, 0xbb, 0x91, 0xfc, 0xb8, 0x0b, 0xd6, 0xf8, 0x88, 0xfb, 0x74, 0x0c,
0x95, 0xd3, 0xff, 0x03, 0x2a, 0x5f, 0xc9, 0x7f, 0xff, 0xb4, 0x9a, 0x7a, 0xfc, 0xc7, 0x4c, 0xca,
0x58, 0x81, 0xfc, 0x52, 0x9b, 0xd8, 0x8c, 0x17, 0xf6, 0x2a, 0xe4, 0x1d, 0xf9, 0x5b, 0x1c, 0x47,
0xc6, 0x7a, 0x53, 0xf5, 0x0d, 0x65, 0x73, 0xd0, 0xab, 0x96, 0x78, 0x6b, 0x34, 0x95, 0x00, 0x45,
0x2e, 0xc6, 0x03, 0x28, 0x2d, 0xef, 0x06, 0x3e, 0x61, 0x6b, 0x01, 0x13, 0x95, 0x78, 0x1b, 0x72,
0x58, 0x08, 0x04, 0x5a, 0xbe, 0x4f, 0xf9, 0xd0, 0x0c, 0x49, 0xad, 0x7e, 0x1e, 0xb2, 0x78, 0xd7,
0xae, 0x33, 0xc9, 0xdd, 0x92, 0x34, 0xcb, 0x2e, 0x73, 0x21, 0x0a, 0x75, 0xc6, 0x1a, 0xc0, 0x75,
0x1c, 0x41, 0x2f, 0xc0, 0x84, 0x3a, 0xab, 0x41, 0x02, 0xbd, 0x2e, 0x9d, 0x27, 0xd0, 0xa0, 0x1a,
0x0d, 0xdb, 0x1b, 0x0f, 0xa0, 0x20, 0x48, 0xc6, 0x39, 0xcf, 0x53, 0x10, 0x1c, 0x93, 0x28, 0x51,
0x0a, 0xc2, 0x02, 0x85, 0xba, 0xe8, 0xd2, 0xa4, 0x47, 0x5d, 0x9a, 0x58, 0x5d, 0x9b, 0x50, 0x0a,
0x7d, 0xd5, 0x3d, 0x4e, 0x14, 0xe1, 0x22, 0xe4, 0x55, 0x9a, 0x32, 0x4a, 0xd4, 0xb9, 0x15, 0x10,
0x8a, 0x2c, 0x62, 0xd1, 0xb6, 0x61, 0xe0, 0xc2, 0x24, 0x0b, 0x76, 0x01, 0x4e, 0x49, 0xd2, 0xca,
0x58, 0x13, 0xd2, 0xec, 0x94, 0xaa, 0x99, 0xd2, 0xc7, 0x22, 0x7d, 0x09, 0xe5, 0x51, 0x0d, 0xff,
0x15, 0xae, 0x74, 0xf2, 0x54, 0x8c, 0xef, 0x34, 0x98, 0x8c, 0x23, 0x25, 0x3f, 0xbe, 0xe4, 0x41,
0x8e, 0x6f, 0x8f, 0xb1, 0x8a, 0xfc, 0xa8, 0xc1, 0xd4, 0xc0, 0xd6, 0x4e, 0x74, 0xe2, 0x27, 0x48,
0x2a, 0x4e, 0x8e, 0xcc, 0x09, 0xc8, 0xf1, 0x6b, 0x1a, 0x4a, 0x37, 0xed, 0x4d, 0xdc, 0xdc, 0xc0,
0x4d, 0x5c, 0x67, 0x3e, 0xd1, 0xbb, 0x50, 0x6c, 0xd9, 0xac, 0xbe, 0x2d, 0xa4, 0xea, 0xf9, 0xb2,
0x92, 0xb4, 0xa4, 0x01, 0x1c, 0x73, 0xb5, 0x0f, 0xb2, 0xec, 0x31, 0xd2, 0xb5, 0x5e, 0x93, 0x09,
0x15, 0x63, 0x1a, 0x14, 0x8f, 0x25, 0xa6, 0x0d, 0xb1, 0x5e, 0xde, 0x0d, 0x78, 0x5f, 0x3a, 0xe9,
0x88, 0x33, 0x90, 0x00, 0xc2, 0x9f, 0xb7, 0x5d, 0x82, 0x5b, 0xd8, 0x63, 0xfd, 0x69, 0x63, 0x75,
0x08, 0x1d, 0x1d, 0x8a, 0x37, 0xfd, 0x21, 0x4c, 0x0e, 0xa7, 0xae, 0x4f, 0x42, 0x66, 0x07, 0x77,
0xc3, 0xb3, 0x42, 0xfc, 0xa7, 0x3e, 0x05, 0xd9, 0x8e, 0xdd, 0x6c, 0xcb, 0x9b, 0x88, 0xc2, 0xc5,
0x95, 0xf4, 0x65, 0xcd, 0xf8, 0x49, 0x83, 0xf2, 0xa8, 0x44, 0xf4, 0x37, 0x62, 0x40, 0x56, 0x51,
0x66, 0x95, 0xb9, 0x81, 0xbb, 0x21, 0xea, 0x32, 0xe4, 0xfd, 0x80, 0xcf, 0x86, 0x3e, 0x91, 0x27,
0x7e, 0x41, 0x9d, 0xe2, 0x9a, 0x94, 0x1f, 0xf4, 0xaa, 0x67, 0x07, 0xe0, 0x95, 0x02, 0x45, 0xae,
0xba, 0x01, 0x39, 0x91, 0x0f, 0x2d, 0x67, 0xc4, 0x6b, 0x04, 0xbc, 0xaf, 0xde, 0x15, 0x12, 0x24,
0x35, 0xc6, 0x17, 0x90, 0xe7, 0x4f, 0xed, 0x2a, 0x66, 0x36, 0x27, 0x0f, 0xc5, 0xcd, 0xad, 0x9b,
0xae, 0xb7, 0x23, 0x53, 0x8b, 0xc8, 0xb3, 0x21, 0xe5, 0x28, 0xb2, 0x38, 0xaa, 0xbd, 0xa6, 0x4f,
0xd8, 0x5e, 0x0f, 0x34, 0x38, 0xbd, 0xf6, 0xc8, 0xc3, 0x04, 0xf1, 0x51, 0x0f, 0x7b, 0xe1, 0x28,
0x23, 0x6e, 0x95, 0x36, 0x72, 0xe8, 0x50, 0xc3, 0x4e, 0x66, 0xe4, 0xb0, 0xf3, 0x11, 0x64, 0xda,
0xae, 0x23, 0x86, 0x92, 0x82, 0x65, 0xaa, 0xea, 0xde, 0x59, 0x59, 0x3a, 0xe8, 0x55, 0xab, 0x47,
0xcf, 0xe5, 0xac, 0x1b, 0x60, 0x6a, 0xde, 0x59, 0x59, 0x42, 0xdc, 0x95, 0x8f, 0x4b, 0x76, 0xe0,
0xaa, 0x6d, 0x65, 0x05, 0x50, 0x34, 0x2e, 0xf5, 0x9f, 0x7c, 0x14, 0xb3, 0xd2, 0x4d, 0x80, 0xba,
0xef, 0x31, 0xe2, 0x37, 0x9b, 0x98, 0x94, 0x73, 0xe1, 0x6b, 0xc6, 0xed, 0x17, 0x23, 0x29, 0x8a,
0x59, 0x18, 0x17, 0xa1, 0x80, 0x7c, 0x9f, 0xad, 0xdb, 0x6c, 0x9b, 0xea, 0x55, 0xc8, 0x06, 0xfc,
0x87, 0x9c, 0x1b, 0xc4, 0x78, 0x24, 0x34, 0x28, 0x94, 0x1b, 0xdf, 0x6a, 0x70, 0x6e, 0xe4, 0x43,
0xce, 0xf3, 0xad, 0x47, 0x2b, 0x59, 0xbb, 0x28, 0xdf, 0xbe, 0x1d, 0x8a, 0x59, 0xe9, 0xef, 0x43,
0x69, 0xe0, 0xf5, 0x97, 0xa7, 0x77, 0x56, 0xba, 0x95, 0x06, 0xa2, 0xa1, 0x41, 0x5b, 0xe3, 0x9f,
0x34, 0xe4, 0x36, 0x98, 0xcd, 0xda, 0x54, 0xbf, 0x0f, 0x79, 0x7e, 0xf1, 0x1c, 0x9b, 0xd9, 0x22,
0x72, 0xc2, 0x21, 0x57, 0xb1, 0xae, 0xcf, 0x31, 0x25, 0x41, 0x11, 0x1e, 0x9f, 0x0e, 0xa8, 0x88,
0x22, 0x93, 0x8b, 0xa6, 0x83, 0x30, 0x36, 0x92, 0x5a, 0xde, 0x21, 0x5b, 0x98, 0x52, 0xbb, 0xa1,
0x68, 0x11, 0x75, 0xc8, 0xd5, 0x50, 0x8c, 0x94, 0x5e, 0x7f, 0x0f, 0x72, 0x04, 0xdb, 0xd4, 0xf7,
0x24, 0x3f, 0x2a, 0x0a, 0x12, 0x09, 0xe9, 0x41, 0xaf, 0x3a, 0x2e, 0xc1, 0xc5, 0x1a, 0x49, 0x6b,
0xfd, 0x13, 0x38, 0xe5, 0x60, 0x66, 0xbb, 0x4d, 0x2a, 0xf8, 0x50, 0x9c, 0x9f, 0x4b, 0x34, 0x9e,
0x09, 0xa8, 0xa5, 0xd0, 0xd1, 0x2a, 0xf2, 0x8c, 0xe4, 0x02, 0x29, 0x38, 0x4e, 0xe8, 0xba, 0xef,
0x60, 0x41, 0x99, 0x6c, 0x9f, 0xd0, 0x8b, 0xbe, 0x83, 0x91, 0xd0, 0x18, 0x4f, 0x34, 0x28, 0x86,
0x48, 0x8b, 0x76, 0x9b, 0x62, 0x7d, 0x2e, 0xda, 0x43, 0x78, 0xd4, 0xe7, 0x94, 0xcf, 0xed, 0x6e,
0x80, 0x0f, 0x7a, 0xd5, 0x82, 0x30, 0xe3, 0x8b, 0x28, 0xfd, 0x58, 0x85, 0xd2, 0xc7, 0x54, 0xe8,
0x3c, 0x64, 0xb7, 0x5c, 0xdc, 0x54, 0x2f, 0x5b, 0xf4, 0x26, 0x5d, 0xe3, 0x42, 0x14, 0xea, 0x8c,
0x1f, 0xd2, 0x50, 0x1a, 0xd8, 0x5c, 0x82, 0x8f, 0x90, 0xe8, 0xb1, 0x4b, 0x27, 0x18, 0xa0, 0x46,
0x7f, 0x75, 0xdc, 0x83, 0x5c, 0x9d, 0xef, 0x4f, 0x7d, 0xf2, 0xd5, 0x92, 0x1f, 0x84, 0xa8, 0x4b,
0x9f, 0x45, 0x62, 0x49, 0x91, 0x84, 0xd3, 0xaf, 0xc3, 0x19, 0x82, 0x19, 0xe9, 0x2e, 0x6c, 0x31,
0x4c, 0x36, 0x70, 0xdd, 0xf7, 0x9c, 0xf0, 0xb0, 0xb3, 0x51, 0x85, 0xcf, 0xa0, 0x61, 0x03, 0x74,
0xd8, 0xc7, 0x68, 0xc2, 0xd8, 0x6d, 0xb7, 0x85, 0x79, 0xd1, 0xa9, 0x84, 0x09, 0x67, 0xe5, 0xa8,
0xe8, 0xca, 0x59, 0xe9, 0x79, 0x6d, 0x3c, 0xdb, 0xf3, 0x43, 0xa2, 0x67, 0xfb, 0xb5, 0xb9, 0xc5,
0x85, 0x28, 0xd4, 0x5d, 0x99, 0xe2, 0xef, 0xf5, 0x37, 0x7b, 0xd5, 0xd4, 0x93, 0xbd, 0x6a, 0xea,
0xe9, 0x9e, 0x7c, 0xbb, 0x3f, 0x85, 0x02, 0x8f, 0x46, 0x99, 0xdd, 0x0a, 0xfe, 0xeb, 0x90, 0xc6,
0x67, 0x90, 0xe7, 0x3c, 0x12, 0xef, 0xc3, 0xf1, 0xbd, 0x79, 0xb0, 0x6f, 0xa6, 0x93, 0xf4, 0x4d,
0x63, 0x1e, 0xc2, 0x0f, 0x41, 0xde, 0x03, 0x5d, 0x86, 0x5b, 0x03, 0x3d, 0x70, 0x85, 0x0b, 0x50,
0x28, 0x8f, 0x8d, 0x2b, 0x5f, 0x6b, 0x00, 0xf7, 0xc4, 0x8b, 0xdd, 0xe1, 0xcf, 0xe9, 0x0c, 0x8c,
0xf1, 0x06, 0x3e, 0x9c, 0x98, 0xb8, 0x00, 0x42, 0xa3, 0x6f, 0x40, 0xce, 0xdf, 0x7c, 0x88, 0xe5,
0xf7, 0x43, 0x71, 0xfe, 0x9d, 0x11, 0x9c, 0x91, 0xff, 0xd5, 0x31, 0x91, 0xfd, 0x68, 0x79, 0x97,
0x61, 0x8f, 0x67, 0xd8, 0xe7, 0xcb, 0x9a, 0x80, 0x40, 0x12, 0xca, 0x7a, 0xeb, 0xd9, 0x8b, 0x4a,
0xea, 0xf9, 0x8b, 0x4a, 0xea, 0xf7, 0x17, 0x95, 0xd4, 0xe3, 0xfd, 0x8a, 0xf6, 0x6c, 0xbf, 0xa2,
0x3d, 0xdf, 0xaf, 0x68, 0x7f, 0xee, 0x57, 0xb4, 0x27, 0x7f, 0x55, 0x52, 0xf7, 0xd3, 0x9d, 0xb9,
0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x94, 0x53, 0x56, 0x06, 0xf6, 0x12, 0x00, 0x00,
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -446,3 +446,17 @@ message Verbs {
repeated string items = 1;
}
// Event represents a single event to a watched resource.
//
// +protobuf=true
message WatchEvent {
optional string type = 1;
// Object is:
// * If Type is Added or Modified: the new state of the object.
// * If Type is Deleted: the state of the object immediately before deletion.
// * If Type is Error: *Status is recommended; other types may make sense
// depending on context.
optional k8s.io.kubernetes.pkg.runtime.RawExtension object = 2;
}

View File

@ -21,7 +21,7 @@ import (
"fmt"
"strings"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying

View File

@ -19,8 +19,8 @@ package v1
import (
"fmt"
"k8s.io/client-go/pkg/labels"
"k8s.io/client-go/pkg/selection"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
)
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements

View File

@ -17,7 +17,7 @@ limitations under the License.
package v1
import (
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// ListMetaAccessor retrieves the list interface from an object

View File

@ -17,7 +17,8 @@ limitations under the License.
package v1
import (
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name for this API.
@ -26,7 +27,25 @@ const GroupName = "meta.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: "", Version: ""}
// WatchEventKind is name reserved for serializing watch events.
const WatchEventKind = "WatchEvent"
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// AddToGroupVersion registers common meta types into schemas.
func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) {
scheme.AddKnownTypeWithName(groupVersion.WithKind(WatchEventKind), &WatchEvent{})
scheme.AddKnownTypeWithName(
schema.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal}.WithKind(WatchEventKind),
&InternalEvent{},
)
scheme.AddConversionFuncs(
Convert_versioned_Event_to_watch_Event,
Convert_versioned_InternalEvent_to_versioned_Event,
Convert_watch_Event_to_versioned_Event,
Convert_versioned_Event_to_versioned_InternalEvent,
)
}

View File

@ -20,7 +20,7 @@ import (
"encoding/json"
"time"
"k8s.io/client-go/pkg/genericapiserver/openapi/common"
"k8s.io/apimachinery/pkg/genericapiserver/openapi/common"
"github.com/go-openapi/spec"
"github.com/google/gofuzz"

View File

@ -31,7 +31,7 @@ import (
"github.com/ugorji/go/codec"
"k8s.io/client-go/pkg/types"
"k8s.io/apimachinery/pkg/types"
)
// TypeMeta describes an individual object in an API response or request
@ -87,7 +87,7 @@ type OwnerReference struct {
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// UID of the referent.
// More info: http://kubernetes.io/docs/user-guide/identifiers#uids
UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`
UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
// If true, this reference points to the managing controller.
// +optional
Controller *bool `json:"controller,omitempty" protobuf:"varint,6,opt,name=controller"`

View File

@ -26,11 +26,11 @@ import (
"github.com/golang/glog"
metav1 "k8s.io/client-go/pkg/apis/meta/v1"
"k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/runtime/schema"
"k8s.io/client-go/pkg/types"
"k8s.io/client-go/pkg/util/json"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/json"
)
// Unstructured allows objects that do not have Golang structs registered to be manipulated

Some files were not shown because too many files have changed in this diff Show More