1
0
mirror of https://github.com/rancher/rke.git synced 2025-06-27 07:50:30 +00:00

Merge pull request #346 from galal-hussein/external_etcd

External etcd
This commit is contained in:
Alena Prokharchyk 2018-02-14 13:37:27 -08:00 committed by GitHub
commit 98518c4b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 21362 additions and 14973 deletions

View File

@ -222,6 +222,32 @@ ingress:
RKE will deploy Nginx Ingress controller as a DaemonSet with `hostnetwork: true`, so ports `80`, and `443` will be opened on each node where the controller is deployed. RKE will deploy Nginx Ingress controller as a DaemonSet with `hostnetwork: true`, so ports `80`, and `443` will be opened on each node where the controller is deployed.
## External etcd
RKE supports using external etcd instead of deploying etcd servers, to enable external etcd the following parameters should be populated:
```
services:
etcd:
path: /etcdcluster
external_urls:
- https://etcd-example.com:2379
ca_cert: |-
-----BEGIN CERTIFICATE-----
xxxxxxxxxx
-----END CERTIFICATE-----
cert: |-
-----BEGIN CERTIFICATE-----
xxxxxxxxxx
-----END CERTIFICATE-----
key: |-
-----BEGIN PRIVATE KEY-----
xxxxxxxxxx
-----END PRIVATE KEY-----
```
Note that RKE only supports connecting to TLS enabled etcd setup, user can enable multiple endpoints in the `external_urls` field. RKE will not accept having external urls and nodes with `etcd` role at the same time, user should only specify either etcd role for servers or external etcd but not both.
## Operating Systems Notes ## Operating Systems Notes
### Atomic OS ### Atomic OS

View File

@ -68,9 +68,24 @@ nodes:
services: services:
etcd: etcd:
# if external etcd is used
# path: /etcdcluster
# external_urls:
# - https://etcd-example.com:2379
# ca_cert: |-
# -----BEGIN CERTIFICATE-----
# xxxxxxxxxx
# -----END CERTIFICATE-----
# cert: |-
# -----BEGIN CERTIFICATE-----
# xxxxxxxxxx
# -----END CERTIFICATE-----
# key: |-
# -----BEGIN PRIVATE KEY-----
# xxxxxxxxxx
# -----END PRIVATE KEY-----
kube-api: kube-api:
service_cluster_ip_range: 10.233.0.0/18 service_cluster_ip_range: 10.233.0.0/18
pod_security_policy: false pod_security_policy: false
extra_args: extra_args:

View File

@ -22,26 +22,26 @@ func SetUpAuthentication(ctx context.Context, kubeCluster, currentCluster *Clust
if currentCluster != nil { if currentCluster != nil {
kubeCluster.Certificates = currentCluster.Certificates kubeCluster.Certificates = currentCluster.Certificates
} else { } else {
log.Infof(ctx, "[certificates] Attempting to recover certificates from backup on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Attempting to recover certificates from backup on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
kubeCluster.Certificates, err = pki.FetchCertificatesFromHost(ctx, kubeCluster.EtcdHosts, kubeCluster.EtcdHosts[0], kubeCluster.SystemImages.Alpine, kubeCluster.LocalKubeConfigPath, kubeCluster.PrivateRegistriesMap) kubeCluster.Certificates, err = pki.FetchCertificatesFromHost(ctx, kubeCluster.EtcdHosts, kubeCluster.ControlPlaneHosts[0], kubeCluster.SystemImages.Alpine, kubeCluster.LocalKubeConfigPath, kubeCluster.PrivateRegistriesMap)
if err != nil { if err != nil {
return err return err
} }
if kubeCluster.Certificates != nil { if kubeCluster.Certificates != nil {
log.Infof(ctx, "[certificates] Certificate backup found on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Certificate backup found on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
return nil return nil
} }
log.Infof(ctx, "[certificates] No Certificate backup found on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] No Certificate backup found on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
kubeCluster.Certificates, err = pki.GenerateRKECerts(ctx, kubeCluster.RancherKubernetesEngineConfig, kubeCluster.LocalKubeConfigPath, "") kubeCluster.Certificates, err = pki.GenerateRKECerts(ctx, kubeCluster.RancherKubernetesEngineConfig, kubeCluster.LocalKubeConfigPath, "")
if err != nil { if err != nil {
return fmt.Errorf("Failed to generate Kubernetes certificates: %v", err) return fmt.Errorf("Failed to generate Kubernetes certificates: %v", err)
} }
log.Infof(ctx, "[certificates] Temporarily saving certs to etcd host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Temporarily saving certs to control host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
if err := pki.DeployCertificatesOnHost(ctx, kubeCluster.EtcdHosts[0], kubeCluster.Certificates, kubeCluster.SystemImages.CertDownloader, pki.TempCertPath, kubeCluster.PrivateRegistriesMap); err != nil { if err := pki.DeployCertificatesOnHost(ctx, kubeCluster.ControlPlaneHosts[0], kubeCluster.Certificates, kubeCluster.SystemImages.CertDownloader, pki.TempCertPath, kubeCluster.PrivateRegistriesMap); err != nil {
return err return err
} }
log.Infof(ctx, "[certificates] Saved certs to etcd host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Saved certs to control host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
} }
} }
return nil return nil
@ -123,11 +123,14 @@ func saveCertToKubernetes(kubeClient *kubernetes.Clientset, crtName string, crt
timeout := make(chan bool, 1) timeout := make(chan bool, 1)
// build secret Data // build secret Data
secretData := map[string][]byte{ secretData := make(map[string][]byte)
"Certificate": cert.EncodeCertPEM(crt.Certificate), if crt.Certificate != nil {
"Key": cert.EncodePrivateKeyPEM(crt.Key), secretData["Certificate"] = cert.EncodeCertPEM(crt.Certificate)
"EnvName": []byte(crt.EnvName), secretData["EnvName"] = []byte(crt.EnvName)
"KeyEnvName": []byte(crt.KeyEnvName), }
if crt.Key != nil {
secretData["Key"] = cert.EncodePrivateKeyPEM(crt.Key)
secretData["KeyEnvName"] = []byte(crt.KeyEnvName)
} }
if len(crt.Config) > 0 { if len(crt.Config) > 0 {
secretData["ConfigEnvName"] = []byte(crt.ConfigEnvName) secretData["ConfigEnvName"] = []byte(crt.ConfigEnvName)

View File

@ -55,10 +55,14 @@ const (
func (c *Cluster) DeployControlPlane(ctx context.Context) error { func (c *Cluster) DeployControlPlane(ctx context.Context) error {
// Deploy Etcd Plane // Deploy Etcd Plane
etcdProcessHostMap := c.getEtcdProcessHostMap(nil) etcdProcessHostMap := c.getEtcdProcessHostMap(nil)
if len(c.Services.Etcd.ExternalURLs) > 0 {
log.Infof(ctx, "[etcd] External etcd connection string has been specified, skipping etcd plane")
} else {
if err := services.RunEtcdPlane(ctx, c.EtcdHosts, etcdProcessHostMap, c.LocalConnDialerFactory, c.PrivateRegistriesMap); err != nil { if err := services.RunEtcdPlane(ctx, c.EtcdHosts, etcdProcessHostMap, c.LocalConnDialerFactory, c.PrivateRegistriesMap); err != nil {
return fmt.Errorf("[etcd] Failed to bring up Etcd Plane: %v", err) return fmt.Errorf("[etcd] Failed to bring up Etcd Plane: %v", err)
} }
}
// Deploy Control plane // Deploy Control plane
processMap := map[string]v3.Process{ processMap := map[string]v3.Process{
services.SidekickContainerName: c.BuildSidecarProcess(), services.SidekickContainerName: c.BuildSidecarProcess(),

View File

@ -21,7 +21,7 @@ const (
func (c *Cluster) TunnelHosts(ctx context.Context, local bool) error { func (c *Cluster) TunnelHosts(ctx context.Context, local bool) error {
if local { if local {
if err := c.EtcdHosts[0].TunnelUpLocal(ctx); err != nil { if err := c.ControlPlaneHosts[0].TunnelUpLocal(ctx); err != nil {
return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err) return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err)
} }
return nil return nil

View File

@ -73,11 +73,15 @@ const (
APIRoot = "APIRoot" APIRoot = "APIRoot"
// kubernetes client certificates and kubeconfig paths // kubernetes client certificates and kubeconfig paths
ClientCert = "ClientCert" EtcdClientCert = "EtcdClientCert"
EtcdClientKey = "EtcdClientKey"
EtcdClientCA = "EtcdClientCA"
EtcdClientCertPath = "EtcdClientCertPath"
EtcdClientKeyPath = "EtcdClientKeyPath"
EtcdClientCAPath = "EtcdClientCAPath"
ClientCertPath = "ClientCertPath" ClientCertPath = "ClientCertPath"
ClientKey = "ClientKey"
ClientKeyPath = "ClientKeyPath" ClientKeyPath = "ClientKeyPath"
ClientCA = "ClientCA"
ClientCAPath = "ClientCAPath" ClientCAPath = "ClientCAPath"
KubeCfg = "KubeCfg" KubeCfg = "KubeCfg"
@ -144,19 +148,28 @@ func (c *Cluster) doFlannelDeploy(ctx context.Context) error {
} }
func (c *Cluster) doCalicoDeploy(ctx context.Context) error { func (c *Cluster) doCalicoDeploy(ctx context.Context) error {
clientCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.KubeNodeCertName].Certificate))
clientkey := b64.StdEncoding.EncodeToString(cert.EncodePrivateKeyPEM(c.Certificates[pki.KubeNodeCertName].Key)) etcdEndpoints := services.GetEtcdConnString(c.EtcdHosts)
etcdClientCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.KubeNodeCertName].Certificate))
etcdClientkey := b64.StdEncoding.EncodeToString(cert.EncodePrivateKeyPEM(c.Certificates[pki.KubeNodeCertName].Key))
etcdCaCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.CACertName].Certificate))
clientConfig := pki.GetConfigPath(pki.KubeNodeCertName) clientConfig := pki.GetConfigPath(pki.KubeNodeCertName)
caCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.CACertName].Certificate)) // handling external etcd
if len(c.Services.Etcd.ExternalURLs) > 0 {
etcdClientCert = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.Cert))
etcdClientkey = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.Key))
etcdCaCert = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.CACert))
etcdEndpoints = strings.Join(c.Services.Etcd.ExternalURLs, ",")
}
calicoConfig := map[string]string{ calicoConfig := map[string]string{
EtcdEndpoints: services.GetEtcdConnString(c.EtcdHosts), EtcdEndpoints: etcdEndpoints,
APIRoot: "https://127.0.0.1:6443", APIRoot: "https://127.0.0.1:6443",
ClientCert: clientCert, EtcdClientCA: etcdCaCert,
ClientCertPath: pki.GetCertPath(pki.KubeNodeCertName), EtcdClientCert: etcdClientCert,
ClientKey: clientkey, EtcdClientKey: etcdClientkey,
ClientKeyPath: pki.GetKeyPath(pki.KubeNodeCertName), EtcdClientKeyPath: pki.GetKeyPath(pki.EtcdClientCertName),
ClientCA: caCert, EtcdClientCertPath: pki.GetCertPath(pki.EtcdClientCertName),
ClientCAPath: pki.GetCertPath(pki.CACertName), EtcdClientCAPath: pki.GetCertPath(pki.EtcdClientCACertName),
KubeCfg: clientConfig, KubeCfg: clientConfig,
ClusterCIDR: c.ClusterCIDR, ClusterCIDR: c.ClusterCIDR,
CNIImage: c.SystemImages.CalicoCNI, CNIImage: c.SystemImages.CalicoCNI,

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"strconv" "strconv"
"strings"
"github.com/rancher/rke/hosts" "github.com/rancher/rke/hosts"
"github.com/rancher/rke/pki" "github.com/rancher/rke/pki"
@ -11,6 +12,10 @@ import (
"github.com/rancher/types/apis/management.cattle.io/v3" "github.com/rancher/types/apis/management.cattle.io/v3"
) )
const (
EtcdPathPrefix = "/registry"
)
func GeneratePlan(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig) (v3.RKEPlan, error) { func GeneratePlan(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig) (v3.RKEPlan, error) {
clusterPlan := v3.RKEPlan{} clusterPlan := v3.RKEPlan{}
myCluster, _ := ParseCluster(ctx, rkeConfig, "", "", nil, nil) myCluster, _ := ParseCluster(ctx, rkeConfig, "", "", nil, nil)
@ -55,8 +60,20 @@ func BuildRKEConfigNodePlan(ctx context.Context, myCluster *Cluster, host *hosts
} }
func (c *Cluster) BuildKubeAPIProcess() v3.Process { func (c *Cluster) BuildKubeAPIProcess() v3.Process {
etcdConnString := services.GetEtcdConnString(c.EtcdHosts) // check if external etcd is used
args := []string{} etcdConnectionString := services.GetEtcdConnString(c.EtcdHosts)
etcdPathPrefix := EtcdPathPrefix
etcdClientCert := pki.GetCertPath(pki.KubeNodeCertName)
etcdClientKey := pki.GetKeyPath(pki.KubeNodeCertName)
etcdCAClientCert := pki.GetCertPath(pki.CACertName)
if len(c.Services.Etcd.ExternalURLs) > 0 {
etcdConnectionString = strings.Join(c.Services.Etcd.ExternalURLs, ",")
etcdPathPrefix = c.Services.Etcd.Path
etcdClientCert = pki.GetCertPath(pki.EtcdClientCertName)
etcdClientKey = pki.GetKeyPath(pki.EtcdClientCertName)
etcdCAClientCert = pki.GetCertPath(pki.EtcdClientCACertName)
}
Command := []string{ Command := []string{
"/opt/rke/entrypoint.sh", "/opt/rke/entrypoint.sh",
"kube-apiserver", "kube-apiserver",
@ -76,11 +93,14 @@ func (c *Cluster) BuildKubeAPIProcess() v3.Process {
"--tls-cert-file=" + pki.GetCertPath(pki.KubeAPICertName), "--tls-cert-file=" + pki.GetCertPath(pki.KubeAPICertName),
"--tls-private-key-file=" + pki.GetKeyPath(pki.KubeAPICertName), "--tls-private-key-file=" + pki.GetKeyPath(pki.KubeAPICertName),
"--service-account-key-file=" + pki.GetKeyPath(pki.KubeAPICertName), "--service-account-key-file=" + pki.GetKeyPath(pki.KubeAPICertName),
"--etcd-cafile=" + pki.GetCertPath(pki.CACertName),
"--etcd-certfile=" + pki.GetCertPath(pki.KubeAPICertName),
"--etcd-keyfile=" + pki.GetKeyPath(pki.KubeAPICertName),
} }
args = append(args, "--etcd-servers="+etcdConnString) args := []string{
"--etcd-cafile=" + etcdCAClientCert,
"--etcd-certfile=" + etcdClientCert,
"--etcd-keyfile=" + etcdClientKey,
"--etcd-servers=" + etcdConnectionString,
"--etcd-prefix=" + etcdPathPrefix,
}
if c.Authorization.Mode == services.RBACAuthorizationMode { if c.Authorization.Mode == services.RBACAuthorizationMode {
args = append(args, "--authorization-mode=RBAC") args = append(args, "--authorization-mode=RBAC")

View File

@ -10,6 +10,10 @@ import (
) )
func (c *Cluster) ClusterRemove(ctx context.Context) error { func (c *Cluster) ClusterRemove(ctx context.Context) error {
externalEtcd := false
if len(c.Services.Etcd.ExternalURLs) > 0 {
externalEtcd = true
}
// Remove Worker Plane // Remove Worker Plane
if err := services.RemoveWorkerPlane(ctx, c.WorkerHosts, true); err != nil { if err := services.RemoveWorkerPlane(ctx, c.WorkerHosts, true); err != nil {
return err return err
@ -26,7 +30,7 @@ func (c *Cluster) ClusterRemove(ctx context.Context) error {
} }
// Clean up all hosts // Clean up all hosts
if err := cleanUpHosts(ctx, c.ControlPlaneHosts, c.WorkerHosts, c.EtcdHosts, c.SystemImages.Alpine, c.PrivateRegistriesMap); err != nil { if err := cleanUpHosts(ctx, c.ControlPlaneHosts, c.WorkerHosts, c.EtcdHosts, c.SystemImages.Alpine, c.PrivateRegistriesMap, externalEtcd); err != nil {
return err return err
} }
@ -34,14 +38,14 @@ func (c *Cluster) ClusterRemove(ctx context.Context) error {
return nil return nil
} }
func cleanUpHosts(ctx context.Context, cpHosts, workerHosts, etcdHosts []*hosts.Host, cleanerImage string, prsMap map[string]v3.PrivateRegistry) error { func cleanUpHosts(ctx context.Context, cpHosts, workerHosts, etcdHosts []*hosts.Host, cleanerImage string, prsMap map[string]v3.PrivateRegistry, externalEtcd bool) error {
allHosts := []*hosts.Host{} allHosts := []*hosts.Host{}
allHosts = append(allHosts, cpHosts...) allHosts = append(allHosts, cpHosts...)
allHosts = append(allHosts, workerHosts...) allHosts = append(allHosts, workerHosts...)
allHosts = append(allHosts, etcdHosts...) allHosts = append(allHosts, etcdHosts...)
for _, host := range allHosts { for _, host := range allHosts {
if err := host.CleanUpAll(ctx, cleanerImage, prsMap); err != nil { if err := host.CleanUpAll(ctx, cleanerImage, prsMap, externalEtcd); err != nil {
return err return err
} }
} }

View File

@ -12,9 +12,12 @@ func (c *Cluster) ValidateCluster() error {
if len(c.ControlPlaneHosts) == 0 { if len(c.ControlPlaneHosts) == 0 {
return fmt.Errorf("Cluster must have at least one control plane host") return fmt.Errorf("Cluster must have at least one control plane host")
} }
if len(c.EtcdHosts) == 0 { if len(c.EtcdHosts) == 0 && len(c.Services.Etcd.ExternalURLs) == 0 {
return fmt.Errorf("Cluster must have at least one etcd plane host") return fmt.Errorf("Cluster must have at least one etcd plane host")
} }
if len(c.EtcdHosts) > 0 && len(c.Services.Etcd.ExternalURLs) > 0 {
return fmt.Errorf("Cluster can't have both internal and external etcd")
}
// validate hosts options // validate hosts options
if err := validateHostsOptions(c); err != nil { if err := validateHostsOptions(c); err != nil {
@ -94,6 +97,21 @@ func validateServicesOptions(c *Cluster) error {
return fmt.Errorf("%s can't be empty", strings.Join(strings.Split(optionName, "_"), " ")) return fmt.Errorf("%s can't be empty", strings.Join(strings.Split(optionName, "_"), " "))
} }
} }
// Validate external etcd information
if len(c.Services.Etcd.ExternalURLs) > 0 {
if len(c.Services.Etcd.CACert) == 0 {
return fmt.Errorf("External CA Certificate for etcd can't be empty")
}
if len(c.Services.Etcd.Cert) == 0 {
return fmt.Errorf("External Client Certificate for etcd can't be empty")
}
if len(c.Services.Etcd.Key) == 0 {
return fmt.Errorf("External Client Key for etcd can't be empty")
}
if len(c.Services.Etcd.Path) == 0 {
return fmt.Errorf("External etcd path can't be empty")
}
}
return nil return nil
} }

View File

@ -41,16 +41,18 @@ const (
CleanerContainerName = "kube-cleaner" CleanerContainerName = "kube-cleaner"
) )
func (h *Host) CleanUpAll(ctx context.Context, cleanerImage string, prsMap map[string]v3.PrivateRegistry) error { func (h *Host) CleanUpAll(ctx context.Context, cleanerImage string, prsMap map[string]v3.PrivateRegistry, externalEtcd bool) error {
log.Infof(ctx, "[hosts] Cleaning up host [%s]", h.Address) log.Infof(ctx, "[hosts] Cleaning up host [%s]", h.Address)
toCleanPaths := []string{ toCleanPaths := []string{
ToCleanEtcdDir,
ToCleanSSLDir, ToCleanSSLDir,
ToCleanCNIConf, ToCleanCNIConf,
ToCleanCNIBin, ToCleanCNIBin,
ToCleanCalicoRun, ToCleanCalicoRun,
ToCleanTempCertPath, ToCleanTempCertPath,
} }
if externalEtcd {
toCleanPaths = append(toCleanPaths, ToCleanEtcdDir)
}
return h.CleanUp(ctx, toCleanPaths, cleanerImage, prsMap) return h.CleanUp(ctx, toCleanPaths, cleanerImage, prsMap)
} }

View File

@ -16,6 +16,8 @@ const (
KubeProxyCertName = "kube-proxy" KubeProxyCertName = "kube-proxy"
KubeNodeCertName = "kube-node" KubeNodeCertName = "kube-node"
EtcdCertName = "kube-etcd" EtcdCertName = "kube-etcd"
EtcdClientCACertName = "kube-etcd-client-ca"
EtcdClientCertName = "kube-etcd-client"
KubeNodeCommonName = "system:node" KubeNodeCommonName = "system:node"
KubeNodeOrganizationName = "system:nodes" KubeNodeOrganizationName = "system:nodes"

View File

@ -111,9 +111,27 @@ func GenerateRKECerts(ctx context.Context, rkeConfig v3.RancherKubernetesEngineC
kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey) kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey)
kubeAdminCertObj.Config = kubeAdminConfig kubeAdminCertObj.Config = kubeAdminConfig
kubeAdminCertObj.ConfigPath = localKubeConfigPath kubeAdminCertObj.ConfigPath = localKubeConfigPath
kubeAdminCertObj.ConfigEnvName = ""
certs[KubeAdminCertName] = kubeAdminCertObj certs[KubeAdminCertName] = kubeAdminCertObj
// generate etcd certificate and key // generate etcd certificate and key
if len(rkeConfig.Services.Etcd.ExternalURLs) > 0 {
clientCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.Cert))
if err != nil {
return nil, err
}
clientKey, err := cert.ParsePrivateKeyPEM([]byte(rkeConfig.Services.Etcd.Key))
if err != nil {
return nil, err
}
certs[EtcdClientCertName] = ToCertObject(EtcdClientCertName, "", "", clientCert[0], clientKey.(*rsa.PrivateKey))
caCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.CACert))
if err != nil {
return nil, err
}
certs[EtcdClientCACertName] = ToCertObject(EtcdClientCACertName, "", "", caCert[0], nil)
}
etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole) etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole)
etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP) etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP)
for _, host := range etcdHosts { for _, host := range etcdHosts {

View File

@ -107,11 +107,14 @@ func GetAltNames(cpHosts []*hosts.Host, clusterDomain string, KubernetesServiceI
} }
func (c *CertificatePKI) ToEnv() []string { func (c *CertificatePKI) ToEnv() []string {
env := []string{ env := []string{}
c.CertToEnv(), if c.Key != nil {
c.KeyToEnv(), env = append(env, c.KeyToEnv())
} }
if c.Config != "" { if c.Certificate != nil {
env = append(env, c.CertToEnv())
}
if c.Config != "" && c.ConfigEnvName != "" {
env = append(env, c.ConfigToEnv()) env = append(env, c.ConfigToEnv())
} }
return env return env
@ -218,6 +221,8 @@ func getControlCertKeys() []string {
KubeSchedulerCertName, KubeSchedulerCertName,
KubeProxyCertName, KubeProxyCertName,
KubeNodeCertName, KubeNodeCertName,
EtcdClientCertName,
EtcdClientCACertName,
} }
} }
@ -226,6 +231,8 @@ func getWorkerCertKeys() []string {
CACertName, CACertName,
KubeProxyCertName, KubeProxyCertName,
KubeNodeCertName, KubeNodeCertName,
EtcdClientCertName,
EtcdClientCACertName,
} }
} }
@ -267,3 +274,12 @@ func GetLocalKubeConfig(configPath, configDir string) string {
baseDir += "/" baseDir += "/"
return fmt.Sprintf("%s%s%s", baseDir, KubeAdminConfigPrefix, fileName) return fmt.Sprintf("%s%s%s", baseDir, KubeAdminConfigPrefix, fileName)
} }
func strCrtToEnv(crtName, crt string) string {
return fmt.Sprintf("%s=%s", getEnvFromName(crtName), crt)
}
func strKeyToEnv(crtName, key string) string {
envName := getEnvFromName(crtName)
return fmt.Sprintf("%s=%s", getKeyEnvFromEnv(envName), key)
}

View File

