replace zxq.co/ripple/hanayo
This commit is contained in:
544
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
Normal file
544
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
Normal file
@@ -0,0 +1,544 @@
|
||||
// +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 fast-path.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
// Fast path functions try to create a fast path encode or decode implementation
|
||||
// for common maps and slices.
|
||||
//
|
||||
// We define the functions and register then in this single file
|
||||
// so as not to pollute the encode.go and decode.go, and create a dependency in there.
|
||||
// This file can be omitted without causing a build failure.
|
||||
//
|
||||
// The advantage of fast paths is:
|
||||
// - Many calls bypass reflection altogether
|
||||
//
|
||||
// Currently support
|
||||
// - slice of all builtin types,
|
||||
// - map of all builtin types to string or interface value
|
||||
// - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
|
||||
// This should provide adequate "typical" implementations.
|
||||
//
|
||||
// Note that fast track decode functions must handle values for which an address cannot be obtained.
|
||||
// For example:
|
||||
// m2 := map[string]int{}
|
||||
// p2 := []interface{}{m2}
|
||||
// // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
|
||||
//
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const fastpathEnabled = true
|
||||
|
||||
type fastpathT struct {}
|
||||
|
||||
var fastpathTV fastpathT
|
||||
|
||||
type fastpathE struct {
|
||||
rtid uintptr
|
||||
rt reflect.Type
|
||||
encfn func(*Encoder, *codecFnInfo, reflect.Value)
|
||||
decfn func(*Decoder, *codecFnInfo, reflect.Value)
|
||||
}
|
||||
|
||||
type fastpathA [{{ .FastpathLen }}]fastpathE
|
||||
|
||||
func (x *fastpathA) index(rtid uintptr) int {
|
||||
// use binary search to grab the index (adapted from sort/search.go)
|
||||
h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
|
||||
for i < j {
|
||||
h = i + (j-i)/2
|
||||
if x[h].rtid < rtid {
|
||||
i = h + 1
|
||||
} else {
|
||||
j = h
|
||||
}
|
||||
}
|
||||
if i < {{ .FastpathLen }} && x[i].rtid == rtid {
|
||||
return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
type fastpathAslice []fastpathE
|
||||
|
||||
func (x fastpathAslice) Len() int { return len(x) }
|
||||
func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
|
||||
func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
var fastpathAV fastpathA
|
||||
|
||||
// due to possible initialization loop error, make fastpath in an init()
|
||||
func init() {
|
||||
i := 0
|
||||
fn := func(v interface{},
|
||||
fe func(*Encoder, *codecFnInfo, reflect.Value),
|
||||
fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
|
||||
xrt := reflect.TypeOf(v)
|
||||
xptr := rt2id(xrt)
|
||||
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
|
||||
i++
|
||||
return
|
||||
}
|
||||
{{/* 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 .MapKey }}
|
||||
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
|
||||
|
||||
sort.Sort(fastpathAslice(fastpathAV[:]))
|
||||
}
|
||||
|
||||
// -- encode
|
||||
|
||||
// -- -- fast path type switch
|
||||
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
|
||||
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 }}
|
||||
case []{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||
case *[]{{ .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
|
||||
}
|
||||
|
||||
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
|
||||
switch v := iv.(type) {
|
||||
{{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 ****
|
||||
*/}}
|
||||
|
||||
// -- -- fast path functions
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if f.ti.mbs {
|
||||
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
||||
} else {
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
||||
}
|
||||
}
|
||||
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.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 {
|
||||
if esep { ee.WriteArrayElem() }
|
||||
{{ encmd .Elem "v2"}}
|
||||
} */}}
|
||||
ee.WriteArrayEnd()
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
|
||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||
if len(v)%2 == 1 {
|
||||
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
|
||||
return
|
||||
}
|
||||
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 {
|
||||
if esep {
|
||||
if j%2 == 0 {
|
||||
ee.WriteMapElemKey()
|
||||
} else {
|
||||
ee.WriteMapElemValue()
|
||||
}
|
||||
}
|
||||
{{ encmd .Elem "v2"}}
|
||||
} */}}
|
||||
ee.WriteMapEnd()
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
|
||||
}
|
||||
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.WriteMapStart(len(v))
|
||||
if e.h.Canonical {
|
||||
{{if eq .MapKey "interface{}"}}{{/* out of band
|
||||
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
|
||||
e2 := NewEncoderBytes(&mksv, e.hh)
|
||||
v2 := make([]bytesI, len(v))
|
||||
var i, l int
|
||||
var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
|
||||
for k2, _ := range v {
|
||||
l = len(mksv)
|
||||
e2.MustEncode(k2)
|
||||
vp = &v2[i]
|
||||
vp.v = mksv[l:]
|
||||
vp.i = k2
|
||||
i++
|
||||
}
|
||||
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 {
|
||||
if esep { ee.WriteMapElemKey() }
|
||||
e.asis(v2[j].v)
|
||||
if esep { ee.WriteMapElemValue() }
|
||||
e.encode(v[v2[j].i])
|
||||
} */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
|
||||
var i int
|
||||
for k, _ := range v {
|
||||
v2[i] = {{ $x }}(k)
|
||||
i++
|
||||
}
|
||||
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 {
|
||||
if esep { ee.WriteMapElemKey() }
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||
if esep { ee.WriteMapElemValue() }
|
||||
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||
} */}} {{end}}
|
||||
} else {
|
||||
if esep {
|
||||
for k2, v2 := range v {
|
||||
ee.WriteMapElemKey()
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||
ee.WriteMapElemValue()
|
||||
{{ 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()
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
// -- decode
|
||||
|
||||
// -- -- fast path type switch
|
||||
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
|
||||
var changed bool
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||
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)
|
||||
}
|
||||
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:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
case *[]{{ .Elem }}:
|
||||
*v = nil {{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||
*v = nil {{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// -- -- fast path functions
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
{{/*
|
||||
Slices can change if they
|
||||
- did not come from an array
|
||||
- are addressable (from a ptr)
|
||||
- are settable (e.g. contained in an interface{})
|
||||
*/}}
|
||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
|
||||
vp := rv2i(rv).(*[]{{ .Elem }})
|
||||
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
|
||||
if changed { *vp = v }
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
|
||||
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
|
||||
if changed { *vp = v }
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
||||
dd := d.d{{/*
|
||||
// if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
|
||||
*/}}
|
||||
slh, containerLenS := d.decSliceHelperStart()
|
||||
if containerLenS == 0 {
|
||||
if canChange {
|
||||
if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
|
||||
changed = true
|
||||
}
|
||||
slh.End()
|
||||
return v, changed
|
||||
}
|
||||
hasLen := containerLenS > 0
|
||||
var xlen int
|
||||
if hasLen && canChange {
|
||||
if containerLenS > cap(v) {
|
||||
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
||||
if xlen <= cap(v) {
|
||||
v = v[:xlen]
|
||||
} else {
|
||||
v = make([]{{ .Elem }}, xlen)
|
||||
}
|
||||
changed = true
|
||||
} else if containerLenS != len(v) {
|
||||
v = v[:containerLenS]
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
j := 0
|
||||
for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
|
||||
if j == 0 && len(v) == 0 && canChange {
|
||||
if hasLen {
|
||||
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
||||
} else {
|
||||
xlen = 8
|
||||
}
|
||||
v = make([]{{ .Elem }}, xlen)
|
||||
changed = true
|
||||
}
|
||||
// if indefinite, etc, then expand the slice if necessary
|
||||
var decodeIntoBlank bool
|
||||
if j >= len(v) {
|
||||
if canChange {
|
||||
v = append(v, {{ zerocmd .Elem }})
|
||||
changed = true
|
||||
} else {
|
||||
d.arrayCannotExpand(len(v), j+1)
|
||||
decodeIntoBlank = true
|
||||
}
|
||||
}
|
||||
slh.ElemContainerState(j)
|
||||
if decodeIntoBlank {
|
||||
d.swallow()
|
||||
} else if dd.TryDecodeAsNil() {
|
||||
v[j] = {{ zerocmd .Elem }}
|
||||
} else {
|
||||
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
|
||||
}
|
||||
}
|
||||
if canChange {
|
||||
if j < len(v) {
|
||||
v = v[:j]
|
||||
changed = true
|
||||
} else if j == 0 && v == nil {
|
||||
v = make([]{{ .Elem }}, 0)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
slh.End()
|
||||
return v, changed
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
{{/*
|
||||
Maps can change if they are
|
||||
- addressable (from a ptr)
|
||||
- settable (e.g. contained in an interface{})
|
||||
*/}}
|
||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if rv.Kind() == reflect.Ptr {
|
||||
vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
|
||||
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
|
||||
if changed { *vp = v }
|
||||
} else {
|
||||
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) {
|
||||
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,
|
||||
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
||||
dd, esep := d.d, d.hh.hasElemSeparators(){{/*
|
||||
// if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
|
||||
*/}}
|
||||
containerLen := dd.ReadMapStart()
|
||||
if canChange && v == nil {
|
||||
xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
|
||||
v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
|
||||
changed = true
|
||||
}
|
||||
if containerLen == 0 {
|
||||
dd.ReadMapEnd()
|
||||
return v, changed
|
||||
}
|
||||
{{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
|
||||
{{end}}var mk {{ .MapKey }}
|
||||
var mv {{ .Elem }}
|
||||
hasLen := containerLen > 0
|
||||
for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
|
||||
if esep { dd.ReadMapElemKey() }
|
||||
{{ if eq .MapKey "interface{}" }}mk = nil
|
||||
d.decode(&mk)
|
||||
if bv, bok := mk.([]byte); bok {
|
||||
mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
|
||||
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
|
||||
if esep { dd.ReadMapElemValue() }
|
||||
if dd.TryDecodeAsNil() {
|
||||
if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
|
||||
continue
|
||||
}
|
||||
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
|
||||
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
|
||||
if v != nil { v[mk] = mv }
|
||||
}
|
||||
dd.ReadMapEnd()
|
||||
return v, changed
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
Reference in New Issue
Block a user