summaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go95
1 files changed, 63 insertions, 32 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
index 28bb91b53..2b795b5b8 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
@@ -19,9 +19,11 @@ package json
import (
"encoding/json"
"io"
+ "strconv"
+ "unsafe"
"github.com/ghodss/yaml"
- "github.com/ugorji/go/codec"
+ jsoniter "github.com/json-iterator/go"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -66,11 +68,59 @@ type Serializer struct {
var _ runtime.Serializer = &Serializer{}
var _ recognizer.RecognizingDecoder = &Serializer{}
+func init() {
+ // Force jsoniter to decode number to interface{} via ints, if possible.
+ decodeNumberAsInt64IfPossible := func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
+ switch iter.WhatIsNext() {
+ case jsoniter.NumberValue:
+ var number json.Number
+ iter.ReadVal(&number)
+ u64, err := strconv.ParseUint(string(number), 10, 64)
+ if err == nil {
+ *(*interface{})(ptr) = u64
+ return
+ }
+ i64, err := strconv.ParseInt(string(number), 10, 64)
+ if err == nil {
+ *(*interface{})(ptr) = i64
+ return
+ }
+ f64, err := strconv.ParseFloat(string(number), 64)
+ if err == nil {
+ *(*interface{})(ptr) = f64
+ return
+ }
+ // Not much we can do here.
+ default:
+ *(*interface{})(ptr) = iter.Read()
+ }
+ }
+ jsoniter.RegisterTypeDecoderFunc("interface {}", decodeNumberAsInt64IfPossible)
+}
+
+// gvkWithDefaults returns group kind and version defaulting from provided default
+func gvkWithDefaults(actual, defaultGVK schema.GroupVersionKind) schema.GroupVersionKind {
+ if len(actual.Kind) == 0 {
+ actual.Kind = defaultGVK.Kind
+ }
+ if len(actual.Version) == 0 && len(actual.Group) == 0 {
+ actual.Group = defaultGVK.Group
+ actual.Version = defaultGVK.Version
+ }
+ if len(actual.Version) == 0 && actual.Group == defaultGVK.Group {
+ actual.Version = defaultGVK.Version
+ }
+ return actual
+}
+
// Decode attempts to convert the provided data into YAML or JSON, extract the stored schema kind, apply the provided default gvk, and then
-// load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown, the raw data will be
-// extracted and no decoding will be performed. If into is not registered with the typer, then the object will be straight decoded using
-// normal JSON/YAML unmarshalling. If into is provided and the original data is not fully qualified with kind/version/group, the type of
-// the into will be used to alter the returned gvk. On success or most errors, the method will return the calculated schema kind.
+// load that data into an object matching the desired schema kind or the provided into.
+// If into is *runtime.Unknown, the raw data will be extracted and no decoding will be performed.
+// If into is not registered with the typer, then the object will be straight decoded using normal JSON/YAML unmarshalling.
+// If into is provided and the original data is not fully qualified with kind/version/group, the type of the into will be used to alter the returned gvk.
+// If into is nil or data's gvk different from into's gvk, it will generate a new Object with ObjectCreater.New(gvk)
+// On success or most errors, the method will return the calculated schema kind.
+// The gvk calculate priority will be originalData > default gvk > into
func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
if versioned, ok := into.(*runtime.VersionedObjects); ok {
into = versioned.Last()
@@ -97,17 +147,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
}
if gvk != nil {
- // apply kind and version defaulting from provided default
- if len(actual.Kind) == 0 {
- actual.Kind = gvk.Kind
- }
- if len(actual.Version) == 0 && len(actual.Group) == 0 {
- actual.Group = gvk.Group
- actual.Version = gvk.Version
- }
- if len(actual.Version) == 0 && actual.Group == gvk.Group {
- actual.Version = gvk.Version
- }
+ *actual = gvkWithDefaults(*actual, *gvk)
}
if unk, ok := into.(*runtime.Unknown); ok && unk != nil {
@@ -118,27 +158,18 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
}
if into != nil {
+ _, isUnstructured := into.(runtime.Unstructured)
types, _, err := s.typer.ObjectKinds(into)
switch {
- case runtime.IsNotRegisteredError(err):
- if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(into); err != nil {
+ case runtime.IsNotRegisteredError(err), isUnstructured:
+ if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(data, into); err != nil {
return nil, actual, err
}
return into, actual, nil
case err != nil:
return nil, actual, err
default:
- typed := types[0]
- if len(actual.Kind) == 0 {
- actual.Kind = typed.Kind
- }
- if len(actual.Version) == 0 && len(actual.Group) == 0 {
- actual.Group = typed.Group
- actual.Version = typed.Version
- }
- if len(actual.Version) == 0 && actual.Group == typed.Group {
- actual.Version = typed.Version
- }
+ *actual = gvkWithDefaults(*actual, types[0])
}
}
@@ -155,7 +186,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
return nil, actual, err
}
- if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
+ if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(data, obj); err != nil {
return nil, actual, err
}
return obj, actual, nil
@@ -164,7 +195,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
// Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
if s.yaml {
- json, err := json.Marshal(obj)
+ json, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(obj)
if err != nil {
return err
}
@@ -177,7 +208,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
}
if s.pretty {
- data, err := json.MarshalIndent(obj, "", " ")
+ data, err := jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent(obj, "", " ")
if err != nil {
return err
}