@ -9,6 +9,7 @@ import (
) )
func runKubeAPI(ctx context.Context, host *hosts.Host, df hosts.DialerFactory, prsMap map[string]v3.PrivateRegistry, kubeAPIProcess v3.Process) error { func runKubeAPI(ctx context.Context, host *hosts.Host, df hosts.DialerFactory, prsMap map[string]v3.PrivateRegistry, kubeAPIProcess v3.Process) error {
imageCfg, hostCfg, healthCheckURL := getProcessConfig(kubeAPIProcess) imageCfg, hostCfg, healthCheckURL := getProcessConfig(kubeAPIProcess)
if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole, prsMap); err != nil { if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole, prsMap); err != nil {
return err return err

View File

@ -104,9 +104,9 @@ data:
{ {
"type": "calico", "type": "calico",
"etcd_endpoints": "{{.EtcdEndpoints}}", "etcd_endpoints": "{{.EtcdEndpoints}}",
"etcd_key_file": "{{.ClientKeyPath}}", "etcd_key_file": "{{.EtcdClientKeyPath}}",
"etcd_cert_file": "{{.ClientCertPath}}", "etcd_cert_file": "{{.EtcdClientCertPath}}",
"etcd_ca_cert_file": "{{.ClientCAPath}}", "etcd_ca_cert_file": "{{.EtcdClientCAPath}}",
"log_level": "info", "log_level": "info",
"mtu": 1500, "mtu": 1500,
"ipam": { "ipam": {
@ -114,10 +114,8 @@ data:
}, },
"policy": { "policy": {
"type": "k8s", "type": "k8s",
"k8s_api_root": "{{.APIRoot}}", "k8s_api_root": "https://__KUBERNETES_SERVICE_HOST__:__KUBERNETES_SERVICE_PORT__",
"k8s_client_certificate": "{{.ClientCertPath}}", "k8s_auth_token": "__SERVICEACCOUNT_TOKEN__"
"k8s_client_key": "{{.ClientKeyPath}}",
"k8s_certificate_authority": "{{.ClientCAPath}}"
}, },
"kubernetes": { "kubernetes": {
"kubeconfig": "{{.KubeCfg}}" "kubeconfig": "{{.KubeCfg}}"
@ -144,9 +142,9 @@ metadata:
name: calico-etcd-secrets name: calico-etcd-secrets
namespace: kube-system namespace: kube-system
data: data:
etcd-key: {{.ClientKey}} etcd-key: {{.EtcdClientKey}}
etcd-cert: {{.ClientCert}} etcd-cert: {{.EtcdClientCert}}
etcd-ca: {{.ClientCA}} etcd-ca: {{.EtcdClientCA}}
--- ---

View File

@ -24,4 +24,4 @@ github.com/coreos/go-semver e214231b295a8ea9479f11b70b35d5acf3556d9
github.com/ugorji/go/codec ccfe18359b55b97855cee1d3f74e5efbda4869dc github.com/ugorji/go/codec ccfe18359b55b97855cee1d3f74e5efbda4869dc
github.com/rancher/norman 151aa66e3e99de7e0d195e2d5ca96b1f95544555 github.com/rancher/norman 151aa66e3e99de7e0d195e2d5ca96b1f95544555
github.com/rancher/types 700826b4d92263e1701650df5429b4bff0ce2edd github.com/rancher/types 933af7a29f7ddea094ff359de3ad396b31146ea9

View File

@ -74,7 +74,7 @@ type TargetNode struct {
} }
type TargetPod struct { type TargetPod struct {
PodName string `json:"podName,omitempty" norman:"required,type=reference[pod]"` PodName string `json:"podName,omitempty" norman:"required,type=reference[/v3/projects/schemas/pod]"`
Condition string `json:"condition,omitempty" norman:"required,options=notrunning|notscheduled|restarts,default=notrunning"` Condition string `json:"condition,omitempty" norman:"required,options=notrunning|notscheduled|restarts,default=notrunning"`
RestartTimes int `json:"restartTimes,omitempty" norman:"min=1"` RestartTimes int `json:"restartTimes,omitempty" norman:"min=1"`
RestartIntervalSeconds int `json:"restartIntervalSeconds,omitempty" norman:"min=1"` RestartIntervalSeconds int `json:"restartIntervalSeconds,omitempty" norman:"min=1"`

View File

@ -9,10 +9,10 @@ type Token struct {
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
Token string `json:"token" norman:"writeOnly,noupdate"` Token string `json:"token" norman:"writeOnly,noupdate"`
UserPrincipal Principal `json:"userPrincipal" norman:"type=reference[Principal]"` UserPrincipal Principal `json:"userPrincipal" norman:"type=reference[principal]"`
GroupPrincipals []Principal `json:"groupPrincipals" norman:"type=array[reference[Principal]]"` GroupPrincipals []Principal `json:"groupPrincipals" norman:"type=array[reference[principal]]"`
ProviderInfo map[string]string `json:"providerInfo,omitempty"` ProviderInfo map[string]string `json:"providerInfo,omitempty"`
UserID string `json:"userId" norman:"type=reference[User]"` UserID string `json:"userId" norman:"type=reference[user]"`
AuthProvider string `json:"authProvider"` AuthProvider string `json:"authProvider"`
TTLMillis int `json:"ttl"` TTLMillis int `json:"ttl"`
LastUpdateTime string `json:"lastUpdateTime"` LastUpdateTime string `json:"lastUpdateTime"`
@ -29,7 +29,7 @@ type User struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
Password string `json:"password,omitempty" norman:"writeOnly,noupdate"` Password string `json:"password,omitempty" norman:"writeOnly,noupdate"`
MustChangePassword bool `json:"mustChangePassword,omitempty"` MustChangePassword bool `json:"mustChangePassword,omitempty"`
PrincipalIDs []string `json:"principalIds,omitempty" norman:"type=array[reference[Principal]]"` PrincipalIDs []string `json:"principalIds,omitempty" norman:"type=array[reference[principal]]"`
Me bool `json:"me,omitempty"` Me bool `json:"me,omitempty"`
} }
@ -45,7 +45,7 @@ type GroupMember struct {
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
GroupName string `json:"groupName,omitempty" norman:"type=reference[group]"` GroupName string `json:"groupName,omitempty" norman:"type=reference[group]"`
PrincipalID string `json:"principalId,omitempty" norman:"type=reference[Principal]"` PrincipalID string `json:"principalId,omitempty" norman:"type=reference[principal]"`
} }
type Principal struct { type Principal struct {
@ -85,7 +85,7 @@ type AuthConfig struct {
Type string `json:"type"` Type string `json:"type"`
Enabled bool `json:"enabled,omitempty"` Enabled bool `json:"enabled,omitempty"`
AccessMode string `json:"accessMode,omitempty" norman:"required,notnullable,type=enum,options=required|restricted|unrestricted"` AccessMode string `json:"accessMode,omitempty" norman:"required,notnullable,type=enum,options=required|restricted|unrestricted"`
AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" norman:"type=array[reference[Principal]]"` AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" norman:"type=array[reference[principal]]"`
} }
//GithubConfig structure contains the github config definition //GithubConfig structure contains the github config definition

View File

@ -16,6 +16,7 @@ var (
type Project struct { type Project struct {
types.Namespaced types.Namespaced
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`

View File

@ -12,12 +12,11 @@ type ClusterConditionType string
const ( const (
// ClusterConditionReady Cluster ready to serve API (healthy when true, unhealthy when false) // ClusterConditionReady Cluster ready to serve API (healthy when true, unhealthy when false)
ClusterConditionReady condition.Cond = "Ready" ClusterConditionReady condition.Cond = "Ready"
ClusterConditionMachinesCreated condition.Cond = "MachinesCreated" ClusterConditionPending condition.Cond = "Pending"
// ClusterConditionProvisioned Cluster is provisioned // ClusterConditionProvisioned Cluster is provisioned
ClusterConditionProvisioned condition.Cond = "Provisioned" ClusterConditionProvisioned condition.Cond = "Provisioned"
ClusterConditionUpdated condition.Cond = "Updated" ClusterConditionUpdated condition.Cond = "Updated"
ClusterConditionRemoved condition.Cond = "Removed" ClusterConditionRemoved condition.Cond = "Removed"
ClusterConditionRegistered condition.Cond = "Registered"
// ClusterConditionNoDiskPressure true when all cluster nodes have sufficient disk // ClusterConditionNoDiskPressure true when all cluster nodes have sufficient disk
ClusterConditionNoDiskPressure condition.Cond = "NoDiskPressure" ClusterConditionNoDiskPressure condition.Cond = "NoDiskPressure"
// ClusterConditionNoMemoryPressure true when all cluster nodes have sufficient memory // ClusterConditionNoMemoryPressure true when all cluster nodes have sufficient memory
@ -43,12 +42,11 @@ type Cluster struct {
} }
type ClusterSpec struct { type ClusterSpec struct {
Nodes []MachineConfig `json:"nodes"` NodePools []NodePool `json:"nodePools"`
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
Description string `json:"description"` Description string `json:"description"`
Internal bool `json:"internal" norman:"nocreate,noupdate"` Internal bool `json:"internal" norman:"nocreate,noupdate"`
ImportedConfig *ImportedConfig `json:"importedConfig" norman:"noupdate"` ImportedConfig *ImportedConfig `json:"importedConfig,omitempty" norman:"nocreate,noupdate"`
EmbeddedConfig *K8sServerConfig `json:"embeddedConfig" norman:"noupdate"`
GoogleKubernetesEngineConfig *GoogleKubernetesEngineConfig `json:"googleKubernetesEngineConfig,omitempty"` GoogleKubernetesEngineConfig *GoogleKubernetesEngineConfig `json:"googleKubernetesEngineConfig,omitempty"`
AzureKubernetesServiceConfig *AzureKubernetesServiceConfig `json:"azureKubernetesServiceConfig,omitempty"` AzureKubernetesServiceConfig *AzureKubernetesServiceConfig `json:"azureKubernetesServiceConfig,omitempty"`
RancherKubernetesEngineConfig *RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty"` RancherKubernetesEngineConfig *RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty"`
@ -60,11 +58,6 @@ type ImportedConfig struct {
KubeConfig string `json:"kubeConfig" norman:"type=password"` KubeConfig string `json:"kubeConfig" norman:"type=password"`
} }
type K8sServerConfig struct {
AdmissionControllers []string `json:"admissionControllers,omitempty"`
ServiceNetCIDR string `json:"serviceNetCidr,omitempty"`
}
type ClusterStatus struct { type ClusterStatus struct {
//Conditions represent the latest available observations of an object's current state: //Conditions represent the latest available observations of an object's current state:
//More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties //More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties
@ -215,6 +208,7 @@ type ClusterRegistrationTokenSpec struct {
type ClusterRegistrationTokenStatus struct { type ClusterRegistrationTokenStatus struct {
Command string `json:"command"` Command string `json:"command"`
NodeCommand string `json:"nodeCommand"`
ManifestURL string `json:"manifestUrl"` ManifestURL string `json:"manifestUrl"`
Token string `json:"token"` Token string `json:"token"`
} }

View File

@ -7,24 +7,24 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
type MachineTemplate struct { type NodeTemplate struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
// Standard objects metadata. More info: // Standard objects metadata. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
// Specification of the desired behavior of the the cluster. More info: // Specification of the desired behavior of the the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Spec MachineTemplateSpec `json:"spec"` Spec NodeTemplateSpec `json:"spec"`
// Most recent observed status of the cluster. More info: // Most recent observed status of the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Status MachineTemplateStatus `json:"status"` Status NodeTemplateStatus `json:"status"`
} }
type MachineTemplateStatus struct { type NodeTemplateStatus struct {
Conditions []MachineTemplateCondition `json:"conditions"` Conditions []NodeTemplateCondition `json:"conditions"`
} }
type MachineTemplateCondition struct { type NodeTemplateCondition struct {
// Type of cluster condition. // Type of cluster condition.
Type string `json:"type"` Type string `json:"type"`
// Status of the condition, one of True, False, Unknown. // Status of the condition, one of True, False, Unknown.
@ -37,14 +37,14 @@ type MachineTemplateCondition struct {
Reason string `json:"reason,omitempty"` Reason string `json:"reason,omitempty"`
} }
type MachineTemplateSpec struct { type NodeTemplateSpec struct {
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
Description string `json:"description"` Description string `json:"description"`
Driver string `json:"driver"` Driver string `json:"driver"`
MachineCommonParams `json:",inline"` NodeCommonParams `json:",inline"`
} }
type Machine struct { type Node struct {
types.Namespaced types.Namespaced
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
@ -53,35 +53,33 @@ type Machine struct {
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
// Specification of the desired behavior of the the cluster. More info: // Specification of the desired behavior of the the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Spec MachineSpec `json:"spec"` Spec NodeSpec `json:"spec"`
// Most recent observed status of the cluster. More info: // Most recent observed status of the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Status MachineStatus `json:"status"` Status NodeStatus `json:"status"`
} }
type MachineStatus struct { type NodeStatus struct {
Conditions []MachineCondition `json:"conditions,omitempty"` Conditions []NodeCondition `json:"conditions,omitempty"`
NodeStatus v1.NodeStatus `json:"nodeStatus,omitempty"` InternalNodeStatus v1.NodeStatus `json:"internalNodeStatus,omitempty"`
NodeName string `json:"nodeName,omitempty"` NodeName string `json:"nodeName,omitempty"`
Requested v1.ResourceList `json:"requested,omitempty"` Requested v1.ResourceList `json:"requested,omitempty"`
Limits v1.ResourceList `json:"limits,omitempty"` Limits v1.ResourceList `json:"limits,omitempty"`
MachineTemplateSpec *MachineTemplateSpec `json:"machineTemplateSpec,omitempty"` NodeTemplateSpec *NodeTemplateSpec `json:"nodeTemplateSpec,omitempty"`
NodeConfig *RKEConfigNode `json:"rkeNode,omitempty"` NodeConfig *RKEConfigNode `json:"rkeNode,omitempty"`
SSHUser string `json:"sshUser,omitempty"`
MachineDriverConfig string `json:"machineDriverConfig,omitempty"`
NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty"` NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty"`
NodeLabels map[string]string `json:"nodeLabels,omitempty"` NodeLabels map[string]string `json:"nodeLabels,omitempty"`
NodeTaints []v1.Taint `json:"nodeTaints,omitempty"` NodeTaints []v1.Taint `json:"nodeTaints,omitempty"`
} }
var ( var (
MachineConditionInitialized condition.Cond = "Initialized" NodeConditionInitialized condition.Cond = "Initialized"
MachineConditionProvisioned condition.Cond = "Provisioned" NodeConditionProvisioned condition.Cond = "Provisioned"
MachineConditionConfigSaved condition.Cond = "Saved" NodeConditionConfigSaved condition.Cond = "Saved"
MachineConditionReady condition.Cond = "Ready" NodeConditionReady condition.Cond = "Ready"
) )
type MachineCondition struct { type NodeCondition struct {
// Type of cluster condition. // Type of cluster condition.
Type condition.Cond `json:"type"` Type condition.Cond `json:"type"`
// Status of the condition, one of True, False, Unknown. // Status of the condition, one of True, False, Unknown.
@ -96,8 +94,12 @@ type MachineCondition struct {
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
} }
type MachineConfig struct { type NodePool struct {
MachineSpec CommonNodeSpec
UUID string `json:"uuid" norman:"nocreate,noupdate"`
HostnamePrefix string `json:"hostnamePrefix" norman:"required"`
Quantity int `json:"quantity" norman:"required,default=1"`
Labels map[string]string `json:"labels"` Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"` Annotations map[string]string `json:"annotations"`
} }
@ -115,20 +117,26 @@ type CustomConfig struct {
SSHKey string `yaml:"ssh_key" json:"sshKey,omitempty"` SSHKey string `yaml:"ssh_key" json:"sshKey,omitempty"`
} }
type MachineSpec struct { type CommonNodeSpec struct {
NodeSpec v1.NodeSpec `json:"nodeSpec"` Etcd bool `json:"etcd"`
ControlPlane bool `json:"controlPlane"`
Worker bool `json:"worker"`
NodeTemplateName string `json:"nodeTemplateName,omitempty" norman:"type=reference[nodeTemplate],noupdate"`
}
type NodeSpec struct {
CommonNodeSpec `json:",inline"`
NodePoolUUID string `json:"nodePoolUuid" norman:"nocreate,noupdate"`
CustomConfig *CustomConfig `json:"customConfig"` CustomConfig *CustomConfig `json:"customConfig"`
Imported bool `json:"imported"` Imported bool `json:"imported"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
RequestedHostname string `json:"requestedHostname,omitempty" norman:"type=dnsLabel,nullable,noupdate,required"` RequestedHostname string `json:"requestedHostname,omitempty" norman:"type=dnsLabel,nullable,noupdate,required"`
ClusterName string `json:"clusterName,omitempty" norman:"type=reference[cluster],noupdate,required"` ClusterName string `json:"clusterName,omitempty" norman:"type=reference[cluster],noupdate,required"`
Role []string `json:"role,omitempty" norman:"noupdate,type=array[enum],options=etcd|worker|controlplane"` InternalNodeSpec v1.NodeSpec `json:"internalNodeSpec"`
MachineTemplateName string `json:"machineTemplateName,omitempty" norman:"type=reference[machineTemplate],noupdate"`
UseInternalIPAddress bool `json:"useInternalIpAddress,omitempty" norman:"default=true,noupdate"`
} }
type MachineCommonParams struct { type NodeCommonParams struct {
AuthCertificateAuthority string `json:"authCertificateAuthority,omitempty"` AuthCertificateAuthority string `json:"authCertificateAuthority,omitempty"`
AuthKey string `json:"authKey,omitempty"` AuthKey string `json:"authKey,omitempty"`
EngineInstallURL string `json:"engineInstallURL,omitempty"` EngineInstallURL string `json:"engineInstallURL,omitempty"`
@ -139,32 +147,33 @@ type MachineCommonParams struct {
EngineLabel map[string]string `json:"engineLabel,omitempty"` EngineLabel map[string]string `json:"engineLabel,omitempty"`
EngineStorageDriver string `json:"engineStorageDriver,omitempty"` EngineStorageDriver string `json:"engineStorageDriver,omitempty"`
EngineEnv map[string]string `json:"engineEnv,omitempty"` EngineEnv map[string]string `json:"engineEnv,omitempty"`
UseInternalIPAddress bool `json:"useInternalIpAddress,omitempty" norman:"default=true,noupdate"`
} }
type MachineDriver struct { type NodeDriver struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
// Standard objects metadata. More info: // Standard objects metadata. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
// Specification of the desired behavior of the the cluster. More info: // Specification of the desired behavior of the the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Spec MachineDriverSpec `json:"spec"` Spec NodeDriverSpec `json:"spec"`
// Most recent observed status of the cluster. More info: // Most recent observed status of the cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
Status MachineDriverStatus `json:"status"` Status NodeDriverStatus `json:"status"`
} }
type MachineDriverStatus struct { type NodeDriverStatus struct {
Conditions []MachineDriverCondition `json:"conditions"` Conditions []NodeDriverCondition `json:"conditions"`
} }
var ( var (
MachineDriverConditionDownloaded condition.Cond = "Downloaded" NodeDriverConditionDownloaded condition.Cond = "Downloaded"
MachineDriverConditionActive condition.Cond = "Active" NodeDriverConditionActive condition.Cond = "Active"
MachineDriverConditionInactive condition.Cond = "Inactive" NodeDriverConditionInactive condition.Cond = "Inactive"
) )
type MachineDriverCondition struct { type NodeDriverCondition struct {
// Type of cluster condition. // Type of cluster condition.
Type string `json:"type"` Type string `json:"type"`
// Status of the condition, one of True, False, Unknown. // Status of the condition, one of True, False, Unknown.
@ -179,7 +188,7 @@ type MachineDriverCondition struct {
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
} }
type MachineDriverSpec struct { type NodeDriverSpec struct {
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
Description string `json:"description"` Description string `json:"description"`
URL string `json:"url" norman:"required"` URL string `json:"url" norman:"required"`

View File

@ -0,0 +1,224 @@
package v3
import (
"github.com/rancher/norman/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type ClusterPipeline struct {
types.Namespaced
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterPipelineSpec `json:"spec"`
Status ClusterPipelineStatus `json:"status"`
}
type Pipeline struct {
types.Namespaced
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec PipelineSpec `json:"spec"`
Status PipelineStatus `json:"status"`
}
type PipelineExecution struct {
types.Namespaced
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec PipelineExecutionSpec `json:"spec"`
Status PipelineExecutionStatus `json:"status"`
}
type PipelineExecutionLog struct {
types.Namespaced
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec PipelineExecutionLogSpec `json:"spec"`
}
type SourceCodeCredential struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec SourceCodeCredentialSpec `json:"spec"`
Status SourceCodeCredentialStatus `json:"status"`
}
type SourceCodeRepository struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec SourceCodeRepositorySpec `json:"spec"`
Status SourceCodeRepositoryStatus `json:"status"`
}
type ClusterPipelineSpec struct {
ClusterName string `json:"clusterName" norman:"type=reference[cluster]"`
Deploy bool `json:"deploy"`
GithubConfig *GithubClusterConfig `json:"githubConfig,omitempty"`
}
type ClusterPipelineStatus struct {
}
type GithubClusterConfig struct {
TLS bool `json:"tls,omitempty"`
Host string `json:"host,omitempty"`
ClientID string `json:"clientId,omitempty"`
ClientSecret string `json:"clientSecret,omitempty"`
RedirectURL string `json:"redirectUrl,omitempty"`
}
type PipelineStatus struct {
State string `json:"state,omitempty" norman:"required,options=active|inactive,default=active"`
NextRun int `json:"nextRun" yaml:"nextRun,omitempty" norman:"default=1,min=1"`
LastExecutionID string `json:"lastExecutionId,omitempty" yaml:"lastExecutionId,omitempty"`
LastRunState string `json:"lastRunState,omitempty" yaml:"lastRunState,omitempty"`
LastStarted string `json:"lastStarted,omitempty" yaml:"lastStarted,omitempty"`
NextStart string `json:"nextStart,omitempty" yaml:"nextStart,omitempty"`
WebHookID string `json:"webhookId,omitempty" yaml:"webhookId,omitempty"`
Token string `json:"token,omitempty" yaml:"token,omitempty"`
}
type PipelineSpec struct {
ProjectName string `json:"projectName" yaml:"projectName" norman:"required,type=reference[project]"`
DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty" norman:"required"`
TriggerWebhook bool `json:"triggerWebhook,omitempty" yaml:"triggerWebhook,omitempty"`
TriggerCronTimezone string `json:"triggerCronTimezone,omitempty" yaml:"triggerCronTimezone,omitempty"`
TriggerCronExpression string `json:"triggerCronExpression,omitempty" yaml:"triggerCronExpression,omitempty"`
Stages []Stage `json:"stages,omitempty" yaml:"stages,omitempty" norman:"required"`
}
type Stage struct {
Name string `json:"name,omitempty" yaml:"name,omitempty" norman:"required"`
Steps []Step `json:"steps,omitempty" yaml:"steps,omitempty" norman:"required"`
}
type Step struct {
SourceCodeConfig *SourceCodeConfig `json:"sourceCodeConfig,omitempty" yaml:"sourceCodeConfig,omitempty"`
RunScriptConfig *RunScriptConfig `json:"runScriptConfig,omitempty" yaml:"runScriptConfig,omitempty"`
PublishImageConfig *PublishImageConfig `json:"publishImageConfig,omitempty" yaml:"publishImageConfig,omitempty"`
//Step timeout in minutes
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
type SourceCodeConfig struct {
URL string `json:"url,omitempty" yaml:"url,omitempty" norman:"required"`
Branch string `json:"branch,omitempty" yaml:"branch,omitempty" `
BranchCondition string `json:"branchCondition,omitempty" yaml:"branchCondition,omitempty" norman:"options=only|except|all"`
SourceCodeCredentialName string `json:"sourceCodeCredentialName,omitempty" yaml:"sourceCodeCredentialName,omitempty" norman:"type=reference[sourceCodeCredential]"`
}
type RunScriptConfig struct {
Image string `json:"image,omitempty" yaml:"image,omitempty" norman:"required"`
IsShell bool `json:"isShell,omitempty" yaml:"isShell,omitempty"`
ShellScript string `json:"shellScript,omitempty" yaml:"shellScript,omitempty"`
Entrypoint string `json:"entrypoint,omitempty" yaml:"enrtypoint,omitempty"`
Command string `json:"command,omitempty" yaml:"command,omitempty"`
Env []string `json:"env,omitempty" yaml:"env,omitempty"`
}
type PublishImageConfig struct {
DockerfilePath string `json:"dockerfilePath,omittempty" yaml:"dockerfilePath,omitempty" norman:"required,default=./Dockerfile"`
BuildContext string `json:"buildContext,omitempty" yaml:"buildContext,omitempty" norman:"required,default=."`
Tag string `json:"tag,omitempty" yaml:"tag,omitempty" norman:"required,default=${CICD_GIT_REPOSITORY_NAME}:${CICD_GIT_BRANCH}"`
}
type PipelineExecutionSpec struct {
ProjectName string `json:"projectName" norman:"required,type=reference[project]"`
PipelineName string `json:"pipelineName" norman:"required,type=reference[pipeline]"`
Run int `json:"run,omitempty" norman:"required,min=1"`
TriggeredBy string `json:"triggeredBy,omitempty" norman:"required,options=user|cron|webhook"`
TriggerUserName string `json:"triggerUserName,omitempty" norman:"type=reference[user]"`
Pipeline Pipeline `json:"pipeline,omitempty" norman:"required"`
}
type PipelineExecutionStatus struct {
Commit string `json:"commit,omitempty"`
State string `json:"state,omitempty"`
Started string `json:"started,omitempty"`
Ended string `json:"ended,omitempty"`
Stages []StageStatus `json:"stages,omitempty"`
}
type StageStatus struct {
State string `json:"state,omitempty"`
Started string `json:"started,omitempty"`
Ended string `json:"ended,omitempty"`
Steps []StepStatus `json:"steps,omitempty"`
}
type StepStatus struct {
State string `json:"state,omitempty"`
Started string `json:"started,omitempty"`
Ended string `json:"ended,omitempty"`
}
type SourceCodeCredentialSpec struct {
ClusterName string `json:"clusterName" norman:"required,type=reference[cluster]"`
SourceCodeType string `json:"sourceCodeType,omitempty" norman:"required,options=github"`
UserName string `json:"userName" norman:"required,type=reference[user]"`
DisplayName string `json:"displayName,omitempty" norman:"required"`
AvatarURL string `json:"avatarUrl,omitempty"`
HTMLURL string `json:"htmlUrl,omitempty"`
LoginName string `json:"loginName,omitempty"`
AccessToken string `json:"accessToken,omitempty"`
}
type SourceCodeCredentialStatus struct {
}
type SourceCodeRepositorySpec struct {
ClusterName string `json:"clusterName" norman:"required,type=reference[cluster]"`
SourceCodeType string `json:"sourceCodeType,omitempty" norman:"required,options=github"`
UserName string `json:"userName" norman:"required,type=reference[user]"`
SourceCodeCredentialName string `json:"sourceCodeCredentialName,omitempty" norman:"required,type=reference[sourceCodeCredential]"`
URL string `json:"url,omitempty"`
Permissions RepoPerm `json:"permissions,omitempty"`
Language string `json:"language,omitempty"`
}
type SourceCodeRepositoryStatus struct {
}
type RepoPerm struct {
Pull bool `json:"pull,omitempty"`
Push bool `json:"push,omitempty"`
Admin bool `json:"admin,omitempty"`
}
type PipelineExecutionLogSpec struct {
ProjectName string `json:"projectName" yaml:"projectName" norman:"required,type=reference[project]"`
PipelineExecutionName string `json:"pipelineExecutionName,omitempty" norman:"type=reference[pipelineExecution]"`
Stage int `json:"stage,omitempty" norman:"min=1"`
Step int `json:"step,omitempty" norman:"min=1"`
Line int `json:"line,omitempty"`
Message string `json:"message,omitempty"`
}
type AuthAppInput struct {
SourceCodeType string `json:"sourceCodeType,omitempty" norman:"type=string,required"`
RedirectURL string `json:"redirectUrl,omitempty" norman:"type=string"`
TLS bool `json:"tls,omitempty"`
Host string `json:"host,omitempty"`
ClientID string `json:"clientId,omitempty" norman:"type=string,required"`
ClientSecret string `json:"clientSecret,omitempty" norman:"type=string,required"`
Code string `json:"code,omitempty" norman:"type=string,required"`
}
type AuthUserInput struct {
SourceCodeType string `json:"sourceCodeType,omitempty" norman:"type=string,required"`
RedirectURL string `json:"redirectUrl,omitempty" norman:"type=string"`
Code string `json:"code,omitempty" norman:"type=string,required"`
}

View File

@ -85,7 +85,7 @@ type RKESystemImages struct {
type RKEConfigNode struct { type RKEConfigNode struct {
// Name of the host provisioned via docker machine // Name of the host provisioned via docker machine
MachineName string `yaml:"machine_name,omitempty" json:"machineName,omitempty" norman:"type=reference[machine]"` NodeName string `yaml:"-" json:"-" norman:"type=reference[node]"`
// IP or FQDN that is fully resolvable and used for SSH communication // IP or FQDN that is fully resolvable and used for SSH communication
Address string `yaml:"address" json:"address,omitempty"` Address string `yaml:"address" json:"address,omitempty"`
// Optional - Internal address that will be used for components communication // Optional - Internal address that will be used for components communication
@ -124,6 +124,16 @@ type RKEConfigServices struct {
type ETCDService struct { type ETCDService struct {
// Base service properties // Base service properties
BaseService `yaml:",inline" json:",inline"` BaseService `yaml:",inline" json:",inline"`
// List of etcd urls
ExternalURLs []string `yaml:"external_urls" json:"externalUrls,omitempty"`
// External CA certificate
CACert string `yaml:"ca_cert" json:"caCert,omitempty"`
// External Client certificate
Cert string `yaml:"cert" json:"cert,omitempty"`
// External Client key
Key string `yaml:"key" json:"key,omitempty"`
// External etcd prefix
Path string `yaml:"path" json:"path,omitempty"`
} }
type KubeAPIService struct { type KubeAPIService struct {

View File

@ -0,0 +1,252 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
ClusterPipelineGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "ClusterPipeline",
}
ClusterPipelineResource = metav1.APIResource{
Name: "clusterpipelines",
SingularName: "clusterpipeline",
Namespaced: true,
Kind: ClusterPipelineGroupVersionKind.Kind,
}
)
type ClusterPipelineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterPipeline
}
type ClusterPipelineHandlerFunc func(key string, obj *ClusterPipeline) error
type ClusterPipelineLister interface {
List(namespace string, selector labels.Selector) (ret []*ClusterPipeline, err error)
Get(namespace, name string) (*ClusterPipeline, error)
}
type ClusterPipelineController interface {
Informer() cache.SharedIndexInformer
Lister() ClusterPipelineLister
AddHandler(name string, handler ClusterPipelineHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler ClusterPipelineHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type ClusterPipelineInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*ClusterPipeline) (*ClusterPipeline, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*ClusterPipeline, error)
Get(name string, opts metav1.GetOptions) (*ClusterPipeline, error)
Update(*ClusterPipeline) (*ClusterPipeline, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*ClusterPipelineList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() ClusterPipelineController
AddHandler(name string, sync ClusterPipelineHandlerFunc)
AddLifecycle(name string, lifecycle ClusterPipelineLifecycle)
AddClusterScopedHandler(name, clusterName string, sync ClusterPipelineHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle ClusterPipelineLifecycle)
}
type clusterPipelineLister struct {
controller *clusterPipelineController
}
func (l *clusterPipelineLister) List(namespace string, selector labels.Selector) (ret []*ClusterPipeline, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*ClusterPipeline))
})
return
}
func (l *clusterPipelineLister) Get(namespace, name string) (*ClusterPipeline, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: ClusterPipelineGroupVersionKind.Group,
Resource: "clusterPipeline",
}, name)
}
return obj.(*ClusterPipeline), nil
}
type clusterPipelineController struct {
controller.GenericController
}
func (c *clusterPipelineController) Lister() ClusterPipelineLister {
return &clusterPipelineLister{
controller: c,
}
}
func (c *clusterPipelineController) AddHandler(name string, handler ClusterPipelineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*ClusterPipeline))
})
}
func (c *clusterPipelineController) AddClusterScopedHandler(name, cluster string, handler ClusterPipelineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*ClusterPipeline))
})
}
type clusterPipelineFactory struct {
}
func (c clusterPipelineFactory) Object() runtime.Object {
return &ClusterPipeline{}
}
func (c clusterPipelineFactory) List() runtime.Object {
return &ClusterPipelineList{}
}
func (s *clusterPipelineClient) Controller() ClusterPipelineController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.clusterPipelineControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(ClusterPipelineGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &clusterPipelineController{
GenericController: genericController,
}
s.client.clusterPipelineControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type clusterPipelineClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller ClusterPipelineController
}
func (s *clusterPipelineClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *clusterPipelineClient) Create(o *ClusterPipeline) (*ClusterPipeline, error) {
obj, err := s.objectClient.Create(o)
return obj.(*ClusterPipeline), err
}
func (s *clusterPipelineClient) Get(name string, opts metav1.GetOptions) (*ClusterPipeline, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*ClusterPipeline), err
}
func (s *clusterPipelineClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*ClusterPipeline, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*ClusterPipeline), err
}
func (s *clusterPipelineClient) Update(o *ClusterPipeline) (*ClusterPipeline, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*ClusterPipeline), err
}
func (s *clusterPipelineClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *clusterPipelineClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *clusterPipelineClient) List(opts metav1.ListOptions) (*ClusterPipelineList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*ClusterPipelineList), err
}
func (s *clusterPipelineClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *clusterPipelineClient) Patch(o *ClusterPipeline, data []byte, subresources ...string) (*ClusterPipeline, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*ClusterPipeline), err
}
func (s *clusterPipelineClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *clusterPipelineClient) AddHandler(name string, sync ClusterPipelineHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *clusterPipelineClient) AddLifecycle(name string, lifecycle ClusterPipelineLifecycle) {
sync := NewClusterPipelineLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *clusterPipelineClient) AddClusterScopedHandler(name, clusterName string, sync ClusterPipelineHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *clusterPipelineClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle ClusterPipelineLifecycle) {
sync := NewClusterPipelineLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type ClusterPipelineLifecycle interface {
Create(obj *ClusterPipeline) (*ClusterPipeline, error)
Remove(obj *ClusterPipeline) (*ClusterPipeline, error)
Updated(obj *ClusterPipeline) (*ClusterPipeline, error)
}
type clusterPipelineLifecycleAdapter struct {
lifecycle ClusterPipelineLifecycle
}
func (w *clusterPipelineLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*ClusterPipeline))
if o == nil {
return nil, err
}
return o, err
}
func (w *clusterPipelineLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*ClusterPipeline))
if o == nil {
return nil, err
}
return o, err
}
func (w *clusterPipelineLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*ClusterPipeline))
if o == nil {
return nil, err
}
return o, err
}
func NewClusterPipelineLifecycleAdapter(name string, clusterScoped bool, client ClusterPipelineInterface, l ClusterPipelineLifecycle) ClusterPipelineHandlerFunc {
adapter := &clusterPipelineLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *ClusterPipeline) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -14,9 +14,9 @@ type Interface interface {
RESTClient() rest.Interface RESTClient() rest.Interface
controller.Starter controller.Starter
MachinesGetter NodesGetter
MachineDriversGetter NodeDriversGetter
MachineTemplatesGetter NodeTemplatesGetter
ProjectsGetter ProjectsGetter
GlobalRolesGetter GlobalRolesGetter
GlobalRoleBindingsGetter GlobalRoleBindingsGetter
@ -45,6 +45,12 @@ type Interface interface {
NotifiersGetter NotifiersGetter
ClusterAlertsGetter ClusterAlertsGetter
ProjectAlertsGetter ProjectAlertsGetter
SourceCodeCredentialsGetter
ClusterPipelinesGetter
PipelinesGetter
PipelineExecutionsGetter
SourceCodeRepositoriesGetter
PipelineExecutionLogsGetter
} }
type Client struct { type Client struct {
@ -52,9 +58,9 @@ type Client struct {
restClient rest.Interface restClient rest.Interface
starters []controller.Starter starters []controller.Starter
machineControllers map[string]MachineController nodeControllers map[string]NodeController
machineDriverControllers map[string]MachineDriverController nodeDriverControllers map[string]NodeDriverController
machineTemplateControllers map[string]MachineTemplateController nodeTemplateControllers map[string]NodeTemplateController
projectControllers map[string]ProjectController projectControllers map[string]ProjectController
globalRoleControllers map[string]GlobalRoleController globalRoleControllers map[string]GlobalRoleController
globalRoleBindingControllers map[string]GlobalRoleBindingController globalRoleBindingControllers map[string]GlobalRoleBindingController
@ -83,6 +89,12 @@ type Client struct {
notifierControllers map[string]NotifierController notifierControllers map[string]NotifierController
clusterAlertControllers map[string]ClusterAlertController clusterAlertControllers map[string]ClusterAlertController
projectAlertControllers map[string]ProjectAlertController projectAlertControllers map[string]ProjectAlertController
sourceCodeCredentialControllers map[string]SourceCodeCredentialController
clusterPipelineControllers map[string]ClusterPipelineController
pipelineControllers map[string]PipelineController
pipelineExecutionControllers map[string]PipelineExecutionController
sourceCodeRepositoryControllers map[string]SourceCodeRepositoryController
pipelineExecutionLogControllers map[string]PipelineExecutionLogController
} }
func NewForConfig(config rest.Config) (Interface, error) { func NewForConfig(config rest.Config) (Interface, error) {
@ -99,9 +111,9 @@ func NewForConfig(config rest.Config) (Interface, error) {
return &Client{ return &Client{
restClient: restClient, restClient: restClient,
machineControllers: map[string]MachineController{}, nodeControllers: map[string]NodeController{},
machineDriverControllers: map[string]MachineDriverController{}, nodeDriverControllers: map[string]NodeDriverController{},
machineTemplateControllers: map[string]MachineTemplateController{}, nodeTemplateControllers: map[string]NodeTemplateController{},
projectControllers: map[string]ProjectController{}, projectControllers: map[string]ProjectController{},
globalRoleControllers: map[string]GlobalRoleController{}, globalRoleControllers: map[string]GlobalRoleController{},
globalRoleBindingControllers: map[string]GlobalRoleBindingController{}, globalRoleBindingControllers: map[string]GlobalRoleBindingController{},
@ -130,6 +142,12 @@ func NewForConfig(config rest.Config) (Interface, error) {
notifierControllers: map[string]NotifierController{}, notifierControllers: map[string]NotifierController{},
clusterAlertControllers: map[string]ClusterAlertController{}, clusterAlertControllers: map[string]ClusterAlertController{},
projectAlertControllers: map[string]ProjectAlertController{}, projectAlertControllers: map[string]ProjectAlertController{},
sourceCodeCredentialControllers: map[string]SourceCodeCredentialController{},
clusterPipelineControllers: map[string]ClusterPipelineController{},
pipelineControllers: map[string]PipelineController{},
pipelineExecutionControllers: map[string]PipelineExecutionController{},
sourceCodeRepositoryControllers: map[string]SourceCodeRepositoryController{},
pipelineExecutionLogControllers: map[string]PipelineExecutionLogController{},
}, nil }, nil
} }
@ -145,39 +163,39 @@ func (c *Client) Start(ctx context.Context, threadiness int) error {
return controller.Start(ctx, threadiness, c.starters...) return controller.Start(ctx, threadiness, c.starters...)
} }
type MachinesGetter interface { type NodesGetter interface {
Machines(namespace string) MachineInterface Nodes(namespace string) NodeInterface
} }
func (c *Client) Machines(namespace string) MachineInterface { func (c *Client) Nodes(namespace string) NodeInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &MachineResource, MachineGroupVersionKind, machineFactory{}) objectClient := clientbase.NewObjectClient(namespace, c.restClient, &NodeResource, NodeGroupVersionKind, nodeFactory{})
return &machineClient{ return &nodeClient{
ns: namespace, ns: namespace,
client: c, client: c,
objectClient: objectClient, objectClient: objectClient,
} }
} }
type MachineDriversGetter interface { type NodeDriversGetter interface {
MachineDrivers(namespace string) MachineDriverInterface NodeDrivers(namespace string) NodeDriverInterface
} }
func (c *Client) MachineDrivers(namespace string) MachineDriverInterface { func (c *Client) NodeDrivers(namespace string) NodeDriverInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &MachineDriverResource, MachineDriverGroupVersionKind, machineDriverFactory{}) objectClient := clientbase.NewObjectClient(namespace, c.restClient, &NodeDriverResource, NodeDriverGroupVersionKind, nodeDriverFactory{})
return &machineDriverClient{ return &nodeDriverClient{
ns: namespace, ns: namespace,
client: c, client: c,
objectClient: objectClient, objectClient: objectClient,
} }
} }
type MachineTemplatesGetter interface { type NodeTemplatesGetter interface {
MachineTemplates(namespace string) MachineTemplateInterface NodeTemplates(namespace string) NodeTemplateInterface
} }
func (c *Client) MachineTemplates(namespace string) MachineTemplateInterface { func (c *Client) NodeTemplates(namespace string) NodeTemplateInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &MachineTemplateResource, MachineTemplateGroupVersionKind, machineTemplateFactory{}) objectClient := clientbase.NewObjectClient(namespace, c.restClient, &NodeTemplateResource, NodeTemplateGroupVersionKind, nodeTemplateFactory{})
return &machineTemplateClient{ return &nodeTemplateClient{
ns: namespace, ns: namespace,
client: c, client: c,
objectClient: objectClient, objectClient: objectClient,
@ -547,3 +565,81 @@ func (c *Client) ProjectAlerts(namespace string) ProjectAlertInterface {
objectClient: objectClient, objectClient: objectClient,
} }
} }
type SourceCodeCredentialsGetter interface {
SourceCodeCredentials(namespace string) SourceCodeCredentialInterface
}
func (c *Client) SourceCodeCredentials(namespace string) SourceCodeCredentialInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &SourceCodeCredentialResource, SourceCodeCredentialGroupVersionKind, sourceCodeCredentialFactory{})
return &sourceCodeCredentialClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}
type ClusterPipelinesGetter interface {
ClusterPipelines(namespace string) ClusterPipelineInterface
}
func (c *Client) ClusterPipelines(namespace string) ClusterPipelineInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &ClusterPipelineResource, ClusterPipelineGroupVersionKind, clusterPipelineFactory{})
return &clusterPipelineClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}
type PipelinesGetter interface {
Pipelines(namespace string) PipelineInterface
}
func (c *Client) Pipelines(namespace string) PipelineInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &PipelineResource, PipelineGroupVersionKind, pipelineFactory{})
return &pipelineClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}
type PipelineExecutionsGetter interface {
PipelineExecutions(namespace string) PipelineExecutionInterface
}
func (c *Client) PipelineExecutions(namespace string) PipelineExecutionInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &PipelineExecutionResource, PipelineExecutionGroupVersionKind, pipelineExecutionFactory{})
return &pipelineExecutionClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}
type SourceCodeRepositoriesGetter interface {
SourceCodeRepositories(namespace string) SourceCodeRepositoryInterface
}
func (c *Client) SourceCodeRepositories(namespace string) SourceCodeRepositoryInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &SourceCodeRepositoryResource, SourceCodeRepositoryGroupVersionKind, sourceCodeRepositoryFactory{})
return &sourceCodeRepositoryClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}
type PipelineExecutionLogsGetter interface {
PipelineExecutionLogs(namespace string) PipelineExecutionLogInterface
}
func (c *Client) PipelineExecutionLogs(namespace string) PipelineExecutionLogInterface {
objectClient := clientbase.NewObjectClient(namespace, c.restClient, &PipelineExecutionLogResource, PipelineExecutionLogGroupVersionKind, pipelineExecutionLogFactory{})
return &pipelineExecutionLogClient{
ns: namespace,
client: c,
objectClient: objectClient,
}
}

View File

