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 (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 (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 }
// grow grows the slice s so that it can hold extra more values, allocating // more capacity if needed. It also returns the old and new slice lengths. func grow(s reflect.Value, extra int) (reflect.Value, int, int) { i0 := s.Len() i1 := i0 + extra if i1 < i0 { panic("reflect.Append: slice overflow") } m := s.Cap() if i1 <= m { return s.Slice(0, i1), i0, i1 } if m == 0 { m = extra } else { for m < i1 { if i0 < 1024 { m += m } else { m += m / 4 } } } t := reflect.MakeSlice(s.Type(), i1, m) reflect.Copy(t, s) return t, i0, i1 }
func (f *Field) Unpack(buf []byte, val reflect.Value, length int, options *Options) error { typ := f.Type.Resolve(options) if typ == Pad || f.kind == reflect.String { if typ == Pad { return nil } else { val.SetString(string(buf)) return nil } } else if f.Slice { if val.Cap() < length { val.Set(reflect.MakeSlice(val.Type(), length, length)) } else if val.Len() < length { val.Set(val.Slice(0, length)) } // special case byte slices for performance if !f.Array && typ == Uint8 && f.defType == Uint8 { copy(val.Bytes(), buf[:length]) return nil } pos := 0 size := typ.Size() for i := 0; i < length; i++ { if err := f.unpackVal(buf[pos:pos+size], val.Index(i), 1, options); err != nil { return err } pos += size } return nil } else { return f.unpackVal(buf, val, length, options) } }
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) 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 }
func setSliceField(value reflect.Value, str string, ctx *context) error { if ctx.defaultVal != "" { return ErrDefaultUnsupportedOnSlice } elType := value.Type().Elem() tnz := newSliceTokenizer(str) slice := reflect.MakeSlice(value.Type(), value.Len(), value.Cap()) for tnz.scan() { token := tnz.text() el := reflect.New(elType).Elem() if err := parseValue(el, token, ctx); err != nil { return err } slice = reflect.Append(slice, el) } value.Set(slice) return tnz.Err() }
// Validate checks whether the given value is writeable to this schema. func (*NullSchema) Validate(v reflect.Value) bool { // Check if the value is something that can be null switch v.Kind() { case reflect.Interface: return v.IsNil() case reflect.Array: return v.Cap() == 0 case reflect.Slice: return v.IsNil() || v.Cap() == 0 case reflect.Map: return len(v.MapKeys()) == 0 case reflect.String: return len(v.String()) == 0 case reflect.Float32: // Should NaN floats be treated as null? return math.IsNaN(v.Float()) case reflect.Float64: // Should NaN floats be treated as null? return math.IsNaN(v.Float()) case reflect.Ptr: return v.IsNil() case reflect.Invalid: return true } // Nothing else in particular, so this should not validate? return false }
func ensureLen(d reflect.Value, n int) { if n > d.Cap() { d.Set(reflect.MakeSlice(d.Type(), n, n)) } else { d.SetLen(n) } }
func deStructSlice(dataValue reflect.Value) (interface{}, interface{}, map[string]interface{}) { if dataValue.Kind() == reflect.Uint8 { newDataValue := reflect.MakeSlice(dataValue.Type(), dataValue.Len(), dataValue.Cap()) newDataValue = reflect.AppendSlice(newDataValue, dataValue) return newDataValue.Interface(), newDataValue.Interface(), nil } //TODO if the type inside the slice is not a struct, recreate the slice with the same definition newData := make([]interface{}, dataValue.Len()) flatData := make(map[string]interface{}) for i := 0; i < dataValue.Len(); i++ { subDataValue := dataValue.Index(i) key := strconv.Itoa(i) fieldCopy, fieldScalar, fieldMap := deStructValue(subDataValue) newData[i] = fieldCopy if fieldScalar != nil { flatData[key] = fieldScalar } for fieldMapKey, fieldMapValue := range fieldMap { flatData[key+"."+fieldMapKey] = fieldMapValue } } return newData, nil, flatData }
// rcopy performs a recursive copy of values from the source to destination. // // root is used to skip certain aspects of the copy which are not valid // for the root node of a object. func rcopy(dst, src reflect.Value, root bool) { if !src.IsValid() { return } switch src.Kind() { case reflect.Ptr: if _, ok := src.Interface().(io.Reader); ok { if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { dst.Elem().Set(src) } else if dst.CanSet() { dst.Set(src) } } else { e := src.Type().Elem() if dst.CanSet() && !src.IsNil() { dst.Set(reflect.New(e)) } if src.Elem().IsValid() { // Keep the current root state since the depth hasn't changed rcopy(dst.Elem(), src.Elem(), root) } } case reflect.Struct: if !root { dst.Set(reflect.New(src.Type()).Elem()) } t := dst.Type() for i := 0; i < t.NumField(); i++ { name := t.Field(i).Name srcval := src.FieldByName(name) if srcval.IsValid() { rcopy(dst.FieldByName(name), srcval, false) } } case reflect.Slice: s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) dst.Set(s) for i := 0; i < src.Len(); i++ { rcopy(dst.Index(i), src.Index(i), false) } case reflect.Map: s := reflect.MakeMap(src.Type()) dst.Set(s) for _, k := range src.MapKeys() { v := src.MapIndex(k) v2 := reflect.New(v.Type()).Elem() rcopy(v2, v, false) dst.SetMapIndex(k, v2) } default: // Assign the value if possible. If its not assignable, the value would // need to be converted and the impact of that may be unexpected, or is // not compatible with the dst type. if src.Type().AssignableTo(dst.Type()) { dst.Set(src) } } }
// NewChannelDescriptor creates a ChannelDescriptor for the channel in the // parameter func NewChannelDescriptor(val reflect.Value) *ChannelDescriptor { t := val.Type() return &ChannelDescriptor{ Dir: t.ChanDir(), TypeName: types.NameOf(t.Elem()), Size: val.Cap(), } }
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 *sliceDecoder) decode(dv, sv reflect.Value) { if dv.Kind() == reflect.Slice { dv.Set(reflect.MakeSlice(dv.Type(), dv.Len(), dv.Cap())) } if !sv.IsNil() { d.arrayDec(dv, sv) } }
//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)) } }
// copyRecursive does the actual copying of the interface. It currently has // limited support for what it can handle. Add as needed. func copyRecursive(original, cpy reflect.Value) { // handle according to original's Kind switch original.Kind() { case reflect.Ptr: // Get the actual value being pointed to. originalValue := original.Elem() // if it isn't valid, return. if !originalValue.IsValid() { return } cpy.Set(reflect.New(originalValue.Type())) copyRecursive(originalValue, cpy.Elem()) case reflect.Interface: // Get the value for the interface, not the pointer. originalValue := original.Elem() if !originalValue.IsValid() { return } // Get the value by calling Elem(). copyValue := reflect.New(originalValue.Type()).Elem() copyRecursive(originalValue, copyValue) cpy.Set(copyValue) case reflect.Struct: // Go through each field of the struct and copy it. for i := 0; i < original.NumField(); i++ { if cpy.Field(i).CanSet() { copyRecursive(original.Field(i), cpy.Field(i)) } } case reflect.Slice: // Make a new slice and copy each element. cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap())) for i := 0; i < original.Len(); i++ { copyRecursive(original.Index(i), cpy.Index(i)) } case reflect.Map: cpy.Set(reflect.MakeMap(original.Type())) for _, key := range original.MapKeys() { originalValue := original.MapIndex(key) copyValue := reflect.New(originalValue.Type()).Elem() copyRecursive(originalValue, copyValue) cpy.SetMapIndex(key, copyValue) } // Set the actual values from here on. case reflect.String: cpy.SetString(original.Interface().(string)) case reflect.Int: cpy.SetInt(int64(original.Interface().(int))) case reflect.Bool: cpy.SetBool(original.Interface().(bool)) case reflect.Float64: cpy.SetFloat(original.Interface().(float64)) default: cpy.Set(original) } }
func valueToInterface(f reflect.Value) interface{} { // get to the core value for f.Kind() == reflect.Ptr { if f.IsNil() { return nil } f = reflect.Indirect(f) } switch f.Kind() { case reflect.Uint64: return int64(f.Uint()) case reflect.Float64, reflect.Float32: return int(math.Float64bits(f.Float())) case reflect.Struct: if f.Type().PkgPath() == "time" && f.Type().Name() == "Time" { return f.Interface().(time.Time).UTC().UnixNano() } return structToMap(f) case reflect.Bool: if f.Bool() == true { return int64(1) } return int64(0) case reflect.Map: if f.IsNil() { return nil } newMap := make(map[interface{}]interface{}, f.Len()) for _, mk := range f.MapKeys() { newMap[valueToInterface(mk)] = valueToInterface(f.MapIndex(mk)) } return newMap case reflect.Slice, reflect.Array: if f.Kind() == reflect.Slice && f.IsNil() { return nil } // convert to primitives recursively newSlice := make([]interface{}, f.Len(), f.Cap()) for i := 0; i < len(newSlice); i++ { newSlice[i] = valueToInterface(f.Index(i)) } return newSlice case reflect.Interface: if f.IsNil() { return nil } return f.Interface() default: return f.Interface() } }
func builtinCap(v reflect.Value, vt bool) (reflect.Value, bool, error) { switch v.Kind() { case reflect.Array, reflect.Chan, reflect.Slice: return reflect.ValueOf(v.Cap()), true, nil default: return reflect.Zero(intType), false, errors.New(fmt.Sprintf("invalid argument %v (type %v) for cap", v.Interface(), v.Type())) } }
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 }
func reflectAppend(i int, iface interface{}, slicev reflect.Value) reflect.Value { iv := reflect.ValueOf(iface) if slicev.Len() == i { slicev = reflect.Append(slicev, iv) slicev = slicev.Slice(0, slicev.Cap()) } else { slicev.Index(i).Set(iv) } return slicev }
func convertToBytes(intSize int, v reflect.Value) []byte { if !v.IsValid() { return nil } nbytes := intSize / 8 sh := &reflect.SliceHeader{} sh.Cap = v.Cap() * nbytes sh.Len = v.Len() * nbytes sh.Data = v.Pointer() return *(*[]uint8)(unsafe.Pointer(sh)) }
// decUint8Slice decodes a byte slice and stores in value a slice header // describing the data. // uint8 slices are encoded as an unsigned count followed by the raw bytes. func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) { n, ok := state.getLength() if !ok { errorf("bad %s slice length: %d", value.Type(), n) } if value.Cap() < n { value.Set(reflect.MakeSlice(value.Type(), n, n)) } else { value.Set(value.Slice(0, n)) } if _, err := state.b.Read(value.Bytes()); err != nil { errorf("error decoding []byte: %s", err) } }
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 handleslice(v reflect.Value, abs int, rel float32) (reflect.Value, bool) { len := v.Len() cap := v.Cap() changed := true switch { case len == 0: v = reflect.Zero(v.Type()) case abs >= 0 && cap-len > abs: fallthrough case rel >= 0 && float32(cap-len)/float32(len) > rel: v = makeslice(v, len, len) default: changed = false } return v, changed }
func (w *walker) Slice(s reflect.Value) error { if w.ignoring() { return nil } var newS reflect.Value if s.IsNil() { newS = reflect.Indirect(reflect.New(s.Type())) } else { newS = reflect.MakeSlice(s.Type(), s.Len(), s.Cap()) } w.cs = append(w.cs, newS) w.valPush(newS) return nil }
func alignSlice(intSize int, v reflect.Value) reflect.Value { padding := (addrAlignment * 8) / intSize nslice := v length := v.Len() + padding if v.Cap() < length { nslice = reflect.MakeSlice(v.Type(), length, length) } idx := 0 addr := unsafe.Pointer(nslice.Pointer()) for !isAligned(intSize, uintptr(addr), idx) { idx++ } return reflect.AppendSlice(nslice.Slice(idx, idx), v) }
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 }