func()

in map.go [231:320]


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)
	}
}