@ -1,252 +0,0 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
MachineGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "Machine",
}
MachineResource = metav1.APIResource{
Name: "machines",
SingularName: "machine",
Namespaced: true,
Kind: MachineGroupVersionKind.Kind,
}
)
type MachineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Machine
}
type MachineHandlerFunc func(key string, obj *Machine) error
type MachineLister interface {
List(namespace string, selector labels.Selector) (ret []*Machine, err error)
Get(namespace, name string) (*Machine, error)
}
type MachineController interface {
Informer() cache.SharedIndexInformer
Lister() MachineLister
AddHandler(name string, handler MachineHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler MachineHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type MachineInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*Machine) (*Machine, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Machine, error)
Get(name string, opts metav1.GetOptions) (*Machine, error)
Update(*Machine) (*Machine, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*MachineList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() MachineController
AddHandler(name string, sync MachineHandlerFunc)
AddLifecycle(name string, lifecycle MachineLifecycle)
AddClusterScopedHandler(name, clusterName string, sync MachineHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineLifecycle)
}
type machineLister struct {
controller *machineController
}
func (l *machineLister) List(namespace string, selector labels.Selector) (ret []*Machine, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*Machine))
})
return
}
func (l *machineLister) Get(namespace, name string) (*Machine, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: MachineGroupVersionKind.Group,
Resource: "machine",
}, name)
}
return obj.(*Machine), nil
}
type machineController struct {
controller.GenericController
}
func (c *machineController) Lister() MachineLister {
return &machineLister{
controller: c,
}
}
func (c *machineController) AddHandler(name string, handler MachineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*Machine))
})
}
func (c *machineController) AddClusterScopedHandler(name, cluster string, handler MachineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*Machine))
})
}
type machineFactory struct {
}
func (c machineFactory) Object() runtime.Object {
return &Machine{}
}
func (c machineFactory) List() runtime.Object {
return &MachineList{}
}
func (s *machineClient) Controller() MachineController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.machineControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(MachineGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &machineController{
GenericController: genericController,
}
s.client.machineControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type machineClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller MachineController
}
func (s *machineClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *machineClient) Create(o *Machine) (*Machine, error) {
obj, err := s.objectClient.Create(o)
return obj.(*Machine), err
}
func (s *machineClient) Get(name string, opts metav1.GetOptions) (*Machine, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*Machine), err
}
func (s *machineClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Machine, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*Machine), err
}
func (s *machineClient) Update(o *Machine) (*Machine, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*Machine), err
}
func (s *machineClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *machineClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *machineClient) List(opts metav1.ListOptions) (*MachineList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*MachineList), err
}
func (s *machineClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *machineClient) Patch(o *Machine, data []byte, subresources ...string) (*Machine, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*Machine), err
}
func (s *machineClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *machineClient) AddHandler(name string, sync MachineHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *machineClient) AddLifecycle(name string, lifecycle MachineLifecycle) {
sync := NewMachineLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *machineClient) AddClusterScopedHandler(name, clusterName string, sync MachineHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *machineClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineLifecycle) {
sync := NewMachineLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -1,251 +0,0 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
MachineDriverGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "MachineDriver",
}
MachineDriverResource = metav1.APIResource{
Name: "machinedrivers",
SingularName: "machinedriver",
Namespaced: false,
Kind: MachineDriverGroupVersionKind.Kind,
}
)
type MachineDriverList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []MachineDriver
}
type MachineDriverHandlerFunc func(key string, obj *MachineDriver) error
type MachineDriverLister interface {
List(namespace string, selector labels.Selector) (ret []*MachineDriver, err error)
Get(namespace, name string) (*MachineDriver, error)
}
type MachineDriverController interface {
Informer() cache.SharedIndexInformer
Lister() MachineDriverLister
AddHandler(name string, handler MachineDriverHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler MachineDriverHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type MachineDriverInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*MachineDriver) (*MachineDriver, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*MachineDriver, error)
Get(name string, opts metav1.GetOptions) (*MachineDriver, error)
Update(*MachineDriver) (*MachineDriver, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*MachineDriverList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() MachineDriverController
AddHandler(name string, sync MachineDriverHandlerFunc)
AddLifecycle(name string, lifecycle MachineDriverLifecycle)
AddClusterScopedHandler(name, clusterName string, sync MachineDriverHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineDriverLifecycle)
}
type machineDriverLister struct {
controller *machineDriverController
}
func (l *machineDriverLister) List(namespace string, selector labels.Selector) (ret []*MachineDriver, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*MachineDriver))
})
return
}
func (l *machineDriverLister) Get(namespace, name string) (*MachineDriver, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: MachineDriverGroupVersionKind.Group,
Resource: "machineDriver",
}, name)
}
return obj.(*MachineDriver), nil
}
type machineDriverController struct {
controller.GenericController
}
func (c *machineDriverController) Lister() MachineDriverLister {
return &machineDriverLister{
controller: c,
}
}
func (c *machineDriverController) AddHandler(name string, handler MachineDriverHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*MachineDriver))
})
}
func (c *machineDriverController) AddClusterScopedHandler(name, cluster string, handler MachineDriverHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*MachineDriver))
})
}
type machineDriverFactory struct {
}
func (c machineDriverFactory) Object() runtime.Object {
return &MachineDriver{}
}
func (c machineDriverFactory) List() runtime.Object {
return &MachineDriverList{}
}
func (s *machineDriverClient) Controller() MachineDriverController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.machineDriverControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(MachineDriverGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &machineDriverController{
GenericController: genericController,
}
s.client.machineDriverControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type machineDriverClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller MachineDriverController
}
func (s *machineDriverClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *machineDriverClient) Create(o *MachineDriver) (*MachineDriver, error) {
obj, err := s.objectClient.Create(o)
return obj.(*MachineDriver), err
}
func (s *machineDriverClient) Get(name string, opts metav1.GetOptions) (*MachineDriver, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*MachineDriver), err
}
func (s *machineDriverClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*MachineDriver, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*MachineDriver), err
}
func (s *machineDriverClient) Update(o *MachineDriver) (*MachineDriver, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*MachineDriver), err
}
func (s *machineDriverClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *machineDriverClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *machineDriverClient) List(opts metav1.ListOptions) (*MachineDriverList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*MachineDriverList), err
}
func (s *machineDriverClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *machineDriverClient) Patch(o *MachineDriver, data []byte, subresources ...string) (*MachineDriver, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*MachineDriver), err
}
func (s *machineDriverClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *machineDriverClient) AddHandler(name string, sync MachineDriverHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *machineDriverClient) AddLifecycle(name string, lifecycle MachineDriverLifecycle) {
sync := NewMachineDriverLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *machineDriverClient) AddClusterScopedHandler(name, clusterName string, sync MachineDriverHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *machineDriverClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineDriverLifecycle) {
sync := NewMachineDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -1,51 +0,0 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type MachineDriverLifecycle interface {
Create(obj *MachineDriver) (*MachineDriver, error)
Remove(obj *MachineDriver) (*MachineDriver, error)
Updated(obj *MachineDriver) (*MachineDriver, error)
}
type machineDriverLifecycleAdapter struct {
lifecycle MachineDriverLifecycle
}
func (w *machineDriverLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*MachineDriver))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineDriverLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*MachineDriver))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineDriverLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*MachineDriver))
if o == nil {
return nil, err
}
return o, err
}
func NewMachineDriverLifecycleAdapter(name string, clusterScoped bool, client MachineDriverInterface, l MachineDriverLifecycle) MachineDriverHandlerFunc {
adapter := &machineDriverLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *MachineDriver) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -1,51 +0,0 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type MachineLifecycle interface {
Create(obj *Machine) (*Machine, error)
Remove(obj *Machine) (*Machine, error)
Updated(obj *Machine) (*Machine, error)
}
type machineLifecycleAdapter struct {
lifecycle MachineLifecycle
}
func (w *machineLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*Machine))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*Machine))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*Machine))
if o == nil {
return nil, err
}
return o, err
}
func NewMachineLifecycleAdapter(name string, clusterScoped bool, client MachineInterface, l MachineLifecycle) MachineHandlerFunc {
adapter := &machineLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *Machine) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -1,251 +0,0 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
MachineTemplateGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "MachineTemplate",
}
MachineTemplateResource = metav1.APIResource{
Name: "machinetemplates",
SingularName: "machinetemplate",
Namespaced: false,
Kind: MachineTemplateGroupVersionKind.Kind,
}
)
type MachineTemplateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []MachineTemplate
}
type MachineTemplateHandlerFunc func(key string, obj *MachineTemplate) error
type MachineTemplateLister interface {
List(namespace string, selector labels.Selector) (ret []*MachineTemplate, err error)
Get(namespace, name string) (*MachineTemplate, error)
}
type MachineTemplateController interface {
Informer() cache.SharedIndexInformer
Lister() MachineTemplateLister
AddHandler(name string, handler MachineTemplateHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler MachineTemplateHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type MachineTemplateInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*MachineTemplate) (*MachineTemplate, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*MachineTemplate, error)
Get(name string, opts metav1.GetOptions) (*MachineTemplate, error)
Update(*MachineTemplate) (*MachineTemplate, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*MachineTemplateList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() MachineTemplateController
AddHandler(name string, sync MachineTemplateHandlerFunc)
AddLifecycle(name string, lifecycle MachineTemplateLifecycle)
AddClusterScopedHandler(name, clusterName string, sync MachineTemplateHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineTemplateLifecycle)
}
type machineTemplateLister struct {
controller *machineTemplateController
}
func (l *machineTemplateLister) List(namespace string, selector labels.Selector) (ret []*MachineTemplate, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*MachineTemplate))
})
return
}
func (l *machineTemplateLister) Get(namespace, name string) (*MachineTemplate, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: MachineTemplateGroupVersionKind.Group,
Resource: "machineTemplate",
}, name)
}
return obj.(*MachineTemplate), nil
}
type machineTemplateController struct {
controller.GenericController
}
func (c *machineTemplateController) Lister() MachineTemplateLister {
return &machineTemplateLister{
controller: c,
}
}
func (c *machineTemplateController) AddHandler(name string, handler MachineTemplateHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*MachineTemplate))
})
}
func (c *machineTemplateController) AddClusterScopedHandler(name, cluster string, handler MachineTemplateHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*MachineTemplate))
})
}
type machineTemplateFactory struct {
}
func (c machineTemplateFactory) Object() runtime.Object {
return &MachineTemplate{}
}
func (c machineTemplateFactory) List() runtime.Object {
return &MachineTemplateList{}
}
func (s *machineTemplateClient) Controller() MachineTemplateController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.machineTemplateControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(MachineTemplateGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &machineTemplateController{
GenericController: genericController,
}
s.client.machineTemplateControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type machineTemplateClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller MachineTemplateController
}
func (s *machineTemplateClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *machineTemplateClient) Create(o *MachineTemplate) (*MachineTemplate, error) {
obj, err := s.objectClient.Create(o)
return obj.(*MachineTemplate), err
}
func (s *machineTemplateClient) Get(name string, opts metav1.GetOptions) (*MachineTemplate, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*MachineTemplate), err
}
func (s *machineTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*MachineTemplate, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*MachineTemplate), err
}
func (s *machineTemplateClient) Update(o *MachineTemplate) (*MachineTemplate, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*MachineTemplate), err
}
func (s *machineTemplateClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *machineTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *machineTemplateClient) List(opts metav1.ListOptions) (*MachineTemplateList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*MachineTemplateList), err
}
func (s *machineTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *machineTemplateClient) Patch(o *MachineTemplate, data []byte, subresources ...string) (*MachineTemplate, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*MachineTemplate), err
}
func (s *machineTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *machineTemplateClient) AddHandler(name string, sync MachineTemplateHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *machineTemplateClient) AddLifecycle(name string, lifecycle MachineTemplateLifecycle) {
sync := NewMachineTemplateLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *machineTemplateClient) AddClusterScopedHandler(name, clusterName string, sync MachineTemplateHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *machineTemplateClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle MachineTemplateLifecycle) {
sync := NewMachineTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -1,51 +0,0 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type MachineTemplateLifecycle interface {
Create(obj *MachineTemplate) (*MachineTemplate, error)
Remove(obj *MachineTemplate) (*MachineTemplate, error)
Updated(obj *MachineTemplate) (*MachineTemplate, error)
}
type machineTemplateLifecycleAdapter struct {
lifecycle MachineTemplateLifecycle
}
func (w *machineTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*MachineTemplate))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*MachineTemplate))
if o == nil {
return nil, err
}
return o, err
}
func (w *machineTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*MachineTemplate))
if o == nil {
return nil, err
}
return o, err
}
func NewMachineTemplateLifecycleAdapter(name string, clusterScoped bool, client MachineTemplateInterface, l MachineTemplateLifecycle) MachineTemplateHandlerFunc {
adapter := &machineTemplateLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *MachineTemplate) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,252 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
NodeGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "Node",
}
NodeResource = metav1.APIResource{
Name: "nodes",
SingularName: "node",
Namespaced: true,
Kind: NodeGroupVersionKind.Kind,
}
)
type NodeList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Node
}
type NodeHandlerFunc func(key string, obj *Node) error
type NodeLister interface {
List(namespace string, selector labels.Selector) (ret []*Node, err error)
Get(namespace, name string) (*Node, error)
}
type NodeController interface {
Informer() cache.SharedIndexInformer
Lister() NodeLister
AddHandler(name string, handler NodeHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler NodeHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type NodeInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*Node) (*Node, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Node, error)
Get(name string, opts metav1.GetOptions) (*Node, error)
Update(*Node) (*Node, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*NodeList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() NodeController
AddHandler(name string, sync NodeHandlerFunc)
AddLifecycle(name string, lifecycle NodeLifecycle)
AddClusterScopedHandler(name, clusterName string, sync NodeHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeLifecycle)
}
type nodeLister struct {
controller *nodeController
}
func (l *nodeLister) List(namespace string, selector labels.Selector) (ret []*Node, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*Node))
})
return
}
func (l *nodeLister) Get(namespace, name string) (*Node, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: NodeGroupVersionKind.Group,
Resource: "node",
}, name)
}
return obj.(*Node), nil
}
type nodeController struct {
controller.GenericController
}
func (c *nodeController) Lister() NodeLister {
return &nodeLister{
controller: c,
}
}
func (c *nodeController) AddHandler(name string, handler NodeHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*Node))
})
}
func (c *nodeController) AddClusterScopedHandler(name, cluster string, handler NodeHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*Node))
})
}
type nodeFactory struct {
}
func (c nodeFactory) Object() runtime.Object {
return &Node{}
}
func (c nodeFactory) List() runtime.Object {
return &NodeList{}
}
func (s *nodeClient) Controller() NodeController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.nodeControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(NodeGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &nodeController{
GenericController: genericController,
}
s.client.nodeControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type nodeClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller NodeController
}
func (s *nodeClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *nodeClient) Create(o *Node) (*Node, error) {
obj, err := s.objectClient.Create(o)
return obj.(*Node), err
}
func (s *nodeClient) Get(name string, opts metav1.GetOptions) (*Node, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*Node), err
}
func (s *nodeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Node, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*Node), err
}
func (s *nodeClient) Update(o *Node) (*Node, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*Node), err
}
func (s *nodeClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *nodeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *nodeClient) List(opts metav1.ListOptions) (*NodeList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*NodeList), err
}
func (s *nodeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *nodeClient) Patch(o *Node, data []byte, subresources ...string) (*Node, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*Node), err
}
func (s *nodeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *nodeClient) AddHandler(name string, sync NodeHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *nodeClient) AddLifecycle(name string, lifecycle NodeLifecycle) {
sync := NewNodeLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *nodeClient) AddClusterScopedHandler(name, clusterName string, sync NodeHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *nodeClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeLifecycle) {
sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,251 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
NodeDriverGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "NodeDriver",
}
NodeDriverResource = metav1.APIResource{
Name: "nodedrivers",
SingularName: "nodedriver",
Namespaced: false,
Kind: NodeDriverGroupVersionKind.Kind,
}
)
type NodeDriverList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NodeDriver
}
type NodeDriverHandlerFunc func(key string, obj *NodeDriver) error
type NodeDriverLister interface {
List(namespace string, selector labels.Selector) (ret []*NodeDriver, err error)
Get(namespace, name string) (*NodeDriver, error)
}
type NodeDriverController interface {
Informer() cache.SharedIndexInformer
Lister() NodeDriverLister
AddHandler(name string, handler NodeDriverHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler NodeDriverHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type NodeDriverInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*NodeDriver) (*NodeDriver, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*NodeDriver, error)
Get(name string, opts metav1.GetOptions) (*NodeDriver, error)
Update(*NodeDriver) (*NodeDriver, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*NodeDriverList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() NodeDriverController
AddHandler(name string, sync NodeDriverHandlerFunc)
AddLifecycle(name string, lifecycle NodeDriverLifecycle)
AddClusterScopedHandler(name, clusterName string, sync NodeDriverHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeDriverLifecycle)
}
type nodeDriverLister struct {
controller *nodeDriverController
}
func (l *nodeDriverLister) List(namespace string, selector labels.Selector) (ret []*NodeDriver, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*NodeDriver))
})
return
}
func (l *nodeDriverLister) Get(namespace, name string) (*NodeDriver, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: NodeDriverGroupVersionKind.Group,
Resource: "nodeDriver",
}, name)
}
return obj.(*NodeDriver), nil
}
type nodeDriverController struct {
controller.GenericController
}
func (c *nodeDriverController) Lister() NodeDriverLister {
return &nodeDriverLister{
controller: c,
}
}
func (c *nodeDriverController) AddHandler(name string, handler NodeDriverHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*NodeDriver))
})
}
func (c *nodeDriverController) AddClusterScopedHandler(name, cluster string, handler NodeDriverHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*NodeDriver))
})
}
type nodeDriverFactory struct {
}
func (c nodeDriverFactory) Object() runtime.Object {
return &NodeDriver{}
}
func (c nodeDriverFactory) List() runtime.Object {
return &NodeDriverList{}
}
func (s *nodeDriverClient) Controller() NodeDriverController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.nodeDriverControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(NodeDriverGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &nodeDriverController{
GenericController: genericController,
}
s.client.nodeDriverControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type nodeDriverClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller NodeDriverController
}
func (s *nodeDriverClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *nodeDriverClient) Create(o *NodeDriver) (*NodeDriver, error) {
obj, err := s.objectClient.Create(o)
return obj.(*NodeDriver), err
}
func (s *nodeDriverClient) Get(name string, opts metav1.GetOptions) (*NodeDriver, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*NodeDriver), err
}
func (s *nodeDriverClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*NodeDriver, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*NodeDriver), err
}
func (s *nodeDriverClient) Update(o *NodeDriver) (*NodeDriver, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*NodeDriver), err
}
func (s *nodeDriverClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *nodeDriverClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *nodeDriverClient) List(opts metav1.ListOptions) (*NodeDriverList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*NodeDriverList), err
}
func (s *nodeDriverClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *nodeDriverClient) Patch(o *NodeDriver, data []byte, subresources ...string) (*NodeDriver, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*NodeDriver), err
}
func (s *nodeDriverClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *nodeDriverClient) AddHandler(name string, sync NodeDriverHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *nodeDriverClient) AddLifecycle(name string, lifecycle NodeDriverLifecycle) {
sync := NewNodeDriverLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *nodeDriverClient) AddClusterScopedHandler(name, clusterName string, sync NodeDriverHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *nodeDriverClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeDriverLifecycle) {
sync := NewNodeDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type NodeDriverLifecycle interface {
Create(obj *NodeDriver) (*NodeDriver, error)
Remove(obj *NodeDriver) (*NodeDriver, error)
Updated(obj *NodeDriver) (*NodeDriver, error)
}
type nodeDriverLifecycleAdapter struct {
lifecycle NodeDriverLifecycle
}
func (w *nodeDriverLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*NodeDriver))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeDriverLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*NodeDriver))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeDriverLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*NodeDriver))
if o == nil {
return nil, err
}
return o, err
}
func NewNodeDriverLifecycleAdapter(name string, clusterScoped bool, client NodeDriverInterface, l NodeDriverLifecycle) NodeDriverHandlerFunc {
adapter := &nodeDriverLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *NodeDriver) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type NodeLifecycle interface {
Create(obj *Node) (*Node, error)
Remove(obj *Node) (*Node, error)
Updated(obj *Node) (*Node, error)
}
type nodeLifecycleAdapter struct {
lifecycle NodeLifecycle
}
func (w *nodeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*Node))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*Node))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*Node))
if o == nil {
return nil, err
}
return o, err
}
func NewNodeLifecycleAdapter(name string, clusterScoped bool, client NodeInterface, l NodeLifecycle) NodeHandlerFunc {
adapter := &nodeLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *Node) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,251 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
NodeTemplateGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "NodeTemplate",
}
NodeTemplateResource = metav1.APIResource{
Name: "nodetemplates",
SingularName: "nodetemplate",
Namespaced: false,
Kind: NodeTemplateGroupVersionKind.Kind,
}
)
type NodeTemplateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NodeTemplate
}
type NodeTemplateHandlerFunc func(key string, obj *NodeTemplate) error
type NodeTemplateLister interface {
List(namespace string, selector labels.Selector) (ret []*NodeTemplate, err error)
Get(namespace, name string) (*NodeTemplate, error)
}
type NodeTemplateController interface {
Informer() cache.SharedIndexInformer
Lister() NodeTemplateLister
AddHandler(name string, handler NodeTemplateHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler NodeTemplateHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type NodeTemplateInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*NodeTemplate) (*NodeTemplate, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*NodeTemplate, error)
Get(name string, opts metav1.GetOptions) (*NodeTemplate, error)
Update(*NodeTemplate) (*NodeTemplate, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*NodeTemplateList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() NodeTemplateController
AddHandler(name string, sync NodeTemplateHandlerFunc)
AddLifecycle(name string, lifecycle NodeTemplateLifecycle)
AddClusterScopedHandler(name, clusterName string, sync NodeTemplateHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeTemplateLifecycle)
}
type nodeTemplateLister struct {
controller *nodeTemplateController
}
func (l *nodeTemplateLister) List(namespace string, selector labels.Selector) (ret []*NodeTemplate, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*NodeTemplate))
})
return
}
func (l *nodeTemplateLister) Get(namespace, name string) (*NodeTemplate, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: NodeTemplateGroupVersionKind.Group,
Resource: "nodeTemplate",
}, name)
}
return obj.(*NodeTemplate), nil
}
type nodeTemplateController struct {
controller.GenericController
}
func (c *nodeTemplateController) Lister() NodeTemplateLister {
return &nodeTemplateLister{
controller: c,
}
}
func (c *nodeTemplateController) AddHandler(name string, handler NodeTemplateHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*NodeTemplate))
})
}
func (c *nodeTemplateController) AddClusterScopedHandler(name, cluster string, handler NodeTemplateHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*NodeTemplate))
})
}
type nodeTemplateFactory struct {
}
func (c nodeTemplateFactory) Object() runtime.Object {
return &NodeTemplate{}
}
func (c nodeTemplateFactory) List() runtime.Object {
return &NodeTemplateList{}
}
func (s *nodeTemplateClient) Controller() NodeTemplateController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.nodeTemplateControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(NodeTemplateGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &nodeTemplateController{
GenericController: genericController,
}
s.client.nodeTemplateControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type nodeTemplateClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller NodeTemplateController
}
func (s *nodeTemplateClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *nodeTemplateClient) Create(o *NodeTemplate) (*NodeTemplate, error) {
obj, err := s.objectClient.Create(o)
return obj.(*NodeTemplate), err
}
func (s *nodeTemplateClient) Get(name string, opts metav1.GetOptions) (*NodeTemplate, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*NodeTemplate), err
}
func (s *nodeTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*NodeTemplate, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*NodeTemplate), err
}
func (s *nodeTemplateClient) Update(o *NodeTemplate) (*NodeTemplate, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*NodeTemplate), err
}
func (s *nodeTemplateClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *nodeTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *nodeTemplateClient) List(opts metav1.ListOptions) (*NodeTemplateList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*NodeTemplateList), err
}
func (s *nodeTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *nodeTemplateClient) Patch(o *NodeTemplate, data []byte, subresources ...string) (*NodeTemplate, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*NodeTemplate), err
}
func (s *nodeTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *nodeTemplateClient) AddHandler(name string, sync NodeTemplateHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *nodeTemplateClient) AddLifecycle(name string, lifecycle NodeTemplateLifecycle) {
sync := NewNodeTemplateLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *nodeTemplateClient) AddClusterScopedHandler(name, clusterName string, sync NodeTemplateHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *nodeTemplateClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle NodeTemplateLifecycle) {
sync := NewNodeTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type NodeTemplateLifecycle interface {
Create(obj *NodeTemplate) (*NodeTemplate, error)
Remove(obj *NodeTemplate) (*NodeTemplate, error)
Updated(obj *NodeTemplate) (*NodeTemplate, error)
}
type nodeTemplateLifecycleAdapter struct {
lifecycle NodeTemplateLifecycle
}
func (w *nodeTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*NodeTemplate))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*NodeTemplate))
if o == nil {
return nil, err
}
return o, err
}
func (w *nodeTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*NodeTemplate))
if o == nil {
return nil, err
}
return o, err
}
func NewNodeTemplateLifecycleAdapter(name string, clusterScoped bool, client NodeTemplateInterface, l NodeTemplateLifecycle) NodeTemplateHandlerFunc {
adapter := &nodeTemplateLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *NodeTemplate) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,252 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
PipelineGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "Pipeline",
}
PipelineResource = metav1.APIResource{
Name: "pipelines",
SingularName: "pipeline",
Namespaced: true,
Kind: PipelineGroupVersionKind.Kind,
}
)
type PipelineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Pipeline
}
type PipelineHandlerFunc func(key string, obj *Pipeline) error
type PipelineLister interface {
List(namespace string, selector labels.Selector) (ret []*Pipeline, err error)
Get(namespace, name string) (*Pipeline, error)
}
type PipelineController interface {
Informer() cache.SharedIndexInformer
Lister() PipelineLister
AddHandler(name string, handler PipelineHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler PipelineHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type PipelineInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*Pipeline) (*Pipeline, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Pipeline, error)
Get(name string, opts metav1.GetOptions) (*Pipeline, error)
Update(*Pipeline) (*Pipeline, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*PipelineList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() PipelineController
AddHandler(name string, sync PipelineHandlerFunc)
AddLifecycle(name string, lifecycle PipelineLifecycle)
AddClusterScopedHandler(name, clusterName string, sync PipelineHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineLifecycle)
}
type pipelineLister struct {
controller *pipelineController
}
func (l *pipelineLister) List(namespace string, selector labels.Selector) (ret []*Pipeline, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*Pipeline))
})
return
}
func (l *pipelineLister) Get(namespace, name string) (*Pipeline, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: PipelineGroupVersionKind.Group,
Resource: "pipeline",
}, name)
}
return obj.(*Pipeline), nil
}
type pipelineController struct {
controller.GenericController
}
func (c *pipelineController) Lister() PipelineLister {
return &pipelineLister{
controller: c,
}
}
func (c *pipelineController) AddHandler(name string, handler PipelineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*Pipeline))
})
}
func (c *pipelineController) AddClusterScopedHandler(name, cluster string, handler PipelineHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*Pipeline))
})
}
type pipelineFactory struct {
}
func (c pipelineFactory) Object() runtime.Object {
return &Pipeline{}
}
func (c pipelineFactory) List() runtime.Object {
return &PipelineList{}
}
func (s *pipelineClient) Controller() PipelineController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.pipelineControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(PipelineGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &pipelineController{
GenericController: genericController,
}
s.client.pipelineControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type pipelineClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller PipelineController
}
func (s *pipelineClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *pipelineClient) Create(o *Pipeline) (*Pipeline, error) {
obj, err := s.objectClient.Create(o)
return obj.(*Pipeline), err
}
func (s *pipelineClient) Get(name string, opts metav1.GetOptions) (*Pipeline, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*Pipeline), err
}
func (s *pipelineClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*Pipeline, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*Pipeline), err
}
func (s *pipelineClient) Update(o *Pipeline) (*Pipeline, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*Pipeline), err
}
func (s *pipelineClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *pipelineClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *pipelineClient) List(opts metav1.ListOptions) (*PipelineList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*PipelineList), err
}
func (s *pipelineClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *pipelineClient) Patch(o *Pipeline, data []byte, subresources ...string) (*Pipeline, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*Pipeline), err
}
func (s *pipelineClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *pipelineClient) AddHandler(name string, sync PipelineHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *pipelineClient) AddLifecycle(name string, lifecycle PipelineLifecycle) {
sync := NewPipelineLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *pipelineClient) AddClusterScopedHandler(name, clusterName string, sync PipelineHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *pipelineClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineLifecycle) {
sync := NewPipelineLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,252 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
PipelineExecutionGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "PipelineExecution",
}
PipelineExecutionResource = metav1.APIResource{
Name: "pipelineexecutions",
SingularName: "pipelineexecution",
Namespaced: true,
Kind: PipelineExecutionGroupVersionKind.Kind,
}
)
type PipelineExecutionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []PipelineExecution
}
type PipelineExecutionHandlerFunc func(key string, obj *PipelineExecution) error
type PipelineExecutionLister interface {
List(namespace string, selector labels.Selector) (ret []*PipelineExecution, err error)
Get(namespace, name string) (*PipelineExecution, error)
}
type PipelineExecutionController interface {
Informer() cache.SharedIndexInformer
Lister() PipelineExecutionLister
AddHandler(name string, handler PipelineExecutionHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler PipelineExecutionHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type PipelineExecutionInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*PipelineExecution) (*PipelineExecution, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*PipelineExecution, error)
Get(name string, opts metav1.GetOptions) (*PipelineExecution, error)
Update(*PipelineExecution) (*PipelineExecution, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*PipelineExecutionList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() PipelineExecutionController
AddHandler(name string, sync PipelineExecutionHandlerFunc)
AddLifecycle(name string, lifecycle PipelineExecutionLifecycle)
AddClusterScopedHandler(name, clusterName string, sync PipelineExecutionHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineExecutionLifecycle)
}
type pipelineExecutionLister struct {
controller *pipelineExecutionController
}
func (l *pipelineExecutionLister) List(namespace string, selector labels.Selector) (ret []*PipelineExecution, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*PipelineExecution))
})
return
}
func (l *pipelineExecutionLister) Get(namespace, name string) (*PipelineExecution, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: PipelineExecutionGroupVersionKind.Group,
Resource: "pipelineExecution",
}, name)
}
return obj.(*PipelineExecution), nil
}
type pipelineExecutionController struct {
controller.GenericController
}
func (c *pipelineExecutionController) Lister() PipelineExecutionLister {
return &pipelineExecutionLister{
controller: c,
}
}
func (c *pipelineExecutionController) AddHandler(name string, handler PipelineExecutionHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*PipelineExecution))
})
}
func (c *pipelineExecutionController) AddClusterScopedHandler(name, cluster string, handler PipelineExecutionHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*PipelineExecution))
})
}
type pipelineExecutionFactory struct {
}
func (c pipelineExecutionFactory) Object() runtime.Object {
return &PipelineExecution{}
}
func (c pipelineExecutionFactory) List() runtime.Object {
return &PipelineExecutionList{}
}
func (s *pipelineExecutionClient) Controller() PipelineExecutionController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.pipelineExecutionControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(PipelineExecutionGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &pipelineExecutionController{
GenericController: genericController,
}
s.client.pipelineExecutionControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type pipelineExecutionClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller PipelineExecutionController
}
func (s *pipelineExecutionClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *pipelineExecutionClient) Create(o *PipelineExecution) (*PipelineExecution, error) {
obj, err := s.objectClient.Create(o)
return obj.(*PipelineExecution), err
}
func (s *pipelineExecutionClient) Get(name string, opts metav1.GetOptions) (*PipelineExecution, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*PipelineExecution), err
}
func (s *pipelineExecutionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*PipelineExecution, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*PipelineExecution), err
}
func (s *pipelineExecutionClient) Update(o *PipelineExecution) (*PipelineExecution, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*PipelineExecution), err
}
func (s *pipelineExecutionClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *pipelineExecutionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *pipelineExecutionClient) List(opts metav1.ListOptions) (*PipelineExecutionList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*PipelineExecutionList), err
}
func (s *pipelineExecutionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *pipelineExecutionClient) Patch(o *PipelineExecution, data []byte, subresources ...string) (*PipelineExecution, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*PipelineExecution), err
}
func (s *pipelineExecutionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *pipelineExecutionClient) AddHandler(name string, sync PipelineExecutionHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *pipelineExecutionClient) AddLifecycle(name string, lifecycle PipelineExecutionLifecycle) {
sync := NewPipelineExecutionLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *pipelineExecutionClient) AddClusterScopedHandler(name, clusterName string, sync PipelineExecutionHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *pipelineExecutionClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineExecutionLifecycle) {
sync := NewPipelineExecutionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type PipelineExecutionLifecycle interface {
Create(obj *PipelineExecution) (*PipelineExecution, error)
Remove(obj *PipelineExecution) (*PipelineExecution, error)
Updated(obj *PipelineExecution) (*PipelineExecution, error)
}
type pipelineExecutionLifecycleAdapter struct {
lifecycle PipelineExecutionLifecycle
}
func (w *pipelineExecutionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*PipelineExecution))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineExecutionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*PipelineExecution))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineExecutionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*PipelineExecution))
if o == nil {
return nil, err
}
return o, err
}
func NewPipelineExecutionLifecycleAdapter(name string, clusterScoped bool, client PipelineExecutionInterface, l PipelineExecutionLifecycle) PipelineExecutionHandlerFunc {
adapter := &pipelineExecutionLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *PipelineExecution) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,252 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
PipelineExecutionLogGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "PipelineExecutionLog",
}
PipelineExecutionLogResource = metav1.APIResource{
Name: "pipelineexecutionlogs",
SingularName: "pipelineexecutionlog",
Namespaced: true,
Kind: PipelineExecutionLogGroupVersionKind.Kind,
}
)
type PipelineExecutionLogList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []PipelineExecutionLog
}
type PipelineExecutionLogHandlerFunc func(key string, obj *PipelineExecutionLog) error
type PipelineExecutionLogLister interface {
List(namespace string, selector labels.Selector) (ret []*PipelineExecutionLog, err error)
Get(namespace, name string) (*PipelineExecutionLog, error)
}
type PipelineExecutionLogController interface {
Informer() cache.SharedIndexInformer
Lister() PipelineExecutionLogLister
AddHandler(name string, handler PipelineExecutionLogHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler PipelineExecutionLogHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type PipelineExecutionLogInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*PipelineExecutionLog) (*PipelineExecutionLog, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*PipelineExecutionLog, error)
Get(name string, opts metav1.GetOptions) (*PipelineExecutionLog, error)
Update(*PipelineExecutionLog) (*PipelineExecutionLog, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*PipelineExecutionLogList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() PipelineExecutionLogController
AddHandler(name string, sync PipelineExecutionLogHandlerFunc)
AddLifecycle(name string, lifecycle PipelineExecutionLogLifecycle)
AddClusterScopedHandler(name, clusterName string, sync PipelineExecutionLogHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineExecutionLogLifecycle)
}
type pipelineExecutionLogLister struct {
controller *pipelineExecutionLogController
}
func (l *pipelineExecutionLogLister) List(namespace string, selector labels.Selector) (ret []*PipelineExecutionLog, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*PipelineExecutionLog))
})
return
}
func (l *pipelineExecutionLogLister) Get(namespace, name string) (*PipelineExecutionLog, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: PipelineExecutionLogGroupVersionKind.Group,
Resource: "pipelineExecutionLog",
}, name)
}
return obj.(*PipelineExecutionLog), nil
}
type pipelineExecutionLogController struct {
controller.GenericController
}
func (c *pipelineExecutionLogController) Lister() PipelineExecutionLogLister {
return &pipelineExecutionLogLister{
controller: c,
}
}
func (c *pipelineExecutionLogController) AddHandler(name string, handler PipelineExecutionLogHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*PipelineExecutionLog))
})
}
func (c *pipelineExecutionLogController) AddClusterScopedHandler(name, cluster string, handler PipelineExecutionLogHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*PipelineExecutionLog))
})
}
type pipelineExecutionLogFactory struct {
}
func (c pipelineExecutionLogFactory) Object() runtime.Object {
return &PipelineExecutionLog{}
}
func (c pipelineExecutionLogFactory) List() runtime.Object {
return &PipelineExecutionLogList{}
}
func (s *pipelineExecutionLogClient) Controller() PipelineExecutionLogController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.pipelineExecutionLogControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(PipelineExecutionLogGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &pipelineExecutionLogController{
GenericController: genericController,
}
s.client.pipelineExecutionLogControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type pipelineExecutionLogClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller PipelineExecutionLogController
}
func (s *pipelineExecutionLogClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *pipelineExecutionLogClient) Create(o *PipelineExecutionLog) (*PipelineExecutionLog, error) {
obj, err := s.objectClient.Create(o)
return obj.(*PipelineExecutionLog), err
}
func (s *pipelineExecutionLogClient) Get(name string, opts metav1.GetOptions) (*PipelineExecutionLog, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*PipelineExecutionLog), err
}
func (s *pipelineExecutionLogClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*PipelineExecutionLog, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*PipelineExecutionLog), err
}
func (s *pipelineExecutionLogClient) Update(o *PipelineExecutionLog) (*PipelineExecutionLog, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*PipelineExecutionLog), err
}
func (s *pipelineExecutionLogClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *pipelineExecutionLogClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *pipelineExecutionLogClient) List(opts metav1.ListOptions) (*PipelineExecutionLogList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*PipelineExecutionLogList), err
}
func (s *pipelineExecutionLogClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *pipelineExecutionLogClient) Patch(o *PipelineExecutionLog, data []byte, subresources ...string) (*PipelineExecutionLog, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*PipelineExecutionLog), err
}
func (s *pipelineExecutionLogClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *pipelineExecutionLogClient) AddHandler(name string, sync PipelineExecutionLogHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *pipelineExecutionLogClient) AddLifecycle(name string, lifecycle PipelineExecutionLogLifecycle) {
sync := NewPipelineExecutionLogLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *pipelineExecutionLogClient) AddClusterScopedHandler(name, clusterName string, sync PipelineExecutionLogHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *pipelineExecutionLogClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle PipelineExecutionLogLifecycle) {
sync := NewPipelineExecutionLogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type PipelineExecutionLogLifecycle interface {
Create(obj *PipelineExecutionLog) (*PipelineExecutionLog, error)
Remove(obj *PipelineExecutionLog) (*PipelineExecutionLog, error)
Updated(obj *PipelineExecutionLog) (*PipelineExecutionLog, error)
}
type pipelineExecutionLogLifecycleAdapter struct {
lifecycle PipelineExecutionLogLifecycle
}
func (w *pipelineExecutionLogLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*PipelineExecutionLog))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineExecutionLogLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*PipelineExecutionLog))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineExecutionLogLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*PipelineExecutionLog))
if o == nil {
return nil, err
}
return o, err
}
func NewPipelineExecutionLogLifecycleAdapter(name string, clusterScoped bool, client PipelineExecutionLogInterface, l PipelineExecutionLogLifecycle) PipelineExecutionLogHandlerFunc {
adapter := &pipelineExecutionLogLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *PipelineExecutionLog) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type PipelineLifecycle interface {
Create(obj *Pipeline) (*Pipeline, error)
Remove(obj *Pipeline) (*Pipeline, error)
Updated(obj *Pipeline) (*Pipeline, error)
}
type pipelineLifecycleAdapter struct {
lifecycle PipelineLifecycle
}
func (w *pipelineLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*Pipeline))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*Pipeline))
if o == nil {
return nil, err
}
return o, err
}
func (w *pipelineLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*Pipeline))
if o == nil {
return nil, err
}
return o, err
}
func NewPipelineLifecycleAdapter(name string, clusterScoped bool, client PipelineInterface, l PipelineLifecycle) PipelineHandlerFunc {
adapter := &pipelineLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *Pipeline) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -33,12 +33,12 @@ func addKnownTypes(scheme *runtime.Scheme) error {
// TODO this gets cleaned up when the types are fixed // TODO this gets cleaned up when the types are fixed
scheme.AddKnownTypes(SchemeGroupVersion, scheme.AddKnownTypes(SchemeGroupVersion,
&Machine{}, &Node{},
&MachineList{}, &NodeList{},
&MachineDriver{}, &NodeDriver{},
&MachineDriverList{}, &NodeDriverList{},
&MachineTemplate{}, &NodeTemplate{},
&MachineTemplateList{}, &NodeTemplateList{},
&Project{}, &Project{},
&ProjectList{}, &ProjectList{},
&GlobalRole{}, &GlobalRole{},
@ -95,6 +95,18 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&ClusterAlertList{}, &ClusterAlertList{},
&ProjectAlert{}, &ProjectAlert{},
&ProjectAlertList{}, &ProjectAlertList{},
&SourceCodeCredential{},
&SourceCodeCredentialList{},
&ClusterPipeline{},
&ClusterPipelineList{},
&Pipeline{},
&PipelineList{},
&PipelineExecution{},
&PipelineExecutionList{},
&SourceCodeRepository{},
&SourceCodeRepositoryList{},
&PipelineExecutionLog{},
&PipelineExecutionLogList{},
) )
return nil return nil
} }

