in marshal.go [1665:1725]
func unmarshalList(info TypeInfo, data []byte, value interface{}) error {
listInfo, ok := info.(CollectionType)
if !ok {
return unmarshalErrorf("unmarshal: can not unmarshal none collection type into list")
}
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()
k := t.Kind()
switch k {
case reflect.Slice, reflect.Array:
if data == nil {
if k == reflect.Array {
return unmarshalErrorf("unmarshal list: can not store nil in array value")
}
if rv.IsNil() {
return nil
}
rv.Set(reflect.Zero(t))
return nil
}
n, p, err := readCollectionSize(listInfo, data)
if err != nil {
return err
}
data = data[p:]
if k == reflect.Array {
if rv.Len() != n {
return unmarshalErrorf("unmarshal list: array with wrong size")
}
} else {
rv.Set(reflect.MakeSlice(t, n, n))
}
for i := 0; i < n; i++ {
m, p, err := readCollectionSize(listInfo, data)
if err != nil {
return err
}
data = data[p:]
// In case m < 0, the value is null, and unmarshalData should be nil.
var unmarshalData []byte
if m >= 0 {
if len(data) < m {
return unmarshalErrorf("unmarshal list: unexpected eof")
}
unmarshalData = data[:m]
data = data[m:]
}
if err := Unmarshal(listInfo.Elem, unmarshalData, rv.Index(i).Addr().Interface()); err != nil {
return err
}
}
return nil
}
return unmarshalErrorf("can not unmarshal %s into %T. Accepted types: *slice, *array.", info, value)
}