|
@@ -95,11 +95,13 @@ func init() {
|
|
|
i++
|
|
i++
|
|
|
}
|
|
}
|
|
|
{{/* do not register []uint8 in fast-path */}}
|
|
{{/* do not register []uint8 in fast-path */}}
|
|
|
- {{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}}{{end}}
|
|
|
|
|
|
|
+ {{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}}{{end}}
|
|
|
|
|
|
|
|
- {{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}}
|
|
|
|
|
|
|
+ {{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}}
|
|
|
|
|
|
|
|
sort.Sort(fastpathAslice(fastpathAV[:]))
|
|
sort.Sort(fastpathAslice(fastpathAV[:]))
|
|
|
}
|
|
}
|
|
@@ -109,60 +111,20 @@ 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 }}{{if ne .Elem "uint8"}}
|
|
|
|
|
- case []{{ .Elem }}:
|
|
|
|
|
- fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
|
|
|
|
- case *[]{{ .Elem }}:
|
|
|
|
|
- fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
|
|
|
|
|
-*/}}{{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:
|
|
|
|
|
- _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
|
|
|
- return false
|
|
|
|
|
- }
|
|
|
|
|
- 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 {
|
|
|
|
|
- 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 }}:
|
|
case []{{ .Elem }}:
|
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
|
|
case *[]{{ .Elem }}:
|
|
case *[]{{ .Elem }}:
|
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
|
|
-{{end}}{{end}}{{end}}
|
|
|
|
|
- default:
|
|
|
|
|
- _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
|
|
|
- return false
|
|
|
|
|
- }
|
|
|
|
|
- return true
|
|
|
|
|
-}
|
|
|
|
|
|
|
+{{end}}{{end}}{{end}}{{end -}}
|
|
|
|
|
|
|
|
-func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
|
|
|
|
|
- switch v := iv.(type) {
|
|
|
|
|
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
|
|
|
|
|
|
+{{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
|
|
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
|
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
|
|
-{{end}}{{end}}{{end}}
|
|
|
|
|
|
|
+{{end}}{{end}}{{end -}}
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
|
return false
|
|
return false
|
|
@@ -170,17 +132,8 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
|
|
|
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)
|
|
@@ -218,9 +171,9 @@ func (fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Enco
|
|
|
e.mapEnd()
|
|
e.mapEnd()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-{{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)
|
|
|
}
|
|
}
|
|
@@ -271,40 +224,36 @@ func (fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem
|
|
|
}
|
|
}
|
|
|
e.mapEnd()
|
|
e.mapEnd()
|
|
|
}
|
|
}
|
|
|
-{{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
|
|
|
|
|
|
|
+ var changed bool
|
|
|
|
|
+ var containerLen int
|
|
|
switch v := iv.(type) {
|
|
switch v := iv.(type) {
|
|
|
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
|
|
|
|
|
|
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8" -}}
|
|
|
case []{{ .Elem }}:
|
|
case []{{ .Elem }}:
|
|
|
- var v2 []{{ .Elem }}
|
|
|
|
|
- v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
|
|
|
|
- if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
|
|
|
|
|
- copy(v, v2)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}N(v, d)
|
|
|
case *[]{{ .Elem }}:
|
|
case *[]{{ .Elem }}:
|
|
|
var v2 []{{ .Elem }}
|
|
var v2 []{{ .Elem }}
|
|
|
- v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
|
|
|
|
|
- if changed {
|
|
|
|
|
|
|
+ if v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}Y(*v, d); changed {
|
|
|
*v = v2
|
|
*v = v2
|
|
|
- }{{/*
|
|
|
|
|
-*/}}{{end}}{{end}}{{end}}{{end}}
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+{{end}}{{end}}{{end}}{{end -}}
|
|
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
|
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
|
|
|
// maps only change if nil, and in that case, there's no point copying
|
|
// maps only change if nil, and in that case, there's no point copying
|
|
|
-*/}}
|
|
|
|
|
|
|
+*/ -}}
|
|
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
|
|
- fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
|
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}L(v, d.mapStart(), d)
|
|
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
|
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}}
|
|
|
|
|
|
|
+ containerLen = d.mapStart()
|
|
|
|
|
+ if *v == nil {
|
|
|
|
|
+ *v = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
|
|
|
|
|
+ }
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}L(*v, containerLen, d)
|
|
|
|
|
+{{end}}{{end}}{{end -}}
|
|
|
default:
|
|
default:
|
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
|
return false
|
|
return false
|
|
@@ -314,14 +263,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
|
|
|
|
|
|
|
|
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) 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 }}:
|
|
case *[]{{ .Elem }}:
|
|
|
- *v = nil {{/*
|
|
|
|
|
-*/}}{{end}}{{end}}{{end}}
|
|
|
|
|
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
|
|
|
|
|
|
+ *v = nil
|
|
|
|
|
+{{end}}{{end}}{{end}}
|
|
|
|
|
+{{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
|
|
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
|
|
- *v = nil {{/*
|
|
|
|
|
-*/}}{{end}}{{end}}{{end}}
|
|
|
|
|
|
|
+ *v = nil
|
|
|
|
|
+{{end}}{{end}}{{end}}
|
|
|
default:
|
|
default:
|
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
|
|
return false
|
|
return false
|
|
@@ -330,44 +279,37 @@ func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// -- -- fast path functions
|
|
// -- -- fast path functions
|
|
|
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
|
|
|
|
|
|
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
|
|
|
{{/*
|
|
{{/*
|
|
|
-Slices can change if they
|
|
|
|
|
|
|
+Slices can change if they
|
|
|
- did not come from an array
|
|
- did not come from an array
|
|
|
- are addressable (from a ptr)
|
|
- are addressable (from a ptr)
|
|
|
- are settable (e.g. contained in an interface{})
|
|
- are settable (e.g. contained in an interface{})
|
|
|
*/}}
|
|
*/}}
|
|
|
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 f.seq != seqTypeArray && rv.Kind() == reflect.Ptr {
|
|
|
vp := rv2i(rv).(*[]{{ .Elem }})
|
|
vp := rv2i(rv).(*[]{{ .Elem }})
|
|
|
- if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d); changed { *vp = v }
|
|
|
|
|
|
|
+ if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}Y(*vp, d); changed { *vp = v }
|
|
|
} else {
|
|
} else {
|
|
|
- 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)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}N(rv2i(rv).([]{{ .Elem }}), d)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
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 { *vp = v }
|
|
|
|
|
|
|
+ if v, changed := f.{{ .MethodNamePfx "Dec" false }}Y(*vp, d); changed { *vp = v }
|
|
|
}
|
|
}
|
|
|
-func (fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
|
|
|
|
|
|
+func (fastpathT) {{ .MethodNamePfx "Dec" false }}Y(v []{{ .Elem }}, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
|
|
{{/* dd := d.d
|
|
{{/* dd := d.d
|
|
|
// if d.d.isContainerType(valueTypeNil) { d.d.TryDecodeAsNil() }
|
|
// if d.d.isContainerType(valueTypeNil) { d.d.TryDecodeAsNil() }
|
|
|
*/ -}}
|
|
*/ -}}
|
|
|
slh, containerLenS := d.decSliceHelperStart()
|
|
slh, containerLenS := d.decSliceHelperStart()
|
|
|
if containerLenS == 0 {
|
|
if containerLenS == 0 {
|
|
|
- if canChange {
|
|
|
|
|
- if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
|
|
|
|
|
- changed = true
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
|
|
|
slh.End()
|
|
slh.End()
|
|
|
- return v, changed
|
|
|
|
|
|
|
+ return v, true
|
|
|
}
|
|
}
|
|
|
hasLen := containerLenS > 0
|
|
hasLen := containerLenS > 0
|
|
|
var xlen int
|
|
var xlen int
|
|
|
- if hasLen && canChange {
|
|
|
|
|
|
|
+ if hasLen {
|
|
|
if containerLenS > cap(v) {
|
|
if containerLenS > cap(v) {
|
|
|
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
|
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
|
|
if xlen <= cap(v) {
|
|
if xlen <= cap(v) {
|
|
@@ -383,7 +325,7 @@ func (fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bo
|
|
|
}
|
|
}
|
|
|
var j int
|
|
var j int
|
|
|
for j = 0; (hasLen && j < containerLenS) || !(hasLen || d.d.CheckBreak()); j++ {
|
|
for j = 0; (hasLen && j < containerLenS) || !(hasLen || d.d.CheckBreak()); j++ {
|
|
|
- if j == 0 && len(v) == 0 && canChange {
|
|
|
|
|
|
|
+ if j == 0 && len(v) == 0 {
|
|
|
if hasLen {
|
|
if hasLen {
|
|
|
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
|
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
|
|
} else {
|
|
} else {
|
|
@@ -393,69 +335,104 @@ func (fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bo
|
|
|
changed = true
|
|
changed = true
|
|
|
}
|
|
}
|
|
|
{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
|
|
{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
|
|
|
- var decodeIntoBlank bool
|
|
|
|
|
if j >= len(v) {
|
|
if j >= len(v) {
|
|
|
- if canChange {
|
|
|
|
|
- v = append(v, {{ zerocmd .Elem }})
|
|
|
|
|
- changed = true
|
|
|
|
|
- } else {
|
|
|
|
|
- d.arrayCannotExpand(len(v), j+1)
|
|
|
|
|
- decodeIntoBlank = true
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ v = append(v, {{ zerocmd .Elem }})
|
|
|
|
|
+ changed = true
|
|
|
}
|
|
}
|
|
|
slh.ElemContainerState(j)
|
|
slh.ElemContainerState(j)
|
|
|
- if decodeIntoBlank {
|
|
|
|
|
- d.swallow()
|
|
|
|
|
- } else if d.d.TryDecodeAsNil() {
|
|
|
|
|
|
|
+ if d.d.TryDecodeAsNil() {
|
|
|
v[uint(j)] = {{ zerocmd .Elem }}
|
|
v[uint(j)] = {{ zerocmd .Elem }}
|
|
|
} else {
|
|
} else {
|
|
|
{{ if eq .Elem "interface{}" }}d.decode(&v[uint(j)]){{ else }}v[uint(j)] = {{ decmd .Elem }}{{ end }}
|
|
{{ if eq .Elem "interface{}" }}d.decode(&v[uint(j)]){{ else }}v[uint(j)] = {{ decmd .Elem }}{{ end }}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if canChange {
|
|
|
|
|
- if j < len(v) {
|
|
|
|
|
- v = v[:uint(j)]
|
|
|
|
|
- changed = true
|
|
|
|
|
- } else if j == 0 && v == nil {
|
|
|
|
|
- v = make([]{{ .Elem }}, 0)
|
|
|
|
|
- changed = true
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if j < len(v) {
|
|
|
|
|
+ v = v[:uint(j)]
|
|
|
|
|
+ changed = true
|
|
|
|
|
+ } else if j == 0 && v == nil {
|
|
|
|
|
+ v = []{{ .Elem }}{}
|
|
|
|
|
+ changed = true
|
|
|
}
|
|
}
|
|
|
slh.End()
|
|
slh.End()
|
|
|
return v, changed
|
|
return v, changed
|
|
|
}
|
|
}
|
|
|
-{{end}}{{end}}{{end}}
|
|
|
|
|
|
|
+func (fastpathT) {{ .MethodNamePfx "Dec" false }}N(v []{{ .Elem }}, d *Decoder) {
|
|
|
|
|
+ {{/* dd := d.d
|
|
|
|
|
+ // if d.d.isContainerType(valueTypeNil) { d.d.TryDecodeAsNil() }
|
|
|
|
|
+ */ -}}
|
|
|
|
|
+ slh, containerLenS := d.decSliceHelperStart()
|
|
|
|
|
+ if containerLenS == 0 {
|
|
|
|
|
+ slh.End()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ hasLen := containerLenS > 0
|
|
|
|
|
+ for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.d.CheckBreak()); j++ {
|
|
|
|
|
+ {{/* // if indefinite, etc, then expand the slice if necessary */ -}}
|
|
|
|
|
+ if j >= len(v) {
|
|
|
|
|
+ d.arrayCannotExpand(len(v), j+1)
|
|
|
|
|
+ slh.ElemContainerState(j)
|
|
|
|
|
+ d.swallow()
|
|
|
|
|
+ for ; (hasLen && j < containerLenS) || !(hasLen || d.d.CheckBreak()); j++ {
|
|
|
|
|
+ slh.ElemContainerState(j)
|
|
|
|
|
+ d.swallow()
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ slh.ElemContainerState(j)
|
|
|
|
|
+ if d.d.TryDecodeAsNil() {
|
|
|
|
|
+ v[uint(j)] = {{ zerocmd .Elem }}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ {{ if eq .Elem "interface{}" }}d.decode(&v[uint(j)]){{ else }}v[uint(j)] = {{ decmd .Elem }}{{ end }}
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ slh.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
|
|
|
- addressable (from a ptr)
|
|
- addressable (from a ptr)
|
|
|
- settable (e.g. contained in an interface{})
|
|
- settable (e.g. contained in an interface{})
|
|
|
-*/}}
|
|
|
|
|
|
|
+*/ -}}
|
|
|
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 d.d.isContainerType(valueTypeNil) {d.d.TryDecodeAsNil() */ -}}
|
|
|
|
|
+ containerLen := d.mapStart()
|
|
|
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 { *vp = v }
|
|
|
|
|
|
|
+ if *vp == nil {
|
|
|
|
|
+ *vp = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
|
|
|
|
|
+ }
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}L(*vp, containerLen, d)
|
|
|
} else {
|
|
} else {
|
|
|
- fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
|
|
|
|
|
|
|
+ fastpathTV.{{ .MethodNamePfx "Dec" false }}L(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), containerLen, d)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
|
|
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 }
|
|
|
|
|
|
|
+ containerLen := d.mapStart()
|
|
|
|
|
+ if *vp == nil {
|
|
|
|
|
+ *vp = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
|
|
|
|
|
+ }
|
|
|
|
|
+ f.{{ .MethodNamePfx "Dec" false }}L(*vp, containerLen, d)
|
|
|
}
|
|
}
|
|
|
-func (fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
|
|
|
|
|
- d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
|
|
|
|
- {{/*
|
|
|
|
|
- // if d.d.isContainerType(valueTypeNil) {d.d.TryDecodeAsNil()
|
|
|
|
|
- */ -}}
|
|
|
|
|
|
|
+{{/*
|
|
|
|
|
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}Y(v map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
|
|
containerLen := d.mapStart()
|
|
containerLen := d.mapStart()
|
|
|
- if canChange && v == nil {
|
|
|
|
|
|
|
+ if v == nil {
|
|
|
v = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
|
|
v = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
|
|
|
changed = true
|
|
changed = true
|
|
|
}
|
|
}
|
|
|
|
|
+ f.{{ .MethodNamePfx "Dec" false }}L(v, containerLen, d)
|
|
|
|
|
+ return v, changed
|
|
|
|
|
+}
|
|
|
|
|
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}N(v map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
|
|
|
|
|
+ f.{{ .MethodNamePfx "Dec" false }}L(v, d.mapStart(), d)
|
|
|
|
|
+}
|
|
|
|
|
+*/ -}}
|
|
|
|
|
+func (fastpathT) {{ .MethodNamePfx "Dec" false }}L(v map[{{ .MapKey }}]{{ .Elem }}, containerLen int, d *Decoder) {
|
|
|
if containerLen == 0 {
|
|
if containerLen == 0 {
|
|
|
d.mapEnd()
|
|
d.mapEnd()
|
|
|
- return v, changed
|
|
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
{{if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
|
|
{{if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
|
|
|
{{else if eq .Elem "bytes" "[]byte" }}mapGet := v != nil && !d.h.MapValueReset
|
|
{{else if eq .Elem "bytes" "[]byte" }}mapGet := v != nil && !d.h.MapValueReset
|
|
@@ -488,6 +465,5 @@ func (fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem
|
|
|
if v != nil { v[mk] = mv }
|
|
if v != nil { v[mk] = mv }
|
|
|
}
|
|
}
|
|
|
d.mapEnd()
|
|
d.mapEnd()
|
|
|
- return v, changed
|
|
|
|
|
}
|
|
}
|
|
|
{{end}}{{end}}{{end}}
|
|
{{end}}{{end}}{{end}}
|