View File

@ -0,0 +1,251 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
SourceCodeCredentialGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "SourceCodeCredential",
}
SourceCodeCredentialResource = metav1.APIResource{
Name: "sourcecodecredentials",
SingularName: "sourcecodecredential",
Namespaced: false,
Kind: SourceCodeCredentialGroupVersionKind.Kind,
}
)
type SourceCodeCredentialList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []SourceCodeCredential
}
type SourceCodeCredentialHandlerFunc func(key string, obj *SourceCodeCredential) error
type SourceCodeCredentialLister interface {
List(namespace string, selector labels.Selector) (ret []*SourceCodeCredential, err error)
Get(namespace, name string) (*SourceCodeCredential, error)
}
type SourceCodeCredentialController interface {
Informer() cache.SharedIndexInformer
Lister() SourceCodeCredentialLister
AddHandler(name string, handler SourceCodeCredentialHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler SourceCodeCredentialHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type SourceCodeCredentialInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*SourceCodeCredential) (*SourceCodeCredential, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*SourceCodeCredential, error)
Get(name string, opts metav1.GetOptions) (*SourceCodeCredential, error)
Update(*SourceCodeCredential) (*SourceCodeCredential, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*SourceCodeCredentialList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() SourceCodeCredentialController
AddHandler(name string, sync SourceCodeCredentialHandlerFunc)
AddLifecycle(name string, lifecycle SourceCodeCredentialLifecycle)
AddClusterScopedHandler(name, clusterName string, sync SourceCodeCredentialHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle SourceCodeCredentialLifecycle)
}
type sourceCodeCredentialLister struct {
controller *sourceCodeCredentialController
}
func (l *sourceCodeCredentialLister) List(namespace string, selector labels.Selector) (ret []*SourceCodeCredential, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*SourceCodeCredential))
})
return
}
func (l *sourceCodeCredentialLister) Get(namespace, name string) (*SourceCodeCredential, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: SourceCodeCredentialGroupVersionKind.Group,
Resource: "sourceCodeCredential",
}, name)
}
return obj.(*SourceCodeCredential), nil
}
type sourceCodeCredentialController struct {
controller.GenericController
}
func (c *sourceCodeCredentialController) Lister() SourceCodeCredentialLister {
return &sourceCodeCredentialLister{
controller: c,
}
}
func (c *sourceCodeCredentialController) AddHandler(name string, handler SourceCodeCredentialHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*SourceCodeCredential))
})
}
func (c *sourceCodeCredentialController) AddClusterScopedHandler(name, cluster string, handler SourceCodeCredentialHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*SourceCodeCredential))
})
}
type sourceCodeCredentialFactory struct {
}
func (c sourceCodeCredentialFactory) Object() runtime.Object {
return &SourceCodeCredential{}
}
func (c sourceCodeCredentialFactory) List() runtime.Object {
return &SourceCodeCredentialList{}
}
func (s *sourceCodeCredentialClient) Controller() SourceCodeCredentialController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.sourceCodeCredentialControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(SourceCodeCredentialGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &sourceCodeCredentialController{
GenericController: genericController,
}
s.client.sourceCodeCredentialControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type sourceCodeCredentialClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller SourceCodeCredentialController
}
func (s *sourceCodeCredentialClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *sourceCodeCredentialClient) Create(o *SourceCodeCredential) (*SourceCodeCredential, error) {
obj, err := s.objectClient.Create(o)
return obj.(*SourceCodeCredential), err
}
func (s *sourceCodeCredentialClient) Get(name string, opts metav1.GetOptions) (*SourceCodeCredential, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*SourceCodeCredential), err
}
func (s *sourceCodeCredentialClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*SourceCodeCredential, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*SourceCodeCredential), err
}
func (s *sourceCodeCredentialClient) Update(o *SourceCodeCredential) (*SourceCodeCredential, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*SourceCodeCredential), err
}
func (s *sourceCodeCredentialClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *sourceCodeCredentialClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *sourceCodeCredentialClient) List(opts metav1.ListOptions) (*SourceCodeCredentialList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*SourceCodeCredentialList), err
}
func (s *sourceCodeCredentialClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *sourceCodeCredentialClient) Patch(o *SourceCodeCredential, data []byte, subresources ...string) (*SourceCodeCredential, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*SourceCodeCredential), err
}
func (s *sourceCodeCredentialClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *sourceCodeCredentialClient) AddHandler(name string, sync SourceCodeCredentialHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *sourceCodeCredentialClient) AddLifecycle(name string, lifecycle SourceCodeCredentialLifecycle) {
sync := NewSourceCodeCredentialLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *sourceCodeCredentialClient) AddClusterScopedHandler(name, clusterName string, sync SourceCodeCredentialHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *sourceCodeCredentialClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle SourceCodeCredentialLifecycle) {
sync := NewSourceCodeCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type SourceCodeCredentialLifecycle interface {
Create(obj *SourceCodeCredential) (*SourceCodeCredential, error)
Remove(obj *SourceCodeCredential) (*SourceCodeCredential, error)
Updated(obj *SourceCodeCredential) (*SourceCodeCredential, error)
}
type sourceCodeCredentialLifecycleAdapter struct {
lifecycle SourceCodeCredentialLifecycle
}
func (w *sourceCodeCredentialLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*SourceCodeCredential))
if o == nil {
return nil, err
}
return o, err
}
func (w *sourceCodeCredentialLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*SourceCodeCredential))
if o == nil {
return nil, err
}
return o, err
}
func (w *sourceCodeCredentialLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*SourceCodeCredential))
if o == nil {
return nil, err
}
return o, err
}
func NewSourceCodeCredentialLifecycleAdapter(name string, clusterScoped bool, client SourceCodeCredentialInterface, l SourceCodeCredentialLifecycle) SourceCodeCredentialHandlerFunc {
adapter := &sourceCodeCredentialLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *SourceCodeCredential) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -0,0 +1,251 @@
package v3
import (
"context"
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/controller"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
)
var (
SourceCodeRepositoryGroupVersionKind = schema.GroupVersionKind{
Version: Version,
Group: GroupName,
Kind: "SourceCodeRepository",
}
SourceCodeRepositoryResource = metav1.APIResource{
Name: "sourcecoderepositories",
SingularName: "sourcecoderepository",
Namespaced: false,
Kind: SourceCodeRepositoryGroupVersionKind.Kind,
}
)
type SourceCodeRepositoryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []SourceCodeRepository
}
type SourceCodeRepositoryHandlerFunc func(key string, obj *SourceCodeRepository) error
type SourceCodeRepositoryLister interface {
List(namespace string, selector labels.Selector) (ret []*SourceCodeRepository, err error)
Get(namespace, name string) (*SourceCodeRepository, error)
}
type SourceCodeRepositoryController interface {
Informer() cache.SharedIndexInformer
Lister() SourceCodeRepositoryLister
AddHandler(name string, handler SourceCodeRepositoryHandlerFunc)
AddClusterScopedHandler(name, clusterName string, handler SourceCodeRepositoryHandlerFunc)
Enqueue(namespace, name string)
Sync(ctx context.Context) error
Start(ctx context.Context, threadiness int) error
}
type SourceCodeRepositoryInterface interface {
ObjectClient() *clientbase.ObjectClient
Create(*SourceCodeRepository) (*SourceCodeRepository, error)
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*SourceCodeRepository, error)
Get(name string, opts metav1.GetOptions) (*SourceCodeRepository, error)
Update(*SourceCodeRepository) (*SourceCodeRepository, error)
Delete(name string, options *metav1.DeleteOptions) error
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
List(opts metav1.ListOptions) (*SourceCodeRepositoryList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error)
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
Controller() SourceCodeRepositoryController
AddHandler(name string, sync SourceCodeRepositoryHandlerFunc)
AddLifecycle(name string, lifecycle SourceCodeRepositoryLifecycle)
AddClusterScopedHandler(name, clusterName string, sync SourceCodeRepositoryHandlerFunc)
AddClusterScopedLifecycle(name, clusterName string, lifecycle SourceCodeRepositoryLifecycle)
}
type sourceCodeRepositoryLister struct {
controller *sourceCodeRepositoryController
}
func (l *sourceCodeRepositoryLister) List(namespace string, selector labels.Selector) (ret []*SourceCodeRepository, err error) {
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
ret = append(ret, obj.(*SourceCodeRepository))
})
return
}
func (l *sourceCodeRepositoryLister) Get(namespace, name string) (*SourceCodeRepository, error) {
var key string
if namespace != "" {
key = namespace + "/" + name
} else {
key = name
}
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(schema.GroupResource{
Group: SourceCodeRepositoryGroupVersionKind.Group,
Resource: "sourceCodeRepository",
}, name)
}
return obj.(*SourceCodeRepository), nil
}
type sourceCodeRepositoryController struct {
controller.GenericController
}
func (c *sourceCodeRepositoryController) Lister() SourceCodeRepositoryLister {
return &sourceCodeRepositoryLister{
controller: c,
}
}
func (c *sourceCodeRepositoryController) AddHandler(name string, handler SourceCodeRepositoryHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
return handler(key, obj.(*SourceCodeRepository))
})
}
func (c *sourceCodeRepositoryController) AddClusterScopedHandler(name, cluster string, handler SourceCodeRepositoryHandlerFunc) {
c.GenericController.AddHandler(name, func(key string) error {
obj, exists, err := c.Informer().GetStore().GetByKey(key)
if err != nil {
return err
}
if !exists {
return handler(key, nil)
}
if !controller.ObjectInCluster(cluster, obj) {
return nil
}
return handler(key, obj.(*SourceCodeRepository))
})
}
type sourceCodeRepositoryFactory struct {
}
func (c sourceCodeRepositoryFactory) Object() runtime.Object {
return &SourceCodeRepository{}
}
func (c sourceCodeRepositoryFactory) List() runtime.Object {
return &SourceCodeRepositoryList{}
}
func (s *sourceCodeRepositoryClient) Controller() SourceCodeRepositoryController {
s.client.Lock()
defer s.client.Unlock()
c, ok := s.client.sourceCodeRepositoryControllers[s.ns]
if ok {
return c
}
genericController := controller.NewGenericController(SourceCodeRepositoryGroupVersionKind.Kind+"Controller",
s.objectClient)
c = &sourceCodeRepositoryController{
GenericController: genericController,
}
s.client.sourceCodeRepositoryControllers[s.ns] = c
s.client.starters = append(s.client.starters, c)
return c
}
type sourceCodeRepositoryClient struct {
client *Client
ns string
objectClient *clientbase.ObjectClient
controller SourceCodeRepositoryController
}
func (s *sourceCodeRepositoryClient) ObjectClient() *clientbase.ObjectClient {
return s.objectClient
}
func (s *sourceCodeRepositoryClient) Create(o *SourceCodeRepository) (*SourceCodeRepository, error) {
obj, err := s.objectClient.Create(o)
return obj.(*SourceCodeRepository), err
}
func (s *sourceCodeRepositoryClient) Get(name string, opts metav1.GetOptions) (*SourceCodeRepository, error) {
obj, err := s.objectClient.Get(name, opts)
return obj.(*SourceCodeRepository), err
}
func (s *sourceCodeRepositoryClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*SourceCodeRepository, error) {
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
return obj.(*SourceCodeRepository), err
}
func (s *sourceCodeRepositoryClient) Update(o *SourceCodeRepository) (*SourceCodeRepository, error) {
obj, err := s.objectClient.Update(o.Name, o)
return obj.(*SourceCodeRepository), err
}
func (s *sourceCodeRepositoryClient) Delete(name string, options *metav1.DeleteOptions) error {
return s.objectClient.Delete(name, options)
}
func (s *sourceCodeRepositoryClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
return s.objectClient.DeleteNamespaced(namespace, name, options)
}
func (s *sourceCodeRepositoryClient) List(opts metav1.ListOptions) (*SourceCodeRepositoryList, error) {
obj, err := s.objectClient.List(opts)
return obj.(*SourceCodeRepositoryList), err
}
func (s *sourceCodeRepositoryClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
return s.objectClient.Watch(opts)
}
// Patch applies the patch and returns the patched deployment.
func (s *sourceCodeRepositoryClient) Patch(o *SourceCodeRepository, data []byte, subresources ...string) (*SourceCodeRepository, error) {
obj, err := s.objectClient.Patch(o.Name, o, data, subresources...)
return obj.(*SourceCodeRepository), err
}
func (s *sourceCodeRepositoryClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
}
func (s *sourceCodeRepositoryClient) AddHandler(name string, sync SourceCodeRepositoryHandlerFunc) {
s.Controller().AddHandler(name, sync)
}
func (s *sourceCodeRepositoryClient) AddLifecycle(name string, lifecycle SourceCodeRepositoryLifecycle) {
sync := NewSourceCodeRepositoryLifecycleAdapter(name, false, s, lifecycle)
s.AddHandler(name, sync)
}
func (s *sourceCodeRepositoryClient) AddClusterScopedHandler(name, clusterName string, sync SourceCodeRepositoryHandlerFunc) {
s.Controller().AddClusterScopedHandler(name, clusterName, sync)
}
func (s *sourceCodeRepositoryClient) AddClusterScopedLifecycle(name, clusterName string, lifecycle SourceCodeRepositoryLifecycle) {
sync := NewSourceCodeRepositoryLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
s.AddClusterScopedHandler(name, clusterName, sync)
}

View File

@ -0,0 +1,51 @@
package v3
import (
"github.com/rancher/norman/lifecycle"
"k8s.io/apimachinery/pkg/runtime"
)
type SourceCodeRepositoryLifecycle interface {
Create(obj *SourceCodeRepository) (*SourceCodeRepository, error)
Remove(obj *SourceCodeRepository) (*SourceCodeRepository, error)
Updated(obj *SourceCodeRepository) (*SourceCodeRepository, error)
}
type sourceCodeRepositoryLifecycleAdapter struct {
lifecycle SourceCodeRepositoryLifecycle
}
func (w *sourceCodeRepositoryLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Create(obj.(*SourceCodeRepository))
if o == nil {
return nil, err
}
return o, err
}
func (w *sourceCodeRepositoryLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Remove(obj.(*SourceCodeRepository))
if o == nil {
return nil, err
}
return o, err
}
func (w *sourceCodeRepositoryLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
o, err := w.lifecycle.Updated(obj.(*SourceCodeRepository))
if o == nil {
return nil, err
}
return o, err
}
func NewSourceCodeRepositoryLifecycleAdapter(name string, clusterScoped bool, client SourceCodeRepositoryInterface, l SourceCodeRepositoryLifecycle) SourceCodeRepositoryHandlerFunc {
adapter := &sourceCodeRepositoryLifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
return func(key string, obj *SourceCodeRepository) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}

View File

@ -5,4 +5,4 @@ k8s.io/kubernetes v1.8.3
bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
github.com/rancher/norman 722cedfe014fbfe9f1e5572b5582960f7eb3a2fb github.com/rancher/norman bfea703723da186d3153c87cf629410d796beb8c

