http urls monitor.

fast-path.go.tmpl 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // +build !notfastpath
  2. // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
  3. // Use of this source code is governed by a MIT license found in the LICENSE file.
  4. // Code generated from fast-path.go.tmpl - DO NOT EDIT.
  5. package codec
  6. // Fast path functions try to create a fast path encode or decode implementation
  7. // for common maps and slices.
  8. //
  9. // We define the functions and register then in this single file
  10. // so as not to pollute the encode.go and decode.go, and create a dependency in there.
  11. // This file can be omitted without causing a build failure.
  12. //
  13. // The advantage of fast paths is:
  14. // - Many calls bypass reflection altogether
  15. //
  16. // Currently support
  17. // - slice of all builtin types,
  18. // - map of all builtin types to string or interface value
  19. // - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
  20. // This should provide adequate "typical" implementations.
  21. //
  22. // Note that fast track decode functions must handle values for which an address cannot be obtained.
  23. // For example:
  24. // m2 := map[string]int{}
  25. // p2 := []interface{}{m2}
  26. // // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
  27. //
  28. import (
  29. "reflect"
  30. "sort"
  31. )
  32. const fastpathEnabled = true
  33. type fastpathT struct {}
  34. var fastpathTV fastpathT
  35. type fastpathE struct {
  36. rtid uintptr
  37. rt reflect.Type
  38. encfn func(*Encoder, *codecFnInfo, reflect.Value)
  39. decfn func(*Decoder, *codecFnInfo, reflect.Value)
  40. }
  41. type fastpathA [{{ .FastpathLen }}]fastpathE
  42. func (x *fastpathA) index(rtid uintptr) int {
  43. // use binary search to grab the index (adapted from sort/search.go)
  44. h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
  45. for i < j {
  46. h = i + (j-i)/2
  47. if x[h].rtid < rtid {
  48. i = h + 1
  49. } else {
  50. j = h
  51. }
  52. }
  53. if i < {{ .FastpathLen }} && x[i].rtid == rtid {
  54. return i
  55. }
  56. return -1
  57. }
  58. type fastpathAslice []fastpathE
  59. func (x fastpathAslice) Len() int { return len(x) }
  60. func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
  61. func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  62. var fastpathAV fastpathA
  63. // due to possible initialization loop error, make fastpath in an init()
  64. func init() {
  65. i := 0
  66. fn := func(v interface{},
  67. fe func(*Encoder, *codecFnInfo, reflect.Value),
  68. fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
  69. xrt := reflect.TypeOf(v)
  70. xptr := rt2id(xrt)
  71. fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
  72. i++
  73. return
  74. }
  75. {{/* do not register []uint8 in fast-path */}}
  76. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
  77. fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
  78. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  79. fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
  80. sort.Sort(fastpathAslice(fastpathAV[:]))
  81. }
  82. // -- encode
  83. // -- -- fast path type switch
  84. func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
  85. switch v := iv.(type) {
  86. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
  87. case []{{ .Elem }}:
  88. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
  89. case *[]{{ .Elem }}:
  90. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
  91. */}}{{end}}{{end}}{{end}}{{end}}
  92. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  93. case map[{{ .MapKey }}]{{ .Elem }}:
  94. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
  95. case *map[{{ .MapKey }}]{{ .Elem }}:
  96. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
  97. */}}{{end}}{{end}}{{end}}
  98. default:
  99. _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
  100. return false
  101. }
  102. return true
  103. }
  104. {{/*
  105. **** removing this block, as they are never called directly ****
  106. **** removing this block, as they are never called directly ****
  107. func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
  108. switch v := iv.(type) {
  109. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
  110. case []{{ .Elem }}:
  111. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
  112. case *[]{{ .Elem }}:
  113. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
  114. {{end}}{{end}}{{end}}
  115. default:
  116. _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
  117. return false
  118. }
  119. return true
  120. }
  121. func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
  122. switch v := iv.(type) {
  123. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  124. case map[{{ .MapKey }}]{{ .Elem }}:
  125. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
  126. case *map[{{ .MapKey }}]{{ .Elem }}:
  127. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
  128. {{end}}{{end}}{{end}}
  129. default:
  130. _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
  131. return false
  132. }
  133. return true
  134. }
  135. **** removing this block, as they are never called directly ****
  136. **** removing this block, as they are never called directly ****
  137. */}}
  138. // -- -- fast path functions
  139. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
  140. func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
  141. if f.ti.mbs {
  142. fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
  143. } else {
  144. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).([]{{ .Elem }}), e)
  145. }
  146. }
  147. func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
  148. if v == nil { e.e.EncodeNil(); return }
  149. ee, esep := e.e, e.hh.hasElemSeparators()
  150. ee.WriteArrayStart(len(v))
  151. if esep {
  152. for _, v2 := range v {
  153. ee.WriteArrayElem()
  154. {{ encmd .Elem "v2"}}
  155. }
  156. } else {
  157. for _, v2 := range v {
  158. {{ encmd .Elem "v2"}}
  159. }
  160. } {{/*
  161. for _, v2 := range v {
  162. if esep { ee.WriteArrayElem() }
  163. {{ encmd .Elem "v2"}}
  164. } */}}
  165. ee.WriteArrayEnd()
  166. }
  167. func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
  168. ee, esep := e.e, e.hh.hasElemSeparators()
  169. if len(v)%2 == 1 {
  170. e.errorf("mapBySlice requires even slice length, but got %v", len(v))
  171. return
  172. }
  173. ee.WriteMapStart(len(v) / 2)
  174. if esep {
  175. for j, v2 := range v {
  176. if j%2 == 0 {
  177. ee.WriteMapElemKey()
  178. } else {
  179. ee.WriteMapElemValue()
  180. }
  181. {{ encmd .Elem "v2"}}
  182. }
  183. } else {
  184. for _, v2 := range v {
  185. {{ encmd .Elem "v2"}}
  186. }
  187. } {{/*
  188. for j, v2 := range v {
  189. if esep {
  190. if j%2 == 0 {
  191. ee.WriteMapElemKey()
  192. } else {
  193. ee.WriteMapElemValue()
  194. }
  195. }
  196. {{ encmd .Elem "v2"}}
  197. } */}}
  198. ee.WriteMapEnd()
  199. }
  200. {{end}}{{end}}{{end}}
  201. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  202. func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
  203. fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
  204. }
  205. func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
  206. if v == nil { e.e.EncodeNil(); return }
  207. ee, esep := e.e, e.hh.hasElemSeparators()
  208. ee.WriteMapStart(len(v))
  209. if e.h.Canonical {
  210. {{if eq .MapKey "interface{}"}}{{/* out of band
  211. */}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
  212. e2 := NewEncoderBytes(&mksv, e.hh)
  213. v2 := make([]bytesI, len(v))
  214. var i, l int
  215. var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
  216. for k2, _ := range v {
  217. l = len(mksv)
  218. e2.MustEncode(k2)
  219. vp = &v2[i]
  220. vp.v = mksv[l:]
  221. vp.i = k2
  222. i++
  223. }
  224. sort.Sort(bytesISlice(v2))
  225. if esep {
  226. for j := range v2 {
  227. ee.WriteMapElemKey()
  228. e.asis(v2[j].v)
  229. ee.WriteMapElemValue()
  230. e.encode(v[v2[j].i])
  231. }
  232. } else {
  233. for j := range v2 {
  234. e.asis(v2[j].v)
  235. e.encode(v[v2[j].i])
  236. }
  237. } {{/*
  238. for j := range v2 {
  239. if esep { ee.WriteMapElemKey() }
  240. e.asis(v2[j].v)
  241. if esep { ee.WriteMapElemValue() }
  242. e.encode(v[v2[j].i])
  243. } */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
  244. var i int
  245. for k, _ := range v {
  246. v2[i] = {{ $x }}(k)
  247. i++
  248. }
  249. sort.Sort({{ sorttype .MapKey false}}(v2))
  250. if esep {
  251. for _, k2 := range v2 {
  252. ee.WriteMapElemKey()
  253. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
  254. ee.WriteMapElemValue()
  255. {{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
  256. }
  257. } else {
  258. for _, k2 := range v2 {
  259. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
  260. {{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
  261. }
  262. } {{/*
  263. for _, k2 := range v2 {
  264. if esep { ee.WriteMapElemKey() }
  265. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
  266. if esep { ee.WriteMapElemValue() }
  267. {{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
  268. } */}} {{end}}
  269. } else {
  270. if esep {
  271. for k2, v2 := range v {
  272. ee.WriteMapElemKey()
  273. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
  274. ee.WriteMapElemValue()
  275. {{ encmd .Elem "v2"}}
  276. }
  277. } else {
  278. for k2, v2 := range v {
  279. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
  280. {{ encmd .Elem "v2"}}
  281. }
  282. } {{/*
  283. for k2, v2 := range v {
  284. if esep { ee.WriteMapElemKey() }
  285. {{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
  286. if esep { ee.WriteMapElemValue() }
  287. {{ encmd .Elem "v2"}}
  288. } */}}
  289. }
  290. ee.WriteMapEnd()
  291. }
  292. {{end}}{{end}}{{end}}
  293. // -- decode
  294. // -- -- fast path type switch
  295. func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
  296. var changed bool
  297. switch v := iv.(type) {
  298. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
  299. case []{{ .Elem }}:
  300. var v2 []{{ .Elem }}
  301. v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
  302. if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
  303. copy(v, v2)
  304. }
  305. case *[]{{ .Elem }}:
  306. var v2 []{{ .Elem }}
  307. v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
  308. if changed {
  309. *v = v2
  310. }{{/*
  311. */}}{{end}}{{end}}{{end}}{{end}}
  312. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
  313. // maps only change if nil, and in that case, there's no point copying
  314. */}}
  315. case map[{{ .MapKey }}]{{ .Elem }}:
  316. fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
  317. case *map[{{ .MapKey }}]{{ .Elem }}:
  318. var v2 map[{{ .MapKey }}]{{ .Elem }}
  319. v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
  320. if changed {
  321. *v = v2
  322. }{{/*
  323. */}}{{end}}{{end}}{{end}}
  324. default:
  325. _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
  326. return false
  327. }
  328. return true
  329. }
  330. func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
  331. switch v := iv.(type) {
  332. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
  333. case *[]{{ .Elem }}:
  334. *v = nil {{/*
  335. */}}{{end}}{{end}}{{end}}
  336. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  337. case *map[{{ .MapKey }}]{{ .Elem }}:
  338. *v = nil {{/*
  339. */}}{{end}}{{end}}{{end}}
  340. default:
  341. _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
  342. return false
  343. }
  344. return true
  345. }
  346. // -- -- fast path functions
  347. {{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
  348. {{/*
  349. Slices can change if they
  350. - did not come from an array
  351. - are addressable (from a ptr)
  352. - are settable (e.g. contained in an interface{})
  353. */}}
  354. func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
  355. if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
  356. vp := rv2i(rv).(*[]{{ .Elem }})
  357. v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
  358. if changed { *vp = v }
  359. } else {
  360. v := rv2i(rv).([]{{ .Elem }})
  361. v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
  362. if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
  363. copy(v, v2)
  364. }
  365. }
  366. }
  367. func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
  368. v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
  369. if changed { *vp = v }
  370. }
  371. func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
  372. dd := d.d{{/*
  373. // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
  374. */}}
  375. slh, containerLenS := d.decSliceHelperStart()
  376. if containerLenS == 0 {
  377. if canChange {
  378. if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
  379. changed = true
  380. }
  381. slh.End()
  382. return v, changed
  383. }
  384. hasLen := containerLenS > 0
  385. var xlen int
  386. if hasLen && canChange {
  387. if containerLenS > cap(v) {
  388. xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
  389. if xlen <= cap(v) {
  390. v = v[:xlen]
  391. } else {
  392. v = make([]{{ .Elem }}, xlen)
  393. }
  394. changed = true
  395. } else if containerLenS != len(v) {
  396. v = v[:containerLenS]
  397. changed = true
  398. }
  399. }
  400. j := 0
  401. for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
  402. if j == 0 && len(v) == 0 && canChange {
  403. if hasLen {
  404. xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
  405. } else {
  406. xlen = 8
  407. }
  408. v = make([]{{ .Elem }}, xlen)
  409. changed = true
  410. }
  411. // if indefinite, etc, then expand the slice if necessary
  412. var decodeIntoBlank bool
  413. if j >= len(v) {
  414. if canChange {
  415. v = append(v, {{ zerocmd .Elem }})
  416. changed = true
  417. } else {
  418. d.arrayCannotExpand(len(v), j+1)
  419. decodeIntoBlank = true
  420. }
  421. }
  422. slh.ElemContainerState(j)
  423. if decodeIntoBlank {
  424. d.swallow()
  425. } else if dd.TryDecodeAsNil() {
  426. v[j] = {{ zerocmd .Elem }}
  427. } else {
  428. {{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
  429. }
  430. }
  431. if canChange {
  432. if j < len(v) {
  433. v = v[:j]
  434. changed = true
  435. } else if j == 0 && v == nil {
  436. v = make([]{{ .Elem }}, 0)
  437. changed = true
  438. }
  439. }
  440. slh.End()
  441. return v, changed
  442. }
  443. {{end}}{{end}}{{end}}
  444. {{range .Values}}{{if not .Primitive}}{{if .MapKey }}
  445. {{/*
  446. Maps can change if they are
  447. - addressable (from a ptr)
  448. - settable (e.g. contained in an interface{})
  449. */}}
  450. func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
  451. if rv.Kind() == reflect.Ptr {
  452. vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
  453. v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
  454. if changed { *vp = v }
  455. } else {
  456. fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
  457. }
  458. }
  459. func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
  460. v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
  461. if changed { *vp = v }
  462. }
  463. func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
  464. d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
  465. dd, esep := d.d, d.hh.hasElemSeparators(){{/*
  466. // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
  467. */}}
  468. containerLen := dd.ReadMapStart()
  469. if canChange && v == nil {
  470. xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
  471. v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
  472. changed = true
  473. }
  474. if containerLen == 0 {
  475. dd.ReadMapEnd()
  476. return v, changed
  477. }
  478. {{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
  479. {{end}}var mk {{ .MapKey }}
  480. var mv {{ .Elem }}
  481. hasLen := containerLen > 0
  482. for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
  483. if esep { dd.ReadMapElemKey() }
  484. {{ if eq .MapKey "interface{}" }}mk = nil
  485. d.decode(&mk)
  486. if bv, bok := mk.([]byte); bok {
  487. mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
  488. }{{ else }}mk = {{ decmd .MapKey }}{{ end }}
  489. if esep { dd.ReadMapElemValue() }
  490. if dd.TryDecodeAsNil() {
  491. if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
  492. continue
  493. }
  494. {{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
  495. d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
  496. if v != nil { v[mk] = mv }
  497. }
  498. dd.ReadMapEnd()
  499. return v, changed
  500. }
  501. {{end}}{{end}}{{end}}