// reflectSliceWithProperType does the opposite thing as setSliceWithProperType. func reflectSliceWithProperType(key *Key, field reflect.Value, delim string) error { slice := field.Slice(0, field.Len()) if field.Len() == 0 { return nil } var buf bytes.Buffer sliceOf := field.Type().Elem().Kind() for i := 0; i < field.Len(); i++ { switch sliceOf { case reflect.String: buf.WriteString(slice.Index(i).String()) case reflect.Int, reflect.Int64: buf.WriteString(fmt.Sprint(slice.Index(i).Int())) case reflect.Uint, reflect.Uint64: buf.WriteString(fmt.Sprint(slice.Index(i).Uint())) case reflect.Float64: buf.WriteString(fmt.Sprint(slice.Index(i).Float())) case reflectTime: buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339)) default: return fmt.Errorf("unsupported type '[]%s'", sliceOf) } buf.WriteString(delim) } key.SetValue(buf.String()[:buf.Len()-1]) return nil }
func decComplex128Array(state *decoderState, v reflect.Value, length int, ovfl error) bool { // Can only slice if it is addressable. if !v.CanAddr() { return false } return decComplex128Slice(state, v.Slice(0, v.Len()), length, ovfl) }
func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(val.Int(), 10), nil, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return strconv.FormatUint(val.Uint(), 10), nil, nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil case reflect.String: return val.String(), nil, nil case reflect.Bool: return strconv.FormatBool(val.Bool()), nil, nil case reflect.Array: if typ.Elem().Kind() != reflect.Uint8 { break } // [...]byte var bytes []byte if val.CanAddr() { bytes = val.Slice(0, val.Len()).Bytes() } else { bytes = make([]byte, val.Len()) reflect.Copy(reflect.ValueOf(bytes), val) } return "", bytes, nil case reflect.Slice: if typ.Elem().Kind() != reflect.Uint8 { break } // []byte return "", val.Bytes(), nil } return "", nil, &UnsupportedTypeError{typ} }
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) } }
// 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 (d *decoder) sequence(n *node, out reflect.Value) (good bool) { l := len(n.children) var iface reflect.Value switch out.Kind() { case reflect.Slice: out.Set(reflect.MakeSlice(out.Type(), l, l)) case reflect.Interface: // No type hints. Will have to use a generic sequence. iface = out out = settableValueOf(make([]interface{}, l)) default: d.terror(n, yaml_SEQ_TAG, out) return false } et := out.Type().Elem() j := 0 for i := 0; i < l; i++ { e := reflect.New(et).Elem() if ok := d.unmarshal(n.children[i], e); ok { out.Index(j).Set(e) j++ } } out.Set(out.Slice(0, j)) if iface.IsValid() { iface.Set(out) } return true }
func encodeByteArray(b []byte, v reflect.Value) []byte { n := v.Len() if n < (0xec - 0xe0) { b = append(b, byte(0xe0+n)) } else { b = encodeK4(b, 0xec, uint64(n)) } // Fast path for when the array is addressable (which it almost // always will be). if v.CanAddr() { return append(b, v.Slice(0, n).Bytes()...) } i := len(b) j := i + n if j > cap(b) { t := make([]byte, i, j) copy(t, b) b = t } reflect.Copy(reflect.ValueOf(b[i:j]), v) return b[:j] }
func Slice(expectedSlice reflect.Value, actualSlice reflect.Value) (bool, diff.Difference) { for i := 0; i < actualSlice.Len(); i++ { if i >= expectedSlice.Len() { return false, diff.SliceExtraElements{ ExtraElements: actualSlice.Slice(i, actualSlice.Len()), AllElements: actualSlice, } } equal, difference := Compare(expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface()) if !equal { return false, diff.SliceNested{ Index: i, NestedDifference: difference, } } } if expectedSlice.Len() > actualSlice.Len() { return false, diff.SliceMissingElements{ MissingElements: expectedSlice.Slice(actualSlice.Len(), expectedSlice.Len()), AllElements: actualSlice, } } return true, diff.NoDifference{} }
// reflectWithProperType does the opposite thing with setWithProperType. func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error { switch t.Kind() { case reflect.String: key.SetValue(field.String()) case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float64, reflectTime: key.SetValue(fmt.Sprint(field)) case reflect.Slice: vals := field.Slice(0, field.Len()) if field.Len() == 0 { return nil } var buf bytes.Buffer isTime := fmt.Sprint(field.Type()) == "[]time.Time" for i := 0; i < field.Len(); i++ { if isTime { buf.WriteString(vals.Index(i).Interface().(time.Time).Format(time.RFC3339)) } else { buf.WriteString(fmt.Sprint(vals.Index(i))) } buf.WriteString(delim) } key.SetValue(buf.String()[:buf.Len()-1]) default: return fmt.Errorf("unsupported type '%s'", t) } return nil }
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)) } sv := v.Index(i) if err := d.DecodeValue(sv); err != nil { return err } } return nil }
func encComplex64Array(state *encoderState, v reflect.Value) bool { // Can only slice if it is addressable. if !v.CanAddr() { return false } return encComplex64Slice(state, v.Slice(0, v.Len())) }
func (encoder *Encoder) encode(v reflect.Value) error { switch v.Kind() { case reflect.Map: return encoder.encodeMap(v) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return encoder.encodeUint(v.Uint()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return encoder.encodeInt(v.Int()) case reflect.String: return encoder.encodeString(v.String()) case reflect.Array: v = v.Slice(0, v.Len()) return encoder.encodeSlice(v) case reflect.Slice: return encoder.encodeSlice(v) case reflect.Float64, reflect.Float32: return encoder.encodeFloat(v.Float()) case reflect.Interface: v = reflect.ValueOf(v.Interface()) return encoder.encode(v) case reflect.Ptr: if v.IsNil() { return encoder.encodeNull() } vv := reflect.Indirect(v) if vv.Kind() == reflect.Struct { return encoder.encodeStruct(v) } return encoder.encode(vv) } return errors.New("unsupported type:" + v.Type().String()) }
// encodeFixedArray writes the XDR encoded representation of each element // in the passed array represented by the reflection value to the encapsulated // writer and returns the number of bytes written. The ignoreOpaque flag // controls whether or not uint8 (byte) elements should be encoded individually // or as a fixed sequence of opaque data. // // A MarshalError is returned if any issues are encountered while encoding // the array elements. // // Reference: // RFC Section 4.12 - Fixed-Length Array // Individually XDR encoded array elements func (enc *Encoder) encodeFixedArray(v reflect.Value, ignoreOpaque bool) (int, error) { // Treat [#]byte (byte is alias for uint8) as opaque data unless ignored. if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 { // Create a slice of the underlying array for better efficiency // when possible. Can't create a slice of an unaddressable // value. if v.CanAddr() { return enc.EncodeFixedOpaque(v.Slice(0, v.Len()).Bytes()) } // When the underlying array isn't addressable fall back to // copying the array into a new slice. This is rather ugly, but // the inability to create a constant slice from an // unaddressable array is a limitation of Go. slice := make([]byte, v.Len(), v.Len()) reflect.Copy(reflect.ValueOf(slice), v) return enc.EncodeFixedOpaque(slice) } // Encode each array element. var n int for i := 0; i < v.Len(); i++ { n2, err := enc.encode(v.Index(i)) n += n2 if err != nil { return n, err } } return n, nil }
func DeleteSliceElementVal(sliceVal reflect.Value, idx int) reflect.Value { if idx < 0 || idx >= sliceVal.Len() { return sliceVal } before := sliceVal.Slice(0, idx) after := sliceVal.Slice(idx+1, sliceVal.Len()) sliceVal = reflect.AppendSlice(before, after) return sliceVal }
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 }
// Sets the length of a slice by sub-slicing a slice that's too long, // or appending empty fields if slice is too short. func SetSliceLengh(slice reflect.Value, length int) reflect.Value { if length > slice.Len() { for i := slice.Len(); i < length; i++ { slice = AppendEmptySliceField(slice) } } else if length < slice.Len() { slice = slice.Slice(0, length) } return slice }
// Create the pages we expect to see. func wantedPages(vWant reflect.Value, pageSize int) []interface{} { var pages []interface{} for i, j := 0, pageSize; i < vWant.Len(); i, j = j, j+pageSize { if j > vWant.Len() { j = vWant.Len() } pages = append(pages, vWant.Slice(i, j).Interface()) } return pages }
func slicefmt(v reflect.Value) string { length := v.Len() slice := v.Slice(0, length) str := "[" for i := 0; i < length; i += 1 { str = fmt.Sprintf("%s%v, ", str, format(slice.Index(i))) } str += "\b\b]" return fmt.Sprintf("%v(%s[%d])", str, v.Type().String(), length) }
func nextSlice(s Stream, sliceValue reflect.Value, toInterface func(reflect.Value) interface{}) bool { length := sliceValue.Len() numCopied := copyToSlice(s, sliceValue, toInterface) if numCopied == 0 { return false } if numCopied < length { sliceValue.Set(sliceValue.Slice(0, numCopied)) } return true }
func slicefmt(v reflect.Value) (string, string) { length := v.Len() slice := v.Slice(0, length) str := "[" for i := 0; i < length; i += 1 { v, _ := format(slice.Index(i)) str = fmt.Sprintf("%s%v, ", str, v) } str += "\b\b]" return fmt.Sprintf("%v", str), fmt.Sprintf("%s[%d]", v.Type().String(), length) }
func setString(slice reflect.Value, b []byte) { switch slice.Kind() { case reflect.Array, reflect.Slice: reflect.Copy(slice.Slice(0, slice.Len()), reflect.ValueOf(b)) case reflect.String: slice.SetString(string(b)) default: panic("bad type for setString: " + slice.Kind().String()) } }
func writeByteArray(val reflect.Value, w *encbuf) error { if !val.CanAddr() { // Slice requires the value to be addressable. // Make it addressable by copying. copy := reflect.New(val.Type()).Elem() copy.Set(val) val = copy } size := val.Len() slice := val.Slice(0, size).Bytes() w.encodeString(slice) return nil }
func (f *protoFuzzer) Fuzz(v reflect.Value) { if !v.CanSet() { return } switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: f.FuzzInt(v) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: f.FuzzUint(v) case reflect.String: str := "" for i := 0; i < v.Len(); i++ { str = str + string(' '+rune(f.r.Intn(94))) } v.SetString(str) return case reflect.Ptr: if !v.IsNil() { f.Fuzz(v.Elem()) } return case reflect.Slice: mode := f.r.Intn(3) switch { case v.Len() > 0 && mode == 0: // fuzz entry f.Fuzz(v.Index(f.r.Intn(v.Len()))) case v.Len() > 0 && mode == 1: // remove entry entry := f.r.Intn(v.Len()) pre := v.Slice(0, entry) post := v.Slice(entry+1, v.Len()) v.Set(reflect.AppendSlice(pre, post)) default: // add entry entry := reflect.MakeSlice(v.Type(), 1, 1) f.Fuzz(entry) // XXX fill all fields v.Set(reflect.AppendSlice(v, entry)) } return case reflect.Struct: f.Fuzz(v.Field(f.r.Intn(v.NumField()))) return case reflect.Map: // TODO fuzz map default: panic(fmt.Sprintf("Not fuzzing %v %+v", v.Kind(), v)) } }
func encodeByteArrayValue(e *Encoder, v reflect.Value) error { if err := e.encodeBytesLen(v.Len()); err != nil { return err } if v.CanAddr() { b := v.Slice(0, v.Len()).Bytes() return e.write(b) } b := make([]byte, v.Len()) reflect.Copy(reflect.ValueOf(b), v) return e.write(b) }
// 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 main() { var a []int var value reflect.Value = reflect.ValueOf(&a) //判断指针是否指向内存地址 if !value.CanSet() { value = value.Elem() //使指针指向内存地址 } value = reflect.AppendSlice(value, reflect.ValueOf([]int{1, 2})) //支持切片 value = reflect.AppendSlice(value, reflect.ValueOf([]int{3, 4, 5, 6, 7, 8, 9})) //支持切片 fmt.Println(value.Kind(), value.Slice(0, value.Len()).Interface()) ///// >> slice [1 2 3 4 5 6 7 8 9] }
func (f *encFnInfo) kArray(rv reflect.Value) { // We cannot share kSlice method, because the array may be non-addressable. // E.g. type struct S{B [2]byte}; Encode(S{}) will bomb on "panic: slice of unaddressable array". // So we have to duplicate the functionality here. // f.e.encodeValue(rv.Slice(0, rv.Len())) // f.kSlice(rv.Slice(0, rv.Len())) l := rv.Len() // Handle an array of bytes specially (in line with what is done for slices) rtelem := f.ti.rt.Elem() if rtelem.Kind() == reflect.Uint8 { if l == 0 { f.ee.encodeStringBytes(c_RAW, nil) return } var bs []byte if rv.CanAddr() { bs = rv.Slice(0, l).Bytes() } else { bs = make([]byte, l) for i := 0; i < l; i++ { bs[i] = byte(rv.Index(i).Uint()) } } f.ee.encodeStringBytes(c_RAW, bs) return } if f.ti.mbs { if l%2 == 1 { encErr("mapBySlice: invalid length (must be divisible by 2): %v", l) } f.ee.encodeMapPreamble(l / 2) } else { f.ee.encodeArrayPreamble(l) } if l == 0 { return } for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() } fn := f.e.getEncFn(rtelem) for j := 0; j < l; j++ { // TODO: Consider perf implication of encoding odd index values as symbols if type is string f.e.encodeValue(rv.Index(j), fn) } }
func DeleteEmptySliceElementsVal(sliceVal reflect.Value) reflect.Value { if sliceVal.Kind() != reflect.Slice { panic("Argument is not a slice: " + sliceVal.String()) } zeroVal := reflect.Zero(sliceVal.Type().Elem()) for i := 0; i < sliceVal.Len(); i++ { elemVal := sliceVal.Index(i) if reflect.DeepEqual(elemVal.Interface(), zeroVal.Interface()) { before := sliceVal.Slice(0, i) after := sliceVal.Slice(i+1, sliceVal.Len()) sliceVal = reflect.AppendSlice(before, after) i-- } } return sliceVal }
func (e *Encoder) encodeBytes(v reflect.Value, ln int) error { if ln <= 0xff { e.WriteByte(0xc4) e.WriteByte(byte(ln)) } else if ln <= 0xffff { e.WriteByte(0xc5) binary.Write(e.writer, binary.BigEndian, uint16(ln)) } else if ln <= 0xffffffff { e.WriteByte(0xc6) binary.Write(e.writer, binary.BigEndian, uint16(ln)) } else { return fmt.Errorf("bytes overflow length: %d", ln) } e.writer.Write(v.Slice(0, ln).Bytes()) return nil }
func decodeByteArray(b []byte, v reflect.Value) []byte { var n uint64 switch k := b[0]; { case k == 0x10: return b[1:] case 0xe0 <= k && k <= 0xeb: n, b = uint64(k-0xe0), b[1:] case 0xe0 <= k && k <= 0xef: n, b = decodeK4(b, 0xec) default: throwf("binn: cannot unmarshal %s into %s", describe(b), v.Type()) } copy(v.Slice(0, v.Len()).Bytes(), b[:n]) return b[n:] }