22
vendor/github.com/ugorji/go/LICENSE generated vendored
View File

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2012-2015 Ugorji Nwoke.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,20 +0,0 @@
# go/codec
This repository contains the `go-codec` library,
a High Performance and Feature-Rich Idiomatic encode/decode and rpc library for
- msgpack: https://github.com/msgpack/msgpack
- binc: http://github.com/ugorji/binc
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
- json: http://json.org http://tools.ietf.org/html/rfc7159
For more information:
- [see the codec/Readme for quick usage information](https://github.com/ugorji/go/tree/master/codec#readme)
- [view the API on godoc](http://godoc.org/github.com/ugorji/go/codec)
- [read the detailed usage/how-to primer](http://ugorji.net/blog/go-codec-primer)
Install using:
go get github.com/ugorji/go/codec

View File

@ -1,9 +1,10 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
/* /*
High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library for Package codec provides a
binc, msgpack, cbor, json High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
for binc, msgpack, cbor, json.
Supported Serialization formats are: Supported Serialization formats are:
@ -32,15 +33,14 @@ Rich Feature Set includes:
- Simple but extremely powerful and feature-rich API - Simple but extremely powerful and feature-rich API
- Support for go1.4 and above, while selectively using newer APIs for later releases - Support for go1.4 and above, while selectively using newer APIs for later releases
- Good code coverage ( > 70% ) - Excellent code coverage ( > 90% )
- Very High Performance. - Very High Performance.
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X. Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
- Careful selected use of 'unsafe' for targeted performance gains. - Careful selected use of 'unsafe' for targeted performance gains.
100% mode exists where 'unsafe' is not used at all. 100% mode exists where 'unsafe' is not used at all.
- Lock-free (sans mutex) concurrency for scaling to 100's of cores - Lock-free (sans mutex) concurrency for scaling to 100's of cores
- Multiple conversions: - Coerce types where appropriate
Package coerces types where appropriate e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
e.g. decode an int in the stream into a float, etc.
- Corner Cases: - Corner Cases:
Overflows, nil maps/slices, nil values in streams are handled correctly Overflows, nil maps/slices, nil values in streams are handled correctly
- Standard field renaming via tags - Standard field renaming via tags
@ -49,10 +49,16 @@ Rich Feature Set includes:
(struct, slice, map, primitives, pointers, interface{}, etc) (struct, slice, map, primitives, pointers, interface{}, etc)
- Extensions to support efficient encoding/decoding of any named types - Extensions to support efficient encoding/decoding of any named types
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
- Support IsZero() bool to determine if a value is a zero value.
Analogous to time.Time.IsZero() bool.
- Decoding without a schema (into a interface{}). - Decoding without a schema (into a interface{}).
Includes Options to configure what specific map or slice type to use Includes Options to configure what specific map or slice type to use
when decoding an encoded list or map into a nil interface{} when decoding an encoded list or map into a nil interface{}
- Mapping a non-interface type to an interface, so we can decode appropriately
into any interface type with a correctly configured non-interface value.
- Encode a struct as an array, and decode struct from an array in the data stream - Encode a struct as an array, and decode struct from an array in the data stream
- Option to encode struct keys as numbers (instead of strings)
(to support structured streams with fields encoded as numeric codes)
- Comprehensive support for anonymous fields - Comprehensive support for anonymous fields
- Fast (no-reflection) encoding/decoding of common maps and slices - Fast (no-reflection) encoding/decoding of common maps and slices
- Code-generation for faster performance. - Code-generation for faster performance.
@ -93,6 +99,27 @@ encoded as an empty map because it has no exported fields, while UUID
would be encoded as a string. However, with extension support, you can would be encoded as a string. However, with extension support, you can
encode any of these however you like. encode any of these however you like.
Custom Encoding and Decoding
This package maintains symmetry in the encoding and decoding halfs.
We determine how to encode or decode by walking this decision tree
- is type a codec.Selfer?
- is there an extension registered for the type?
- is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
- is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
- is format text-based, and type an encoding.TextMarshaler?
- else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
This symmetry is important to reduce chances of issues happening because the
encoding and decoding sides are out of sync e.g. decoded via very specific
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
Consequently, if a type only defines one-half of the symmetry
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
then that type doesn't satisfy the check and we will continue walking down the
decision tree.
RPC RPC
RPC Client and Server Codecs are implemented, so the codecs can be used RPC Client and Server Codecs are implemented, so the codecs can be used
@ -180,6 +207,63 @@ Running Benchmarks
Please see http://github.com/ugorji/go-codec-bench . Please see http://github.com/ugorji/go-codec-bench .
Caveats
Struct fields matching the following are ignored during encoding and decoding
- struct tag value set to -
- func, complex numbers, unsafe pointers
- unexported and not embedded
- unexported and embedded and not struct kind
- unexported and embedded pointers (from go1.10)
Every other field in a struct will be encoded/decoded.
Embedded fields are encoded as if they exist in the top-level struct,
with some caveats. See Encode documentation.
*/ */
package codec package codec
// TODO:
// - In Go 1.10, when mid-stack inlining is enabled,
// we should use committed functions for writeXXX and readXXX calls.
// This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
// and using those (decReaderSwitch and encWriterSwitch) in all handles
// instead of encWriter and decReader.
// The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
// will be inlined, giving a performance bump for that typical case.
// However, it will only be inlined if mid-stack inlining is enabled,
// as we call panic to raise errors, and panic currently prevents inlining.
//
// - Unexport BasicHandle.
// If godoc can now show the embedded options, then unexport it.
//
// PUNTED:
// - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
// and use overlay methods on *BasicHandle to call through to extHandle after initializing
// the "xh *extHandle" to point to a real slice.
//
// - Allow mapping a concrete type to an interface, for use during decoding.
//
// BEFORE EACH RELEASE:
// - Look through and fix padding for each type, to eliminate false sharing
// - critical shared objects that are read many times
// TypeInfos
// - pooled objects:
// decNaked, decNakedContainers, codecFner, typeInfoLoadArray,
// - small objects allocated independently, that we read/use much across threads:
// codecFn, typeInfo
// - Objects allocated independently and used a lot
// Decoder, Encoder,
// xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
// - In all above, arrange values modified together to be close to each other.
//
// For all of these, either ensure that they occupy full cache lines,
// or ensure that the things just past the cache line boundary are hardly read/written
// e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
//
// Occupying full cache lines means they occupy 8*N words (where N is an integer).
// Check this out by running: ./run.sh -z
// - look at those tagged ****, meaning they are not occupying full cache lines
// - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
// - Run "golint -min_confidence 0.81"

View File

@ -31,15 +31,14 @@ Rich Feature Set includes:
- Simple but extremely powerful and feature-rich API - Simple but extremely powerful and feature-rich API
- Support for go1.4 and above, while selectively using newer APIs for later releases - Support for go1.4 and above, while selectively using newer APIs for later releases
- Good code coverage ( > 70% ) - Excellent code coverage ( > 90% )
- Very High Performance. - Very High Performance.
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X. Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
- Careful selected use of 'unsafe' for targeted performance gains. - Careful selected use of 'unsafe' for targeted performance gains.
100% mode exists where 'unsafe' is not used at all. 100% mode exists where 'unsafe' is not used at all.
- Lock-free (sans mutex) concurrency for scaling to 100's of cores - Lock-free (sans mutex) concurrency for scaling to 100's of cores
- Multiple conversions: - Coerce types where appropriate
Package coerces types where appropriate e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
e.g. decode an int in the stream into a float, etc.
- Corner Cases: - Corner Cases:
Overflows, nil maps/slices, nil values in streams are handled correctly Overflows, nil maps/slices, nil values in streams are handled correctly
- Standard field renaming via tags - Standard field renaming via tags
@ -48,10 +47,16 @@ Rich Feature Set includes:
(struct, slice, map, primitives, pointers, interface{}, etc) (struct, slice, map, primitives, pointers, interface{}, etc)
- Extensions to support efficient encoding/decoding of any named types - Extensions to support efficient encoding/decoding of any named types
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
- Support IsZero() bool to determine if a value is a zero value.
Analogous to time.Time.IsZero() bool.
- Decoding without a schema (into a interface{}). - Decoding without a schema (into a interface{}).
Includes Options to configure what specific map or slice type to use Includes Options to configure what specific map or slice type to use
when decoding an encoded list or map into a nil interface{} when decoding an encoded list or map into a nil interface{}
- Mapping a non-interface type to an interface, so we can decode appropriately
into any interface type with a correctly configured non-interface value.
- Encode a struct as an array, and decode struct from an array in the data stream - Encode a struct as an array, and decode struct from an array in the data stream
- Option to encode struct keys as numbers (instead of strings)
(to support structured streams with fields encoded as numeric codes)
- Comprehensive support for anonymous fields - Comprehensive support for anonymous fields
- Fast (no-reflection) encoding/decoding of common maps and slices - Fast (no-reflection) encoding/decoding of common maps and slices
- Code-generation for faster performance. - Code-generation for faster performance.
@ -91,6 +96,27 @@ encoded as an empty map because it has no exported fields, while UUID
would be encoded as a string. However, with extension support, you can would be encoded as a string. However, with extension support, you can
encode any of these however you like. encode any of these however you like.
## Custom Encoding and Decoding
This package maintains symmetry in the encoding and decoding halfs.
We determine how to encode or decode by walking this decision tree
- is type a codec.Selfer?
- is there an extension registered for the type?
- is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
- is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
- is format text-based, and type an encoding.TextMarshaler?
- else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
This symmetry is important to reduce chances of issues happening because the
encoding and decoding sides are out of sync e.g. decoded via very specific
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
Consequently, if a type only defines one-half of the symmetry
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
then that type doesn't satisfy the check and we will continue walking down the
decision tree.
## RPC ## RPC
RPC Client and Server Codecs are implemented, so the codecs can be used RPC Client and Server Codecs are implemented, so the codecs can be used
@ -164,3 +190,17 @@ You can run the tag 'safe' to run tests or build in safe mode. e.g.
Please see http://github.com/ugorji/go-codec-bench . Please see http://github.com/ugorji/go-codec-bench .
## Caveats
Struct fields matching the following are ignored during encoding and decoding
- struct tag value set to -
- func, complex numbers, unsafe pointers
- unexported and not embedded
- unexported and embedded and not struct kind
- unexported and embedded pointers (from go1.10)
Every other field in a struct will be encoded/decoded.
Embedded fields are encoded as if they exist in the top-level struct,
with some caveats. See Encode documentation.

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -57,38 +57,31 @@ const (
type bincEncDriver struct { type bincEncDriver struct {
e *Encoder e *Encoder
h *BincHandle
w encWriter w encWriter
m map[string]uint16 // symbols m map[string]uint16 // symbols
b [scratchByteArrayLen]byte b [16]byte // scratch, used for encoding numbers - bigendian style
s uint16 // symbols sequencer s uint16 // symbols sequencer
// c containerState
encDriverTrackContainerWriter
noBuiltInTypes
// encNoSeparator // encNoSeparator
encDriverNoopContainerWriter
}
func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool {
return rt == timeTypId
}
func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {
if rt == timeTypId {
var bs []byte
switch x := v.(type) {
case time.Time:
bs = encodeTime(x)
case *time.Time:
bs = encodeTime(*x)
default:
e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v)
}
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
e.w.writeb(bs)
}
} }
func (e *bincEncDriver) EncodeNil() { func (e *bincEncDriver) EncodeNil() {
e.w.writen1(bincVdSpecial<<4 | bincSpNil) e.w.writen1(bincVdSpecial<<4 | bincSpNil)
} }
func (e *bincEncDriver) EncodeTime(t time.Time) {
if t.IsZero() {
e.EncodeNil()
} else {
bs := bincEncodeTime(t)
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
e.w.writeb(bs)
}
}
func (e *bincEncDriver) EncodeBool(b bool) { func (e *bincEncDriver) EncodeBool(b bool) {
if b { if b {
e.w.writen1(bincVdSpecial<<4 | bincSpTrue) e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
@ -198,13 +191,19 @@ func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
func (e *bincEncDriver) WriteArrayStart(length int) { func (e *bincEncDriver) WriteArrayStart(length int) {
e.encLen(bincVdArray<<4, uint64(length)) e.encLen(bincVdArray<<4, uint64(length))
e.c = containerArrayStart
} }
func (e *bincEncDriver) WriteMapStart(length int) { func (e *bincEncDriver) WriteMapStart(length int) {
e.encLen(bincVdMap<<4, uint64(length)) e.encLen(bincVdMap<<4, uint64(length))
e.c = containerMapStart
} }
func (e *bincEncDriver) EncodeString(c charEncoding, v string) { func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
e.EncodeSymbol(v)
return
}
l := uint64(len(v)) l := uint64(len(v))
e.encBytesLen(c, l) e.encBytesLen(c, l)
if l > 0 { if l > 0 {
@ -214,7 +213,7 @@ func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
func (e *bincEncDriver) EncodeSymbol(v string) { func (e *bincEncDriver) EncodeSymbol(v string) {
// if WriteSymbolsNoRefs { // if WriteSymbolsNoRefs {
// e.encodeString(c_UTF8, v) // e.encodeString(cUTF8, v)
// return // return
// } // }
@ -224,10 +223,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
l := len(v) l := len(v)
if l == 0 { if l == 0 {
e.encBytesLen(c_UTF8, 0) e.encBytesLen(cUTF8, 0)
return return
} else if l == 1 { } else if l == 1 {
e.encBytesLen(c_UTF8, 1) e.encBytesLen(cUTF8, 1)
e.w.writen1(v[0]) e.w.writen1(v[0])
return return
} }
@ -277,6 +276,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
} }
func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) { func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
if v == nil {
e.EncodeNil()
return
}
l := uint64(len(v)) l := uint64(len(v))
e.encBytesLen(c, l) e.encBytesLen(c, l)
if l > 0 { if l > 0 {
@ -286,7 +289,7 @@ func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) { func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
//TODO: support bincUnicodeOther (for now, just use string or bytearray) //TODO: support bincUnicodeOther (for now, just use string or bytearray)
if c == c_RAW { if c == cRAW {
e.encLen(bincVdByteArray<<4, length) e.encLen(bincVdByteArray<<4, length)
} else { } else {
e.encLen(bincVdString<<4, length) e.encLen(bincVdString<<4, length)
@ -325,6 +328,9 @@ type bincDecSymbol struct {
} }
type bincDecDriver struct { type bincDecDriver struct {
decDriverNoopContainerReader
noBuiltInTypes
d *Decoder d *Decoder
h *BincHandle h *BincHandle
r decReader r decReader
@ -333,14 +339,15 @@ type bincDecDriver struct {
bd byte bd byte
vd byte vd byte
vs byte vs byte
// noStreamingCodec _ [3]byte // padding
// decNoSeparator
b [scratchByteArrayLen]byte
// linear searching on this slice is ok, // linear searching on this slice is ok,
// because we typically expect < 32 symbols in each stream. // because we typically expect < 32 symbols in each stream.
s []bincDecSymbol s []bincDecSymbol
decDriverNoopContainerReader
// noStreamingCodec
// decNoSeparator
b [8 * 8]byte // scratch
} }
func (d *bincDecDriver) readNextBd() { func (d *bincDecDriver) readNextBd() {
@ -371,9 +378,10 @@ func (d *bincDecDriver) ContainerType() (vt valueType) {
return valueTypeArray return valueTypeArray
} else if d.vd == bincVdMap { } else if d.vd == bincVdMap {
return valueTypeMap return valueTypeMap
} else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
} }
// else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
// }
return valueTypeUnset return valueTypeUnset
} }
@ -388,27 +396,24 @@ func (d *bincDecDriver) TryDecodeAsNil() bool {
return false return false
} }
func (d *bincDecDriver) IsBuiltinType(rt uintptr) bool { func (d *bincDecDriver) DecodeTime() (t time.Time) {
return rt == timeTypId
}
func (d *bincDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
if rt == timeTypId { if d.bd == bincVdSpecial<<4|bincSpNil {
d.bdRead = false
return
}
if d.vd != bincVdTimestamp { if d.vd != bincVdTimestamp {
d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd) d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
return return
} }
tt, err := decodeTime(d.r.readx(int(d.vs))) t, err := bincDecodeTime(d.r.readx(int(d.vs)))
if err != nil { if err != nil {
panic(err) panic(err)
} }
var vt *time.Time = v.(*time.Time)
*vt = tt
d.bdRead = false d.bdRead = false
} return
} }
func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) { func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
@ -497,45 +502,33 @@ func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
return return
} }
} else { } else {
d.d.errorf("number can only be decoded from uint or int values. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd) d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
return return
} }
return return
} }
func (d *bincDecDriver) DecodeInt(bitsize uint8) (i int64) { func (d *bincDecDriver) DecodeInt64() (i int64) {
ui, neg := d.decCheckInteger() ui, neg := d.decCheckInteger()
i, overflow := chkOvf.SignedInt(ui) i = chkOvf.SignedIntV(ui)
if overflow {
d.d.errorf("simple: overflow converting %v to signed integer", ui)
return
}
if neg { if neg {
i = -i i = -i
} }
if chkOvf.Int(i, bitsize) {
d.d.errorf("binc: overflow integer: %v for num bits: %v", i, bitsize)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *bincDecDriver) DecodeUint(bitsize uint8) (ui uint64) { func (d *bincDecDriver) DecodeUint64() (ui uint64) {
ui, neg := d.decCheckInteger() ui, neg := d.decCheckInteger()
if neg { if neg {
d.d.errorf("Assigning negative signed value to unsigned type") d.d.errorf("Assigning negative signed value to unsigned type")
return return
} }
if chkOvf.Uint(ui, bitsize) {
d.d.errorf("binc: overflow integer: %v", ui)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { func (d *bincDecDriver) DecodeFloat64() (f float64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -557,11 +550,7 @@ func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
} else if vd == bincVdFloat { } else if vd == bincVdFloat {
f = d.decFloat() f = d.decFloat()
} else { } else {
f = float64(d.DecodeInt(64)) f = float64(d.DecodeInt64())
}
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("binc: float32 overflow: %v", f)
return
} }
d.bdRead = false d.bdRead = false
return return
@ -633,7 +622,8 @@ func (d *bincDecDriver) decLenNumber() (v uint64) {
return return
} }
func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (bs2 []byte, s string) { func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
bs2 []byte, s string) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -641,7 +631,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
d.bdRead = false d.bdRead = false
return return
} }
var slen int = -1 var slen = -1
// var ok bool // var ok bool
switch d.vd { switch d.vd {
case bincVdString, bincVdByteArray: case bincVdString, bincVdByteArray:
@ -743,6 +733,11 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
d.bdRead = false d.bdRead = false
return nil return nil
} }
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
if d.vd == bincVdArray {
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
return
}
var clen int var clen int
if d.vd == bincVdString || d.vd == bincVdByteArray { if d.vd == bincVdString || d.vd == bincVdByteArray {
clen = d.decLen() clen = d.decLen()
@ -863,8 +858,8 @@ func (d *bincDecDriver) DecodeNaked() {
n.v = valueTypeBytes n.v = valueTypeBytes
n.l = d.DecodeBytes(nil, false) n.l = d.DecodeBytes(nil, false)
case bincVdTimestamp: case bincVdTimestamp:
n.v = valueTypeTimestamp n.v = valueTypeTime
tt, err := decodeTime(d.r.readx(int(d.vs))) tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -912,27 +907,50 @@ type BincHandle struct {
BasicHandle BasicHandle
binaryEncodingType binaryEncodingType
noElemSeparators noElemSeparators
// AsSymbols defines what should be encoded as symbols.
//
// Encoding as symbols can reduce the encoded size significantly.
//
// However, during decoding, each string to be encoded as a symbol must
// be checked to see if it has been seen before. Consequently, encoding time
// will increase if using symbols, because string comparisons has a clear cost.
//
// Values:
// - 0: default: library uses best judgement
// - 1: use symbols
// - 2: do not use symbols
AsSymbols uint8
// AsSymbols: may later on introduce more options ...
// - m: map keys
// - s: struct fields
// - n: none
// - a: all: same as m, s, ...
_ [1]uint64 // padding
} }
// Name returns the name of the handle: binc
func (h *BincHandle) Name() string { return "binc" }
// SetBytesExt sets an extension
func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, &setExtWrapper{b: ext}) return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
} }
func (h *BincHandle) newEncDriver(e *Encoder) encDriver { func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
return &bincEncDriver{e: e, w: e.w} return &bincEncDriver{e: e, h: h, w: e.w}
} }
func (h *BincHandle) newDecDriver(d *Decoder) decDriver { func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes} return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
} }
func (_ *BincHandle) IsBuiltinType(rt uintptr) bool {
return rt == timeTypId
}
func (e *bincEncDriver) reset() { func (e *bincEncDriver) reset() {
e.w = e.e.w e.w = e.e.w
e.s = 0 e.s = 0
e.c = 0
e.m = nil e.m = nil
} }
@ -942,5 +960,165 @@ func (d *bincDecDriver) reset() {
d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0 d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
} }
// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
// EncodeTime encodes a time.Time as a []byte, including
// information on the instant in time and UTC offset.
//
// Format Description
//
// A timestamp is composed of 3 components:
//
// - secs: signed integer representing seconds since unix epoch
// - nsces: unsigned integer representing fractional seconds as a
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
// - tz: signed integer representing timezone offset in minutes east of UTC,
// and a dst (daylight savings time) flag
//
// When encoding a timestamp, the first byte is the descriptor, which
// defines which components are encoded and how many bytes are used to
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
// is not encoded in the byte array explicitly*.
//
// Descriptor 8 bits are of the form `A B C DDD EE`:
// A: Is secs component encoded? 1 = true
// B: Is nsecs component encoded? 1 = true
// C: Is tz component encoded? 1 = true
// DDD: Number of extra bytes for secs (range 0-7).
// If A = 1, secs encoded in DDD+1 bytes.
// If A = 0, secs is not encoded, and is assumed to be 0.
// If A = 1, then we need at least 1 byte to encode secs.
// DDD says the number of extra bytes beyond that 1.
// E.g. if DDD=0, then secs is represented in 1 byte.
// if DDD=2, then secs is represented in 3 bytes.
// EE: Number of extra bytes for nsecs (range 0-3).
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
//
// Following the descriptor bytes, subsequent bytes are:
//
// secs component encoded in `DDD + 1` bytes (if A == 1)
// nsecs component encoded in `EE + 1` bytes (if B == 1)
// tz component encoded in 2 bytes (if C == 1)
//
// secs and nsecs components are integers encoded in a BigEndian
// 2-complement encoding format.
//
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
// Least significant bit 0 are described below:
//
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
//
func bincEncodeTime(t time.Time) []byte {
//t := rv.Interface().(time.Time)
tsecs, tnsecs := t.Unix(), t.Nanosecond()
var (
bd byte
btmp [8]byte
bs [16]byte
i int = 1
)
l := t.Location()
if l == time.UTC {
l = nil
}
if tsecs != 0 {
bd = bd | 0x80
bigen.PutUint64(btmp[:], uint64(tsecs))
f := pruneSignExt(btmp[:], tsecs >= 0)
bd = bd | (byte(7-f) << 2)
copy(bs[i:], btmp[f:])
i = i + (8 - f)
}
if tnsecs != 0 {
bd = bd | 0x40
bigen.PutUint32(btmp[:4], uint32(tnsecs))
f := pruneSignExt(btmp[:4], true)
bd = bd | byte(3-f)
copy(bs[i:], btmp[f:4])
i = i + (4 - f)
}
if l != nil {
bd = bd | 0x20
// Note that Go Libs do not give access to dst flag.
_, zoneOffset := t.Zone()
//zoneName, zoneOffset := t.Zone()
zoneOffset /= 60
z := uint16(zoneOffset)
bigen.PutUint16(btmp[:2], z)
// clear dst flags
bs[i] = btmp[0] & 0x3f
bs[i+1] = btmp[1]
i = i + 2
}
bs[0] = bd
return bs[0:i]
}
// bincDecodeTime decodes a []byte into a time.Time.
func bincDecodeTime(bs []byte) (tt time.Time, err error) {
bd := bs[0]
var (
tsec int64
tnsec uint32
tz uint16
i byte = 1
i2 byte
n byte
)
if bd&(1<<7) != 0 {
var btmp [8]byte
n = ((bd >> 2) & 0x7) + 1
i2 = i + n
copy(btmp[8-n:], bs[i:i2])
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
if bs[i]&(1<<7) != 0 {
copy(btmp[0:8-n], bsAll0xff)
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
}
i = i2
tsec = int64(bigen.Uint64(btmp[:]))
}
if bd&(1<<6) != 0 {
var btmp [4]byte
n = (bd & 0x3) + 1
i2 = i + n
copy(btmp[4-n:], bs[i:i2])
i = i2
tnsec = bigen.Uint32(btmp[:])
}
if bd&(1<<5) == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
return
}
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
// However, we need name here, so it can be shown when time is printed.
// Zone name is in form: UTC-08:00.
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
i2 = i + 2
tz = bigen.Uint16(bs[i:i2])
// i = i2
// sign extend sign bit into top 2 MSB (which were dst bits):
if tz&(1<<13) == 0 { // positive
tz = tz & 0x3fff //clear 2 MSBs: dst bits
} else { // negative
tz = tz | 0xc000 //set 2 MSBs: dst bits
}
tzint := int16(tz)
if tzint == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
} else {
// For Go Time, do not use a descriptive timezone.
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
// var zoneName = timeLocUTCName(tzint)
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
}
return
}
var _ decDriver = (*bincDecDriver)(nil) var _ decDriver = (*bincDecDriver)(nil)
var _ encDriver = (*bincEncDriver)(nil) var _ encDriver = (*bincEncDriver)(nil)

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -6,6 +6,7 @@ package codec
import ( import (
"math" "math"
"reflect" "reflect"
"time"
) )
const ( const (
@ -38,6 +39,8 @@ const (
cborBdBreak = 0xff cborBdBreak = 0xff
) )
// These define some in-stream descriptors for
// manual encoding e.g. when doing explicit indefinite-length
const ( const (
CborStreamBytes byte = 0x5f CborStreamBytes byte = 0x5f
CborStreamString = 0x7f CborStreamString = 0x7f
@ -67,6 +70,7 @@ type cborEncDriver struct {
w encWriter w encWriter
h *CborHandle h *CborHandle
x [8]byte x [8]byte
_ [3]uint64 // padding
} }
func (e *cborEncDriver) EncodeNil() { func (e *cborEncDriver) EncodeNil() {
@ -124,6 +128,24 @@ func (e *cborEncDriver) encLen(bd byte, length int) {
e.encUint(uint64(length), bd) e.encUint(uint64(length), bd)
} }
func (e *cborEncDriver) EncodeTime(t time.Time) {
if t.IsZero() {
e.EncodeNil()
} else if e.h.TimeRFC3339 {
e.encUint(0, cborBaseTag)
e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
} else {
e.encUint(1, cborBaseTag)
t = t.UTC().Round(time.Microsecond)
sec, nsec := t.Unix(), uint64(t.Nanosecond())
if nsec == 0 {
e.EncodeInt(sec)
} else {
e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
}
}
}
func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) { func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
e.encUint(uint64(xtag), cborBaseTag) e.encUint(uint64(xtag), cborBaseTag)
if v := ext.ConvertExt(rv); v == nil { if v := ext.ConvertExt(rv); v == nil {
@ -173,21 +195,49 @@ func (e *cborEncDriver) WriteArrayEnd() {
} }
func (e *cborEncDriver) EncodeString(c charEncoding, v string) { func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
e.encLen(cborBaseString, len(v)) e.encStringBytesS(cborBaseString, v)
e.w.writestr(v)
}
func (e *cborEncDriver) EncodeSymbol(v string) {
e.EncodeString(c_UTF8, v)
} }
func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) { func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
if c == c_RAW { if v == nil {
e.encLen(cborBaseBytes, len(v)) e.EncodeNil()
} else if c == cRAW {
e.encStringBytesS(cborBaseBytes, stringView(v))
} else { } else {
e.encLen(cborBaseString, len(v)) e.encStringBytesS(cborBaseString, stringView(v))
}
}
func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
if e.h.IndefiniteLength {
if bb == cborBaseBytes {
e.w.writen1(cborBdIndefiniteBytes)
} else {
e.w.writen1(cborBdIndefiniteString)
}
blen := len(v) / 4
if blen == 0 {
blen = 64
} else if blen > 1024 {
blen = 1024
}
for i := 0; i < len(v); {
var v2 string
i2 := i + blen
if i2 < len(v) {
v2 = v[i:i2]
} else {
v2 = v[i:]
}
e.encLen(bb, len(v2))
e.w.writestr(v2)
i = i2
}
e.w.writen1(cborBdBreak)
} else {
e.encLen(bb, len(v))
e.w.writestr(v)
} }
e.w.writeb(v)
} }
// ---------------------- // ----------------------
@ -196,13 +246,14 @@ type cborDecDriver struct {
d *Decoder d *Decoder
h *CborHandle h *CborHandle
r decReader r decReader
b [scratchByteArrayLen]byte // b [scratchByteArrayLen]byte
br bool // bytes reader br bool // bytes reader
bdRead bool bdRead bool
bd byte bd byte
noBuiltInTypes noBuiltInTypes
// decNoSeparator // decNoSeparator
decDriverNoopContainerReader decDriverNoopContainerReader
_ [3]uint64 // padding
} }
func (d *cborDecDriver) readNextBd() { func (d *cborDecDriver) readNextBd() {
@ -231,9 +282,10 @@ func (d *cborDecDriver) ContainerType() (vt valueType) {
return valueTypeArray return valueTypeArray
} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) { } else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
return valueTypeMap return valueTypeMap
} else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
} }
// else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
// }
return valueTypeUnset return valueTypeUnset
} }
@ -296,46 +348,30 @@ func (d *cborDecDriver) decCheckInteger() (neg bool) {
return return
} }
func (d *cborDecDriver) DecodeInt(bitsize uint8) (i int64) { func (d *cborDecDriver) DecodeInt64() (i int64) {
neg := d.decCheckInteger() neg := d.decCheckInteger()
ui := d.decUint() ui := d.decUint()
// check if this number can be converted to an int without overflow // check if this number can be converted to an int without overflow
var overflow bool
if neg { if neg {
if i, overflow = chkOvf.SignedInt(ui + 1); overflow { i = -(chkOvf.SignedIntV(ui + 1))
d.d.errorf("cbor: overflow converting %v to signed integer", ui+1)
return
}
i = -i
} else { } else {
if i, overflow = chkOvf.SignedInt(ui); overflow { i = chkOvf.SignedIntV(ui)
d.d.errorf("cbor: overflow converting %v to signed integer", ui)
return
}
}
if chkOvf.Int(i, bitsize) {
d.d.errorf("cbor: overflow integer: %v", i)
return
} }
d.bdRead = false d.bdRead = false
return return
} }
func (d *cborDecDriver) DecodeUint(bitsize uint8) (ui uint64) { func (d *cborDecDriver) DecodeUint64() (ui uint64) {
if d.decCheckInteger() { if d.decCheckInteger() {
d.d.errorf("Assigning negative signed value to unsigned type") d.d.errorf("Assigning negative signed value to unsigned type")
return return
} }
ui = d.decUint() ui = d.decUint()
if chkOvf.Uint(ui, bitsize) {
d.d.errorf("cbor: overflow integer: %v", ui)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *cborDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { func (d *cborDecDriver) DecodeFloat64() (f float64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -346,15 +382,11 @@ func (d *cborDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
} else if bd == cborBdFloat64 { } else if bd == cborBdFloat64 {
f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
} else if bd >= cborBaseUint && bd < cborBaseBytes { } else if bd >= cborBaseUint && bd < cborBaseBytes {
f = float64(d.DecodeInt(64)) f = float64(d.DecodeInt64())
} else { } else {
d.d.errorf("Float only valid from float16/32/64: Invalid descriptor: %v", bd) d.d.errorf("Float only valid from float16/32/64: Invalid descriptor: %v", bd)
return return
} }
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("cbor: float32 overflow: %v", f)
return
}
d.bdRead = false d.bdRead = false
return return
} }
@ -408,7 +440,8 @@ func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
break break
} }
if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText { if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
d.d.errorf("cbor: expect bytes or string major type in indefinite string/bytes; got: %v, byte: %v", major, d.bd) d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
" got: %v, byte: %v", major, d.bd)
return nil return nil
} }
n := d.decLen() n := d.decLen()
@ -438,29 +471,84 @@ func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
return nil return nil
} }
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString { if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
d.bdRead = false
if bs == nil { if bs == nil {
return d.decAppendIndefiniteBytes(nil) if zerocopy {
return d.decAppendIndefiniteBytes(d.d.b[:0])
}
return d.decAppendIndefiniteBytes(zeroByteSlice)
} }
return d.decAppendIndefiniteBytes(bs[:0]) return d.decAppendIndefiniteBytes(bs[:0])
} }
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
return
}
clen := d.decLen() clen := d.decLen()
d.bdRead = false d.bdRead = false
if zerocopy { if zerocopy {
if d.br { if d.br {
return d.r.readx(clen) return d.r.readx(clen)
} else if len(bs) == 0 { } else if len(bs) == 0 {
bs = d.b[:] bs = d.d.b[:]
} }
} }
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs) return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
} }
func (d *cborDecDriver) DecodeString() (s string) { func (d *cborDecDriver) DecodeString() (s string) {
return string(d.DecodeBytes(d.b[:], true)) return string(d.DecodeBytes(d.d.b[:], true))
} }
func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) { func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
return d.DecodeBytes(d.b[:], true) return d.DecodeBytes(d.d.b[:], true)
}
func (d *cborDecDriver) DecodeTime() (t time.Time) {
if !d.bdRead {
d.readNextBd()
}
if d.bd == cborBdNil || d.bd == cborBdUndefined {
d.bdRead = false
return
}
xtag := d.decUint()
d.bdRead = false
return d.decodeTime(xtag)
}
func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
if !d.bdRead {
d.readNextBd()
}
switch xtag {
case 0:
var err error
if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
d.d.errorv(err)
}
case 1:
// decode an int64 or a float, and infer time.Time from there.
// for floats, round to microseconds, as that is what is guaranteed to fit well.
switch {
case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
f1, f2 := math.Modf(d.DecodeFloat64())
t = time.Unix(int64(f1), int64(f2*1e9))
case d.bd == cborBdFloat64:
f1, f2 := math.Modf(d.DecodeFloat64())
t = time.Unix(int64(f1), int64(f2*1e9))
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
t = time.Unix(d.DecodeInt64(), 0)
default:
d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
}
default:
d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
}
t = t.UTC().Round(time.Microsecond)
return
} }
func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
@ -503,12 +591,9 @@ func (d *cborDecDriver) DecodeNaked() {
case cborBdTrue: case cborBdTrue:
n.v = valueTypeBool n.v = valueTypeBool
n.b = true n.b = true
case cborBdFloat16, cborBdFloat32: case cborBdFloat16, cborBdFloat32, cborBdFloat64:
n.v = valueTypeFloat n.v = valueTypeFloat
n.f = d.DecodeFloat(true) n.f = d.DecodeFloat64()
case cborBdFloat64:
n.v = valueTypeFloat
n.f = d.DecodeFloat(false)
case cborBdIndefiniteBytes: case cborBdIndefiniteBytes:
n.v = valueTypeBytes n.v = valueTypeBytes
n.l = d.DecodeBytes(nil, false) n.l = d.DecodeBytes(nil, false)
@ -526,14 +611,14 @@ func (d *cborDecDriver) DecodeNaked() {
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt: case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
if d.h.SignedInteger { if d.h.SignedInteger {
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
} else { } else {
n.v = valueTypeUint n.v = valueTypeUint
n.u = d.DecodeUint(64) n.u = d.DecodeUint64()
} }
case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes: case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
case d.bd >= cborBaseBytes && d.bd < cborBaseString: case d.bd >= cborBaseBytes && d.bd < cborBaseString:
n.v = valueTypeBytes n.v = valueTypeBytes
n.l = d.DecodeBytes(nil, false) n.l = d.DecodeBytes(nil, false)
@ -550,6 +635,11 @@ func (d *cborDecDriver) DecodeNaked() {
n.v = valueTypeExt n.v = valueTypeExt
n.u = d.decUint() n.u = d.decUint()
n.l = nil n.l = nil
if n.u == 0 || n.u == 1 {
d.bdRead = false
n.v = valueTypeTime
n.t = d.decodeTime(n.u)
}
// d.bdRead = false // d.bdRead = false
// d.d.decode(&re.Value) // handled by decode itself. // d.d.decode(&re.Value) // handled by decode itself.
// decodeFurther = true // decodeFurther = true
@ -580,23 +670,8 @@ func (d *cborDecDriver) DecodeNaked() {
// //
// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box. // None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
// Users can implement them as needed (using SetExt), including spec-documented ones: // Users can implement them as needed (using SetExt), including spec-documented ones:
// - timestamp, BigNum, BigFloat, Decimals, Encoded Text (e.g. URL, regexp, base64, MIME Message), etc. // - timestamp, BigNum, BigFloat, Decimals,
// // - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
// To encode with indefinite lengths (streaming), users will use
// (Must)Encode methods of *Encoder, along with writing CborStreamXXX constants.
//
// For example, to encode "one-byte" as an indefinite length string:
// var buf bytes.Buffer
// e := NewEncoder(&buf, new(CborHandle))
// buf.WriteByte(CborStreamString)
// e.MustEncode("one-")
// e.MustEncode("byte")
// buf.WriteByte(CborStreamBreak)
// encodedBytes := buf.Bytes()
// var vv interface{}
// NewDecoderBytes(buf.Bytes(), new(CborHandle)).MustDecode(&vv)
// // Now, vv contains the same string "one-byte"
//
type CborHandle struct { type CborHandle struct {
binaryEncodingType binaryEncodingType
noElemSeparators noElemSeparators
@ -604,10 +679,20 @@ type CborHandle struct {
// IndefiniteLength=true, means that we encode using indefinitelength // IndefiniteLength=true, means that we encode using indefinitelength
IndefiniteLength bool IndefiniteLength bool
// TimeRFC3339 says to encode time.Time using RFC3339 format.
// If unset, we encode time.Time using seconds past epoch.
TimeRFC3339 bool
_ [1]uint64 // padding
} }
// Name returns the name of the handle: cbor
func (h *CborHandle) Name() string { return "cbor" }
// SetInterfaceExt sets an extension
func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
return h.SetExt(rt, tag, &setExtWrapper{i: ext}) return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
} }
func (h *CborHandle) newEncDriver(e *Encoder) encDriver { func (h *CborHandle) newEncDriver(e *Encoder) encDriver {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,7 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // 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. // Use of this source code is governed by a MIT license found in the LICENSE file.
// ************************************************************ // Code generated from fast-path.go.tmpl - DO NOT EDIT.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from fast-path.go.tmpl
// ************************************************************
package codec package codec
@ -86,17 +83,13 @@ func init() {
fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) { fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
xrt := reflect.TypeOf(v) xrt := reflect.TypeOf(v)
xptr := rt2id(xrt) xptr := rt2id(xrt)
if useLookupRecognizedTypes {
recognizedRtids = append(recognizedRtids, xptr)
recognizedRtidPtrs = append(recognizedRtidPtrs, rt2id(reflect.PtrTo(xrt)))
}
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
i++ i++
return return
} }
{{/* do not register []uint8 in fast-path */}}
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }} {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
@ -109,21 +102,37 @@ func init() {
// -- -- fast path type switch // -- -- fast path type switch
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case []{{ .Elem }}:{{else}} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
case map[{{ .MapKey }}]{{ .Elem }}:{{end}} case []{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e){{if not .MapKey }} fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
case *[]{{ .Elem }}:{{else}} case *[]{{ .Elem }}:
case *map[{{ .MapKey }}]{{ .Elem }}:{{end}} fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e) */}}{{end}}{{end}}{{end}}{{end}}
{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
case map[{{ .MapKey }}]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
case *map[{{ .MapKey }}]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
*/}}{{end}}{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
} }
{{/*
**** removing this block, as they are never called directly ****
**** removing this block, as they are never called directly ****
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
@ -133,7 +142,7 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
@ -148,15 +157,23 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
} }
**** removing this block, as they are never called directly ****
**** removing this block, as they are never called directly ****
*/}}
// -- -- fast path functions // -- -- fast path functions
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) { func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
if f.ti.mbs { if f.ti.mbs {
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e) fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
@ -165,15 +182,25 @@ func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv r
} }
} }
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) { func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
if v == nil { e.e.EncodeNil(); return }
ee, esep := e.e, e.hh.hasElemSeparators() ee, esep := e.e, e.hh.hasElemSeparators()
ee.WriteArrayStart(len(v)) ee.WriteArrayStart(len(v))
if esep {
for _, v2 := range v {
ee.WriteArrayElem()
{{ encmd .Elem "v2"}}
}
} else {
for _, v2 := range v {
{{ encmd .Elem "v2"}}
}
} {{/*
for _, v2 := range v { for _, v2 := range v {
if esep { ee.WriteArrayElem() } if esep { ee.WriteArrayElem() }
{{ encmd .Elem "v2"}} {{ encmd .Elem "v2"}}
} } */}}
ee.WriteArrayEnd() ee.WriteArrayEnd()
} }
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) { func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
ee, esep := e.e, e.hh.hasElemSeparators() ee, esep := e.e, e.hh.hasElemSeparators()
if len(v)%2 == 1 { if len(v)%2 == 1 {
@ -181,6 +208,20 @@ func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *En
return return
} }
ee.WriteMapStart(len(v) / 2) ee.WriteMapStart(len(v) / 2)
if esep {
for j, v2 := range v {
if j%2 == 0 {
ee.WriteMapElemKey()
} else {
ee.WriteMapElemValue()
}
{{ encmd .Elem "v2"}}
}
} else {
for _, v2 := range v {
{{ encmd .Elem "v2"}}
}
} {{/*
for j, v2 := range v { for j, v2 := range v {
if esep { if esep {
if j%2 == 0 { if j%2 == 0 {
@ -190,22 +231,20 @@ func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *En
} }
} }
{{ encmd .Elem "v2"}} {{ encmd .Elem "v2"}}
} } */}}
ee.WriteMapEnd() ee.WriteMapEnd()
} }
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }} {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) { func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
} }
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) { func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
if v == nil { e.e.EncodeNil(); return }
ee, esep := e.e, e.hh.hasElemSeparators() ee, esep := e.e, e.hh.hasElemSeparators()
ee.WriteMapStart(len(v)) ee.WriteMapStart(len(v))
{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 if e.h.Canonical {
{{end}}if e.h.Canonical {
{{if eq .MapKey "interface{}"}}{{/* out of band {{if eq .MapKey "interface{}"}}{{/* out of band
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding */}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
e2 := NewEncoderBytes(&mksv, e.hh) e2 := NewEncoderBytes(&mksv, e.hh)
@ -221,76 +260,126 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele
i++ i++
} }
sort.Sort(bytesISlice(v2)) sort.Sort(bytesISlice(v2))
if esep {
for j := range v2 {
ee.WriteMapElemKey()
e.asis(v2[j].v)
ee.WriteMapElemValue()
e.encode(v[v2[j].i])
}
} else {
for j := range v2 {
e.asis(v2[j].v)
e.encode(v[v2[j].i])
}
} {{/*
for j := range v2 { for j := range v2 {
if esep { ee.WriteMapElemKey() } if esep { ee.WriteMapElemKey() }
e.asis(v2[j].v) e.asis(v2[j].v)
if esep { ee.WriteMapElemValue() } if esep { ee.WriteMapElemValue() }
e.encode(v[v2[j].i]) e.encode(v[v2[j].i])
} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v)) } */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
var i int var i int
for k, _ := range v { for k, _ := range v {
v2[i] = {{ $x }}(k) v2[i] = {{ $x }}(k)
i++ i++
} }
sort.Sort({{ sorttype .MapKey false}}(v2)) sort.Sort({{ sorttype .MapKey false}}(v2))
if esep {
for _, k2 := range v2 {
ee.WriteMapElemKey()
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
ee.WriteMapElemValue()
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
}
} else {
for _, k2 := range v2 {
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
}
} {{/*
for _, k2 := range v2 { for _, k2 := range v2 {
if esep { ee.WriteMapElemKey() } if esep { ee.WriteMapElemKey() }
{{if eq .MapKey "string"}}if asSymbols { {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
ee.EncodeSymbol(k2)
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
if esep { ee.WriteMapElemValue() } if esep { ee.WriteMapElemValue() }
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }} {{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
} {{end}} } */}} {{end}}
} else { } else {
if esep {
for k2, v2 := range v { for k2, v2 := range v {
if esep { ee.WriteMapElemKey() } ee.WriteMapElemKey()
{{if eq .MapKey "string"}}if asSymbols { {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
ee.EncodeSymbol(k2) ee.WriteMapElemValue()
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ encmd .MapKey "k2"}}{{end}}
if esep { ee.WriteMapElemValue() }
{{ encmd .Elem "v2"}} {{ encmd .Elem "v2"}}
} }
} else {
for k2, v2 := range v {
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
{{ encmd .Elem "v2"}}
}
} {{/*
for k2, v2 := range v {
if esep { ee.WriteMapElemKey() }
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
if esep { ee.WriteMapElemValue() }
{{ encmd .Elem "v2"}}
} */}}
} }
ee.WriteMapEnd() ee.WriteMapEnd()
} }
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
// -- decode // -- decode
// -- -- fast path type switch // -- -- fast path type switch
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
var changed bool
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
case []{{ .Elem }}:{{else}} case []{{ .Elem }}:
case map[{{ .MapKey }}]{{ .Elem }}:{{end}} var v2 []{{ .Elem }}
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d){{if not .MapKey }} v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
case *[]{{ .Elem }}: {{else}} if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
case *map[{{ .MapKey }}]{{ .Elem }}: {{end}} copy(v, v2)
if v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d); changed2 {
*v = v2
} }
{{end}}{{end}} case *[]{{ .Elem }}:
var v2 []{{ .Elem }}
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
if changed {
*v = v2
}{{/*
*/}}{{end}}{{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
// maps only change if nil, and in that case, there's no point copying
*/}}
case map[{{ .MapKey }}]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
case *map[{{ .MapKey }}]{{ .Elem }}:
var v2 map[{{ .MapKey }}]{{ .Elem }}
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
if changed {
*v = v2
}{{/*
*/}}{{end}}{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
} }
func fastpathDecodeSetZeroTypeSwitch(iv interface{}, d *Decoder) bool { func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case *[]{{ .Elem }}: {{else}} case *[]{{ .Elem }}:
case *map[{{ .MapKey }}]{{ .Elem }}: {{end}} *v = nil {{/*
*v = nil */}}{{end}}{{end}}{{end}}
{{end}}{{end}} {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
case *map[{{ .MapKey }}]{{ .Elem }}:
*v = nil {{/*
*/}}{{end}}{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
@ -306,37 +395,34 @@ Slices can change if they
*/}} */}}
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr { if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
var vp = rv2i(rv).(*[]{{ .Elem }}) vp := rv2i(rv).(*[]{{ .Elem }})
if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d); changed { v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
*vp = v if changed { *vp = v }
}
} else { } else {
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).([]{{ .Elem }}), !array, d) v := rv2i(rv).([]{{ .Elem }})
v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
copy(v, v2)
}
} }
} }
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) { func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
if v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed { v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
*vp = v if changed { *vp = v }
}
} }
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) { func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
dd := d.d dd := d.d{{/*
{{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}} // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
*/}}
slh, containerLenS := d.decSliceHelperStart() slh, containerLenS := d.decSliceHelperStart()
if containerLenS == 0 { if containerLenS == 0 {
if canChange { if canChange {
if v == nil { if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
v = []{{ .Elem }}{}
} else if len(v) != 0 {
v = v[:0]
}
changed = true changed = true
} }
slh.End() slh.End()
return v, changed return v, changed
} }
hasLen := containerLenS > 0 hasLen := containerLenS > 0
var xlen int var xlen int
if hasLen && canChange { if hasLen && canChange {
@ -355,7 +441,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
} }
j := 0 j := 0
for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ { for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
if j == 0 && len(v) == 0 { if j == 0 && len(v) == 0 && canChange {
if hasLen { if hasLen {
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }}) xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
} else { } else {
@ -378,6 +464,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
slh.ElemContainerState(j) slh.ElemContainerState(j)
if decodeIntoBlank { if decodeIntoBlank {
d.swallow() d.swallow()
} else if dd.TryDecodeAsNil() {
v[j] = {{ zerocmd .Elem }}
} else { } else {
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }} {{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
} }
@ -394,10 +482,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
slh.End() slh.End()
return v, changed return v, changed
} }
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }} {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
{{/* {{/*
Maps can change if they are Maps can change if they are
@ -407,22 +493,21 @@ Maps can change if they are
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
if rv.Kind() == reflect.Ptr { if rv.Kind() == reflect.Ptr {
vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }}) vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed { v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
*vp = v if changed { *vp = v }
} } else {
return
}
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d) fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
} }
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
if v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed {
*vp = v
} }
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
if changed { *vp = v }
} }
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool, func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) { d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
dd, esep := d.d, d.hh.hasElemSeparators() dd, esep := d.d, d.hh.hasElemSeparators(){{/*
{{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}} // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
*/}}
containerLen := dd.ReadMapStart() containerLen := dd.ReadMapStart()
if canChange && v == nil { if canChange && v == nil {
xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}) xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
@ -433,8 +518,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele
dd.ReadMapEnd() dd.ReadMapEnd()
return v, changed return v, changed
} }
{{ if eq .Elem "interface{}" }}mapGet := !d.h.MapValueReset && !d.h.InterfaceReset{{end}} {{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
var mk {{ .MapKey }} {{end}}var mk {{ .MapKey }}
var mv {{ .Elem }} var mv {{ .Elem }}
hasLen := containerLen > 0 hasLen := containerLen > 0
for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ { for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
@ -446,17 +531,14 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele
}{{ else }}mk = {{ decmd .MapKey }}{{ end }} }{{ else }}mk = {{ decmd .MapKey }}{{ end }}
if esep { dd.ReadMapElemValue() } if esep { dd.ReadMapElemValue() }
if dd.TryDecodeAsNil() { if dd.TryDecodeAsNil() {
if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} } if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
continue continue
} }
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil } {{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }} d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
if v != nil { if v != nil { v[mk] = mv }
v[mk] = mv
}
} }
dd.ReadMapEnd() dd.ReadMapEnd()
return v, changed return v, changed
} }
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}

