in map.go [163:228]
func (d *Decoder) decMapByValue(value reflect.Value) error {
var (
tag byte
err error
entryKey interface{}
entryValue interface{}
)
// tag, _ = d.readBufByte()
tag, err = d.ReadByte()
// check error
if err != nil {
return perrors.WithStack(err)
}
switch tag {
case BC_NULL:
// null map tag check
return nil
case BC_REF:
refObj, decErr := d.decRef(int32(tag))
if decErr != nil {
return perrors.WithStack(decErr)
}
SetValue(value, EnsurePackValue(refObj))
return nil
case BC_MAP:
d.decString(TAG_READ) // read map type , ignored
case BC_MAP_UNTYPED:
// do nothing
default:
return perrors.Errorf("expect map header, but get %x", tag)
}
m := reflect.MakeMap(UnpackPtrType(value.Type()))
// pack with pointer, so that to ref the same map
m = PackPtr(m)
d.appendRefs(m)
// read key and value
for {
entryKey, err = d.DecodeValue()
if err != nil {
// EOF means the end flag 'Z' of map is already read
if perrors.Is(err, io.EOF) {
break
} else {
return perrors.WithStack(err)
}
}
if entryKey == nil {
break
}
entryValue, err = d.DecodeValue()
// fix: check error
if err != nil {
return perrors.WithStack(err)
}
m.Elem().SetMapIndex(EnsurePackValue(entryKey), EnsureRawValue(entryValue))
}
SetValue(value, m)
return nil
}