in marshal.go [1949:2020]
func unmarshalMap(info TypeInfo, data []byte, value interface{}) error {
mapInfo, ok := info.(CollectionType)
if !ok {
return unmarshalErrorf("unmarshal: can not unmarshal none collection type into map")
}
rv := reflect.ValueOf(value)
if rv.Kind() != reflect.Ptr {
return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
}
rv = rv.Elem()
t := rv.Type()
if t.Kind() != reflect.Map {
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
}
if data == nil {
rv.Set(reflect.Zero(t))
return nil
}
n, p, err := readCollectionSize(mapInfo, data)
if err != nil {
return err
}
if n < 0 {
return unmarshalErrorf("negative map size %d", n)
}
rv.Set(reflect.MakeMapWithSize(t, n))
data = data[p:]
for i := 0; i < n; i++ {
m, p, err := readCollectionSize(mapInfo, data)
if err != nil {
return err
}
data = data[p:]
key := reflect.New(t.Key())
// In case m < 0, the key is null, and unmarshalData should be nil.
var unmarshalData []byte
if m >= 0 {
if len(data) < m {
return unmarshalErrorf("unmarshal map: unexpected eof")
}
unmarshalData = data[:m]
data = data[m:]
}
if err := Unmarshal(mapInfo.Key, unmarshalData, key.Interface()); err != nil {
return err
}
m, p, err = readCollectionSize(mapInfo, data)
if err != nil {
return err
}
data = data[p:]
val := reflect.New(t.Elem())
// In case m < 0, the value is null, and unmarshalData should be nil.
unmarshalData = nil
if m >= 0 {
if len(data) < m {
return unmarshalErrorf("unmarshal map: unexpected eof")
}
unmarshalData = data[:m]
data = data[m:]
}
if err := Unmarshal(mapInfo.Elem, unmarshalData, val.Interface()); err != nil {
return err
}
rv.SetMapIndex(key.Elem(), val.Elem())
}
return nil
}