View File

@ -1,3 +1,6 @@
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build notfastpath // +build notfastpath
package codec package codec
@ -18,7 +21,7 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return f
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false } func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false }
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false } func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false } func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false }
func fastpathDecodeSetZeroTypeSwitch(iv interface{}, d *Decoder) bool { return false } func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool { return false }
type fastpathT struct{} type fastpathT struct{}
type fastpathE struct { type fastpathE struct {
@ -31,5 +34,14 @@ type fastpathA [0]fastpathE
func (x fastpathA) index(rtid uintptr) int { return -1 } func (x fastpathA) index(rtid uintptr) int { return -1 }
func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
fn := d.cfer().get(uint8SliceTyp, true, true)
d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
return v, true
}
var fastpathAV fastpathA var fastpathAV fastpathA
var fastpathTV fastpathT var fastpathTV fastpathT
// ----
type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode

View File

@ -43,7 +43,7 @@ if {{var "l"}} == 0 {
{{var "c"}} = true {{var "c"}} = true
}{{end}} }{{end}}
{{var "h"}}.ElemContainerState({{var "j"}}) {{var "h"}}.ElemContainerState({{var "j"}})
// {{var "dn"}} = r.TryDecodeAsNil() {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }} {{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
{{ decLineVar $x }} {{ decLineVar $x }}
{{var "v"}} <- {{ $x }} {{var "v"}} <- {{ $x }}

View File

@ -3,10 +3,7 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // 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. // Use of this source code is governed by a MIT license found in the LICENSE file.
// ************************************************************ // Code generated from gen-helper.go.tmpl - DO NOT EDIT.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
// ************************************************************
package codec package codec
@ -31,30 +28,73 @@ const GenVersion = 8
// GenHelperEncoder is exported so that it can be used externally by codecgen. // GenHelperEncoder is exported so that it can be used externally by codecgen.
// //
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) { func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
return genHelperEncoder{e: e}, e.e ge = genHelperEncoder{e: e}
ee = genHelperEncDriver{encDriver: e.e}
return
} }
// GenHelperDecoder is exported so that it can be used externally by codecgen. // GenHelperDecoder is exported so that it can be used externally by codecgen.
// //
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) { func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
return genHelperDecoder{d: d}, d.d gd = genHelperDecoder{d: d}
dd = genHelperDecDriver{decDriver: d.d}
return
} }
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. type genHelperEncDriver struct {
func BasicHandleDoNotUse(h Handle) *BasicHandle { encDriver
return h.getBasicHandle() }
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
encStructFieldKey(x.encDriver, keyType, s)
}
func (x genHelperEncDriver) EncodeSymbol(s string) {
x.encDriver.EncodeString(cUTF8, s)
}
type genHelperDecDriver struct {
decDriver
C checkOverflow
}
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
return decStructFieldKey(x.decDriver, keyType, buf)
}
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
}
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
}
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
f = x.DecodeFloat64()
if chkOverflow32 && chkOvf.Float32(f) {
panicv.errorf("float32 overflow: %v", f)
}
return
}
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
f = x.DecodeFloat64()
if chkOvf.Float32(f) {
panicv.errorf("float32 overflow: %v", f)
}
return
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperEncoder struct { type genHelperEncoder struct {
M must
e *Encoder e *Encoder
F fastpathT F fastpathT
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperDecoder struct { type genHelperDecoder struct {
C checkOverflow
d *Decoder d *Decoder
F fastpathT F fastpathT
} }
@ -66,7 +106,12 @@ func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBinary() bool { func (f genHelperEncoder) EncBinary() bool {
return f.e.cf.be // f.e.hh.isBinaryEncoding() return f.e.be // f.e.hh.isBinaryEncoding()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool {
return f.e.js
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@ -79,52 +124,65 @@ func (f genHelperEncoder) EncFallback(iv interface{}) {
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) { func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
bs, fnerr := iv.MarshalText() bs, fnerr := iv.MarshalText()
f.e.marshal(bs, fnerr, false, c_UTF8) f.e.marshal(bs, fnerr, false, cUTF8)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) { func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
bs, fnerr := iv.MarshalJSON() bs, fnerr := iv.MarshalJSON()
f.e.marshal(bs, fnerr, true, c_UTF8) f.e.marshal(bs, fnerr, true, cUTF8)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) { func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
bs, fnerr := iv.MarshalBinary() bs, fnerr := iv.MarshalBinary()
f.e.marshal(bs, fnerr, false, c_RAW) f.e.marshal(bs, fnerr, false, cRAW)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncRaw(iv Raw) { func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
f.e.rawBytes(iv)
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: builtin no longer supported - so we make this method a no-op,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
// if _, ok := f.e.hh.(*BincHandle); ok {
// return timeTypId
// }
// }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
return i2rtid(v)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr { func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
if _, ok := f.e.hh.(*BincHandle); ok { return f.e.h.getExt(rtid)
return timeTypId
}
return 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool { func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
return f.e.cf.js f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) HasExtensions() bool { func (f genHelperEncoder) HasExtensions() bool {
return len(f.e.h.extHandle) != 0 return len(f.e.h.extHandle) != 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) EncExt(v interface{}) (r bool) { func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
rt := reflect.TypeOf(v) if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
rtid := rt2id(rt)
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e) f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
return true return true
} }
@ -144,15 +202,18 @@ func (f genHelperDecoder) DecBinary() bool {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSwallow() { func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
f.d.swallow()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchBuffer() []byte { func (f genHelperDecoder) DecScratchBuffer() []byte {
return f.d.b[:] return f.d.b[:]
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
return &f.d.b
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) { func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
// println(">>>>>>>>> DecFallback") // println(">>>>>>>>> DecFallback")
@ -160,7 +221,7 @@ func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
if chkPtr { if chkPtr {
rv = f.d.ensureDecodeable(rv) rv = f.d.ensureDecodeable(rv)
} }
f.d.decodeValue(rv, nil, false, false) f.d.decodeValue(rv, nil, false)
// f.d.decodeValueFallback(rv) // f.d.decodeValueFallback(rv)
} }
@ -206,17 +267,21 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecRaw() []byte { func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
return f.d.rawBytes()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // 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 { // Deprecated: builtin no longer supported - so we make this method a no-op,
return timeTypId // but leave in-place so that old generated files continue to work without regeneration.
} func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
return 0
} // func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
// // Note: builtin is no longer supported - so make this a no-op
// if _, ok := f.d.hh.(*BincHandle); ok {
// return timeTypId
// }
// return 0
// }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) IsJSONHandle() bool { func (f genHelperDecoder) IsJSONHandle() bool {
@ -224,15 +289,34 @@ func (f genHelperDecoder) IsJSONHandle() bool {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
return i2rtid(v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
return f.d.h.getExt(rtid)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperDecoder) HasExtensions() bool { func (f genHelperDecoder) HasExtensions() bool {
return len(f.d.h.extHandle) != 0 return len(f.d.h.extHandle) != 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperDecoder) DecExt(v interface{}) (r bool) { func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
rt := reflect.TypeOf(v).Elem() if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
rtid := rt2id(rt)
if xfFn := f.d.h.getExt(rtid); xfFn != nil {
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext) f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
return true return true
} }
@ -245,6 +329,7 @@ func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) StringView(v []byte) string { //
return stringView(v) // Deprecated: no longer used,
} // but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }

View File

@ -3,10 +3,7 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // 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. // Use of this source code is governed by a MIT license found in the LICENSE file.
// ************************************************************ // Code generated from gen-helper.go.tmpl - DO NOT EDIT.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
// ************************************************************
package codec package codec
@ -31,30 +28,73 @@ const GenVersion = {{ .Version }}
// GenHelperEncoder is exported so that it can be used externally by codecgen. // GenHelperEncoder is exported so that it can be used externally by codecgen.
// //
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) { func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
return genHelperEncoder{e:e}, e.e ge = genHelperEncoder{e: e}
ee = genHelperEncDriver{encDriver: e.e}
return
} }
// GenHelperDecoder is exported so that it can be used externally by codecgen. // GenHelperDecoder is exported so that it can be used externally by codecgen.
// //
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. // Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) { func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
return genHelperDecoder{d:d}, d.d gd = genHelperDecoder{d: d}
dd = genHelperDecDriver{decDriver: d.d}
return
} }
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. type genHelperEncDriver struct {
func BasicHandleDoNotUse(h Handle) *BasicHandle { encDriver
return h.getBasicHandle() }
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
encStructFieldKey(x.encDriver, keyType, s)
}
func (x genHelperEncDriver) EncodeSymbol(s string) {
x.encDriver.EncodeString(cUTF8, s)
}
type genHelperDecDriver struct {
decDriver
C checkOverflow
}
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
return decStructFieldKey(x.decDriver, keyType, buf)
}
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
}
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
}
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
f = x.DecodeFloat64()
if chkOverflow32 && chkOvf.Float32(f) {
panicv.errorf("float32 overflow: %v", f)
}
return
}
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
f = x.DecodeFloat64()
if chkOvf.Float32(f) {
panicv.errorf("float32 overflow: %v", f)
}
return
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperEncoder struct { type genHelperEncoder struct {
M must
e *Encoder e *Encoder
F fastpathT F fastpathT
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperDecoder struct { type genHelperDecoder struct {
C checkOverflow
d *Decoder d *Decoder
F fastpathT F fastpathT
} }
@ -63,10 +103,13 @@ type genHelperDecoder struct {
func (f genHelperEncoder) EncBasicHandle() *BasicHandle { func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
return f.e.h return f.e.h
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBinary() bool { func (f genHelperEncoder) EncBinary() bool {
return f.e.cf.be // f.e.hh.isBinaryEncoding() return f.e.be // f.e.hh.isBinaryEncoding()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool {
return f.e.js
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncFallback(iv interface{}) { func (f genHelperEncoder) EncFallback(iv interface{}) {
@ -77,58 +120,61 @@ func (f genHelperEncoder) EncFallback(iv interface{}) {
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) { func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
bs, fnerr := iv.MarshalText() bs, fnerr := iv.MarshalText()
f.e.marshal(bs, fnerr, false, c_UTF8) f.e.marshal(bs, fnerr, false, cUTF8)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) { func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
bs, fnerr := iv.MarshalJSON() bs, fnerr := iv.MarshalJSON()
f.e.marshal(bs, fnerr, true, c_UTF8) f.e.marshal(bs, fnerr, true, cUTF8)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) { func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
bs, fnerr := iv.MarshalBinary() bs, fnerr := iv.MarshalBinary()
f.e.marshal(bs, fnerr, false, c_RAW) f.e.marshal(bs, fnerr, false, cRAW)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncRaw(iv Raw) { func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
f.e.rawBytes(iv) // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: builtin no longer supported - so we make this method a no-op,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
// if _, ok := f.e.hh.(*BincHandle); ok {
// return timeTypId
// }
// }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
return i2rtid(v)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr { func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
if _, ok := f.e.hh.(*BincHandle); ok { return f.e.h.getExt(rtid)
return timeTypId
}
return 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool { func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
return f.e.cf.js f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) HasExtensions() bool { func (f genHelperEncoder) HasExtensions() bool {
return len(f.e.h.extHandle) != 0 return len(f.e.h.extHandle) != 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperEncoder) EncExt(v interface{}) (r bool) { func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
rt := reflect.TypeOf(v) if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
rtid := rt2id(rt)
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e) f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
return true return true
} }
return false return false
} }
{{/*
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncSendContainerState(c containerState) {
if f.e.cr != nil {
f.e.cr.sendContainerState(c)
}
}
*/}}
// ---------------- DECODER FOLLOWS ----------------- // ---------------- DECODER FOLLOWS -----------------
@ -141,21 +187,23 @@ func (f genHelperDecoder) DecBinary() bool {
return f.d.be // f.d.hh.isBinaryEncoding() return f.d.be // f.d.hh.isBinaryEncoding()
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSwallow() { func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
f.d.swallow()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchBuffer() []byte { func (f genHelperDecoder) DecScratchBuffer() []byte {
return f.d.b[:] return f.d.b[:]
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
return &f.d.b
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) { func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
// println(">>>>>>>>> DecFallback") // println(">>>>>>>>> DecFallback")
rv := reflect.ValueOf(iv) rv := reflect.ValueOf(iv)
if chkPtr { if chkPtr {
rv = f.d.ensureDecodeable(rv) rv = f.d.ensureDecodeable(rv)
} }
f.d.decodeValue(rv, nil, false, false) f.d.decodeValue(rv, nil, false)
// f.d.decodeValueFallback(rv) // f.d.decodeValueFallback(rv)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@ -194,29 +242,49 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
} }
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecRaw() []byte { func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
return f.d.rawBytes()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // 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 { // Deprecated: builtin no longer supported - so we make this method a no-op,
return timeTypId // but leave in-place so that old generated files continue to work without regeneration.
} func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
return 0 // func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
} // // Note: builtin is no longer supported - so make this a no-op
// if _, ok := f.d.hh.(*BincHandle); ok {
// return timeTypId
// }
// return 0
// }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) IsJSONHandle() bool { func (f genHelperDecoder) IsJSONHandle() bool {
return f.d.js return f.d.js
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
return i2rtid(v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
return f.d.h.getExt(rtid)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperDecoder) HasExtensions() bool { func (f genHelperDecoder) HasExtensions() bool {
return len(f.d.h.extHandle) != 0 return len(f.d.h.extHandle) != 0
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
//
// Deprecated: No longer used,
// but leave in-place so that old generated files continue to work without regeneration.
func (f genHelperDecoder) DecExt(v interface{}) (r bool) { func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
rt := reflect.TypeOf(v).Elem() if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
rtid := rt2id(rt)
if xfFn := f.d.h.getExt(rtid); xfFn != nil {
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext) f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
return true return true
} }
@ -227,170 +295,8 @@ func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
return decInferLen(clen, maxlen, unit) return decInferLen(clen, maxlen, unit)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) StringView(v []byte) string { //
return stringView(v) // Deprecated: no longer used,
} // but leave in-place so that old generated files continue to work without regeneration.
{{/* func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSendContainerState(c containerState) {
if f.d.cr != nil {
f.d.cr.sendContainerState(c)
}
}
*/}}
{{/*
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncDriver() encDriver {
return f.e.e
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecDriver() decDriver {
return f.d.d
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncNil() {
f.e.e.EncodeNil()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBytes(v []byte) {
f.e.e.EncodeStringBytes(c_RAW, v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayStart(length int) {
f.e.e.EncodeArrayStart(length)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayEnd() {
f.e.e.EncodeArrayEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayEntrySeparator() {
f.e.e.EncodeArrayEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapStart(length int) {
f.e.e.EncodeMapStart(length)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapEnd() {
f.e.e.EncodeMapEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapEntrySeparator() {
f.e.e.EncodeMapEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapKVSeparator() {
f.e.e.EncodeMapKVSeparator()
}
// ---------
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecBytes(v *[]byte) {
*v = f.d.d.DecodeBytes(*v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecTryNil() bool {
return f.d.d.TryDecodeAsNil()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsNil() (b bool) {
return f.d.d.IsContainerType(valueTypeNil)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsMap() (b bool) {
return f.d.d.IsContainerType(valueTypeMap)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsArray() (b bool) {
return f.d.d.IsContainerType(valueTypeArray)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecCheckBreak() bool {
return f.d.d.CheckBreak()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapStart() int {
return f.d.d.ReadMapStart()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayStart() int {
return f.d.d.ReadArrayStart()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapEnd() {
f.d.d.ReadMapEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayEnd() {
f.d.d.ReadArrayEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayEntrySeparator() {
f.d.d.ReadArrayEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapEntrySeparator() {
f.d.d.ReadMapEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapKVSeparator() {
f.d.d.ReadMapKVSeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) ReadStringAsBytes(bs []byte) []byte {
return f.d.d.DecodeStringAsBytes(bs)
}
// -- encode calls (primitives)
{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" true }}(v {{ .Primitive }}) {
ee := f.e.e
{{ encmd .Primitive "v" }}
}
{{ end }}{{ end }}{{ end }}
// -- decode calls (primitives)
{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) {{ .MethodNamePfx "Dec" true }}(vp *{{ .Primitive }}) {
dd := f.d.d
*vp = {{ decmd .Primitive }}
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) {{ .MethodNamePfx "Read" true }}() (v {{ .Primitive }}) {
dd := f.d.d
v = {{ decmd .Primitive }}
return
}
{{ end }}{{ end }}{{ end }}
// -- encode calls (slices/maps)
{{range .Values}}{{if not .Primitive }}{{if .Slice }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v []{{ .Elem }}) { {{ else }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
f.F.{{ .MethodNamePfx "Enc" false }}V(v, false, f.e)
}
{{ end }}{{ end }}
// -- decode calls (slices/maps)
{{range .Values}}{{if not .Primitive }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
{{if .Slice }}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *[]{{ .Elem }}) {
{{else}}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
v, changed := f.F.{{ .MethodNamePfx "Dec" false }}V(*vp, false, true, f.d)
if changed {
*vp = v
}
}
{{ end }}{{ end }}
*/}}

View File

@ -1,3 +1,5 @@
// +build codecgen.exec
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // 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. // Use of this source code is governed by a MIT license found in the LICENSE file.
@ -96,7 +98,7 @@ if {{var "l"}} == 0 {
{{var "c"}} = true {{var "c"}} = true
}{{end}} }{{end}}
{{var "h"}}.ElemContainerState({{var "j"}}) {{var "h"}}.ElemContainerState({{var "j"}})
// {{var "dn"}} = r.TryDecodeAsNil() {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }} {{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
{{ decLineVar $x }} {{ decLineVar $x }}
{{var "v"}} <- {{ $x }} {{var "v"}} <- {{ $x }}
@ -129,4 +131,3 @@ if {{var "l"}} == 0 {
}{{end}} }{{end}}
` `

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.10
package codec
const allowSetUnexportedEmbeddedPtr = false

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build !go1.10
package codec
const allowSetUnexportedEmbeddedPtr = true

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -6,74 +6,6 @@ package codec
// All non-std package dependencies live in this file, // All non-std package dependencies live in this file,
// so porting to different environment is easy (just update functions). // so porting to different environment is easy (just update functions).
import (
"errors"
"fmt"
"math"
"reflect"
)
func panicValToErr(panicVal interface{}, err *error) {
if panicVal == nil {
return
}
// case nil
switch xerr := panicVal.(type) {
case error:
*err = xerr
case string:
*err = errors.New(xerr)
default:
*err = fmt.Errorf("%v", panicVal)
}
return
}
func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
switch v.Kind() {
case reflect.Invalid:
return true
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
if deref {
if v.IsNil() {
return true
}
return hIsEmptyValue(v.Elem(), deref, checkStruct)
} else {
return v.IsNil()
}
case reflect.Struct:
if !checkStruct {
return false
}
// return true if all fields are empty. else return false.
// we cannot use equality check, because some fields may be maps/slices/etc
// and consequently the structs are not comparable.
// return v.Interface() == reflect.Zero(v.Type()).Interface()
for i, n := 0, v.NumField(); i < n; i++ {
if !hIsEmptyValue(v.Field(i), deref, checkStruct) {
return false
}
}
return true
}
return false
}
func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
return hIsEmptyValue(v, deref, checkStruct)
}
func pruneSignExt(v []byte, pos bool) (n int) { func pruneSignExt(v []byte, pos bool) (n int) {
if len(v) < 2 { if len(v) < 2 {
} else if pos && v[0] == 0 { } else if pos && v[0] == 0 {
@ -86,37 +18,6 @@ func pruneSignExt(v []byte, pos bool) (n int) {
return return
} }
func implementsIntf(typ, iTyp reflect.Type) (success bool, indir int8) {
if typ == nil {
return
}
rt := typ
// The type might be a pointer and we need to keep
// dereferencing to the base type until we find an implementation.
for {
if rt.Implements(iTyp) {
return true, indir
}
if p := rt; p.Kind() == reflect.Ptr {
indir++
if indir >= math.MaxInt8 { // insane number of indirections
return false, 0
}
rt = p.Elem()
continue
}
break
}
// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
if typ.Kind() != reflect.Ptr {
// Not a pointer, but does the pointer work?
if reflect.PtrTo(typ).Implements(iTyp) {
return true, -1
}
}
return false, 0
}
// validate that this function is correct ... // validate that this function is correct ...
// culled from OGRE (Object-Oriented Graphics Rendering Engine) // culled from OGRE (Object-Oriented Graphics Rendering Engine)
// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html) // function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html)
@ -129,7 +30,8 @@ func halfFloatToFloatBits(yy uint16) (d uint32) {
if e == 0 { if e == 0 {
if m == 0 { // plu or minus 0 if m == 0 { // plu or minus 0
return s << 31 return s << 31
} else { // Denormalized number -- renormalize it }
// Denormalized number -- renormalize it
for (m & 0x00000400) == 0 { for (m & 0x00000400) == 0 {
m <<= 1 m <<= 1
e -= 1 e -= 1
@ -137,13 +39,11 @@ func halfFloatToFloatBits(yy uint16) (d uint32) {
e += 1 e += 1
const zz uint32 = 0x0400 const zz uint32 = 0x0400
m &= ^zz m &= ^zz
}
} else if e == 31 { } else if e == 31 {
if m == 0 { // Inf if m == 0 { // Inf
return (s << 31) | 0x7f800000 return (s << 31) | 0x7f800000
} else { // NaN
return (s << 31) | 0x7f800000 | (m << 13)
} }
return (s << 31) | 0x7f800000 | (m << 13) // NaN
} }
e = e + (127 - 15) e = e + (127 - 15)
m = m << 13 m = m << 13

View File

@ -1,6 +1,6 @@
// +build !go1.7 safe appengine // +build !go1.7 safe appengine
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -8,8 +8,11 @@ package codec
import ( import (
"reflect" "reflect"
"sync/atomic" "sync/atomic"
"time"
) )
const safeMode = true
// stringView returns a view of the []byte as a string. // stringView returns a view of the []byte as a string.
// In unsafe mode, it doesn't incur allocation and copying caused by conversion. // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
// In regular safe mode, it is an allocation and copy. // In regular safe mode, it is an allocation and copy.
@ -31,28 +34,11 @@ func bytesView(v string) []byte {
} }
func definitelyNil(v interface{}) bool { func definitelyNil(v interface{}) bool {
// this is a best-effort option.
// We just return false, so we don't unnecessarily incur the cost of reflection this early.
return false return false
// rv := reflect.ValueOf(v)
// switch rv.Kind() {
// case reflect.Invalid:
// return true
// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
// return rv.IsNil()
// default:
// return false
// }
} }
// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
// //
// // Usage: call this at point where done with the bytes view.
// func keepAlive4BytesView(v string) {}
// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
// //
// // Usage: call this at point where done with the string view.
// func keepAlive4StringView(v []byte) {}
func rv2i(rv reflect.Value) interface{} { func rv2i(rv reflect.Value) interface{} {
return rv.Interface() return rv.Interface()
} }
@ -65,16 +51,50 @@ func rv2rtid(rv reflect.Value) uintptr {
return reflect.ValueOf(rv.Type()).Pointer() return reflect.ValueOf(rv.Type()).Pointer()
} }
func i2rtid(i interface{}) uintptr {
return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
}
// --------------------------
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
switch v.Kind() {
case reflect.Invalid:
return true
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
if deref {
if v.IsNil() {
return true
}
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
}
return v.IsNil()
case reflect.Struct:
return isEmptyStruct(v, tinfos, deref, checkStruct)
}
return false
}
// -------------------------- // --------------------------
// type ptrToRvMap struct{} // type ptrToRvMap struct{}
// func (_ *ptrToRvMap) init() {} // func (*ptrToRvMap) init() {}
// func (_ *ptrToRvMap) get(i interface{}) reflect.Value { // func (*ptrToRvMap) get(i interface{}) reflect.Value {
// return reflect.ValueOf(i).Elem() // return reflect.ValueOf(i).Elem()
// } // }
// -------------------------- // --------------------------
type atomicTypeInfoSlice struct { type atomicTypeInfoSlice struct { // expected to be 2 words
v atomic.Value v atomic.Value
} }
@ -103,54 +123,150 @@ func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
rv.SetBool(d.d.DecodeBool()) rv.SetBool(d.d.DecodeBool())
} }
func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
rv.Set(reflect.ValueOf(d.d.DecodeTime()))
}
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
rv.SetFloat(d.d.DecodeFloat(true)) fv := d.d.DecodeFloat64()
if chkOvf.Float32(fv) {
d.errorf("float32 overflow: %v", fv)
}
rv.SetFloat(fv)
} }
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
rv.SetFloat(d.d.DecodeFloat(false)) rv.SetFloat(d.d.DecodeFloat64())
} }
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
rv.SetInt(d.d.DecodeInt(intBitsize)) rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
} }
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
rv.SetInt(d.d.DecodeInt(8)) rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
} }
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
rv.SetInt(d.d.DecodeInt(16)) rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
} }
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
rv.SetInt(d.d.DecodeInt(32)) rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
} }
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
rv.SetInt(d.d.DecodeInt(64)) rv.SetInt(d.d.DecodeInt64())
} }
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(uintBitsize)) rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
} }
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(uintBitsize)) rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
} }
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(8)) rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
} }
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(16)) rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
} }
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(32)) rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
} }
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
rv.SetUint(d.d.DecodeUint(64)) rv.SetUint(d.d.DecodeUint64())
} }
// ----------------
func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeBool(rv.Bool())
}
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeTime(rv2i(rv).(time.Time))
}
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeString(cUTF8, rv.String())
}
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeFloat64(rv.Float())
}
func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeFloat32(float32(rv.Float()))
}
func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeInt(rv.Int())
}
func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeInt(rv.Int())
}
func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeInt(rv.Int())
}
func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeInt(rv.Int())
}
func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeInt(rv.Int())
}
func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
e.e.EncodeUint(rv.Uint())
}
// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
// //
// // Usage: call this at point where done with the bytes view.
// func keepAlive4BytesView(v string) {}
// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
// //
// // Usage: call this at point where done with the string view.
// func keepAlive4StringView(v []byte) {}
// func definitelyNil(v interface{}) bool {
// rv := reflect.ValueOf(v)
// switch rv.Kind() {
// case reflect.Invalid:
// return true
// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
// return rv.IsNil()
// default:
// return false
// }
// }

View File

@ -2,7 +2,7 @@
// +build !appengine // +build !appengine
// +build go1.7 // +build go1.7
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -10,6 +10,7 @@ package codec
import ( import (
"reflect" "reflect"
"sync/atomic" "sync/atomic"
"time"
"unsafe" "unsafe"
) )
@ -18,6 +19,7 @@ import (
// var zeroRTv [4]uintptr // var zeroRTv [4]uintptr
const safeMode = false
const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
type unsafeString struct { type unsafeString struct {
@ -46,50 +48,49 @@ func stringView(v []byte) string {
if len(v) == 0 { if len(v) == 0 {
return "" return ""
} }
bx := (*unsafeSlice)(unsafe.Pointer(&v)) bx := (*unsafeSlice)(unsafe.Pointer(&v))
sx := unsafeString{bx.Data, bx.Len} return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
return *(*string)(unsafe.Pointer(&sx))
} }
func bytesView(v string) []byte { func bytesView(v string) []byte {
if len(v) == 0 { if len(v) == 0 {
return zeroByteSlice return zeroByteSlice
} }
sx := (*unsafeString)(unsafe.Pointer(&v)) sx := (*unsafeString)(unsafe.Pointer(&v))
bx := unsafeSlice{sx.Data, sx.Len, sx.Len} return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
return *(*[]byte)(unsafe.Pointer(&bx))
} }
func definitelyNil(v interface{}) bool { func definitelyNil(v interface{}) bool {
return (*unsafeIntf)(unsafe.Pointer(&v)).word == nil // There is no global way of checking if an interface is nil.
// For true references (map, ptr, func, chan), you can just look
// at the word of the interface. However, for slices, you have to dereference
// the word, and get a pointer to the 3-word interface value.
//
// However, the following are cheap calls
// - TypeOf(interface): cheap 2-line call.
// - ValueOf(interface{}): expensive
// - type.Kind: cheap call through an interface
// - Value.Type(): cheap call
// except it's a method value (e.g. r.Read, which implies that it is a Func)
return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
} }
// func keepAlive4BytesView(v string) { func rv2i(rv reflect.Value) interface{} {
// runtime.KeepAlive(v)
// }
// func keepAlive4StringView(v []byte) {
// runtime.KeepAlive(v)
// }
// TODO: consider a more generally-known optimization for reflect.Value ==> Interface // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
// //
// Currently, we use this fragile method that taps into implememtation details from // Currently, we use this fragile method that taps into implememtation details from
// the source go stdlib reflect/value.go, // the source go stdlib reflect/value.go, and trims the implementation.
// and trims the implementation.
func rv2i(rv reflect.Value) interface{} {
if false {
return rv.Interface()
}
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
// references that are single-words (map, ptr) may be double-referenced as flagIndir // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
kk := urv.flag & (1<<5 - 1) var ptr unsafe.Pointer
if (kk == uintptr(reflect.Map) || kk == uintptr(reflect.Ptr)) && urv.flag&unsafeFlagIndir != 0 { if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ})) ptr = *(*unsafe.Pointer)(urv.ptr)
} else {
ptr = urv.ptr
} }
return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ})) return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
} }
func rt2id(rt reflect.Type) uintptr { func rt2id(rt reflect.Type) uintptr {
@ -100,16 +101,83 @@ func rv2rtid(rv reflect.Value) uintptr {
return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ) return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
} }
// func rv0t(rt reflect.Type) reflect.Value { func i2rtid(i interface{}) uintptr {
// ut := (*unsafeIntf)(unsafe.Pointer(&rt)) return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
// // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr }
// uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
// return *(*reflect.Value)(unsafe.Pointer(&uv})
// }
// -------------------------- // --------------------------
type atomicTypeInfoSlice struct {
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
if urv.flag == 0 {
return true
}
switch v.Kind() {
case reflect.Invalid:
return true
case reflect.String:
return (*unsafeString)(urv.ptr).Len == 0
case reflect.Slice:
return (*unsafeSlice)(urv.ptr).Len == 0
case reflect.Bool:
return !*(*bool)(urv.ptr)
case reflect.Int:
return *(*int)(urv.ptr) == 0
case reflect.Int8:
return *(*int8)(urv.ptr) == 0
case reflect.Int16:
return *(*int16)(urv.ptr) == 0
case reflect.Int32:
return *(*int32)(urv.ptr) == 0
case reflect.Int64:
return *(*int64)(urv.ptr) == 0
case reflect.Uint:
return *(*uint)(urv.ptr) == 0
case reflect.Uint8:
return *(*uint8)(urv.ptr) == 0
case reflect.Uint16:
return *(*uint16)(urv.ptr) == 0
case reflect.Uint32:
return *(*uint32)(urv.ptr) == 0
case reflect.Uint64:
return *(*uint64)(urv.ptr) == 0
case reflect.Uintptr:
return *(*uintptr)(urv.ptr) == 0
case reflect.Float32:
return *(*float32)(urv.ptr) == 0
case reflect.Float64:
return *(*float64)(urv.ptr) == 0
case reflect.Interface:
isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
if deref {
if isnil {
return true
}
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
}
return isnil
case reflect.Ptr:
isnil := urv.ptr == nil
if deref {
if isnil {
return true
}
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
}
return isnil
case reflect.Struct:
return isEmptyStruct(v, tinfos, deref, checkStruct)
case reflect.Map, reflect.Array, reflect.Chan:
return v.Len() == 0
}
return false
}
// --------------------------
type atomicTypeInfoSlice struct { // expected to be 2 words
v unsafe.Pointer v unsafe.Pointer
_ [8]byte // padding
} }
func (x *atomicTypeInfoSlice) load() *[]rtid2ti { func (x *atomicTypeInfoSlice) load() *[]rtid2ti {
@ -123,9 +191,6 @@ func (x *atomicTypeInfoSlice) store(p *[]rtid2ti) {
// -------------------------- // --------------------------
func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
// if urv.flag&unsafeFlagIndir != 0 {
// urv.ptr = *(*unsafe.Pointer)(urv.ptr)
// }
*(*[]byte)(urv.ptr) = d.rawBytes() *(*[]byte)(urv.ptr) = d.rawBytes()
} }
@ -139,73 +204,214 @@ func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
*(*bool)(urv.ptr) = d.d.DecodeBool() *(*bool)(urv.ptr) = d.d.DecodeBool()
} }
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*float32)(urv.ptr) = float32(d.d.DecodeFloat(true)) *(*time.Time)(urv.ptr) = d.d.DecodeTime()
}
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
fv := d.d.DecodeFloat64()
if chkOvf.Float32(fv) {
d.errorf("float32 overflow: %v", fv)
}
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*float32)(urv.ptr) = float32(fv)
} }
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*float64)(urv.ptr) = d.d.DecodeFloat(false) *(*float64)(urv.ptr) = d.d.DecodeFloat64()
} }
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*int)(urv.ptr) = int(d.d.DecodeInt(intBitsize)) *(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
} }
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*int8)(urv.ptr) = int8(d.d.DecodeInt(8)) *(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
} }
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*int16)(urv.ptr) = int16(d.d.DecodeInt(16)) *(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
} }
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*int32)(urv.ptr) = int32(d.d.DecodeInt(32)) *(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
} }
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*int64)(urv.ptr) = d.d.DecodeInt(64) *(*int64)(urv.ptr) = d.d.DecodeInt64()
} }
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uint)(urv.ptr) = uint(d.d.DecodeUint(uintBitsize)) *(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
} }
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uintptr)(urv.ptr) = uintptr(d.d.DecodeUint(uintBitsize)) *(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
} }
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uint8)(urv.ptr) = uint8(d.d.DecodeUint(8)) *(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
} }
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uint16)(urv.ptr) = uint16(d.d.DecodeUint(16)) *(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
} }
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uint32)(urv.ptr) = uint32(d.d.DecodeUint(32)) *(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
} }
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) { func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv)) urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
*(*uint64)(urv.ptr) = d.d.DecodeUint(64) *(*uint64)(urv.ptr) = d.d.DecodeUint64()
} }
// ------------ // ------------
func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeBool(*(*bool)(v.ptr))
}
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeTime(*(*time.Time)(v.ptr))
}
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeString(cUTF8, *(*string)(v.ptr))
}
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeFloat64(*(*float64)(v.ptr))
}
func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeFloat32(*(*float32)(v.ptr))
}
func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeInt(int64(*(*int)(v.ptr)))
}
func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeInt(int64(*(*int8)(v.ptr)))
}
func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeInt(int64(*(*int16)(v.ptr)))
}
func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeInt(int64(*(*int32)(v.ptr)))
}
func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeInt(int64(*(*int64)(v.ptr)))
}
func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
}
func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
}
func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
}
func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
}
func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
}
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
}
// ------------
// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
// // if urv.flag&unsafeFlagIndir != 0 {
// // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
// // }
// *(*[]byte)(urv.ptr) = d.rawBytes()
// }
// func rv0t(rt reflect.Type) reflect.Value {
// ut := (*unsafeIntf)(unsafe.Pointer(&rt))
// // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
// uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
// return *(*reflect.Value)(unsafe.Pointer(&uv})
// }
// func rv2i(rv reflect.Value) interface{} {
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
// // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
// var ptr unsafe.Pointer
// // kk := reflect.Kind(urv.flag & (1<<5 - 1))
// // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
// if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
// ptr = *(*unsafe.Pointer)(urv.ptr)
// } else {
// ptr = urv.ptr
// }
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
// }
// func definitelyNil(v interface{}) bool {
// var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
// if ui.word == nil {
// return true
// }
// var tk = reflect.TypeOf(v).Kind()
// return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
// fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
// v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
// }
// func keepAlive4BytesView(v string) {
// runtime.KeepAlive(v)
// }
// func keepAlive4StringView(v []byte) {
// runtime.KeepAlive(v)
// }
// func rt2id(rt reflect.Type) uintptr { // func rt2id(rt reflect.Type) uintptr {
// return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word) // return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
// // var i interface{} = rt // // var i interface{} = rt

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,21 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // 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. // Use of this source code is governed by a MIT license found in the LICENSE file.
// ************************************************************ // Code generated from mammoth-test.go.tmpl - DO NOT EDIT.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from mammoth-test.go.tmpl
// ************************************************************
package codec package codec
import "testing"
import "fmt"
import "reflect"
// TestMammoth has all the different paths optimized in fast-path // TestMammoth has all the different paths optimized in fast-path
// It has all the primitives, slices and maps. // It has all the primitives, slices and maps.
// //
// For each of those types, it has a pointer and a non-pointer field. // For each of those types, it has a pointer and a non-pointer field.
func init() { _ = fmt.Printf } // so we can include fmt as needed
type TestMammoth struct { type TestMammoth struct {
{{range .Values }}{{if .Primitive }}{{/* {{range .Values }}{{if .Primitive }}{{/*
@ -31,3 +34,121 @@ type TestMammoth struct {
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}
} }
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
*/}} type {{ .MethodNamePfx "typMbs" false }} []{{ .Elem }}
func (_ {{ .MethodNamePfx "typMbs" false }}) MapBySlice() { }
{{end}}{{end}}{{end}}
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
*/}} type {{ .MethodNamePfx "typMap" false }} map[{{ .MapKey }}]{{ .Elem }}
{{end}}{{end}}{{end}}
func doTestMammothSlices(t *testing.T, h Handle) {
{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
*/}}
var v{{$i}}va [8]{{ .Elem }}
for _, v := range [][]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .Elem }}, {{ zerocmd .Elem }}, {{ zerocmd .Elem }}, {{ nonzerocmd .Elem }} } } { {{/*
// fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
// - encode value to some []byte
// - decode into a length-wise-equal []byte
// - check if equal to initial slice
// - encode ptr to the value
// - check if encode bytes are same
// - decode into ptrs to: nil, then 1-elem slice, equal-length, then large len slice
// - decode into non-addressable slice of equal length, then larger len
// - for each decode, compare elem-by-elem to the original slice
// -
// - rinse and repeat for a MapBySlice version
// -
*/}}
var v{{$i}}v1, v{{$i}}v2 []{{ .Elem }}
v{{$i}}v1 = v
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-noaddr")
// ...
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
v{{$i}}v2 = nil
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
v{{$i}}v2 = v{{$i}}va[:1:1]
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-1")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-1")
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
v{{$i}}v2 = v{{$i}}va[:len(v{{$i}}v1):len(v{{$i}}v1)]
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-len")
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
v{{$i}}v2 = v{{$i}}va[:]
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-cap")
if len(v{{$i}}v1) > 1 {
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
testUnmarshalErr((&v{{$i}}va)[:len(v{{$i}}v1)], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len-noaddr")
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-len-noaddr")
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
testUnmarshalErr((&v{{$i}}va)[:], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap-noaddr")
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-cap-noaddr")
}
// ...
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMbs" false }}
v{{$i}}v2 = nil
if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
v{{$i}}v3 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v1)
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
v{{$i}}v2 = nil
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
}
{{end}}{{end}}{{end}}
}
func doTestMammothMaps(t *testing.T, h Handle) {
{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
*/}}
for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .MapKey }}:{{ zerocmd .Elem }} {{if ne "bool" .MapKey}}, {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} {{end}} } } {
// fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
v{{$i}}v1 = v
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-map-v{{$i}}-noaddr") // decode into non-addressable map value
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-noaddr")
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-len")
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
v{{$i}}v2 = nil
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-nil")
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-nil")
// ...
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMap" false }}
v{{$i}}v3 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v1)
v{{$i}}v4 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v2)
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-map-v{{$i}}-custom")
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-map-v{{$i}}-p-len")
}
{{end}}{{end}}{{end}}
}
func doTestMammothMapsAndSlices(t *testing.T, h Handle) {
doTestMammothSlices(t, h)
doTestMammothMaps(t, h)
}

