func decodeSlice(d *decodeState, kind int, v reflect.Value) { if kind != kindArray { d.saveErrorAndSkip(kind, v.Type()) return } t := v.Type() offset := d.beginDoc() i := 0 for { kind, _ := d.scanKindName() if kind == 0 { break } if i >= v.Cap() { newcap := v.Cap() + v.Cap()/2 if newcap < 4 { newcap = 4 } newv := reflect.MakeSlice(t, v.Len(), newcap) reflect.Copy(newv, v) v.Set(newv) } if i >= v.Len() { v.SetLen(i + 1) } d.decodeValue(kind, v.Index(i)) i += 1 } d.endDoc(offset) }
func (f *decFnInfo) kSlice(rv reflect.Value) { // A slice can be set from a map or array in stream. currEncodedType := f.dd.currentEncodedType() switch currEncodedType { case valueTypeBytes, valueTypeString: if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 { if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 { rv.SetBytes(bs2) } return } } if shortCircuitReflectToFastPath && rv.CanAddr() { switch f.ti.rtid { case intfSliceTypId: f.d.decSliceIntf(rv.Addr().Interface().(*[]interface{}), currEncodedType, f.array) return case uint64SliceTypId: f.d.decSliceUint64(rv.Addr().Interface().(*[]uint64), currEncodedType, f.array) return case int64SliceTypId: f.d.decSliceInt64(rv.Addr().Interface().(*[]int64), currEncodedType, f.array) return case strSliceTypId: f.d.decSliceStr(rv.Addr().Interface().(*[]string), currEncodedType, f.array) return } } containerLen, containerLenS := decContLens(f.dd, currEncodedType) // an array can never return a nil slice. so no need to check f.array here. if rv.IsNil() { rv.Set(reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS)) } if containerLen == 0 { return } if rvcap, rvlen := rv.Len(), rv.Cap(); containerLenS > rvcap { if f.array { // !rv.CanSet() decErr(msgDecCannotExpandArr, rvcap, containerLenS) } rvn := reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS) if rvlen > 0 { reflect.Copy(rvn, rv) } rv.Set(rvn) } else if containerLenS > rvlen { rv.SetLen(containerLenS) } for j := 0; j < containerLenS; j++ { f.d.decodeValue(rv.Index(j)) } }
func setRepeated(field reflect.Value, vslice []Value, setElem setFunc) error { vlen := len(vslice) var flen int switch field.Type().Kind() { case reflect.Slice: // Make a slice of the right size, avoiding allocation if possible. switch { case field.Len() < vlen: field.Set(reflect.MakeSlice(field.Type(), vlen, vlen)) case field.Len() > vlen: field.SetLen(vlen) } flen = vlen case reflect.Array: flen = field.Len() if flen > vlen { // Set extra elements to their zero value. z := reflect.Zero(field.Type().Elem()) for i := vlen; i < flen; i++ { field.Index(i).Set(z) } } default: return fmt.Errorf("bigquery: impossible field type %s", field.Type()) } for i, val := range vslice { if i < flen { // avoid writing past the end of a short array if err := setElem(field.Index(i), val); err != nil { return err } } } return nil }
func (d *Decoder) decodeList(avList []*dynamodb.AttributeValue, v reflect.Value) error { switch v.Kind() { case reflect.Slice: // Make room for the slice elements if needed if v.IsNil() || v.Cap() < len(avList) { // What about if ignoring nil/empty values? v.Set(reflect.MakeSlice(v.Type(), 0, len(avList))) } case reflect.Array: // Limited to capacity of existing array. case reflect.Interface: s := make([]interface{}, len(avList)) for i, av := range avList { if err := d.decode(av, reflect.ValueOf(&s[i]).Elem(), tag{}); err != nil { return err } } v.Set(reflect.ValueOf(s)) return nil default: return &UnmarshalTypeError{Value: "list", Type: v.Type()} } // If v is not a slice, array for i := 0; i < v.Cap() && i < len(avList); i++ { v.SetLen(i + 1) if err := d.decode(avList[i], v.Index(i), tag{}); err != nil { return err } } return nil }
func (d *Decoder) decodeBinary(b []byte, v reflect.Value) error { if v.Kind() == reflect.Interface { buf := make([]byte, len(b)) copy(buf, b) v.Set(reflect.ValueOf(buf)) return nil } switch v.Interface().(type) { case []byte: if v.IsNil() || v.Cap() < len(b) { v.Set(reflect.MakeSlice(byteSliceType, len(b), len(b))) } else if v.Len() != len(b) { v.SetLen(len(b)) } copy(v.Interface().([]byte), b) default: if v.Kind() == reflect.Array && v.Type().Elem().Kind() == reflect.Uint8 { reflect.Copy(v, reflect.ValueOf(b)) break } return &UnmarshalTypeError{Value: "binary", Type: v.Type()} } return nil }
func (d *Decoder) decodeStringSet(ss []*string, v reflect.Value) error { switch v.Kind() { case reflect.Slice: // Make room for the slice elements if needed if v.IsNil() || v.Cap() < len(ss) { v.Set(reflect.MakeSlice(v.Type(), 0, len(ss))) } case reflect.Array: // Limited to capacity of existing array. case reflect.Interface: set := make([]string, len(ss)) for i, s := range ss { if err := d.decodeString(s, reflect.ValueOf(&set[i]).Elem(), tag{}); err != nil { return err } } v.Set(reflect.ValueOf(set)) return nil default: return &UnmarshalTypeError{Value: "string set", Type: v.Type()} } for i := 0; i < v.Cap() && i < len(ss); i++ { v.SetLen(i + 1) u, elem := indirect(v.Index(i), false) if u != nil { return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{SS: ss}) } if err := d.decodeString(ss[i], elem, tag{}); err != nil { return err } } return nil }
// parse a value as the appropriate type and store it in the struct func setSlice(dest reflect.Value, values []string) error { if !dest.CanSet() { return fmt.Errorf("field is not writable") } var ptr bool elem := dest.Type().Elem() if elem.Kind() == reflect.Ptr { ptr = true elem = elem.Elem() } // Truncate the dest slice in case default values exist if !dest.IsNil() { dest.SetLen(0) } for _, s := range values { v := reflect.New(elem) if err := setScalar(v.Elem(), s); err != nil { return err } if !ptr { v = v.Elem() } dest.Set(reflect.Append(dest, v)) } return nil }
func ensureLen(d reflect.Value, n int) { if n > d.Cap() { d.Set(reflect.MakeSlice(d.Type(), n, n)) } else { d.SetLen(n) } }
func (p *Decoder) unmarshalArray(pval *plistValue, val reflect.Value) { subvalues := pval.value.([]*plistValue) var n int if val.Kind() == reflect.Slice { // Slice of element values. // Grow slice. cnt := len(subvalues) + val.Len() if cnt >= val.Cap() { ncap := 2 * cnt if ncap < 4 { ncap = 4 } new := reflect.MakeSlice(val.Type(), val.Len(), ncap) reflect.Copy(new, val) val.Set(new) } n = val.Len() val.SetLen(cnt) } else if val.Kind() == reflect.Array { if len(subvalues) > val.Cap() { panic(fmt.Errorf("plist: attempted to unmarshal %d values into an array of size %d", len(subvalues), val.Cap())) } } else { panic(&incompatibleDecodeTypeError{val.Type(), pval.kind}) } // Recur to read element into slice. for _, sval := range subvalues { p.unmarshal(sval, val.Index(n)) n++ } return }
func decodeSliceElems(s *Stream, val reflect.Value, elemdec decoder) error { i := 0 for ; ; i++ { // grow slice if necessary if i >= val.Cap() { newcap := val.Cap() + val.Cap()/2 if newcap < 4 { newcap = 4 } newv := reflect.MakeSlice(val.Type(), val.Len(), newcap) reflect.Copy(newv, val) val.Set(newv) } if i >= val.Len() { val.SetLen(i + 1) } // decode into element if err := elemdec(s, val.Index(i)); err == EOL { break } else if err != nil { return addErrorContext(err, fmt.Sprint("[", i, "]")) } } if i < val.Len() { val.SetLen(i) } return nil }
func (d *Decoder) decodeSlice(valueField reflect.Value, key string) error { //fmt.Printf("[D] Decode slice tagged as: ->%s<-\n", key) var errors []string seenIndexes := make(map[string]bool) for k := range d.vmx { if !strings.HasPrefix(k, key) { continue } index := getVMXAttrIndex(k, key) if index == "" || seenIndexes[index] { continue } // The reason we have to keep track of seen indexes is because entries // in the vmx file with the same prefix are actually objects, they are // decoded into Go structs, meaning that they only need one pass to be decoded. seenIndexes[index] = true length := valueField.Len() capacity := valueField.Cap() // Grow the slice if needed. This allows us to pass a value // reference to d.decode() so it populates the value addressed by the slice. if length >= capacity { capacity := 2 * length if capacity < 4 { capacity = 4 } newSlice := reflect.MakeSlice(valueField.Type(), length, capacity) reflect.Copy(newSlice, valueField) valueField.Set(newSlice) } valueField.SetLen(length + 1) newKey := key if key != index { newKey = key + index } err := d.decode(valueField.Index(length), newKey) if err != nil { errors = appendErrors(errors, err) valueField.SetLen(length) } } if len(errors) > 0 { return &Error{errors} } return nil }
func (d *Decoder) decodeList(v reflect.Value) error { //if we have an interface, just put a []interface{} in it! if v.Kind() == reflect.Interface { var x []interface{} defer func(p reflect.Value) { p.Set(v) }(v) v = reflect.ValueOf(&x).Elem() } if v.Kind() != reflect.Array && v.Kind() != reflect.Slice { return fmt.Errorf("Cant store a []interface{} into %s", v.Type()) } //read out the l that prefixes the list ch, err := d.readByte() if err != nil { return err } if ch != 'l' { panic("got something other than a list head after a peek") } for i := 0; ; i++ { //peek for the end token and read it out ch, err := d.peekByte() if err != nil { return err } switch ch { case 'e': _, err := d.readByte() //consume the end return err } //grow it if required if i >= v.Cap() && v.IsValid() { newcap := v.Cap() + v.Cap()/2 if newcap < 4 { newcap = 4 } newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) reflect.Copy(newv, v) v.Set(newv) } //reslice into cap (its a slice now since it had to have grown) if i >= v.Len() && v.IsValid() { v.SetLen(i + 1) } //decode a value into the index if err := d.decodeInto(v.Index(i)); err != nil { return err } } panic("unreachable") }
//FIXME: fix when v is invalid // type(1) | name length(1) | item size(4) | raw name bytes | 0x00 // | element number(4) | element1 | ... | elementN func (d *decodeState) array(v reflect.Value) { d.off += 1 // type klen := int(Int8(d.data[d.off:])) d.off += 1 // name length // vlen := int(Int32(d.data[d.off:])) d.off += 4 // content length //var key string if klen > 0 { key := d.data[d.off : d.off+klen-1] d.off += klen v = fieldByTag(v, key) u, pv := d.indirect(v, false) if u != nil { d.off -= 1 + 1 + 4 + klen if err := u.UnmarshalMCPACK(d.next()); err != nil { d.error(err) } return } v = pv } n := int(Int32(d.data[d.off:])) d.off += 4 // member number if v.Kind() == reflect.Slice { if n > v.Cap() { newv := reflect.MakeSlice(v.Type(), n, n) v.Set(newv) } v.SetLen(n) } for i := 0; i < n; i++ { if i < v.Len() { d.value(v.Index(i)) } else { d.value(reflect.Value{}) } } if n < v.Len() { if v.Kind() == reflect.Array { z := reflect.Zero(v.Type().Elem()) for i := 0; i < v.Len(); i++ { v.Index(i).Set(z) } } } if n == 0 && v.Kind() == reflect.Slice { v.Set(reflect.MakeSlice(v.Type(), 0, 0)) } }
func fixSliceLen(slice reflect.Value, lenslice int) reflect.Value { if slice.Len() != lenslice { if slice.Cap() >= lenslice { slice.SetLen(lenslice) } else { slice.Set(reflect.MakeSlice(slice.Type(), lenslice, lenslice)) } } return slice }
// unmarshalAttr unmarshals a single XML attribute into val. func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { if val.Kind() == reflect.Ptr { if val.IsNil() { val.Set(reflect.New(val.Type().Elem())) } val = val.Elem() } if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) { // This is an unmarshaler with a non-pointer receiver, // so it's likely to be incorrect, but we do what we're told. return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) } if val.CanAddr() { pv := val.Addr() if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) { return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) } } // Not an UnmarshalerAttr; try encoding.TextUnmarshaler. if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { // This is an unmarshaler with a non-pointer receiver, // so it's likely to be incorrect, but we do what we're told. return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) } if val.CanAddr() { pv := val.Addr() if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) } } if val.Type().Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 { // Slice of element values. // Grow slice. n := val.Len() val.Set(reflect.Append(val, reflect.Zero(val.Type().Elem()))) // Recur to read element into slice. if err := p.unmarshalAttr(val.Index(n), attr); err != nil { val.SetLen(n) return err } return nil } if val.Type() == attrType { val.Set(reflect.ValueOf(attr)) return nil } return copyValue(val, []byte(attr.Value)) }
func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error { datav := reflect.ValueOf(data) if datav.Kind() != reflect.Slice { return badtype("slice", data) } sliceLen := datav.Len() if rv.IsNil() || rv.Len() < datav.Len() { rv.Set(reflect.MakeSlice(rv.Type(), sliceLen, sliceLen)) } rv.SetLen(datav.Len()) return md.unifySliceArray(datav, rv) }
func setSlice(value reflect.Value, args []string) (n int, err error) { value.SetLen(0) slice := value for _, i := range args { x := reflect.New(value.Type().Elem()) if err = setValue(x.Elem(), i); err != nil { return } slice = reflect.Append(slice, x.Elem()) n++ } value.Set(slice) return }
func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error { datav := reflect.ValueOf(data) if datav.Kind() != reflect.Slice { if !datav.IsValid() { return nil } return badtype("slice", data) } n := datav.Len() if rv.IsNil() || rv.Cap() < n { rv.Set(reflect.MakeSlice(rv.Type(), n, n)) } rv.SetLen(n) return md.unifySliceArray(datav, rv) }
func (f *decFnInfo) kSlice(rv reflect.Value) { // A slice can be set from a map or array in stream. currEncodedType := f.dd.currentEncodedType() switch currEncodedType { case valueTypeBytes, valueTypeString: if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 { if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 { rv.SetBytes(bs2) } return } } containerLen, containerLenS := decContLens(f.dd, currEncodedType) // an array can never return a nil slice. so no need to check f.array here. if rv.IsNil() { rv.Set(reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS)) } if containerLen == 0 { return } if rvcap, rvlen := rv.Len(), rv.Cap(); containerLenS > rvcap { if f.array { // !rv.CanSet() decErr(msgDecCannotExpandArr, rvcap, containerLenS) } rvn := reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS) if rvlen > 0 { reflect.Copy(rvn, rv) } rv.Set(rvn) } else if containerLenS > rvlen { rv.SetLen(containerLenS) } rtelem := f.ti.rt.Elem() for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() } fn := f.d.getDecFn(rtelem) for j := 0; j < containerLenS; j++ { f.d.decodeValue(rv.Index(j), fn) } }
func decodeByteSlice(d *decodeState, kind int, v reflect.Value) { var p []byte switch kind { default: d.saveErrorAndSkip(kind, v.Type()) return case kindBinary: p, _ = d.scanBinary() } if v.IsNil() || v.Cap() < len(p) { v.Set(reflect.MakeSlice(v.Type(), len(p), len(p))) } else { v.SetLen(len(p)) } reflect.Copy(v, reflect.ValueOf(p)) }
func (d *Decoder) decodeNumberSet(ns []*string, v reflect.Value) error { switch v.Kind() { case reflect.Slice: // Make room for the slice elements if needed if v.IsNil() || v.Cap() < len(ns) { // What about if ignoring nil/empty values? v.Set(reflect.MakeSlice(v.Type(), 0, len(ns))) } case reflect.Array: // Limited to capacity of existing array. case reflect.Interface: if d.UseNumber { set := make([]Number, len(ns)) for i, n := range ns { if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem()); err != nil { return err } } v.Set(reflect.ValueOf(set)) } else { set := make([]float64, len(ns)) for i, n := range ns { if err := d.decodeNumber(n, reflect.ValueOf(&set[i]).Elem()); err != nil { return err } } v.Set(reflect.ValueOf(set)) } return nil default: return &UnmarshalTypeError{Value: "number set", Type: v.Type()} } for i := 0; i < v.Cap() && i < len(ns); i++ { v.SetLen(i + 1) u, elem := indirect(v.Index(i), false) if u != nil { return u.UnmarshalDynamoDBAttributeValue(&dynamodb.AttributeValue{NS: ns}) } if err := d.decodeNumber(ns[i], elem); err != nil { return err } } return nil }
func (c *Config) configureArray(v, config reflect.Value, path string) error { vkind := v.Kind() // nil interface if vkind == reflect.Interface && v.NumMethod() == 0 { v.Set(config) return nil } if vkind != reflect.Array && vkind != reflect.Slice { return &ConfigValueError{path, fmt.Sprintf("%v cannot be used to configure %v", config.Type(), v.Type())} } n := config.Len() // grow slice if it's smaller than the config array if vkind == reflect.Slice && v.Cap() < n { t := reflect.MakeSlice(v.Type(), n, n) reflect.Copy(t, v) v.Set(t) } if n > v.Cap() { n = v.Cap() } for i := 0; i < n; i++ { if err := c.configure(v.Index(i), config.Index(i), path+"."+strconv.Itoa(i)); err != nil { return err } } if n < v.Len() { if vkind == reflect.Array { // Array. Zero the rest. z := reflect.Zero(v.Type().Elem()) for i := n; i < v.Len(); i++ { v.Index(i).Set(z) } } else { v.SetLen(n) } } return nil }
func (d *decoder) parse_list(v reflect.Value) { switch v.Kind() { case reflect.Array, reflect.Slice: default: panic(&UnmarshalTypeError{ Value: "array", Type: v.Type(), }) } i := 0 for { if v.Kind() == reflect.Slice && i >= v.Len() { v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) } ok := false if i < v.Len() { ok = d.parse_value(v.Index(i)) } else { _, ok = d.parse_value_interface() } if !ok { break } i++ } if i < v.Len() { if v.Kind() == reflect.Array { z := reflect.Zero(v.Type().Elem()) for n := v.Len(); i < n; i++ { v.Index(i).Set(z) } } else { v.SetLen(i) } } if i == 0 && v.Kind() == reflect.Slice { v.Set(reflect.MakeSlice(v.Type(), 0, 0)) } }
func (d *Decoder) decodeBinary(b []byte, v reflect.Value) error { if v.Kind() == reflect.Interface { buf := make([]byte, len(b)) copy(buf, b) v.Set(reflect.ValueOf(buf)) return nil } if v.Kind() != reflect.Slice { return &UnmarshalTypeError{Value: "binary", Type: v.Type()} } if v.Type() == byteSliceType { // Optimization for []byte types if v.IsNil() || v.Cap() < len(b) { v.Set(reflect.MakeSlice(byteSliceType, len(b), len(b))) } else if v.Len() != len(b) { v.SetLen(len(b)) } copy(v.Interface().([]byte), b) return nil } switch v.Type().Elem().Kind() { case reflect.Uint8: // Fallback to reflection copy for type aliased of []byte type if v.IsNil() || v.Cap() < len(b) { v.Set(reflect.MakeSlice(v.Type(), len(b), len(b))) } else if v.Len() != len(b) { v.SetLen(len(b)) } for i := 0; i < len(b); i++ { v.Index(i).SetUint(uint64(b[i])) } default: if v.Kind() == reflect.Array && v.Type().Elem().Kind() == reflect.Uint8 { reflect.Copy(v, reflect.ValueOf(b)) break } return &UnmarshalTypeError{Value: "binary", Type: v.Type()} } return nil }
// decodeArray treats the next bytes as a variable length series of XDR encoded // elements of the same type as the array represented by the reflection value. // The number of elements is obtained by first decoding the unsigned integer // element count. Then each element is decoded into the passed array. The // ignoreOpaque flag controls whether or not uint8 (byte) elements should be // decoded individually or as a variable sequence of opaque data. It returns // the number of bytes actually read. // // An UnmarshalError is returned if any issues are encountered while decoding // the array elements. // // Reference: // RFC Section 4.13 - Variable-Length Array // Unsigned integer length followed by individually XDR encoded array // elements func (d *Decoder) decodeArray(v reflect.Value, ignoreOpaque bool) (int, error) { dataLen, n, err := d.DecodeUint() if err != nil { return n, err } if uint(dataLen) > uint(math.MaxInt32) || (d.maxReadSize != 0 && uint(dataLen) > d.maxReadSize) { err := unmarshalError("decodeArray", ErrOverflow, errMaxSlice, dataLen, nil) return n, err } // Allocate storage for the slice elements (the underlying array) if // existing slice does not have enough capacity. sliceLen := int(dataLen) if v.Cap() < sliceLen { v.Set(reflect.MakeSlice(v.Type(), sliceLen, sliceLen)) } if v.Len() < sliceLen { v.SetLen(sliceLen) } // Treat []byte (byte is alias for uint8) as opaque data unless ignored. if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 { data, n2, err := d.DecodeFixedOpaque(int32(sliceLen)) n += n2 if err != nil { return n, err } v.SetBytes(data) return n, nil } // Decode each slice element. for i := 0; i < sliceLen; i++ { n2, err := d.decode(v.Index(i)) n += n2 if err != nil { return n, err } } return n, nil }
func unmarshalArray(data string, v reflect.Value, kind reflect.Kind) error { i := 0 vtype := v.Type() l := v.Cap() if v.Len() < l { v.SetLen(l) } for len(data) > 0 { if i >= l { if kind == reflect.Array { break } newl := l + l/2 if newl < 4 { newl = 4 } newv := reflect.MakeSlice(vtype, newl, newl) reflect.Copy(newv, v) v.Set(newv) l = newl } el := v.Index(i) i++ n, err := unmarshal(data, el) data = data[n:] if err != nil { return err } } if i < l { if kind == reflect.Array { // zero out the rest z := reflect.Zero(vtype.Elem()) for ; i < l; i++ { v.Index(i).Set(z) } } else { v.SetLen(i) } } return nil }
func (d *arrayDecoder) decode(dv, sv reflect.Value) { // Iterate through the slice/array and decode each element before adding it // to the dest slice/array i := 0 for i < sv.Len() { if dv.Kind() == reflect.Slice { // Get element of array, growing if necessary. if i >= dv.Cap() { newcap := dv.Cap() + dv.Cap()/2 if newcap < 4 { newcap = 4 } newdv := reflect.MakeSlice(dv.Type(), dv.Len(), newcap) reflect.Copy(newdv, dv) dv.Set(newdv) } if i >= dv.Len() { dv.SetLen(i + 1) } } if i < dv.Len() { // Decode into element. d.elemDec(dv.Index(i), sv.Index(i)) } i++ } // Ensure that the destination is the correct size if i < dv.Len() { if dv.Kind() == reflect.Array { // Array. Zero the rest. z := reflect.Zero(dv.Type().Elem()) for ; i < dv.Len(); i++ { dv.Index(i).Set(z) } } else { dv.SetLen(i) } } }
func (f *decFnInfo) kSlice(rv reflect.Value) { // Be more careful calling Set() here, because a reflect.Value from an array // may have come in here (which may not be settable). // In places where the slice got from an array could be, we should guard with CanSet() calls. if f.rtid == byteSliceTypId { // rawbytes if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 { rv.SetBytes(bs2) } return } containerLen := f.dd.readArrayLen() if rv.IsNil() { rv.Set(reflect.MakeSlice(f.rt, containerLen, containerLen)) } if containerLen == 0 { return } // if we need to reset rv but it cannot be set, we should err out. // for example, if slice is got from unaddressable array, CanSet = false if rvcap, rvlen := rv.Len(), rv.Cap(); containerLen > rvcap { if rv.CanSet() { rvn := reflect.MakeSlice(f.rt, containerLen, containerLen) if rvlen > 0 { reflect.Copy(rvn, rv) } rv.Set(rvn) } else { decErr("Cannot reset slice with less cap: %v than stream contents: %v", rvcap, containerLen) } } else if containerLen > rvlen { rv.SetLen(containerLen) } for j := 0; j < containerLen; j++ { f.d.decodeValue(rv.Index(j)) } }
// setElement ses the element value of a map, array, or slice at the specified index. func setElement(data reflect.Value, p string, v interface{}) error { value := reflect.ValueOf(v) switch data.Kind() { case reflect.Map: key := reflect.ValueOf(p) data.SetMapIndex(key, value) case reflect.Slice, reflect.Array: idx, err := strconv.Atoi(p) if err != nil || idx < 0 { return fmt.Errorf("%v is not a valid array or slice index", p) } if data.Kind() == reflect.Slice { if idx >= data.Cap() { return fmt.Errorf("%v is out of the slice index bound", p) } data.SetLen(idx + 1) } else if idx >= data.Cap() { return fmt.Errorf("%v is out of the array index bound", p) } data.Index(idx).Set(value) } return nil }
func (par *sliceParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int { var v reflect.Value valueOf.SetLen(0) tp := valueOf.Type().Elem() for { v = reflect.New(tp).Elem() var nl int nl = ctx.parse(v, par.Parser, location, err) if nl < 0 { if valueOf.Len() >= par.Min { return location } return nl } if nl <= location { panic("Invalid grammar: 0-length member of ZeroOrMore") } location = nl valueOf.Set(reflect.Append(valueOf, v)) if len(par.Delimiter) > 0 { nl = ctx.skipWS(location) if strAt(ctx.str, nl, par.Delimiter) { location = ctx.skipWS(nl + len(par.Delimiter)) } else { // Here we've got at least one parsed member, so it could not be an error. return nl } } } }