func encodeValue(buf []byte, prefix, name string, fv reflect.Value, inArray, arrayTable bool) ([]byte, error) { switch t := fv.Interface().(type) { case Marshaler: b, err := t.MarshalTOML() if err != nil { return nil, err } return appendNewline(append(appendKey(buf, name, inArray, arrayTable), b...), inArray, arrayTable), nil case time.Time: return appendNewline(encodeTime(appendKey(buf, name, inArray, arrayTable), t), inArray, arrayTable), nil } switch fv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return appendNewline(encodeInt(appendKey(buf, name, inArray, arrayTable), fv.Int()), inArray, arrayTable), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return appendNewline(encodeUint(appendKey(buf, name, inArray, arrayTable), fv.Uint()), inArray, arrayTable), nil case reflect.Float32, reflect.Float64: return appendNewline(encodeFloat(appendKey(buf, name, inArray, arrayTable), fv.Float()), inArray, arrayTable), nil case reflect.Bool: return appendNewline(encodeBool(appendKey(buf, name, inArray, arrayTable), fv.Bool()), inArray, arrayTable), nil case reflect.String: return appendNewline(encodeString(appendKey(buf, name, inArray, arrayTable), fv.String()), inArray, arrayTable), nil case reflect.Slice, reflect.Array: ft := fv.Type().Elem() for ft.Kind() == reflect.Ptr { ft = ft.Elem() } if ft.Kind() == reflect.Struct { name := tableName(prefix, name) var err error for i := 0; i < fv.Len(); i++ { if buf, err = marshal(append(append(append(buf, '[', '['), name...), ']', ']', '\n'), name, fv.Index(i), false, true); err != nil { return nil, err } } return buf, nil } buf = append(appendKey(buf, name, inArray, arrayTable), '[') var err error for i := 0; i < fv.Len(); i++ { if i != 0 { buf = append(buf, ',') } if buf, err = encodeValue(buf, prefix, name, fv.Index(i), true, false); err != nil { return nil, err } } return appendNewline(append(buf, ']'), inArray, arrayTable), nil case reflect.Struct: name := tableName(prefix, name) return marshal(append(append(append(buf, '['), name...), ']', '\n'), name, fv, inArray, arrayTable) case reflect.Interface: var err error if buf, err = encodeInterface(appendKey(buf, name, inArray, arrayTable), fv.Interface()); err != nil { return nil, err } return appendNewline(buf, inArray, arrayTable), nil } return nil, fmt.Errorf("toml: marshal: unsupported type %v", fv.Kind()) }
func (d *decoder) readArrayDocTo(out reflect.Value) { end := int(d.readInt32()) end += d.i - 4 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { corrupted() } i := 0 l := out.Len() for d.in[d.i] != '\x00' { if i >= l { panic("Length mismatch on array field") } kind := d.readByte() for d.i < end && d.in[d.i] != '\x00' { d.i++ } if d.i >= end { corrupted() } d.i++ d.readElemTo(out.Index(i), kind) if d.i >= end { corrupted() } i++ } if i != l { panic("Length mismatch on array field") } d.i++ // '\x00' if d.i != end { corrupted() } }
func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.Func, reflect.Map, reflect.Slice: return v.IsNil() case reflect.Array: z := true for i := 0; i < v.Len(); i++ { z = z && isZero(v.Index(i)) } return z case reflect.Struct: if v.Type() == reflect.TypeOf(t) { if v.Interface().(time.Time).IsZero() { return true } return false } z := true for i := 0; i < v.NumField(); i++ { z = z && isZero(v.Field(i)) } return z } // Compare other types directly: z := reflect.Zero(v.Type()) return v.Interface() == z.Interface() }
// callSliceRequired returns true if CallSlice is required instead of Call. func callSliceRequired(param reflect.Type, val reflect.Value) bool { vt := val.Type() for param.Kind() == reflect.Slice { if val.Kind() == reflect.Interface { val = reflect.ValueOf(val.Interface()) vt = val.Type() } if vt.Kind() != reflect.Slice { return false } vt = vt.Elem() if val.Kind() != reflect.Invalid { if val.Len() > 0 { val = val.Index(0) } else { val = reflect.Value{} } } param = param.Elem() } return true }
func convertSliceToCFArrayHelper(slice reflect.Value, helper func(reflect.Value) (cfTypeRef, error)) (C.CFArrayRef, error) { if slice.Len() == 0 { // short-circuit 0, so we can assume plists[0] is valid later return C.CFArrayCreate(nil, nil, 0, nil), nil } // assume slice is a slice/array, because our caller already checked plists := make([]cfTypeRef, slice.Len()) // defer the release defer func() { for _, cfObj := range plists { cfRelease(cfObj) } }() // convert the slice for i := 0; i < slice.Len(); i++ { cfType, err := helper(slice.Index(i)) if err != nil { return nil, err } plists[i] = cfType } // create the array callbacks := (*C.CFArrayCallBacks)(&C.kCFTypeArrayCallBacks) return C.CFArrayCreate(nil, (*unsafe.Pointer)(&plists[0]), C.CFIndex(len(plists)), callbacks), nil }
func normalizeArray( opts *options, tagOpts tagOptions, ctx context, v reflect.Value, ) (value, Error) { l := v.Len() out := make([]value, 0, l) cfg := New() cfg.metadata = opts.meta cfg.ctx = ctx val := cfgSub{cfg} for i := 0; i < l; i++ { idx := fmt.Sprintf("%v", i) ctx := context{ parent: val, field: idx, } tmp, err := normalizeValue(opts, tagOpts, ctx, v.Index(i)) if err != nil { return nil, err } out = append(out, tmp) } cfg.fields.a = out return val, nil }
func readSlice(in io.Reader, obj reflect.Value) { len := int(readUint(in)) obj.Set(reflect.MakeSlice(obj.Type(), len, len)) for i := 0; i < len; i++ { readAny(in, obj.Index(i)) } }
// checkWhereArray handles the where-matching logic when the seqv value is an // Array or Slice. func checkWhereArray( seqv, kv, mv reflect.Value, path []string, op string) (interface{}, error) { rv := reflect.MakeSlice(seqv.Type(), 0, 0) for i := 0; i < seqv.Len(); i++ { var vvv reflect.Value rvv := seqv.Index(i) if kv.Kind() == reflect.String { vvv = rvv for _, elemName := range path { var err error vvv, err = evaluateSubElem(vvv, elemName) if err != nil { return nil, err } } } else { vv, _ := indirect(rvv) if vv.Kind() == reflect.Map && kv.Type().AssignableTo(vv.Type().Key()) { vvv = vv.MapIndex(kv) } } if ok, err := checkCondition(vvv, mv, op); ok { rv = reflect.Append(rv, rvv) } else if err != nil { return nil, err } } return rv.Interface(), nil }
// isZero reports whether the value is the zero of its type. func isZero(val reflect.Value) bool { switch val.Kind() { case reflect.Array: for i := 0; i < val.Len(); i++ { if !isZero(val.Index(i)) { return false } } return true case reflect.Map, reflect.Slice, reflect.String: return val.Len() == 0 case reflect.Bool: return !val.Bool() case reflect.Complex64, reflect.Complex128: return val.Complex() == 0 case reflect.Chan, reflect.Func, reflect.Ptr: return val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return val.Int() == 0 case reflect.Float32, reflect.Float64: return val.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return val.Uint() == 0 case reflect.Struct: for i := 0; i < val.NumField(); i++ { if !isZero(val.Field(i)) { return false } } return true } panic("unknown type in isZero " + val.Type().String()) }
// visit calls the visitor function for each string it finds, and will descend // recursively into structures and slices. If any visitor returns an error then // the search will stop and that error will be returned. func visit(path string, v reflect.Value, t reflect.Type, fn visitor) error { switch v.Kind() { case reflect.String: return fn(path, v) case reflect.Struct: for i := 0; i < v.NumField(); i++ { vf := v.Field(i) tf := t.Field(i) newPath := fmt.Sprintf("%s.%s", path, tf.Name) if err := visit(newPath, vf, tf.Type, fn); err != nil { return err } } case reflect.Slice: for i := 0; i < v.Len(); i++ { vi := v.Index(i) ti := vi.Type() newPath := fmt.Sprintf("%s[%d]", path, i) if err := visit(newPath, vi, ti, fn); err != nil { return err } } } return nil }
func (e *encoder) slicev(tag string, in reflect.Value) { var ctag *C.yaml_char_t var free func() var cimplicit C.int if tag != "" { ctag, free = ystr(tag) defer free() cimplicit = 0 } else { cimplicit = 1 } cstyle := C.yaml_sequence_style_t(C.YAML_BLOCK_SEQUENCE_STYLE) if e.flow { e.flow = false cstyle = C.YAML_FLOW_SEQUENCE_STYLE } C.yaml_sequence_start_event_initialize(&e.event, nil, ctag, cimplicit, cstyle) e.emit() n := in.Len() for i := 0; i < n; i++ { e.marshal("", in.Index(i)) } C.yaml_sequence_end_event_initialize(&e.event) e.emit() }
func encodeArray(v reflect.Value) interface{} { n := node{} for i := 0; i < v.Len(); i++ { n[strconv.Itoa(i)] = encodeValue(v.Index(i)) } return n }
func (f *Field) Size(val reflect.Value, options *Options) int { typ := f.Type.Resolve(options) size := 0 if typ == Struct { vals := []reflect.Value{val} if f.Slice { vals = make([]reflect.Value, val.Len()) for i := 0; i < val.Len(); i++ { vals[i] = val.Index(i) } } for _, val := range vals { size += f.Fields.Sizeof(val, options) } } else if typ == Pad { size = f.Len } else if f.Slice || f.kind == reflect.String { length := val.Len() if f.Len > 1 { length = f.Len } size = length * typ.Size() } else if typ == CustomType { return val.Addr().Interface().(Custom).Size(options) } else { size = typ.Size() } align := options.ByteAlign if align > 0 && size < align { size = align } return size }
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 convertToFloat64(depth int, v reflect.Value) (float64, bool) { if v.Kind() == reflect.Interface { v = v.Elem() } switch v.Kind() { case reflect.Float32, reflect.Float64: return v.Float(), true case reflect.Int16, reflect.Int8, reflect.Int, reflect.Int32, reflect.Int64: return float64(v.Int()), true case reflect.String: s := v.String() var f float64 var err error if strings.HasPrefix(s, "0x") { f, err = strconv.ParseFloat(s, 64) } else { f, err = strconv.ParseFloat(s, 64) } if err == nil { return float64(f), true } if depth == 0 { s = intStrReplacer.Replace(s) rv := reflect.ValueOf(s) return convertToFloat64(1, rv) } case reflect.Slice: // Should we grab first one? Or Error? //u.Warnf("ToFloat() but is slice?: %T first=%v", v, v.Index(0)) return convertToFloat64(0, v.Index(0)) default: //u.Warnf("Cannot convert type? %v", v.Kind()) } return math.NaN(), false }
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) 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 (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 decodeSlice(v reflect.Value, x interface{}) { t := v.Type() if t.Elem().Kind() == reflect.Uint8 { // Allow, but don't require, byte slices to be encoded as a single string. if s, ok := x.(string); ok { v.SetBytes([]byte(s)) return } } // NOTE: Implicit indexing is currently done at the parseValues level, // so if if an implicitKey reaches here it will always replace the last. implicit := 0 for k, c := range getNode(x) { var i int if k == implicitKey { i = implicit implicit++ } else { explicit, err := strconv.Atoi(k) if err != nil { panic(k + " is not a valid index for type " + t.String()) } i = explicit implicit = explicit + 1 } // "Extend" the slice if it's too short. if l := v.Len(); i >= l { delta := i - l + 1 v.Set(reflect.AppendSlice(v, reflect.MakeSlice(t, delta, delta))) } decodeValue(v.Index(i), c) } }
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 encodeSliceContent(buf *bytes2.ChunkedWriter, val reflect.Value) { lenWriter := NewLenWriter(buf) for i := 0; i < val.Len(); i++ { encodeField(buf, Itoa(i), val.Index(i)) } lenWriter.Close() }
// decodeArrayInterface decodes the source value into []interface{} func decodeArrayInterface(s *decodeState, sv reflect.Value) []interface{} { arr := []interface{}{} for i := 0; i < sv.Len(); i++ { arr = append(arr, decodeInterface(s, sv.Index(i))) } return arr }
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 plain_extract_value(name string, field reflect.Value) url.Values { values := make(url.Values) switch field.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: values.Add(name, strconv.FormatInt(field.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: values.Add(name, strconv.FormatUint(field.Uint(), 10)) case reflect.Bool: values.Add(name, strconv.FormatBool(field.Bool())) case reflect.Struct: values = merge(values, plain_extract_struct(field)) case reflect.Slice: for i := 0; i < field.Len(); i++ { sv := field.Index(i) values = merge(values, plain_extract_value(name, sv)) } case reflect.String: values.Add(name, field.String()) case reflect.Float32, reflect.Float64: values.Add(name, strconv.FormatFloat(field.Float(), 'f', -1, 64)) case reflect.Ptr, reflect.Interface: values = merge(values, plain_extract_pointer(field)) } return values }
func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { // If it's empty, generate an empty value if !value.IsNil() && value.Len() == 0 { v.Set(prefix, "") return nil } // check for unflattened list member if !q.isEC2 && tag.Get("flattened") == "" { prefix += ".member" } for i := 0; i < value.Len(); i++ { slicePrefix := prefix if slicePrefix == "" { slicePrefix = strconv.Itoa(i + 1) } else { slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) } if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil { return err } } return nil }
func display(name string, v reflect.Value) { switch v.Kind() { //uint case reflect.Invalid: fmt.Printf("%s = invalid\n", name) case reflect.Slice, reflect.Array: for i := 0; i < v.Len(); i++ { display(fmt.Sprintf("%s[%d]", name, i), v.Index(i)) } case reflect.Struct: for i := 0; i < v.NumField(); i++ { fieldPath := fmt.Sprintf("%s.%s", name, v.Type().Field(i).Name) display(fieldPath, v.Field(i)) } case reflect.Map: for _, key := range v.MapKeys() { display(fmt.Sprintf("%s[%s]", name, formatAtom(key)), v.MapIndex(key)) } case reflect.Ptr: if v.IsNil() { fmt.Printf("%s = nil\n", name) } else { display(fmt.Sprintf("(*%s)", name), v.Elem()) } case reflect.Interface: if v.IsNil() { fmt.Printf("%s = nil\n", name) } else { fmt.Printf("%s.type = %s\n", name, v.Elem().Type()) display(name+".value", v.Elem()) } default: // basic types, channels, funcs fmt.Printf("%s = %s\n", name, formatAtom(v)) } }
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 assertValid(vObj reflect.Value) error { if !vObj.IsValid() { return nil } if obj, ok := vObj.Interface().(interface { AssertValid() error }); ok && !(vObj.Kind() == reflect.Ptr && vObj.IsNil()) { if err := obj.AssertValid(); err != nil { return err } } switch vObj.Kind() { case reflect.Ptr: return assertValid(vObj.Elem()) case reflect.Struct: return assertStructValid(vObj) case reflect.Slice: for i := 0; i < vObj.Len(); i++ { if err := assertValid(vObj.Index(i)); err != nil { return err } } } 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)) } }
// toInt64 convert all reflect.Value-s into int64. func ToInt64(v reflect.Value) (int64, bool) { if v.Kind() == reflect.Interface { v = v.Elem() } switch v.Kind() { case reflect.Float32, reflect.Float64: return int64(v.Float()), true case reflect.Int, reflect.Int32, reflect.Int64: return v.Int(), true case reflect.String: s := v.String() var i int64 var err error if strings.HasPrefix(s, "0x") { i, err = strconv.ParseInt(s, 16, 64) } else if strings.Contains(s, ".") { fv, err := strconv.ParseFloat(s, 64) if err == nil { return int64(fv), true } return int64(0), false } else { i, err = strconv.ParseInt(s, 10, 64) } if err == nil { return int64(i), true } case reflect.Slice: if v.Len() > 0 { return ToInt64(v.Index(0)) } } return 0, false }