View File

@ -0,0 +1,94 @@
// +build !notfastpath
// 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.
// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
package codec
// Increase codecoverage by covering all the codecgen paths, in fast-path and gen-helper.go....
//
// Add:
// - test file for creating a mammoth generated file as _mammoth_generated.go
// - generate a second mammoth files in a different file: mammoth2_generated_test.go
// - mammoth-test.go.tmpl will do this
// - run codecgen on it, into mammoth2_codecgen_generated_test.go (no build tags)
// - as part of TestMammoth, run it also
// - this will cover all the codecgen, gen-helper, etc in one full run
// - check in mammoth* files into github also
// - then
//
// Now, add some types:
// - some that implement BinaryMarshal, TextMarshal, JSONMarshal, and one that implements none of it
// - create a wrapper type that includes TestMammoth2, with it in slices, and maps, and the custom types
// - this wrapper object is what we work encode/decode (so that the codecgen methods are called)
// import "encoding/binary"
import "fmt"
type TestMammoth2 struct {
{{range .Values }}{{if .Primitive }}{{/*
*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
{{end}}{{end}}
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
{{end}}{{end}}{{end}}
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
{{end}}{{end}}{{end}}
}
// -----------
type testMammoth2Binary uint64
func (x testMammoth2Binary) MarshalBinary() (data []byte, err error) {
data = make([]byte, 8)
bigen.PutUint64(data, uint64(x))
return
}
func (x *testMammoth2Binary) UnmarshalBinary(data []byte) (err error) {
*x = testMammoth2Binary(bigen.Uint64(data))
return
}
type testMammoth2Text uint64
func (x testMammoth2Text) MarshalText() (data []byte, err error) {
data = []byte(fmt.Sprintf("%b", uint64(x)))
return
}
func (x *testMammoth2Text) UnmarshalText(data []byte) (err error) {
_, err = fmt.Sscanf(string(data), "%b", (*uint64)(x))
return
}
type testMammoth2Json uint64
func (x testMammoth2Json) MarshalJSON() (data []byte, err error) {
data = []byte(fmt.Sprintf("%v", uint64(x)))
return
}
func (x *testMammoth2Json) UnmarshalJSON(data []byte) (err error) {
_, err = fmt.Sscanf(string(data), "%v", (*uint64)(x))
return
}
type testMammoth2Basic [4]uint64
type TestMammoth2Wrapper struct {
V TestMammoth2
T testMammoth2Text
B testMammoth2Binary
J testMammoth2Json
C testMammoth2Basic
M map[testMammoth2Basic]TestMammoth2
L []TestMammoth2
A [4]int64
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
/* /*
@ -15,8 +15,8 @@ For compatibility with behaviour of msgpack-c reference implementation:
- Go intX (<0) - Go intX (<0)
IS ENCODED AS IS ENCODED AS
msgpack -ve fixnum, signed msgpack -ve fixnum, signed
*/ */
package codec package codec
import ( import (
@ -25,6 +25,7 @@ import (
"math" "math"
"net/rpc" "net/rpc"
"reflect" "reflect"
"time"
) )
const ( const (
@ -78,6 +79,9 @@ const (
mpNegFixNumMax = 0xff mpNegFixNumMax = 0xff
) )
var mpTimeExtTag int8 = -1
var mpTimeExtTagU = uint8(mpTimeExtTag)
// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec // MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
// that the backend RPC service takes multiple arguments, which have been arranged // that the backend RPC service takes multiple arguments, which have been arranged
// in sequence in the slice. // in sequence in the slice.
@ -94,10 +98,18 @@ type msgpackContainerType struct {
} }
var ( var (
msgpackContainerStr = msgpackContainerType{32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false} msgpackContainerStr = msgpackContainerType{
msgpackContainerBin = msgpackContainerType{0, 0, mpBin8, mpBin16, mpBin32, false, true, true} 32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false,
msgpackContainerList = msgpackContainerType{16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false} }
msgpackContainerMap = msgpackContainerType{16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false} msgpackContainerBin = msgpackContainerType{
0, 0, mpBin8, mpBin16, mpBin32, false, true, true,
}
msgpackContainerList = msgpackContainerType{
16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false,
}
msgpackContainerMap = msgpackContainerType{
16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false,
}
) )
//--------------------------------------------- //---------------------------------------------
@ -110,6 +122,7 @@ type msgpackEncDriver struct {
w encWriter w encWriter
h *MsgpackHandle h *MsgpackHandle
x [8]byte x [8]byte
_ [3]uint64 // padding
} }
func (e *msgpackEncDriver) EncodeNil() { func (e *msgpackEncDriver) EncodeNil() {
@ -117,10 +130,26 @@ func (e *msgpackEncDriver) EncodeNil() {
} }
func (e *msgpackEncDriver) EncodeInt(i int64) { func (e *msgpackEncDriver) EncodeInt(i int64) {
if i >= 0 { // if i >= 0 {
e.EncodeUint(uint64(i)) // e.EncodeUint(uint64(i))
// } else if false &&
if i > math.MaxInt8 {
if i <= math.MaxInt16 {
e.w.writen1(mpInt16)
bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
} else if i <= math.MaxInt32 {
e.w.writen1(mpInt32)
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
} else {
e.w.writen1(mpInt64)
bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
}
} else if i >= -32 { } else if i >= -32 {
if e.h.NoFixedNum {
e.w.writen2(mpInt8, byte(i))
} else {
e.w.writen1(byte(i)) e.w.writen1(byte(i))
}
} else if i >= math.MinInt8 { } else if i >= math.MinInt8 {
e.w.writen2(mpInt8, byte(i)) e.w.writen2(mpInt8, byte(i))
} else if i >= math.MinInt16 { } else if i >= math.MinInt16 {
@ -137,7 +166,11 @@ func (e *msgpackEncDriver) EncodeInt(i int64) {
func (e *msgpackEncDriver) EncodeUint(i uint64) { func (e *msgpackEncDriver) EncodeUint(i uint64) {
if i <= math.MaxInt8 { if i <= math.MaxInt8 {
if e.h.NoFixedNum {
e.w.writen2(mpUint8, byte(i))
} else {
e.w.writen1(byte(i)) e.w.writen1(byte(i))
}
} else if i <= math.MaxUint8 { } else if i <= math.MaxUint8 {
e.w.writen2(mpUint8, byte(i)) e.w.writen2(mpUint8, byte(i))
} else if i <= math.MaxUint16 { } else if i <= math.MaxUint16 {
@ -170,6 +203,39 @@ func (e *msgpackEncDriver) EncodeFloat64(f float64) {
bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f)) bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
} }
func (e *msgpackEncDriver) EncodeTime(t time.Time) {
if t.IsZero() {
e.EncodeNil()
return
}
t = t.UTC()
sec, nsec := t.Unix(), uint64(t.Nanosecond())
var data64 uint64
var l = 4
if sec >= 0 && sec>>34 == 0 {
data64 = (nsec << 34) | uint64(sec)
if data64&0xffffffff00000000 != 0 {
l = 8
}
} else {
l = 12
}
if e.h.WriteExt {
e.encodeExtPreamble(mpTimeExtTagU, l)
} else {
e.writeContainerLen(msgpackContainerStr, l)
}
switch l {
case 4:
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64))
case 8:
bigenHelper{e.x[:8], e.w}.writeUint64(data64)
case 12:
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec))
bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec))
}
}
func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) { func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
bs := ext.WriteExt(v) bs := ext.WriteExt(v)
if bs == nil { if bs == nil {
@ -180,7 +246,7 @@ func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Enc
e.encodeExtPreamble(uint8(xtag), len(bs)) e.encodeExtPreamble(uint8(xtag), len(bs))
e.w.writeb(bs) e.w.writeb(bs)
} else { } else {
e.EncodeStringBytes(c_RAW, bs) e.EncodeStringBytes(cRAW, bs)
} }
} }
@ -224,7 +290,7 @@ func (e *msgpackEncDriver) WriteMapStart(length int) {
func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) { func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
slen := len(s) slen := len(s)
if c == c_RAW && e.h.WriteExt { if c == cRAW && e.h.WriteExt {
e.writeContainerLen(msgpackContainerBin, slen) e.writeContainerLen(msgpackContainerBin, slen)
} else { } else {
e.writeContainerLen(msgpackContainerStr, slen) e.writeContainerLen(msgpackContainerStr, slen)
@ -234,13 +300,13 @@ func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
} }
} }
func (e *msgpackEncDriver) EncodeSymbol(v string) {
e.EncodeString(c_UTF8, v)
}
func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) { func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
if bs == nil {
e.EncodeNil()
return
}
slen := len(bs) slen := len(bs)
if c == c_RAW && e.h.WriteExt { if c == cRAW && e.h.WriteExt {
e.writeContainerLen(msgpackContainerBin, slen) e.writeContainerLen(msgpackContainerBin, slen)
} else { } else {
e.writeContainerLen(msgpackContainerStr, slen) e.writeContainerLen(msgpackContainerStr, slen)
@ -270,7 +336,7 @@ type msgpackDecDriver struct {
d *Decoder d *Decoder
r decReader // *Decoder decReader decReaderT r decReader // *Decoder decReader decReaderT
h *MsgpackHandle h *MsgpackHandle
b [scratchByteArrayLen]byte // b [scratchByteArrayLen]byte
bd byte bd byte
bdRead bool bdRead bool
br bool // bytes reader br bool // bytes reader
@ -278,6 +344,7 @@ type msgpackDecDriver struct {
// noStreamingCodec // noStreamingCodec
// decNoSeparator // decNoSeparator
decDriverNoopContainerReader decDriverNoopContainerReader
_ [3]uint64 // padding
} }
// Note: This returns either a primitive (int, bool, etc) for non-containers, // Note: This returns either a primitive (int, bool, etc) for non-containers,
@ -368,7 +435,12 @@ func (d *msgpackDecDriver) DecodeNaked() {
n.v = valueTypeExt n.v = valueTypeExt
clen := d.readExtLen() clen := d.readExtLen()
n.u = uint64(d.r.readn1()) n.u = uint64(d.r.readn1())
if n.u == uint64(mpTimeExtTagU) {
n.v = valueTypeTime
n.t = d.decodeTime(clen)
} else {
n.l = d.r.readx(clen) n.l = d.r.readx(clen)
}
default: default:
d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd) d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
} }
@ -384,7 +456,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
} }
// int can be decoded from msgpack type: intXXX or uintXXX // int can be decoded from msgpack type: intXXX or uintXXX
func (d *msgpackDecDriver) DecodeInt(bitsize uint8) (i int64) { func (d *msgpackDecDriver) DecodeInt64() (i int64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -416,19 +488,12 @@ func (d *msgpackDecDriver) DecodeInt(bitsize uint8) (i int64) {
return return
} }
} }
// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
if bitsize > 0 {
if trunc := (i << (64 - bitsize)) >> (64 - bitsize); i != trunc {
d.d.errorf("Overflow int value: %v", i)
return
}
}
d.bdRead = false d.bdRead = false
return return
} }
// uint can be decoded from msgpack type: intXXX or uintXXX // uint can be decoded from msgpack type: intXXX or uintXXX
func (d *msgpackDecDriver) DecodeUint(bitsize uint8) (ui uint64) { func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -481,19 +546,12 @@ func (d *msgpackDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
return return
} }
} }
// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
if bitsize > 0 {
if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
d.d.errorf("Overflow uint value: %v", ui)
return
}
}
d.bdRead = false d.bdRead = false
return return
} }
// float can either be decoded from msgpack type: float, double or intX // float can either be decoded from msgpack type: float, double or intX
func (d *msgpackDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -502,11 +560,7 @@ func (d *msgpackDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
} else if d.bd == mpDouble { } else if d.bd == mpDouble {
f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
} else { } else {
f = float64(d.DecodeInt(0)) f = float64(d.DecodeInt64())
}
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("msgpack: float32 overflow: %v", f)
return
} }
d.bdRead = false d.bdRead = false
return return
@ -534,13 +588,15 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
d.readNextBd() d.readNextBd()
} }
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
bd := d.bd
// DecodeBytes could be from: bin str fixstr fixarray array ... // DecodeBytes could be from: bin str fixstr fixarray array ...
var clen int var clen int
vt := d.ContainerType() vt := d.ContainerType()
switch vt { switch vt {
case valueTypeBytes: case valueTypeBytes:
// valueTypeBytes may be a mpBin or an mpStr container // valueTypeBytes may be a mpBin or an mpStr container
if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
clen = d.readContainerLen(msgpackContainerBin) clen = d.readContainerLen(msgpackContainerBin)
} else { } else {
clen = d.readContainerLen(msgpackContainerStr) clen = d.readContainerLen(msgpackContainerStr)
@ -548,28 +604,17 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
case valueTypeString: case valueTypeString:
clen = d.readContainerLen(msgpackContainerStr) clen = d.readContainerLen(msgpackContainerStr)
case valueTypeArray: case valueTypeArray:
clen = d.readContainerLen(msgpackContainerList) if zerocopy && len(bs) == 0 {
// ensure everything after is one byte each bs = d.d.b[:]
for i := 0; i < clen; i++ { }
d.readNextBd() bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
if d.bd == mpNil {
bs = append(bs, 0)
} else if d.bd == mpUint8 {
bs = append(bs, d.r.readn1())
} else {
d.d.errorf("cannot read non-byte into a byte array")
return return
}
}
d.bdRead = false
return bs
default: default:
d.d.errorf("invalid container type: expecting bin|str|array") d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt))
return return
} }
// these are (bin|str)(8|16|32) // these are (bin|str)(8|16|32)
// println("DecodeBytes: clen: ", clen)
d.bdRead = false d.bdRead = false
// bytes may be nil, so handle it. if nil, clen=-1. // bytes may be nil, so handle it. if nil, clen=-1.
if clen < 0 { if clen < 0 {
@ -579,18 +624,18 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
if d.br { if d.br {
return d.r.readx(clen) return d.r.readx(clen)
} else if len(bs) == 0 { } else if len(bs) == 0 {
bs = d.b[:] bs = d.d.b[:]
} }
} }
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs) return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
} }
func (d *msgpackDecDriver) DecodeString() (s string) { func (d *msgpackDecDriver) DecodeString() (s string) {
return string(d.DecodeBytes(d.b[:], true)) return string(d.DecodeBytes(d.d.b[:], true))
} }
func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) { func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
return d.DecodeBytes(d.b[:], true) return d.DecodeBytes(d.d.b[:], true)
} }
func (d *msgpackDecDriver) readNextBd() { func (d *msgpackDecDriver) readNextBd() {
@ -623,9 +668,10 @@ func (d *msgpackDecDriver) ContainerType() (vt valueType) {
return valueTypeArray return valueTypeArray
} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) { } else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
return valueTypeMap return valueTypeMap
} else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
} }
// else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
// }
return valueTypeUnset return valueTypeUnset
} }
@ -635,7 +681,7 @@ func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) {
} }
if d.bd == mpNil { if d.bd == mpNil {
d.bdRead = false d.bdRead = false
v = true return true
} }
return return
} }
@ -701,6 +747,57 @@ func (d *msgpackDecDriver) readExtLen() (clen int) {
return return
} }
func (d *msgpackDecDriver) DecodeTime() (t time.Time) {
// decode time from string bytes or ext
if !d.bdRead {
d.readNextBd()
}
if d.bd == mpNil {
d.bdRead = false
return
}
var clen int
switch d.ContainerType() {
case valueTypeBytes, valueTypeString:
clen = d.readContainerLen(msgpackContainerStr)
default:
// expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1
d.bdRead = false
b2 := d.r.readn1()
if d.bd == mpFixExt4 && b2 == mpTimeExtTagU {
clen = 4
} else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU {
clen = 8
} else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU {
clen = 12
} else {
d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2)
return
}
}
return d.decodeTime(clen)
}
func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) {
// bs = d.r.readx(clen)
d.bdRead = false
switch clen {
case 4:
t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC()
case 8:
tv := bigen.Uint64(d.r.readx(8))
t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC()
case 12:
nsec := bigen.Uint32(d.r.readx(4))
sec := bigen.Uint64(d.r.readx(8))
t = time.Unix(int64(sec), int64(nsec)).UTC()
default:
d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen)
return
}
return
}
func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
if xtag > 0xff { if xtag > 0xff {
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag) d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
@ -750,6 +847,9 @@ type MsgpackHandle struct {
// RawToString controls how raw bytes are decoded into a nil interface{}. // RawToString controls how raw bytes are decoded into a nil interface{}.
RawToString bool RawToString bool
// NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum.
NoFixedNum bool
// WriteExt flag supports encoding configured extensions with extension tags. // WriteExt flag supports encoding configured extensions with extension tags.
// It also controls whether other elements of the new spec are encoded (ie Str8). // It also controls whether other elements of the new spec are encoded (ie Str8).
// //
@ -761,12 +861,19 @@ type MsgpackHandle struct {
// type is provided (e.g. decoding into a nil interface{}), you get back // type is provided (e.g. decoding into a nil interface{}), you get back
// a []byte or string based on the setting of RawToString. // a []byte or string based on the setting of RawToString.
WriteExt bool WriteExt bool
binaryEncodingType binaryEncodingType
noElemSeparators noElemSeparators
_ [1]uint64 // padding
} }
// Name returns the name of the handle: msgpack
func (h *MsgpackHandle) Name() string { return "msgpack" }
// SetBytesExt sets an extension
func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, &setExtWrapper{b: ext}) return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
} }
func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver { func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
@ -804,7 +911,7 @@ func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) err
bodyArr = []interface{}{body} bodyArr = []interface{}{body}
} }
r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr} r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
return c.write(r2, nil, false, true) return c.write(r2, nil, false)
} }
func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error { func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
@ -816,7 +923,7 @@ func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) e
body = nil body = nil
} }
r2 := []interface{}{1, uint32(r.Seq), moe, body} r2 := []interface{}{1, uint32(r.Seq), moe, body}
return c.write(r2, nil, false, true) return c.write(r2, nil, false)
} }
func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error { func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
@ -836,7 +943,6 @@ func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
} }
func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) { func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
if c.isClosed() { if c.isClosed() {
return io.EOF return io.EOF
} }
@ -850,28 +956,34 @@ func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint
// err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1) // err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1)
// return // return
// } // }
var b byte var ba [1]byte
b, err = c.br.ReadByte() var n int
for {
n, err = c.r.Read(ba[:])
if err != nil { if err != nil {
return return
} }
if b != fia { if n == 1 {
err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, b) break
return }
} }
if err = c.read(&b); err != nil { var b = ba[0]
return if b != fia {
} err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, b)
} else {
err = c.read(&b)
if err == nil {
if b != expectTypeByte { if b != expectTypeByte {
err = fmt.Errorf("Unexpected byte descriptor in header. Expecting %v. Received %v", expectTypeByte, b) err = fmt.Errorf("Unexpected byte descriptor. Expecting %v; Received %v",
return expectTypeByte, b)
} else {
err = c.read(msgid)
if err == nil {
err = c.read(methodOrError)
}
} }
if err = c.read(msgid); err != nil {
return
} }
if err = c.read(methodOrError); err != nil {
return
} }
return return
} }
@ -884,7 +996,8 @@ type msgpackSpecRpc struct{}
// MsgpackSpecRpc implements Rpc using the communication protocol defined in // MsgpackSpecRpc implements Rpc using the communication protocol defined in
// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md . // the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered. //
// See GoRpc documentation, for information on buffering for better performance.
var MsgpackSpecRpc msgpackSpecRpc var MsgpackSpecRpc msgpackSpecRpc
func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec { func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
// +build ignore // +build ignore
@ -92,7 +92,8 @@ func (h *noopDrv) EncodeMapStart(length int) { h.start(false) }
func (h *noopDrv) EncodeEnd() { h.end() } func (h *noopDrv) EncodeEnd() { h.end() }
func (h *noopDrv) EncodeString(c charEncoding, v string) {} func (h *noopDrv) EncodeString(c charEncoding, v string) {}
func (h *noopDrv) EncodeSymbol(v string) {}
// func (h *noopDrv) EncodeSymbol(v string) {}
func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {} func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {} func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
@ -119,9 +120,12 @@ func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) }
func (h *noopDrv) ContainerType() (vt valueType) { func (h *noopDrv) ContainerType() (vt valueType) {
// return h.m(2) == 0 // return h.m(2) == 0
// handle kStruct, which will bomb is it calls this and doesn't get back a map or array. // handle kStruct, which will bomb is it calls this and
// consequently, if the return value is not map or array, reset it to one of them based on h.m(7) % 2 // doesn't get back a map or array.
// for kstruct: at least one out of every 2 times, return one of valueTypeMap or Array (else kstruct bombs) // consequently, if the return value is not map or array,
// reset it to one of them based on h.m(7) % 2
// for kstruct: at least one out of every 2 times,
// return one of valueTypeMap or Array (else kstruct bombs)
// however, every 10th time it is called, we just return something else. // however, every 10th time it is called, we just return something else.
var vals = [...]valueType{valueTypeArray, valueTypeMap} var vals = [...]valueType{valueTypeArray, valueTypeMap}
// ------------ TAKE ------------ // ------------ TAKE ------------
@ -150,7 +154,8 @@ func (h *noopDrv) ContainerType() (vt valueType) {
// } // }
// return valueTypeUnset // return valueTypeUnset
// TODO: may need to tweak this so it works. // TODO: may need to tweak this so it works.
// if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap { // if h.ct == valueTypeMap && vt == valueTypeArray ||
// h.ct == valueTypeArray && vt == valueTypeMap {
// h.cb = !h.cb // h.cb = !h.cb
// h.ct = vt // h.ct = vt
// return h.cb // return h.cb

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -11,124 +11,143 @@ import (
"sync" "sync"
) )
// // rpcEncodeTerminator allows a handler specify a []byte terminator to send after each Encode.
// //
// // Some codecs like json need to put a space after each encoded value, to serve as a
// // delimiter for things like numbers (else json codec will continue reading till EOF).
// type rpcEncodeTerminator interface {
// rpcEncodeTerminate() []byte
// }
// Rpc provides a rpc Server or Client Codec for rpc communication. // Rpc provides a rpc Server or Client Codec for rpc communication.
type Rpc interface { type Rpc interface {
ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
} }
// RpcCodecBuffered allows access to the underlying bufio.Reader/Writer // RPCOptions holds options specific to rpc functionality
// used by the rpc connection. It accommodates use-cases where the connection type RPCOptions struct {
// should be used by rpc and non-rpc functions, e.g. streaming a file after // RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
// sending an rpc response. //
type RpcCodecBuffered interface { // Set RPCNoBuffer=true to turn buffering off.
BufferedReader() *bufio.Reader // Buffering can still be done if buffered connections are passed in, or
BufferedWriter() *bufio.Writer // buffering is configured on the handle.
RPCNoBuffer bool
} }
// -------------------------------------
// rpcCodec defines the struct members and common methods. // rpcCodec defines the struct members and common methods.
type rpcCodec struct { type rpcCodec struct {
rwc io.ReadWriteCloser c io.Closer
r io.Reader
w io.Writer
f ioFlusher
dec *Decoder dec *Decoder
enc *Encoder enc *Encoder
bw *bufio.Writer // bw *bufio.Writer
br *bufio.Reader // br *bufio.Reader
mu sync.Mutex mu sync.Mutex
h Handle h Handle
cls bool cls bool
clsmu sync.RWMutex clsmu sync.RWMutex
clsErr error
} }
func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec { func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
bw := bufio.NewWriter(conn) // return newRPCCodec2(bufio.NewReader(conn), bufio.NewWriter(conn), conn, h)
br := bufio.NewReader(conn) return newRPCCodec2(conn, conn, conn, h)
}
func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
// defensive: ensure that jsonH has TermWhitespace turned on. // defensive: ensure that jsonH has TermWhitespace turned on.
if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace { if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true")) panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
} }
// always ensure that we use a flusher, and always flush what was written to the connection.
// we lose nothing by using a buffered writer internally.
f, ok := w.(ioFlusher)
bh := h.getBasicHandle()
if !bh.RPCNoBuffer {
if bh.WriterBufferSize <= 0 {
if !ok {
bw := bufio.NewWriter(w)
f, w = bw, bw
}
}
if bh.ReaderBufferSize <= 0 {
if _, ok = w.(ioPeeker); !ok {
if _, ok = w.(ioBuffered); !ok {
br := bufio.NewReader(r)
r = br
}
}
}
}
return rpcCodec{ return rpcCodec{
rwc: conn, c: c,
bw: bw, w: w,
br: br, r: r,
enc: NewEncoder(bw, h), f: f,
dec: NewDecoder(br, h),
h: h, h: h,
enc: NewEncoder(w, h),
dec: NewDecoder(r, h),
} }
} }
func (c *rpcCodec) BufferedReader() *bufio.Reader { func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
return c.br
}
func (c *rpcCodec) BufferedWriter() *bufio.Writer {
return c.bw
}
func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2, doFlush bool) (err error) {
if c.isClosed() { if c.isClosed() {
return io.EOF return c.clsErr
} }
if err = c.enc.Encode(obj1); err != nil { err = c.enc.Encode(obj1)
return if err == nil {
}
// t, tOk := c.h.(rpcEncodeTerminator)
// if tOk {
// c.bw.Write(t.rpcEncodeTerminate())
// }
if writeObj2 { if writeObj2 {
if err = c.enc.Encode(obj2); err != nil { err = c.enc.Encode(obj2)
return
} }
// if tOk { if err == nil && c.f != nil {
// c.bw.Write(t.rpcEncodeTerminate()) err = c.f.Flush()
// }
} }
if doFlush {
return c.bw.Flush()
} }
return return
} }
func (c *rpcCodec) swallow(err *error) {
defer panicToErr(c.dec, err)
c.dec.swallow()
}
func (c *rpcCodec) read(obj interface{}) (err error) { func (c *rpcCodec) read(obj interface{}) (err error) {
if c.isClosed() { if c.isClosed() {
return io.EOF return c.clsErr
} }
//If nil is passed in, we should still attempt to read content to nowhere. //If nil is passed in, we should read and discard
if obj == nil { if obj == nil {
var obj2 interface{} // var obj2 interface{}
return c.dec.Decode(&obj2) // return c.dec.Decode(&obj2)
c.swallow(&err)
return
} }
return c.dec.Decode(obj) return c.dec.Decode(obj)
} }
func (c *rpcCodec) isClosed() bool { func (c *rpcCodec) isClosed() (b bool) {
if c.c != nil {
c.clsmu.RLock() c.clsmu.RLock()
x := c.cls b = c.cls
c.clsmu.RUnlock() c.clsmu.RUnlock()
return x }
return
} }
func (c *rpcCodec) Close() error { func (c *rpcCodec) Close() error {
if c.isClosed() { if c.c == nil || c.isClosed() {
return io.EOF return c.clsErr
} }
c.clsmu.Lock() c.clsmu.Lock()
c.cls = true c.cls = true
var fErr error
if c.f != nil {
fErr = c.f.Flush()
}
_ = fErr
c.clsErr = c.c.Close()
if c.clsErr == nil && fErr != nil {
c.clsErr = fErr
}
c.clsmu.Unlock() c.clsmu.Unlock()
return c.rwc.Close() return c.clsErr
} }
func (c *rpcCodec) ReadResponseBody(body interface{}) error { func (c *rpcCodec) ReadResponseBody(body interface{}) error {
@ -145,13 +164,13 @@ func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
// Must protect for concurrent access as per API // Must protect for concurrent access as per API
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
return c.write(r, body, true, true) return c.write(r, body, true)
} }
func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error { func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
return c.write(r, body, true, true) return c.write(r, body, true)
} }
func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error { func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
@ -173,7 +192,36 @@ func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
type goRpc struct{} type goRpc struct{}
// GoRpc implements Rpc using the communication protocol defined in net/rpc package. // GoRpc implements Rpc using the communication protocol defined in net/rpc package.
// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered. //
// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
//
// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
// This ensures we use an adequate buffer during reading and writing.
// If not configured, we will internally initialize and use a buffer during reads and writes.
// This can be turned off via the RPCNoBuffer option on the Handle.
// var handle codec.JsonHandle
// handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
//
// Example 1: one way of configuring buffering explicitly:
// var handle codec.JsonHandle // codec handle
// handle.ReaderBufferSize = 1024
// handle.WriterBufferSize = 1024
// var conn io.ReadWriteCloser // connection got from a socket
// var serverCodec = GoRpc.ServerCodec(conn, handle)
// var clientCodec = GoRpc.ClientCodec(conn, handle)
//
// Example 2: you can also explicitly create a buffered connection yourself,
// and not worry about configuring the buffer sizes in the Handle.
// var handle codec.Handle // codec handle
// var conn io.ReadWriteCloser // connection got from a socket
// var bufconn = struct { // bufconn here is a buffered io.ReadWriteCloser
// io.Closer
// *bufio.Reader
// *bufio.Writer
// }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
// var serverCodec = GoRpc.ServerCodec(bufconn, handle)
// var clientCodec = GoRpc.ClientCodec(bufconn, handle)
//
var GoRpc goRpc var GoRpc goRpc
func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec { func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
@ -183,5 +231,3 @@ func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec { func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
return &goRpcCodec{newRPCCodec(conn, h)} return &goRpcCodec{newRPCCodec(conn, h)}
} }
var _ RpcCodecBuffered = (*rpcCodec)(nil) // ensure *rpcCodec implements RpcCodecBuffered

View File

@ -1,4 +1,4 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -6,6 +6,7 @@ package codec
import ( import (
"math" "math"
"reflect" "reflect"
"time"
) )
const ( const (
@ -20,6 +21,8 @@ const (
simpleVdPosInt = 8 simpleVdPosInt = 8
simpleVdNegInt = 12 simpleVdNegInt = 12
simpleVdTime = 24
// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7) // containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
simpleVdString = 216 simpleVdString = 216
simpleVdByteArray = 224 simpleVdByteArray = 224
@ -30,12 +33,15 @@ const (
type simpleEncDriver struct { type simpleEncDriver struct {
noBuiltInTypes noBuiltInTypes
encDriverNoopContainerWriter
// encNoSeparator // encNoSeparator
e *Encoder e *Encoder
h *SimpleHandle h *SimpleHandle
w encWriter w encWriter
b [8]byte b [8]byte
// c containerState
encDriverTrackContainerWriter
// encDriverNoopContainerWriter
_ [2]uint64 // padding
} }
func (e *simpleEncDriver) EncodeNil() { func (e *simpleEncDriver) EncodeNil() {
@ -43,6 +49,10 @@ func (e *simpleEncDriver) EncodeNil() {
} }
func (e *simpleEncDriver) EncodeBool(b bool) { func (e *simpleEncDriver) EncodeBool(b bool) {
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
e.EncodeNil()
return
}
if b { if b {
e.w.writen1(simpleVdTrue) e.w.writen1(simpleVdTrue)
} else { } else {
@ -51,11 +61,19 @@ func (e *simpleEncDriver) EncodeBool(b bool) {
} }
func (e *simpleEncDriver) EncodeFloat32(f float32) { func (e *simpleEncDriver) EncodeFloat32(f float32) {
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
e.EncodeNil()
return
}
e.w.writen1(simpleVdFloat32) e.w.writen1(simpleVdFloat32)
bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f)) bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
} }
func (e *simpleEncDriver) EncodeFloat64(f float64) { func (e *simpleEncDriver) EncodeFloat64(f float64) {
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
e.EncodeNil()
return
}
e.w.writen1(simpleVdFloat64) e.w.writen1(simpleVdFloat64)
bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f)) bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
} }
@ -73,6 +91,10 @@ func (e *simpleEncDriver) EncodeUint(v uint64) {
} }
func (e *simpleEncDriver) encUint(v uint64, bd uint8) { func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
e.EncodeNil()
return
}
if v <= math.MaxUint8 { if v <= math.MaxUint8 {
e.w.writen2(bd, uint8(v)) e.w.writen2(bd, uint8(v))
} else if v <= math.MaxUint16 { } else if v <= math.MaxUint16 {
@ -126,27 +148,54 @@ func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
} }
func (e *simpleEncDriver) WriteArrayStart(length int) { func (e *simpleEncDriver) WriteArrayStart(length int) {
e.c = containerArrayStart
e.encLen(simpleVdArray, length) e.encLen(simpleVdArray, length)
} }
func (e *simpleEncDriver) WriteMapStart(length int) { func (e *simpleEncDriver) WriteMapStart(length int) {
e.c = containerMapStart
e.encLen(simpleVdMap, length) e.encLen(simpleVdMap, length)
} }
func (e *simpleEncDriver) EncodeString(c charEncoding, v string) { func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
e.EncodeNil()
return
}
e.encLen(simpleVdString, len(v)) e.encLen(simpleVdString, len(v))
e.w.writestr(v) e.w.writestr(v)
} }
func (e *simpleEncDriver) EncodeSymbol(v string) { // func (e *simpleEncDriver) EncodeSymbol(v string) {
e.EncodeString(c_UTF8, v) // e.EncodeString(cUTF8, v)
} // }
func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) { func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
if v == nil {
e.EncodeNil()
return
}
e.encLen(simpleVdByteArray, len(v)) e.encLen(simpleVdByteArray, len(v))
e.w.writeb(v) e.w.writeb(v)
} }
func (e *simpleEncDriver) EncodeTime(t time.Time) {
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
if t.IsZero() {
e.EncodeNil()
return
}
v, err := t.MarshalBinary()
if err != nil {
e.e.errorv(err)
return
}
// time.Time marshalbinary takes about 14 bytes.
e.w.writen2(simpleVdTime, uint8(len(v)))
e.w.writeb(v)
}
//------------------------------------ //------------------------------------
type simpleDecDriver struct { type simpleDecDriver struct {
@ -155,11 +204,13 @@ type simpleDecDriver struct {
r decReader r decReader
bdRead bool bdRead bool
bd byte bd byte
br bool // bytes reader br bool // a bytes reader?
b [scratchByteArrayLen]byte c containerState
// b [scratchByteArrayLen]byte
noBuiltInTypes noBuiltInTypes
// noStreamingCodec // noStreamingCodec
decDriverNoopContainerReader decDriverNoopContainerReader
_ [3]uint64 // padding
} }
func (d *simpleDecDriver) readNextBd() { func (d *simpleDecDriver) readNextBd() {
@ -178,23 +229,27 @@ func (d *simpleDecDriver) ContainerType() (vt valueType) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
if d.bd == simpleVdNil { switch d.bd {
case simpleVdNil:
return valueTypeNil return valueTypeNil
} else if d.bd == simpleVdByteArray || d.bd == simpleVdByteArray+1 || case simpleVdByteArray, simpleVdByteArray + 1,
d.bd == simpleVdByteArray+2 || d.bd == simpleVdByteArray+3 || d.bd == simpleVdByteArray+4 { simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
return valueTypeBytes return valueTypeBytes
} else if d.bd == simpleVdString || d.bd == simpleVdString+1 || case simpleVdString, simpleVdString + 1,
d.bd == simpleVdString+2 || d.bd == simpleVdString+3 || d.bd == simpleVdString+4 { simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
return valueTypeString return valueTypeString
} else if d.bd == simpleVdArray || d.bd == simpleVdArray+1 || case simpleVdArray, simpleVdArray + 1,
d.bd == simpleVdArray+2 || d.bd == simpleVdArray+3 || d.bd == simpleVdArray+4 { simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
return valueTypeArray return valueTypeArray
} else if d.bd == simpleVdMap || d.bd == simpleVdMap+1 || case simpleVdMap, simpleVdMap + 1,
d.bd == simpleVdMap+2 || d.bd == simpleVdMap+3 || d.bd == simpleVdMap+4 { simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
return valueTypeMap return valueTypeMap
} else { // case simpleVdTime:
// d.d.errorf("isContainerType: unsupported parameter: %v", vt) // return valueTypeTime
} }
// else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
// }
return valueTypeUnset return valueTypeUnset
} }
@ -235,7 +290,7 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
ui = uint64(bigen.Uint64(d.r.readx(8))) ui = uint64(bigen.Uint64(d.r.readx(8)))
neg = true neg = true
default: default:
d.d.errorf("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd) d.d.errorf("Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
return return
} }
// don't do this check, because callers may only want the unsigned value. // don't do this check, because callers may only want the unsigned value.
@ -246,39 +301,27 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
return return
} }
func (d *simpleDecDriver) DecodeInt(bitsize uint8) (i int64) { func (d *simpleDecDriver) DecodeInt64() (i int64) {
ui, neg := d.decCheckInteger() ui, neg := d.decCheckInteger()
i, overflow := chkOvf.SignedInt(ui) i = chkOvf.SignedIntV(ui)
if overflow {
d.d.errorf("simple: overflow converting %v to signed integer", ui)
return
}
if neg { if neg {
i = -i i = -i
} }
if chkOvf.Int(i, bitsize) {
d.d.errorf("simple: overflow integer: %v", i)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *simpleDecDriver) DecodeUint(bitsize uint8) (ui uint64) { func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
ui, neg := d.decCheckInteger() ui, neg := d.decCheckInteger()
if neg { if neg {
d.d.errorf("Assigning negative signed value to unsigned type") d.d.errorf("Assigning negative signed value to unsigned type")
return return
} }
if chkOvf.Uint(ui, bitsize) {
d.d.errorf("simple: overflow integer: %v", ui)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { func (d *simpleDecDriver) DecodeFloat64() (f float64) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
@ -288,16 +331,12 @@ func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
} else { } else {
if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 { if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
f = float64(d.DecodeInt(64)) f = float64(d.DecodeInt64())
} else { } else {
d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd) d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd)
return return
} }
} }
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("msgpack: float32 overflow: %v", f)
return
}
d.bdRead = false d.bdRead = false
return return
} }
@ -323,6 +362,7 @@ func (d *simpleDecDriver) ReadMapStart() (length int) {
d.readNextBd() d.readNextBd()
} }
d.bdRead = false d.bdRead = false
d.c = containerMapStart
return d.decLen() return d.decLen()
} }
@ -331,9 +371,30 @@ func (d *simpleDecDriver) ReadArrayStart() (length int) {
d.readNextBd() d.readNextBd()
} }
d.bdRead = false d.bdRead = false
d.c = containerArrayStart
return d.decLen() return d.decLen()
} }
func (d *simpleDecDriver) ReadArrayElem() {
d.c = containerArrayElem
}
func (d *simpleDecDriver) ReadArrayEnd() {
d.c = containerArrayEnd
}
func (d *simpleDecDriver) ReadMapElemKey() {
d.c = containerMapKey
}
func (d *simpleDecDriver) ReadMapElemValue() {
d.c = containerMapValue
}
func (d *simpleDecDriver) ReadMapEnd() {
d.c = containerMapEnd
}
func (d *simpleDecDriver) decLen() int { func (d *simpleDecDriver) decLen() int {
switch d.bd % 8 { switch d.bd % 8 {
case 0: case 0:
@ -345,14 +406,14 @@ func (d *simpleDecDriver) decLen() int {
case 3: case 3:
ui := uint64(bigen.Uint32(d.r.readx(4))) ui := uint64(bigen.Uint32(d.r.readx(4)))
if chkOvf.Uint(ui, intBitsize) { if chkOvf.Uint(ui, intBitsize) {
d.d.errorf("simple: overflow integer: %v", ui) d.d.errorf("overflow integer: %v", ui)
return 0 return 0
} }
return int(ui) return int(ui)
case 4: case 4:
ui := bigen.Uint64(d.r.readx(8)) ui := bigen.Uint64(d.r.readx(8))
if chkOvf.Uint(ui, intBitsize) { if chkOvf.Uint(ui, intBitsize) {
d.d.errorf("simple: overflow integer: %v", ui) d.d.errorf("overflow integer: %v", ui)
return 0 return 0
} }
return int(ui) return int(ui)
@ -362,11 +423,11 @@ func (d *simpleDecDriver) decLen() int {
} }
func (d *simpleDecDriver) DecodeString() (s string) { func (d *simpleDecDriver) DecodeString() (s string) {
return string(d.DecodeBytes(d.b[:], true)) return string(d.DecodeBytes(d.d.b[:], true))
} }
func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) { func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
return d.DecodeBytes(d.b[:], true) return d.DecodeBytes(d.d.b[:], true)
} }
func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) { func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
@ -377,18 +438,48 @@ func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
d.bdRead = false d.bdRead = false
return return
} }
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
if len(bs) == 0 && zerocopy {
bs = d.d.b[:]
}
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
return
}
clen := d.decLen() clen := d.decLen()
d.bdRead = false d.bdRead = false
if zerocopy { if zerocopy {
if d.br { if d.br {
return d.r.readx(clen) return d.r.readx(clen)
} else if len(bs) == 0 { } else if len(bs) == 0 {
bs = d.b[:] bs = d.d.b[:]
} }
} }
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs) return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
} }
func (d *simpleDecDriver) DecodeTime() (t time.Time) {
if !d.bdRead {
d.readNextBd()
}
if d.bd == simpleVdNil {
d.bdRead = false
return
}
if d.bd != simpleVdTime {
d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
return
}
d.bdRead = false
clen := int(d.r.readn1())
b := d.r.readx(clen)
if err := (&t).UnmarshalBinary(b); err != nil {
d.d.errorv(err)
}
return
}
func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
if xtag > 0xff { if xtag > 0xff {
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag) d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
@ -419,10 +510,11 @@ func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs [
return return
} }
xbs = d.r.readx(l) xbs = d.r.readx(l)
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: case simpleVdByteArray, simpleVdByteArray + 1,
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
xbs = d.DecodeBytes(nil, true) xbs = d.DecodeBytes(nil, true)
default: default:
d.d.errorf("Invalid d.bd for extensions (Expecting extensions or byte array). Got: 0x%x", d.bd) d.d.errorf("Invalid descriptor - expecting extensions/bytearray, got: 0x%x", d.bd)
return return
} }
d.bdRead = false d.bdRead = false
@ -449,24 +541,29 @@ func (d *simpleDecDriver) DecodeNaked() {
case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3: case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
if d.h.SignedInteger { if d.h.SignedInteger {
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
} else { } else {
n.v = valueTypeUint n.v = valueTypeUint
n.u = d.DecodeUint(64) n.u = d.DecodeUint64()
} }
case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3: case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
case simpleVdFloat32: case simpleVdFloat32:
n.v = valueTypeFloat n.v = valueTypeFloat
n.f = d.DecodeFloat(true) n.f = d.DecodeFloat64()
case simpleVdFloat64: case simpleVdFloat64:
n.v = valueTypeFloat n.v = valueTypeFloat
n.f = d.DecodeFloat(false) n.f = d.DecodeFloat64()
case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: case simpleVdTime:
n.v = valueTypeTime
n.t = d.DecodeTime()
case simpleVdString, simpleVdString + 1,
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
n.v = valueTypeString n.v = valueTypeString
n.s = d.DecodeString() n.s = d.DecodeString()
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: case simpleVdByteArray, simpleVdByteArray + 1,
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
n.v = valueTypeBytes n.v = valueTypeBytes
n.l = d.DecodeBytes(nil, false) n.l = d.DecodeBytes(nil, false)
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
@ -474,7 +571,8 @@ func (d *simpleDecDriver) DecodeNaked() {
l := d.decLen() l := d.decLen()
n.u = uint64(d.r.readn1()) n.u = uint64(d.r.readn1())
n.l = d.r.readx(l) n.l = d.r.readx(l)
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4: case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
simpleVdArray + 3, simpleVdArray + 4:
n.v = valueTypeArray n.v = valueTypeArray
decodeFurther = true decodeFurther = true
case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
@ -500,7 +598,7 @@ func (d *simpleDecDriver) DecodeNaked() {
// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte). // - 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. // There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte) // - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
// - Lenght of containers (strings, bytes, array, map, extensions) // - Length of containers (strings, bytes, array, map, extensions)
// are encoded in 0, 1, 2, 4 or 8 bytes. // are encoded in 0, 1, 2, 4 or 8 bytes.
// Zero-length containers have no length encoded. // Zero-length containers have no length encoded.
// For others, the number of bytes is given by pow(2, bd%3) // For others, the number of bytes is given by pow(2, bd%3)
@ -508,18 +606,29 @@ func (d *simpleDecDriver) DecodeNaked() {
// - arrays are encoded as [bd] [length] [value]... // - arrays are encoded as [bd] [length] [value]...
// - extensions are encoded as [bd] [length] [tag] [byte]... // - extensions are encoded as [bd] [length] [tag] [byte]...
// - strings/bytearrays are encoded as [bd] [length] [byte]... // - strings/bytearrays are encoded as [bd] [length] [byte]...
// - time.Time are encoded as [bd] [length] [byte]...
// //
// The full spec will be published soon. // The full spec will be published soon.
type SimpleHandle struct { type SimpleHandle struct {
BasicHandle BasicHandle
binaryEncodingType binaryEncodingType
noElemSeparators noElemSeparators
// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
EncZeroValuesAsNil bool
_ [1]uint64 // padding
} }
// Name returns the name of the handle: simple
func (h *SimpleHandle) Name() string { return "simple" }
// SetBytesExt sets an extension
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, &setExtWrapper{b: ext}) return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
} }
func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver { func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
return &simpleEncDriver{e: e, w: e.w, h: h} return &simpleEncDriver{e: e, w: e.w, h: h}
} }
@ -529,10 +638,12 @@ func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
} }
func (e *simpleEncDriver) reset() { func (e *simpleEncDriver) reset() {
e.c = 0
e.w = e.e.w e.w = e.e.w
} }
func (d *simpleDecDriver) reset() { func (d *simpleDecDriver) reset() {
d.c = 0
d.r, d.br = d.d.r, d.d.bytes d.r, d.br = d.d.r, d.d.bytes
d.bd, d.bdRead = 0, false d.bd, d.bdRead = 0, false
} }

