123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- package msgpack
- import (
- "fmt"
- "reflect"
- "github.com/vmihailenco/msgpack/v5/msgpcode"
- )
- var sliceStringPtrType = reflect.TypeOf((*[]string)(nil))
- // DecodeArrayLen decodes array length. Length is -1 when array is nil.
- func (d *Decoder) DecodeArrayLen() (int, error) {
- c, err := d.readCode()
- if err != nil {
- return 0, err
- }
- return d.arrayLen(c)
- }
- func (d *Decoder) arrayLen(c byte) (int, error) {
- if c == msgpcode.Nil {
- return -1, nil
- } else if c >= msgpcode.FixedArrayLow && c <= msgpcode.FixedArrayHigh {
- return int(c & msgpcode.FixedArrayMask), nil
- }
- switch c {
- case msgpcode.Array16:
- n, err := d.uint16()
- return int(n), err
- case msgpcode.Array32:
- n, err := d.uint32()
- return int(n), err
- }
- return 0, fmt.Errorf("msgpack: invalid code=%x decoding array length", c)
- }
- func decodeStringSliceValue(d *Decoder, v reflect.Value) error {
- ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string)
- return d.decodeStringSlicePtr(ptr)
- }
- func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error {
- n, err := d.DecodeArrayLen()
- if err != nil {
- return err
- }
- if n == -1 {
- return nil
- }
- ss := makeStrings(*ptr, n)
- for i := 0; i < n; i++ {
- s, err := d.DecodeString()
- if err != nil {
- return err
- }
- ss = append(ss, s)
- }
- *ptr = ss
- return nil
- }
- func makeStrings(s []string, n int) []string {
- if n > sliceAllocLimit {
- n = sliceAllocLimit
- }
- if s == nil {
- return make([]string, 0, n)
- }
- if cap(s) >= n {
- return s[:0]
- }
- s = s[:cap(s)]
- s = append(s, make([]string, n-len(s))...)
- return s[:0]
- }
- func decodeSliceValue(d *Decoder, v reflect.Value) error {
- n, err := d.DecodeArrayLen()
- if err != nil {
- return err
- }
- if n == -1 {
- v.Set(reflect.Zero(v.Type()))
- return nil
- }
- if n == 0 && v.IsNil() {
- v.Set(reflect.MakeSlice(v.Type(), 0, 0))
- return nil
- }
- if v.Cap() >= n {
- v.Set(v.Slice(0, n))
- } else if v.Len() < v.Cap() {
- v.Set(v.Slice(0, v.Cap()))
- }
- for i := 0; i < n; i++ {
- if i >= v.Len() {
- v.Set(growSliceValue(v, n))
- }
- elem := v.Index(i)
- if err := d.DecodeValue(elem); err != nil {
- return err
- }
- }
- return nil
- }
- func growSliceValue(v reflect.Value, n int) reflect.Value {
- diff := n - v.Len()
- if diff > sliceAllocLimit {
- diff = sliceAllocLimit
- }
- v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff))
- return v
- }
- func decodeArrayValue(d *Decoder, v reflect.Value) error {
- n, err := d.DecodeArrayLen()
- if err != nil {
- return err
- }
- if n == -1 {
- return nil
- }
- if n > v.Len() {
- return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n)
- }
- for i := 0; i < n; i++ {
- sv := v.Index(i)
- if err := d.DecodeValue(sv); err != nil {
- return err
- }
- }
- return nil
- }
- func (d *Decoder) DecodeSlice() ([]interface{}, error) {
- c, err := d.readCode()
- if err != nil {
- return nil, err
- }
- return d.decodeSlice(c)
- }
- func (d *Decoder) decodeSlice(c byte) ([]interface{}, error) {
- n, err := d.arrayLen(c)
- if err != nil {
- return nil, err
- }
- if n == -1 {
- return nil, nil
- }
- s := make([]interface{}, 0, min(n, sliceAllocLimit))
- for i := 0; i < n; i++ {
- v, err := d.decodeInterfaceCond()
- if err != nil {
- return nil, err
- }
- s = append(s, v)
- }
- return s, nil
- }
- func (d *Decoder) skipSlice(c byte) error {
- n, err := d.arrayLen(c)
- if err != nil {
- return err
- }
- for i := 0; i < n; i++ {
- if err := d.Skip(); err != nil {
- return err
- }
- }
- return nil
- }
|