示例#1
0
文件: decode.go 项目: rasky/go-xdr
// decodeMap treats the next bytes as an XDR encoded variable array of 2-element
// structures whose fields are of the same type as the map keys and elements
// represented by the passed reflection value.  Pointers are automatically
// indirected and allocated as necessary.  It returns the  the number of bytes
// actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the elements.
func (d *Decoder) decodeMap(v reflect.Value) (int, error) {
	dataLen, n, err := d.DecodeUint()
	if err != nil {
		return n, err
	}

	// Allocate storage for the underlying map if needed.
	vt := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(vt))
	}

	// Decode each key and value according to their type.
	keyType := vt.Key()
	elemType := vt.Elem()
	for i := uint32(0); i < dataLen; i++ {
		key := reflect.New(keyType).Elem()
		n2, err := d.decode(key)
		n += n2
		if err != nil {
			return n, err
		}

		val := reflect.New(elemType).Elem()
		n2, err = d.decode(val)
		n += n2
		if err != nil {
			return n, err
		}
		v.SetMapIndex(key, val)
	}
	return n, nil
}
示例#2
0
func decodeMap(d *decodeState, kind int, v reflect.Value) {
	t := v.Type()
	if t.Key().Kind() != reflect.String || kind != kindDocument {
		d.saveErrorAndSkip(kind, t)
		return
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	subv := reflect.New(t.Elem()).Elem()
	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		subv.Set(reflect.Zero(t.Elem()))
		d.decodeValue(kind, subv)
		v.SetMapIndex(reflect.ValueOf(string(name)), subv)
	}
	d.endDoc(offset)
}
示例#3
0
文件: defaults.go 项目: i/defaults
func setField(field reflect.Value, defaultVal string) {
	var iface interface{}
	var err error

	switch field.Kind() {
	case reflect.Bool:
		iface, err = strconv.ParseBool(defaultVal)
	case reflect.Int:
		iface, err = strconv.ParseInt(defaultVal, 10, 64)
		iface = int(iface.(int64))
	case reflect.Int8:
		iface, err = strconv.ParseInt(defaultVal, 10, 8)
		iface = int8(iface.(int64))
	case reflect.Int16:
		iface, err = strconv.ParseInt(defaultVal, 10, 16)
		iface = int16(iface.(int64))
	case reflect.Int32:
		iface, err = strconv.ParseInt(defaultVal, 10, 32)
		iface = int32(iface.(int64))
	case reflect.Int64:
		t, err := time.ParseDuration(defaultVal)
		if err == nil {
			iface, err = t, nil
		} else {
			iface, err = strconv.ParseInt(defaultVal, 10, 64)
		}
	case reflect.Uint:
		iface, err = strconv.ParseUint(defaultVal, 10, 64)
		iface = uint(iface.(uint64))
	case reflect.Uint8:
		iface, err = strconv.ParseUint(defaultVal, 10, 8)
		iface = uint8(iface.(uint64))
	case reflect.Uint16:
		iface, err = strconv.ParseUint(defaultVal, 10, 16)
		iface = uint16(iface.(uint64))
	case reflect.Uint32:
		iface, err = strconv.ParseUint(defaultVal, 10, 32)
		iface = uint32(iface.(uint64))
	case reflect.Uint64:
		iface, err = strconv.ParseUint(defaultVal, 10, 64)
	case reflect.Uintptr:
		iface, err = strconv.ParseUint(defaultVal, 10, 64)
		iface = uintptr(iface.(uint64))
	case reflect.Float32:
		iface, err = strconv.ParseFloat(defaultVal, 32)
		iface = float32(iface.(float64))
	case reflect.Float64:
		iface, err = strconv.ParseFloat(defaultVal, 64)
	case reflect.String:
		iface = defaultVal
	default:
		err = errInvalidFieldType
	}

	if err == nil {
		if field.CanSet() {
			field.Set(reflect.ValueOf(iface))
		}
	}
}
示例#4
0
func (p *Decoder) unmarshalDictionary(pval *plistValue, val reflect.Value) {
	typ := val.Type()
	switch val.Kind() {
	case reflect.Struct:
		tinfo, err := getTypeInfo(typ)
		if err != nil {
			panic(err)
		}

		subvalues := pval.value.(*dictionary).m
		for _, finfo := range tinfo.fields {
			p.unmarshal(subvalues[finfo.name], finfo.value(val))
		}
	case reflect.Map:
		if val.IsNil() {
			val.Set(reflect.MakeMap(typ))
		}

		subvalues := pval.value.(*dictionary).m
		for k, sval := range subvalues {
			keyv := reflect.ValueOf(k).Convert(typ.Key())
			mapElem := val.MapIndex(keyv)
			if !mapElem.IsValid() {
				mapElem = reflect.New(typ.Elem()).Elem()
			}

			p.unmarshal(sval, mapElem)
			val.SetMapIndex(keyv, mapElem)
		}
	default:
		panic(&incompatibleDecodeTypeError{typ, pval.kind})
	}
}
示例#5
0
func decodeBSONData(d *decodeState, kind int, v reflect.Value) {
	start := d.offset
	d.skipValue(kind)
	bd := BSONData{Kind: kind, Data: make([]byte, d.offset-start)}
	copy(bd.Data, d.data[start:d.offset])
	v.Set(reflect.ValueOf(bd))
}
示例#6
0
func decodeTime(r io.Reader, f reflect.Value) error {
	s, err := decodeStr(r)
	if err != nil {
		return err
	}
	var t time.Time
	if s != "" {
		// Samsung has trailing dots.
		s = strings.TrimRight(s, ".")

		// Jolla Sailfish has trailing "Z".
		s = strings.TrimRight(s, "Z")

		t, err = time.Parse(timeFormat, s)
		if err != nil {
			// Nokia lumia has numTZ
			t, err = time.Parse(timeFormatNumTZ, s)
			if err != nil {
				return err
			}
		}
	}
	f.Set(reflect.ValueOf(t))
	return nil
}
示例#7
0
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string) error {
	if len(data) == 0 && p.parameter.Required && p.parameter.Default == nil {
		return errors.Required(p.Name, p.parameter.In)
	}
	defVal := reflect.Zero(target.Type())
	if defaultValue != nil {
		defVal = reflect.ValueOf(defaultValue)
	}
	if len(data) == 0 {
		target.Set(defVal)
		return nil
	}

	sz := len(data)
	value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)

	for i := 0; i < sz; i++ {
		if err := p.setFieldValue(value.Index(i), nil, data[i]); err != nil {
			return err
		}
	}

	target.Set(value)

	return nil
}
示例#8
0
func getSetter(outt reflect.Type, out reflect.Value) Setter {
	setterMutex.RLock()
	style := setterStyle[outt]
	setterMutex.RUnlock()
	if style == setterNone {
		return nil
	}
	if style == setterUnknown {
		setterMutex.Lock()
		defer setterMutex.Unlock()
		if outt.Implements(setterIface) {
			setterStyle[outt] = setterType
		} else if reflect.PtrTo(outt).Implements(setterIface) {
			setterStyle[outt] = setterAddr
		} else {
			setterStyle[outt] = setterNone
			return nil
		}
		style = setterStyle[outt]
	}
	if style == setterAddr {
		if !out.CanAddr() {
			return nil
		}
		out = out.Addr()
	} else if outt.Kind() == reflect.Ptr && out.IsNil() {
		out.Set(reflect.New(outt.Elem()))
	}
	return out.Interface().(Setter)
}
示例#9
0
文件: decode.go 项目: danprince/yaml
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
	outt := out.Type()
	if outt.Elem() != mapItemType {
		d.terror(n, yaml_MAP_TAG, out)
		return false
	}

	mapType := d.mapType
	d.mapType = outt

	var slice []MapItem
	var l = len(n.children)
	for i := 0; i < l; i += 2 {
		if isMerge(n.children[i]) {
			d.merge(n.children[i+1], out)
			continue
		}
		item := MapItem{}
		k := reflect.ValueOf(&item.Key).Elem()
		if d.unmarshal(n.children[i], k) {
			v := reflect.ValueOf(&item.Value).Elem()
			if d.unmarshal(n.children[i+1], v) {
				slice = append(slice, item)
			}
		}
	}
	out.Set(reflect.ValueOf(slice))
	d.mapType = mapType
	return true
}
示例#10
0
文件: network.go 项目: cgravill/antha
// Add adds a new process with a given name to the network.
// It returns true on success or panics and returns false on error.
func (n *Graph) Add(c interface{}, name string) bool {
	// Check if passed interface is a valid pointer to struct
	v := reflect.ValueOf(c)
	if v.Kind() != reflect.Ptr || v.IsNil() {
		panic("flow.Graph.Add() argument is not a valid pointer")
		return false
	}
	v = v.Elem()
	if v.Kind() != reflect.Struct {
		panic("flow.Graph.Add() argument is not a valid pointer to struct")
		return false
	}
	// Set the link to self in the proccess so that it could use it
	var vNet reflect.Value
	vCom := v.FieldByName("Component")
	if vCom.IsValid() && vCom.Type().Name() == "Component" {
		vNet = vCom.FieldByName("Net")
	} else {
		vGraph := v.FieldByName("Graph")
		if vGraph.IsValid() && vGraph.Type().Name() == "Graph" {
			vNet = vGraph.FieldByName("Net")
		}
	}
	if vNet.IsValid() && vNet.CanSet() {
		vNet.Set(reflect.ValueOf(n))
	}
	// Add to the map of processes
	n.procs[name] = c
	return true
}
示例#11
0
文件: base.go 项目: cgolang/qbs
func (d *base) SetModelValue(driverValue, fieldValue reflect.Value) error {
	// ignore zero types
	if !driverValue.Elem().IsValid() {
		return nil
	}
	switch fieldValue.Type().Kind() {
	case reflect.Bool:
		fieldValue.SetBool(d.Dialect.ParseBool(driverValue.Elem()))
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		fieldValue.SetInt(driverValue.Elem().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		// reading uint from int value causes panic
		switch driverValue.Elem().Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			fieldValue.SetUint(uint64(driverValue.Elem().Int()))
		default:
			fieldValue.SetUint(driverValue.Elem().Uint())
		}
	case reflect.Float32, reflect.Float64:
		fieldValue.SetFloat(driverValue.Elem().Float())
	case reflect.String:
		fieldValue.SetString(string(driverValue.Elem().Bytes()))
	case reflect.Slice:
		if reflect.TypeOf(driverValue.Interface()).Elem().Kind() == reflect.Uint8 {
			fieldValue.SetBytes(driverValue.Elem().Bytes())
		}
	case reflect.Struct:
		if _, ok := fieldValue.Interface().(time.Time); ok {
			fieldValue.Set(driverValue.Elem())
		}
	}
	return nil
}
示例#12
0
// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
func indirect(v reflect.Value) reflect.Value {
	// If v is a named type and is addressable,
	// start with its address, so that if the type has pointer methods,
	// we find them.
	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
		v = v.Addr()
	}
	for {
		// Load value from interface, but only if the result will be
		// usefully addressable.
		if v.Kind() == reflect.Interface && !v.IsNil() {
			e := v.Elem()
			if e.Kind() == reflect.Ptr && !e.IsNil() && e.Elem().Kind() == reflect.Ptr {
				v = e
				continue
			}
		}

		if v.Kind() != reflect.Ptr {
			break
		}

		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		v = v.Elem()
	}
	return v
}
示例#13
0
文件: decode.go 项目: xushiwei/goyaml
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
	if set := d.setter("!!seq", &out, &good); set != nil {
		defer set()
	}
	if out.Kind() == reflect.Interface {
		// No type hints. Will have to use a generic sequence.
		iface := out
		out = settableValueOf(make([]interface{}, 0))
		iface.Set(out)
	}

	if out.Kind() != reflect.Slice {
		return false
	}
	et := out.Type().Elem()

	l := len(n.children)
	for i := 0; i < l; i++ {
		e := reflect.New(et).Elem()
		if ok := d.unmarshal(n.children[i], e); ok {
			out.Set(reflect.Append(out, e))
		}
	}
	return true
}
示例#14
0
func hydrateNestedComponent(v reflect.Value, component *token) error {

	// create a new object to hold the property value
	var vnew, varr = newValue(v)
	if err := hydrateComponent(vnew, component); err != nil {
		return utils.NewError(hydrateNestedComponent, "unable to decode component", component, err)
	}

	if varr {
		// for arrays, append the new value into the array structure
		voldval := dereferencePointerValue(v)
		if !voldval.CanSet() {
			return utils.NewError(hydrateNestedComponent, "unable to set array value", v, nil)
		} else {
			voldval.Set(reflect.Append(voldval, vnew))
		}
	} else if !v.CanSet() {
		return utils.NewError(hydrateNestedComponent, "unable to set pointer value", v, nil)
	} else {
		// everything else should be a pointer, set it directly
		v.Set(vnew)
	}

	return nil

}
示例#15
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))
		}
		sv := v.Index(i)
		if err := d.DecodeValue(sv); err != nil {
			return err
		}
	}

	return nil
}
示例#16
0
文件: decode.go 项目: amasses/form
func decodeMap(v reflect.Value, x interface{}) {
	t := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	for k, c := range getNode(x) {
		i := reflect.New(t.Key()).Elem()
		decodeValue(i, k)

		w := v.MapIndex(i)
		if w.IsValid() { // We have an actual element value to decode into.
			if w.Kind() == reflect.Interface {
				w = w.Elem()
			}
			w = reflect.New(w.Type()).Elem()
		} else if t.Elem().Kind() != reflect.Interface { // The map's element type is concrete.
			w = reflect.New(t.Elem()).Elem()
		} else {
			// The best we can do here is to decode as either a string (for scalars) or a map[string]interface {} (for the rest).
			// We could try to guess the type based on the string (e.g. true/false => bool) but that'll get ugly fast,
			// especially if we have to guess the kind (slice vs. array vs. map) and index type (e.g. string, int, etc.)
			switch c.(type) {
			case node:
				w = reflect.MakeMap(stringMapType)
			case string:
				w = reflect.New(stringType).Elem()
			default:
				panic("value is neither node nor string")
			}
		}

		decodeValue(w, c)
		v.SetMapIndex(i, w)
	}
}
示例#17
0
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()
}
示例#18
0
文件: decode.go 项目: amasses/form
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)
	}
}
示例#19
0
文件: scan.go 项目: 42wim/ulog2queue
func ensureLen(d reflect.Value, n int) {
	if n > d.Cap() {
		d.Set(reflect.MakeSlice(d.Type(), n, n))
	} else {
		d.SetLen(n)
	}
}
示例#20
0
func decodeCustomValues(incoming reflect.Value, incomingField reflect.StructField, data string) error {
	/* Incoming is a slice */
	underlyingType := incoming.Type().Elem()

	var delim = " "
	if it := incomingField.Tag.Get("delim"); it != "" {
		delim = it
	}

	var strip = ""
	if it := incomingField.Tag.Get("strip"); it != "" {
		strip = it
	}

	if strip != "" {
		data = strings.Trim(data, strip)
	}

	for _, el := range strings.Split(data, delim) {
		if strip != "" {
			el = strings.Trim(el, strip)
		}

		targetValue := reflect.New(underlyingType)
		err := decodeValue(targetValue.Elem(), incomingField, el)
		if err != nil {
			return err
		}
		incoming.Set(reflect.Append(incoming, targetValue.Elem()))
	}
	return nil
}
示例#21
0
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
}
示例#22
0
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))
	}
}
示例#23
0
func (p *Decoder) unmarshalLaxString(s string, val reflect.Value) {
	switch val.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i := mustParseInt(s, 10, 64)
		val.SetInt(i)
		return
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		i := mustParseUint(s, 10, 64)
		val.SetUint(i)
		return
	case reflect.Float32, reflect.Float64:
		f := mustParseFloat(s, 64)
		val.SetFloat(f)
		return
	case reflect.Bool:
		b := mustParseBool(s)
		val.SetBool(b)
		return
	case reflect.Struct:
		if val.Type() == timeType {
			t, err := time.Parse(textPlistTimeLayout, s)
			if err != nil {
				panic(err)
			}
			val.Set(reflect.ValueOf(t.In(time.UTC)))
			return
		}
		fallthrough
	default:
		panic(&incompatibleDecodeTypeError{val.Type(), String})
	}
}
示例#24
0
文件: base.go 项目: koujun2012/qbs
func (d base) setModelValue(driverValue, fieldValue reflect.Value) error {
	switch fieldValue.Type().Kind() {
	case reflect.Bool:
		fieldValue.SetBool(d.dialect.parseBool(driverValue.Elem()))
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		fieldValue.SetInt(driverValue.Elem().Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		// reading uint from int value causes panic
		switch driverValue.Elem().Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			fieldValue.SetUint(uint64(driverValue.Elem().Int()))
		default:
			fieldValue.SetUint(driverValue.Elem().Uint())
		}
	case reflect.Float32, reflect.Float64:
		fieldValue.SetFloat(driverValue.Elem().Float())
	case reflect.String:
		fieldValue.SetString(string(driverValue.Elem().Bytes()))
	case reflect.Slice:
		if reflect.TypeOf(driverValue.Interface()).Elem().Kind() == reflect.Uint8 {
			fieldValue.SetBytes(driverValue.Elem().Bytes())
		}
	case reflect.Struct:
		switch fieldValue.Interface().(type) {
		case time.Time:
			fieldValue.Set(driverValue.Elem())
		default:
			if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
				return scanner.Scan(driverValue.Interface())
			}
		}

	}
	return nil
}
示例#25
0
func decodeMapStringInterface(d *decodeState, kind int, v reflect.Value) {
	if kind != kindDocument {
		d.saveErrorAndSkip(kind, v.Type())
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(v.Type()))
	}

	var m map[string]interface{}
	switch mm := v.Interface().(type) {
	case map[string]interface{}:
		m = mm
	case M:
		m = (map[string]interface{})(mm)
	}

	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		m[string(name)] = d.decodeValueInterface(kind)
	}
	d.endDoc(offset)
}
示例#26
0
文件: mapper.go 项目: unrolled/jet
func (m *mapper) unpackValue(keys []string, values []interface{}, out reflect.Value) error {
	switch out.Kind() {
	case reflect.Ptr:
		if out.IsNil() {
			out.Set(reflect.New(out.Type().Elem()))
		}
		return m.unpackValue(keys, values, reflect.Indirect(out))
	case reflect.Slice:
		if keys == nil {
			return m.unpackSimple(nil, values, out)
		} else {
			return m.unpackSlice(keys, values, out)
		}
	case reflect.Struct:
		return m.unpackStruct(keys, values, out)
	case reflect.Map:
		if keys == nil {
			return m.unpackSimple(nil, values, out)
		} else {
			return m.unpackMap(keys, values, out)
		}
	default:
		return m.unpackSimple(nil, values, out)
	}
	return fmt.Errorf("cannot unpack result to %T (%s)", out, out.Kind())
}
示例#27
0
文件: env.go 项目: coolwust/env
// rv must be a non-nil pointer or a settable value
func indirect(rv reflect.Value) (reflect.Value, error) {
	for {
		if rv.Kind() == reflect.Interface && !rv.IsNil() {
			if e := rv.Elem(); e.Kind() == reflect.Ptr && !e.IsNil() {
				rv = e.Elem()
			}
		}

		if rv.Kind() == reflect.Map && rv.IsNil() {
			rv.Set(reflect.MakeMap(rv.Type()))
		}

		if rv.Kind() != reflect.Ptr {
			break
		}

		if rv.IsNil() {
			rv.Set(reflect.New(rv.Type().Elem()))
		}
		rv = rv.Elem()
	}
	if k := rv.Kind(); k != reflect.Struct && k != reflect.Map {
		return reflect.Value{}, &InvalidIndirectError{rv.Type()}
	}
	if rv.Kind() == reflect.Map {
		if t := rv.Type(); t.Key().Kind() != reflect.String || t.Elem().Kind() != reflect.String {
			return reflect.Value{}, &InvalidIndirectError{t}
		}
	}
	return rv, nil
}
示例#28
0
func decodeIntSlice(val *uint16, data []byte, sf *SprotoField, v reflect.Value) error {
	dataLen := len(data)
	if dataLen < 1 {
		return ErrTooShort
	}
	intLen := int(data[0])
	if (dataLen-1)%intLen != 0 {
		return fmt.Errorf("sproto: malformed integer data for field %s", sf.Name)
	}
	sz := (dataLen - 1) / intLen
	vals := reflect.MakeSlice(v.Type(), sz, sz)
	data = data[1:]
	var n uint64
	for i := 0; i < sz; i++ {
		if intLen == 4 {
			n = uint64(readUint32(data[i*intLen:]))
		} else {
			n = readUint64(data[i*intLen:])
		}

		val := vals.Index(i)
		switch e := v.Type().Elem(); e.Kind() {
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
			val.SetInt(int64(n))
		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
			val.SetUint(n)
		}
	}
	v.Set(vals)
	return nil
}
示例#29
0
文件: decode.go 项目: MG-RAST/Shock
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))
	}
}
示例#30
0
// indirect will walk a value's interface or pointer value types. Returning
// the final value or the value a unmarshaler is defined on.
//
// Based on the enoding/json type reflect value type indirection in Go Stdlib
// https://golang.org/src/encoding/json/decode.go indirect func.
func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, reflect.Value) {
	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
		v = v.Addr()
	}
	for {
		if v.Kind() == reflect.Interface && !v.IsNil() {
			e := v.Elem()
			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
				v = e
				continue
			}
		}
		if v.Kind() != reflect.Ptr {
			break
		}
		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
			break
		}
		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		if v.Type().NumMethod() > 0 {
			if u, ok := v.Interface().(Unmarshaler); ok {
				return u, reflect.Value{}
			}
		}
		v = v.Elem()
	}

	return nil, v
}