View File

@ -1,220 +0,0 @@
// 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.
package codec
import (
"fmt"
"time"
)
var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
type timeExt struct{}
func (x timeExt) WriteExt(v interface{}) (bs []byte) {
switch v2 := v.(type) {
case time.Time:
bs = encodeTime(v2)
case *time.Time:
bs = encodeTime(*v2)
default:
panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
}
return
}
func (x timeExt) ReadExt(v interface{}, bs []byte) {
tt, err := decodeTime(bs)
if err != nil {
panic(err)
}
*(v.(*time.Time)) = tt
}
func (x timeExt) ConvertExt(v interface{}) interface{} {
return x.WriteExt(v)
}
func (x timeExt) UpdateExt(v interface{}, src interface{}) {
x.ReadExt(v, src.([]byte))
}
// EncodeTime encodes a time.Time as a []byte, including
// information on the instant in time and UTC offset.
//
// Format Description
//
// A timestamp is composed of 3 components:
//
// - secs: signed integer representing seconds since unix epoch
// - nsces: unsigned integer representing fractional seconds as a
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
// - tz: signed integer representing timezone offset in minutes east of UTC,
// and a dst (daylight savings time) flag
//
// When encoding a timestamp, the first byte is the descriptor, which
// defines which components are encoded and how many bytes are used to
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
// is not encoded in the byte array explicitly*.
//
// Descriptor 8 bits are of the form `A B C DDD EE`:
// A: Is secs component encoded? 1 = true
// B: Is nsecs component encoded? 1 = true
// C: Is tz component encoded? 1 = true
// DDD: Number of extra bytes for secs (range 0-7).
// If A = 1, secs encoded in DDD+1 bytes.
// If A = 0, secs is not encoded, and is assumed to be 0.
// If A = 1, then we need at least 1 byte to encode secs.
// DDD says the number of extra bytes beyond that 1.
// E.g. if DDD=0, then secs is represented in 1 byte.
// if DDD=2, then secs is represented in 3 bytes.
// EE: Number of extra bytes for nsecs (range 0-3).
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
//
// Following the descriptor bytes, subsequent bytes are:
//
// secs component encoded in `DDD + 1` bytes (if A == 1)
// nsecs component encoded in `EE + 1` bytes (if B == 1)
// tz component encoded in 2 bytes (if C == 1)
//
// secs and nsecs components are integers encoded in a BigEndian
// 2-complement encoding format.
//
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
// Least significant bit 0 are described below:
//
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
//
func encodeTime(t time.Time) []byte {
//t := rv.Interface().(time.Time)
tsecs, tnsecs := t.Unix(), t.Nanosecond()
var (
bd byte
btmp [8]byte
bs [16]byte
i int = 1
)
l := t.Location()
if l == time.UTC {
l = nil
}
if tsecs != 0 {
bd = bd | 0x80
bigen.PutUint64(btmp[:], uint64(tsecs))
f := pruneSignExt(btmp[:], tsecs >= 0)
bd = bd | (byte(7-f) << 2)
copy(bs[i:], btmp[f:])
i = i + (8 - f)
}
if tnsecs != 0 {
bd = bd | 0x40
bigen.PutUint32(btmp[:4], uint32(tnsecs))
f := pruneSignExt(btmp[:4], true)
bd = bd | byte(3-f)
copy(bs[i:], btmp[f:4])
i = i + (4 - f)
}
if l != nil {
bd = bd | 0x20
// Note that Go Libs do not give access to dst flag.
_, zoneOffset := t.Zone()
//zoneName, zoneOffset := t.Zone()
zoneOffset /= 60
z := uint16(zoneOffset)
bigen.PutUint16(btmp[:2], z)
// clear dst flags
bs[i] = btmp[0] & 0x3f
bs[i+1] = btmp[1]
i = i + 2
}
bs[0] = bd
return bs[0:i]
}
// DecodeTime decodes a []byte into a time.Time.
func decodeTime(bs []byte) (tt time.Time, err error) {
bd := bs[0]
var (
tsec int64
tnsec uint32
tz uint16
i byte = 1
i2 byte
n byte
)
if bd&(1<<7) != 0 {
var btmp [8]byte
n = ((bd >> 2) & 0x7) + 1
i2 = i + n
copy(btmp[8-n:], bs[i:i2])
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
if bs[i]&(1<<7) != 0 {
copy(btmp[0:8-n], bsAll0xff)
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
}
i = i2
tsec = int64(bigen.Uint64(btmp[:]))
}
if bd&(1<<6) != 0 {
var btmp [4]byte
n = (bd & 0x3) + 1
i2 = i + n
copy(btmp[4-n:], bs[i:i2])
i = i2
tnsec = bigen.Uint32(btmp[:])
}
if bd&(1<<5) == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
return
}
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
// However, we need name here, so it can be shown when time is printed.
// Zone name is in form: UTC-08:00.
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
i2 = i + 2
tz = bigen.Uint16(bs[i:i2])
i = i2
// sign extend sign bit into top 2 MSB (which were dst bits):
if tz&(1<<13) == 0 { // positive
tz = tz & 0x3fff //clear 2 MSBs: dst bits
} else { // negative
tz = tz | 0xc000 //set 2 MSBs: dst bits
//tzname[3] = '-' (TODO: verify. this works here)
}
tzint := int16(tz)
if tzint == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
} else {
// For Go Time, do not use a descriptive timezone.
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
// var zoneName = timeLocUTCName(tzint)
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
}
return
}
// func timeLocUTCName(tzint int16) string {
// if tzint == 0 {
// return "UTC"
// }
// var tzname = []byte("UTC+00:00")
// //tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
// //tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
// var tzhr, tzmin int16
// if tzint < 0 {
// tzname[3] = '-' // (TODO: verify. this works here)
// tzhr, tzmin = -tzint/60, (-tzint)%60
// } else {
// tzhr, tzmin = tzint/60, tzint%60
// }
// tzname[4] = timeDigits[tzhr/10]
// tzname[5] = timeDigits[tzhr%10]
// tzname[7] = timeDigits[tzmin/10]
// tzname[8] = timeDigits[tzmin%10]
// return string(tzname)
// //return time.FixedZone(string(tzname), int(tzint)*60)
// }

View File

@ -1,3 +1,6 @@
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build ignore // +build ignore
package codec package codec
@ -24,7 +27,6 @@ It is a replacement, based on the simplicity and performance of codec.
Look at it like JAXB for Go. Look at it like JAXB for Go.
Challenges: Challenges:
- Need to output XML preamble, with all namespaces at the right location in the output. - Need to output XML preamble, with all namespaces at the right location in the output.
- Each "end" block is dynamic, so we need to maintain a context-aware stack - Each "end" block is dynamic, so we need to maintain a context-aware stack
- How to decide when to use an attribute VS an element - How to decide when to use an attribute VS an element
@ -34,24 +36,26 @@ Challenges:
Extend the struct tag. See representative example: Extend the struct tag. See representative example:
type X struct { type X struct {
ID uint8 codec:"xid|http://ugorji.net/x-namespace id,omitempty,toarray,attr,cdata" ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
// format: [namespace-uri ][namespace-prefix ]local-name, ...
} }
Based on this, we encode Based on this, we encode
- fields as elements, BUT encode as attributes if struct tag contains ",attr". - fields as elements, BUT
encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
- text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata". - text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
In this mode, we only encode as attribute if ",attr" is found, and only encode as CDATA
if ",cdata" is found in the struct tag.
To handle namespaces: To handle namespaces:
- XMLHandle is denoted as being namespace-aware. - XMLHandle is denoted as being namespace-aware.
Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name. Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
- *Encoder and *Decoder know whether the Handle "prefers" namespaces. - *Encoder and *Decoder know whether the Handle "prefers" namespaces.
- add *Encoder.getEncName(*structFieldInfo). - add *Encoder.getEncName(*structFieldInfo).
No one calls *structFieldInfo.indexForEncName directly anymore No one calls *structFieldInfo.indexForEncName directly anymore
- OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
indexForEncName takes a parameter of the form namespace:local-name OR local-name
- add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc - add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
No one accesses .encName anymore except in by being a method on *Decoder, or maybe a method on the Handle itself.
No one accesses .encName anymore
- let encode.go and decode.go use these (for consistency) - let encode.go and decode.go use these (for consistency)
- only problem exists for gen.go, where we create a big switch on encName. - only problem exists for gen.go, where we create a big switch on encName.
Now, we also have to add a switch on strings.endsWith(kName, encNsName) Now, we also have to add a switch on strings.endsWith(kName, encNsName)
@ -62,13 +66,14 @@ To handle namespaces:
default { default {
switch { switch {
case !nsAware: panic(...) case !nsAware: panic(...)
case strings.endsWith("nsabc"): x.abc() case strings.endsWith(":abc"): x.abc()
case strings.endsWith(":def"): x.def()
default: panic(...) default: panic(...)
} }
} }
} }
The structure below accomodates this: The structure below accommodates this:
type typeInfo struct { type typeInfo struct {
sfi []*structFieldInfo // sorted by encName sfi []*structFieldInfo // sorted by encName
@ -88,7 +93,10 @@ indexForEncName is now an internal helper function that takes a sorted array
(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...) (one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
There will be a separate parser from the builder. There will be a separate parser from the builder.
The parser will have a method: next() xmlToken method. The parser will have a method: next() xmlToken method. It has lookahead support,
so you can pop multiple tokens, make a determination, and push them back in the order popped.
This will be needed to determine whether we are "nakedly" decoding a container or not.
The stack will be implemented using a slice and push/pop happens at the [0] element.
xmlToken has fields: xmlToken has fields:
- type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text - type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
@ -132,7 +140,7 @@ At decode time, a structure containing the following is kept
- all internal entities (<>&"' and others written in the document) - all internal entities (<>&"' and others written in the document)
When decode starts, it parses XML namespace declarations and creates a map in the When decode starts, it parses XML namespace declarations and creates a map in the
xmlDecDriver. While parsing, that map continously gets updated. xmlDecDriver. While parsing, that map continuously gets updated.
The only problem happens when a namespace declaration happens on the node that it defines. The only problem happens when a namespace declaration happens on the node that it defines.
e.g. <hn:name xmlns:hn="http://www.ugorji.net" > e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
To handle this, each Element must be fully parsed at a time, To handle this, each Element must be fully parsed at a time,
@ -144,7 +152,7 @@ xmlns is a special attribute name.
*We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.* *We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
Number, bool, null, mapKey, etc can all be decoded from any xmlToken. Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
This accomodates map[int]string for example. This accommodates map[int]string for example.
It should be possible to create a schema from the types, It should be possible to create a schema from the types,
or vice versa (generate types from schema with appropriate tags). or vice versa (generate types from schema with appropriate tags).
@ -178,8 +186,8 @@ An XML document is a name, a map of attributes and a list of children.
Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example). Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
We have to "DecodeNaked" into something that resembles XML data. We have to "DecodeNaked" into something that resembles XML data.
To support DecodeNaked (decode into nil interface{}) we have to define some "supporting" types: To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
type Name struct { // Prefered. Less allocations due to conversions. type Name struct { // Preferred. Less allocations due to conversions.
Local string Local string
Space string Space string
} }
@ -190,6 +198,8 @@ To support DecodeNaked (decode into nil interface{}) we have to define some "sup
} }
Only two "supporting" types are exposed for XML: Name and Element. Only two "supporting" types are exposed for XML: Name and Element.
// ------------------
We considered 'type Name string' where Name is like "Space Local" (space-separated). We considered 'type Name string' where Name is like "Space Local" (space-separated).
We decided against it, because each creation of a name would lead to We decided against it, because each creation of a name would lead to
double allocation (first convert []byte to string, then concatenate them into a string). double allocation (first convert []byte to string, then concatenate them into a string).
@ -215,16 +225,16 @@ intelligent accessor methods to extract information and for performance.
} }
func (x *Element) child(i) interface{} // returns string or *Element func (x *Element) child(i) interface{} // returns string or *Element
Per XML spec and our default handling, white space is insignificant between elements, // ------------------
specifically between parent-child or siblings. White space occuring alone between start
and end element IS significant. However, if xml:space='preserve', then we 'preserve' Per XML spec and our default handling, white space is always treated as
all whitespace. This is more critical when doing a DecodeNaked, but MAY not be as critical insignificant between elements, except in a text node. The xml:space='preserve'
when decoding into a typed value. attribute is ignored.
**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.** **Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
**So treat them as just "directives" that should be interpreted to mean something**. **So treat them as just "directives" that should be interpreted to mean something**.
On encoding, we don't add any prettifying markup (indenting, etc). On encoding, we support indenting aka prettifying markup in the same way we support it for json.
A document or element can only be encoded/decoded from/to a struct. In this mode: A document or element can only be encoded/decoded from/to a struct. In this mode:
- struct name maps to element name (or tag-info from _struct field) - struct name maps to element name (or tag-info from _struct field)
@ -258,15 +268,14 @@ the struct tag signifying it should be attr, then all its fields are encoded as
e.g. e.g.
type X struct { type X struct {
M map[string]int `codec:"m,attr"` // encode as attributes M map[string]int `codec:"m,attr"` // encode keys as attributes named
} }
Question: Question:
- if encoding a map, what if map keys have spaces in them??? - if encoding a map, what if map keys have spaces in them???
Then they cannot be attributes or child elements. Error. Then they cannot be attributes or child elements. Error.
Misc: Options to consider adding later:
- For attribute values, normalize by trimming beginning and ending white space, - For attribute values, normalize by trimming beginning and ending white space,
and converting every white space sequence to a single space. and converting every white space sequence to a single space.
- ATTLIST restrictions are enforced. - ATTLIST restrictions are enforced.
@ -284,6 +293,8 @@ Misc:
CheckName bool CheckName bool
} }
Misc:
ROADMAP (1 weeks): ROADMAP (1 weeks):
- build encoder (1 day) - build encoder (1 day)
- build decoder (based off xmlParser) (1 day) - build decoder (based off xmlParser) (1 day)
@ -292,7 +303,78 @@ ROADMAP (1 weeks):
- integrate and TEST (1 days) - integrate and TEST (1 days)
- write article and post it (1 day) - write article and post it (1 day)
// ---------- MORE NOTES FROM 2017-11-30 ------------
when parsing
- parse the attributes first
- then parse the nodes
basically:
- if encoding a field: we use the field name for the wrapper
- if encoding a non-field, then just use the element type name
map[string]string ==> <map><key>abc</key><value>val</value></map>... or
<map key="abc">val</map>... OR
<key1>val1</key1><key2>val2</key2>... <- PREFERED
[]string ==> <string>v1</string><string>v2</string>...
string v1 ==> <string>v1</string>
bool true ==> <bool>true</bool>
float 1.0 ==> <float>1.0</float>
...
F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
<F1 key="abc">val</F1>... OR
<F1><abc>val</abc>...</F1> <- PREFERED
F2 []string ==> <F2>v1</F2><F2>v2</F2>...
F3 bool ==> <F3>true</F3>
...
- a scalar is encoded as:
(value) of type T ==> <T><value/></T>
(value) of field F ==> <F><value/></F>
- A kv-pair is encoded as:
(key,value) ==> <map><key><value/></key></map> OR <map key="value">
(key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
- A map or struct is just a list of kv-pairs
- A list is encoded as sequences of same node e.g.
<F1 key1="value11">
<F1 key2="value12">
<F2>value21</F2>
<F2>value22</F2>
- we may have to singularize the field name, when entering into xml,
and pluralize them when encoding.
- bi-directional encode->decode->encode is not a MUST.
even encoding/xml cannot decode correctly what was encoded:
see https://play.golang.org/p/224V_nyhMS
func main() {
fmt.Println("Hello, playground")
v := []interface{}{"hello", 1, true, nil, time.Now()}
s, err := xml.Marshal(v)
fmt.Printf("err: %v, \ns: %s\n", err, s)
var v2 []interface{}
err = xml.Unmarshal(s, &v2)
fmt.Printf("err: %v, \nv2: %v\n", err, v2)
type T struct {
V []interface{}
}
v3 := T{V: v}
s, err = xml.Marshal(v3)
fmt.Printf("err: %v, \ns: %s\n", err, s)
var v4 T
err = xml.Unmarshal(s, &v4)
fmt.Printf("err: %v, \nv4: %v\n", err, v4)
}
Output:
err: <nil>,
s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
err: <nil>,
v2: [<nil>]
err: <nil>,
s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
err: <nil>,
v4: {[<nil> <nil> <nil> <nil>]}
-
*/ */
// ----------- PARSER ------------------- // ----------- PARSER -------------------
@ -419,7 +501,7 @@ func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
} }
func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
return h.SetExt(rt, tag, &setExtWrapper{i: ext}) return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
} }
var _ decDriver = (*xmlDecDriver)(nil) var _ decDriver = (*xmlDecDriver)(nil)

View File

@ -1,23 +0,0 @@
// 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.
package codec
import "sort"
// TODO: this is brittle, as it depends on z.go's init() being called last.
// The current build tools all honor that files are passed in lexical order.
// However, we should consider using an init_channel,
// that each person doing init will write to.
func init() {
if !useLookupRecognizedTypes {
return
}
sort.Sort(uintptrSlice(recognizedRtids))
sort.Sort(uintptrSlice(recognizedRtidPtrs))
recognizedRtidOrPtrs = make([]uintptr, len(recognizedRtids)+len(recognizedRtidPtrs))
copy(recognizedRtidOrPtrs, recognizedRtids)
copy(recognizedRtidOrPtrs[len(recognizedRtids):], recognizedRtidPtrs)
sort.Sort(uintptrSlice(recognizedRtidOrPtrs))
}

View File

@ -1,47 +0,0 @@
**MessagePack and [Binc](http://github.com/ugorji/binc) Codec for [Go](http://golang.org) Language.**
*A High Performance, Feature-Rich, Idiomatic encode/decode and rpc library*.
To install:
go get github.com/ugorji/go/codec
Source: [http://github.com/ugorji/go]
Online documentation: [http://godoc.org/github.com/ugorji/go/codec]
Typical usage:
```go
// create and use decoder/encoder
var (
v interface{} // value to decode/encode into
r io.Reader
w io.Writer
b []byte
mh codec.MsgpackHandle
)
dec = codec.NewDecoder(r, &mh)
dec = codec.NewDecoderBytes(b, &mh)
err = dec.Decode(&v)
enc = codec.NewEncoder(w, &mh)
enc = codec.NewEncoderBytes(&b, &mh)
err = enc.Encode(v)
//RPC Server
go func() {
for {
conn, err := listener.Accept()
rpcCodec := codec.GoRpc.ServerCodec(conn, h)
//OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
rpc.ServeCodec(rpcCodec)
}
}()
//RPC Communication (client side)
conn, err = net.Dial("tcp", "localhost:5555")
rpcCodec := codec.GoRpc.ClientCodec(conn, h)
//OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
client := rpc.NewClientWithCodec(rpcCodec)
```