in map.go [240:329]
func (d *Decoder) decMap(flag int32) (interface{}, error) {
var (
err error
tag byte
ok bool
m map[interface{}]interface{}
k interface{}
v interface{}
instValue reflect.Value
fieldName string
fieldValue reflect.Value
typ reflect.Type
)
if flag != TAG_READ {
tag = byte(flag)
} else {
tag, _ = d.ReadByte()
}
switch {
case tag == BC_NULL:
return nil, nil
case tag == BC_REF:
return d.decRef(int32(tag))
case tag == BC_MAP:
if typ, err = d.decMapType(); err != nil {
return nil, err
}
if typ.Kind() == reflect.Map {
instValue = reflect.MakeMap(typ)
} else {
instValue = reflect.New(typ).Elem()
}
d.appendRefs(instValue)
for d.peekByte() != BC_END {
k, err = d.Decode()
if err != nil {
return nil, err
}
v, err = d.Decode()
if err != nil {
return nil, err
}
if typ.Kind() == reflect.Map {
instValue.SetMapIndex(reflect.ValueOf(k), EnsureRawValue(v))
} else {
fieldName, ok = k.(string)
if !ok {
return nil, perrors.Errorf("the type of map key must be string, but get %v", k)
}
fieldValue = instValue.FieldByName(fieldName)
if fieldValue.IsValid() {
fieldValue.Set(EnsureRawValue(v))
}
}
}
_, err = d.ReadByte()
if err != nil {
return nil, perrors.WithStack(err)
}
return instValue.Interface(), nil
case tag == BC_MAP_UNTYPED:
m = make(map[interface{}]interface{})
d.appendRefs(m)
for d.peekByte() != BC_END {
k, err = d.Decode()
if err != nil {
return nil, err
}
v, err = d.Decode()
if err != nil {
return nil, err
}
m[k] = v
}
_, err = d.ReadByte()
if err != nil {
return nil, perrors.WithStack(err)
}
return m, nil
default:
return nil, perrors.Errorf("illegal map type tag:%+v", tag)
}
}