示例#1
0
文件: decode.go 项目: LindenY/gomdise
func (mapDec *mapDecoder) decode(node RMNode, data interface{}, v reflect.Value) {
	values, err := redis.Values(node.Value(), nil)
	if err != nil {
		panic(err)
	}

	size := len(values) / 2
	vals, err := redis.Values(node.Value(), nil)
	if err != nil {
		panic(err)
	}
	v.Set(reflect.MakeMap(v.Type()))

	for i := 0; i < size; i++ {
		mKey, err := redis.String(values[i*2], nil)
		if err != nil {
			panic(err)
		}
		elemV := newValueForType(v.Type().Elem())
		if i < node.Size() {
			mapDec.elemFunc(node.Child(i), vals[i*2+1], elemV)
		} else {
			mapDec.elemFunc(node, vals[i*2+1], elemV)
		}
		v.SetMapIndex(reflect.ValueOf(mKey), elemV)
	}
}
示例#2
0
func (d *decoder) mapCopy(src reflect.Value, dst reflect.Value) error {
	sv := src.MapKeys()
	dt := dst.Type().Elem()

	for i := range sv {
		ot := reflect.New(dt)

		if dt.Kind() == reflect.Ptr {
			ot = reflect.New(ot.Type().Elem())
		}

		d.pushPath(sv[i].String())
		err := d.decode(src.MapIndex(sv[i]), ot)
		if err != nil && err != ErrIncompatStruct {
			err = errors.New(d.pathString() + err.Error())
			d.path = nil
			return err
		}
		d.popPath()

		if err == nil {
			dst.SetMapIndex(sv[i], ot.Elem())
		}
	}
	return nil
}
示例#3
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)
}
示例#4
0
func (d *mapAsMapDecoder) decode(dv, sv reflect.Value) {
	dt := dv.Type()
	dv.Set(reflect.MakeMap(reflect.MapOf(dt.Key(), dt.Elem())))

	var mapKey reflect.Value
	var mapElem reflect.Value

	keyType := dv.Type().Key()
	elemType := dv.Type().Elem()

	for _, sElemKey := range sv.MapKeys() {
		var dElemKey reflect.Value
		var dElemVal reflect.Value

		if !mapKey.IsValid() {
			mapKey = reflect.New(keyType).Elem()
		} else {
			mapKey.Set(reflect.Zero(keyType))
		}
		dElemKey = mapKey

		if !mapElem.IsValid() {
			mapElem = reflect.New(elemType).Elem()
		} else {
			mapElem.Set(reflect.Zero(elemType))
		}
		dElemVal = mapElem

		d.keyDec(dElemKey, sElemKey)
		d.elemDec(dElemVal, sv.MapIndex(sElemKey))

		dv.SetMapIndex(dElemKey, dElemVal)
	}
}
示例#5
0
文件: decode.go 项目: niltonkummer/go
func (f *decFnInfo) kMap(rv reflect.Value) {
	containerLen := f.dd.readMapLen()

	if rv.IsNil() {
		rv.Set(reflect.MakeMap(f.rt))
	}

	if containerLen == 0 {
		return
	}

	ktype, vtype := f.rt.Key(), f.rt.Elem()
	for j := 0; j < containerLen; j++ {
		rvk := reflect.New(ktype).Elem()
		f.d.decodeValue(rvk)

		if ktype == intfTyp {
			rvk = rvk.Elem()
			if rvk.Type() == byteSliceTyp {
				rvk = reflect.ValueOf(string(rvk.Bytes()))
			}
		}
		rvv := rv.MapIndex(rvk)
		if !rvv.IsValid() {
			rvv = reflect.New(vtype).Elem()
		}

		f.d.decodeValue(rvv)
		rv.SetMapIndex(rvk, rvv)
	}
}
示例#6
0
文件: clone.go 项目: zwczou/goserver
func deepCopyMap(src, dst reflect.Value, t reflect.Type) {
	for _, key := range src.MapKeys() {
		var nkey, nval reflect.Value
		if key.IsValid() && key.CanSet() {
			if key.Kind() == reflect.Ptr {
				nkey = reflect.New(key.Elem().Type())
			} else {
				nkey = reflect.New(key.Type())
				nkey = reflect.Indirect(nkey)
			}
			s := reflect.Indirect(key)
			d := reflect.Indirect(nkey)
			tt := s.Type()
			deepCopy(s, d, tt)
		} else {
			nkey = key
		}
		if val := src.MapIndex(key); val.IsValid() && val.CanSet() {
			if val.Kind() == reflect.Ptr {
				nval = reflect.New(val.Elem().Type())
			} else {
				nval = reflect.New(val.Type())
				nval = reflect.Indirect(nval)
			}
			s := reflect.Indirect(val)
			d := reflect.Indirect(nval)
			tt := s.Type()
			deepCopy(s, d, tt)
		} else {
			nval = val
		}
		dst.SetMapIndex(nkey, nval)
	}
}
示例#7
0
func Uniq(source, selector interface{}) interface{} {
	if selector == nil {
		selector = func(value, _ interface{}) Facade {
			return Facade{reflect.ValueOf(value)}
		}
	}

	var mapRV reflect.Value
	var arrRV reflect.Value
	each(source, selector, func(resRV, valueRv, _ reflect.Value) bool {
		if !mapRV.IsValid() {
			mapRT := reflect.MapOf(resRV.Type(), reflect.TypeOf(false))
			mapRV = reflect.MakeMap(mapRT)

			arrRT := reflect.SliceOf(valueRv.Type())
			arrRV = reflect.MakeSlice(arrRT, 0, 0)
		}

		mapValueRV := mapRV.MapIndex(resRV)
		if !mapValueRV.IsValid() {
			mapRV.SetMapIndex(resRV, reflect.ValueOf(true))
			arrRV = reflect.Append(arrRV, valueRv)
		}
		return false
	})
	if mapRV.IsValid() {
		return arrRV.Interface()
	}

	return nil
}
示例#8
0
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
	tmap, ok := mapping.(map[string]interface{})
	if !ok {
		if tmap == nil {
			return nil
		}
		return badtype("map", mapping)
	}
	if rv.IsNil() {
		rv.Set(reflect.MakeMap(rv.Type()))
	}
	for k, v := range tmap {
		md.decoded[md.context.add(k).String()] = true
		md.context = append(md.context, k)

		rvkey := indirect(reflect.New(rv.Type().Key()))
		rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
		if err := md.unify(v, rvval); err != nil {
			return err
		}
		md.context = md.context[0 : len(md.context)-1]

		rvkey.SetString(k)
		rv.SetMapIndex(rvkey, rvval)
	}
	return nil
}
示例#9
0
文件: types.go 项目: DavyC/goa
// MakeMap examines the key type from a Hash and create a map with builtin type if possible.
// The idea is to avoid generating map[interface{}]interface{}, which cannot be handled by json.Marshal.
func (h *Hash) MakeMap(pair map[interface{}]interface{}) interface{} {
	if !h.KeyType.Type.IsPrimitive() {
		// well, a type can't be handled by json.Marshal... not much we can do
		return pair
	}
	if len(pair) == 0 {
		// figure out the map type manually
		switch h.KeyType.Type.Kind() {
		case BooleanKind:
			return map[bool]interface{}{}
		case IntegerKind:
			return map[int]interface{}{}
		case NumberKind:
			return map[float64]interface{}{}
		case StringKind:
			return map[string]interface{}{}
		case DateTimeKind:
			return map[time.Time]interface{}{}
		default:
			return pair
		}
	}
	var newMap reflect.Value
	for key, value := range pair {
		rkey, rvalue := reflect.ValueOf(key), reflect.ValueOf(value)
		if !newMap.IsValid() {
			newMap = reflect.MakeMap(reflect.MapOf(rkey.Type(), rvalue.Type()))
		}
		newMap.SetMapIndex(rkey, rvalue)
	}
	return newMap.Interface()
}
示例#10
0
文件: MapType.go 项目: iizotop/kmg
func (t *MapType) DeleteByPath(v *reflect.Value, path Path) (err error) {
	err = t.Init()
	if err != nil {
		return
	}
	if len(path) > 1 {
		vk, err := t.KeyStringConverter.FromString(path[0])
		if err != nil {
			return err
		}
		ev := v.MapIndex(vk)
		et := t.ElemType
		oEv := ev
		err = et.DeleteByPath(&ev, path[1:])
		if err != nil {
			return err
		}
		if oEv == ev {
			return nil
		}
		v.SetMapIndex(vk, ev)
		return nil
	} else if len(path) == 0 {
		return fmt.Errorf("[MapType.DeleteByPath] delete map with no path.")
	}
	//Addressable?
	vk, err := t.KeyStringConverter.FromString(path[0])
	if err != nil {
		return err
	}
	v.SetMapIndex(vk, reflect.Value{})
	return nil
}
示例#11
0
func (q *queryDecoder) decodeMap(output reflect.Value, prefix string, tag reflect.StructTag) error {
	// check for unflattened list member
	if !q.isEC2 && tag.Get("flattened") == "" {
		prefix += ".entry"
	}
	namer := newMapNamer(prefix, tag)

	mapType := output.Type()
	output.Set(reflect.MakeMap(mapType))

	keyType := mapType.Key()
	valueType := mapType.Elem()

	for i := 0; ; i++ {
		keyName := namer.KeyName(i)
		if !q.containsPrefix(keyName) {
			break
		}

		key, err := q.getValue(keyName, keyType)
		if err != nil {
			return err
		}

		val, err := q.getValue(namer.ValueName(i), valueType)
		if err != nil {
			return err
		}

		output.SetMapIndex(key, val)
	}

	return nil
}
示例#12
0
func ensureMapKey(head P, mid string, obj, key reflect.Value, ctx *Context) (value reflect.Value, err error) {
	value = obj.MapIndex(key)

	if value.Kind() != reflect.Invalid {
		if !ctx.CreateIfMissing {
			return
		}

		if !isNillable(value) || !value.IsNil() {
			return
		}
	}

	if !ctx.CreateIfMissing {
		err = ErrMissing
		return
	}

	if value, err = zero(head, mid, obj.Type().Elem()); err != nil {
		return
	}

	obj.SetMapIndex(key, value)
	return
}
示例#13
0
func parseMap(key, keytail string, values []string, target reflect.Value) {
	t := target.Type()
	mapkey, maptail := keyed(t, key, keytail)

	// BUG(carl): We don't support any map keys except strings, although
	// there's no reason we shouldn't be able to throw the value through our
	// unparsing stack.
	var mk reflect.Value
	if t.Key().Kind() == reflect.String {
		mk = reflect.ValueOf(mapkey).Convert(t.Key())
	} else {
		pebkac("key for map %v isn't a string (it's a %v).", t, t.Key())
	}

	if target.IsNil() {
		target.Set(reflect.MakeMap(t))
	}

	val := target.MapIndex(mk)
	if !val.IsValid() || !val.CanSet() {
		// It's a teensy bit annoying that the value returned by
		// MapIndex isn't Set()table if the key exists.
		val = reflect.New(t.Elem()).Elem()
	}
	parse(key, maptail, values, val)
	target.SetMapIndex(mk, val)
}
示例#14
0
// 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)
		}
	}
}
示例#15
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})
	}
}
示例#16
0
// unmarshalMap transforms the map node to a map represented by field.
// This returns an error if the node cannot be converted to a map type
func unmarshalMap(node yaml.Node, field reflect.Value, supportedYamlTags map[string]bool) error {
	mapNode, err := nodeToMap(node)
	if err != nil {
		return err
	}

	fieldType := field.Type()
	keyType := fieldType.Key()
	elemType := fieldType.Elem()

	// go-gypsy yaml has Map structure as map[string]Node, cannot process any other key type
	if keyType.Kind() != reflect.String {
		return fmt.Errorf("Unable to unmarshal map [%v]. Only string key type is supported.", field)
	}
	if field.IsNil() {
		field.Set(reflect.MakeMap(fieldType))
	}
	for keyNode, valueNode := range mapNode {
		k := reflect.New(keyType).Elem()
		k.SetString(keyNode)

		e := reflect.New(elemType).Elem()
		if err := setValue(valueNode, elemType, e, supportedYamlTags); err != nil {
			return err
		}

		field.SetMapIndex(k, e)
	}
	return nil
}
示例#17
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)
	}
}
示例#18
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
}
示例#19
0
func unmarshalMap(data string, v reflect.Value) error {
	mapType := v.Type()
	if mapType.Key().Kind() != reflect.String {
		return errors.New("tnetstring: only maps with string keys can be unmarshaled")
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(mapType))
	}
	vtype := mapType.Elem()
	var s string
	key := reflect.ValueOf(&s).Elem()
	for len(data) > 0 {
		val := reflect.New(vtype).Elem()
		typ, content, n := readElement(data)
		data = data[n:]
		if typ != ',' {
			return errors.New("tnetstring: non-string key in dictionary")
		}
		s = content
		n, err := unmarshal(data, val)
		data = data[n:]
		if err != nil {
			return err
		}
		v.SetMapIndex(key, val)
	}
	return nil
}
示例#20
0
文件: reify.go 项目: ChongFeng/beats
func reifyMap(opts *options, to reflect.Value, from *Config) Error {
	if to.Type().Key().Kind() != reflect.String {
		return raiseKeyInvalidTypeUnpack(to.Type(), from)
	}

	if len(from.fields.fields) == 0 {
		return nil
	}

	if to.IsNil() {
		to.Set(reflect.MakeMap(to.Type()))
	}
	for k, value := range from.fields.fields {
		key := reflect.ValueOf(k)

		old := to.MapIndex(key)
		var v reflect.Value
		var err Error

		if !old.IsValid() {
			v, err = reifyValue(fieldOptions{opts: opts}, to.Type().Elem(), value)
		} else {
			v, err = reifyMergeValue(fieldOptions{opts: opts}, old, value)
		}

		if err != nil {
			return err
		}
		to.SetMapIndex(key, v)
	}

	return nil
}
示例#21
0
文件: map.go 项目: rjeczalik/msgpack
func (d *Decoder) mapValue(v reflect.Value) error {
	n, err := d.DecodeMapLen()
	if err != nil {
		return err
	}
	if n == -1 {
		return nil
	}

	typ := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(typ))
	}
	keyType := typ.Key()
	valueType := typ.Elem()

	for i := 0; i < n; i++ {
		mk := reflect.New(keyType).Elem()
		if err := d.DecodeValue(mk); err != nil {
			return err
		}

		mv := reflect.New(valueType).Elem()
		if err := d.DecodeValue(mv); err != nil {
			return err
		}

		v.SetMapIndex(mk, mv)
	}

	return nil
}
示例#22
0
func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error {
	if data == nil {
		return nil
	}
	mapData, ok := data.(map[string]interface{})
	if !ok {
		return fmt.Errorf("JSON value is not a map (%#v)", data)
	}

	t := value.Type()
	if value.Kind() == reflect.Ptr {
		t = t.Elem()
		if value.IsNil() {
			value.Set(reflect.New(t))
			value.Elem().Set(reflect.MakeMap(t))
		}

		value = value.Elem()
	}

	for k, v := range mapData {
		kvalue := reflect.ValueOf(k)
		vvalue := reflect.New(value.Type().Elem()).Elem()

		unmarshalAny(vvalue, v, "")
		value.SetMapIndex(kvalue, vvalue)
	}

	return nil
}
示例#23
0
文件: decode.go 项目: pauek/goyaml
func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
	if set := d.setter("!!map", &out, &good); set != nil {
		defer set()
	}
	if out.Kind() == reflect.Struct {
		return d.mappingStruct(n, out)
	}

	if out.Kind() == reflect.Interface {
		// No type hints. Will have to use a generic map.
		iface := out
		out = settableValueOf(make(map[interface{}]interface{}))
		iface.Set(out)
	}

	if out.Kind() != reflect.Map {
		return false
	}
	outt := out.Type()
	kt := outt.Key()
	et := outt.Elem()

	l := len(n.children)
	for i := 0; i < l; i += 2 {
		k := reflect.New(kt).Elem()
		if d.unmarshal(n.children[i], k) {
			e := reflect.New(et).Elem()
			if d.unmarshal(n.children[i+1], e) {
				out.SetMapIndex(k, e)
			}
		}
	}
	return true
}
示例#24
0
文件: decode.go 项目: hail100/cli
func (d *Decoder) mapping(v reflect.Value) {
	u, pv := d.indirect(v)
	if u != nil {
		defer func() {
			if err := u.UnmarshalYAML("!!map", pv.Interface()); err != nil {
				d.error(err)
			}
		}()
		_, pv = d.indirect(pv)
	}
	v = pv

	// Decoding into nil interface?  Switch to non-reflect code.
	if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
		v.Set(reflect.ValueOf(d.mappingInterface()))
		return
	}

	// Check type of target: struct or map[X]Y
	switch v.Kind() {
	case reflect.Struct:
		d.mappingStruct(v)
		return
	case reflect.Map:
	default:
		d.error(errors.New("mapping: invalid type: " + v.Type().String()))
	}

	mapt := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(mapt))
	}

	d.nextEvent()

	keyt := mapt.Key()
	mapElemt := mapt.Elem()

	var mapElem reflect.Value
	for {
		if d.event.event_type == yaml_MAPPING_END_EVENT {
			break
		}
		key := reflect.New(keyt)
		d.parse(key.Elem())

		if !mapElem.IsValid() {
			mapElem = reflect.New(mapElemt).Elem()
		} else {
			mapElem.Set(reflect.Zero(mapElemt))
		}

		d.parse(mapElem)

		v.SetMapIndex(key.Elem(), mapElem)
	}

	d.nextEvent()
}
示例#25
0
文件: unmarshal.go 项目: qinbo/vitess
func MapBuilder(typ reflect.Type, map_ reflect.Value, key reflect.Value) *valueBuilder {
	if typ.Kind() == reflect.Ptr {
		addr := reflect.New(typ.Elem())
		map_.SetMapIndex(key, addr)
		return &valueBuilder{val: addr.Elem()}
	}
	return &valueBuilder{val: reflect.New(typ).Elem(), map_: map_, key: key}
}
示例#26
0
文件: marshal.go 项目: breml/luna
func setMap(destVal reflect.Value, k interface{}, v LuaValue, destType reflect.Type) error {
	dest := reflect.New(destType.Elem())
	if err := convertTableVal(v, dest.Interface()); err != nil {
		return err
	}
	destVal.SetMapIndex(reflect.ValueOf(k), dest.Elem())
	return nil
}
示例#27
0
func (d *Decoder) readObjectField(v reflect.Value, key string) (ignored bool, err error) {
	if !v.CanSet() {
		panic("readObjectField: v must be settable")
	}

	var field reflect.Value

	switch v.Kind() {
	case reflect.Map:
		if v.IsNil() {
			v.Set(reflect.MakeMap(v.Type()))
		}
		elemType := v.Type().Elem()
		if elemType.Kind() == reflect.Ptr {
			field = reflect.New(elemType.Elem())
		} else {
			field = reflect.New(elemType)
		}

	default:
		field = findFieldByName(v, key)

		if !field.IsValid() {
			var tmpobj interface{}
			field = reflect.ValueOf(&tmpobj).Elem()
			d.logPrintln("Prepared dummy value for non-exist key", key)
			ignored = true
		}
		if !field.CanSet() {
			d.logPrintln("v.Type()", v.Type())
			d.logPrintln("field.Type():", field.Type())
			panic("field not settable")
		}
		d.logPrintln("Original field type", field.Type())
		if field.Kind() == reflect.Ptr {
			if field.IsNil() {
				if err = createReflectObject(field, field.Type().Elem()); err != nil {
					return
				}
			}
		} else {
			field = field.Addr()
		}
	}

	err = d.ReadValue(field.Interface())
	d.logPrintln("Read field key", key, "type", field.Type(), "value", field.Elem().Interface())

	if v.Kind() == reflect.Map {
		if v.Type().Elem().Kind() != reflect.Ptr {
			field = field.Elem()
		}
		v.SetMapIndex(reflect.ValueOf(key), field)
	}

	return
}
示例#28
0
文件: decode.go 项目: decebal/ramlapi
// Reset a map, clearing all of its values
func resetMap(out reflect.Value) {

	// Go over all of the Map keys
	for _, k := range out.MapKeys() {

		// Delete the all of the values
		out.SetMapIndex(k, zeroValue)
	}
}
示例#29
0
文件: deepcopy.go 项目: badoo/thunder
// 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)
	}
}
示例#30
0
文件: mergo.go 项目: rusnak/mergo
// Traverses recursively both values, assigning src's fields values to dst.
// The map argument tracks comparisons that have already been seen, which allows
// short circuiting on recursive types.
func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int) error {
	if !src.IsValid() {
		return nil
	}
	if dst.CanAddr() {
		addr := dst.UnsafeAddr()
		h := 17 * addr
		seen := visited[h]
		typ := dst.Type()
		for p := seen; p != nil; p = p.next {
			if p.ptr == addr && p.typ == typ {
				return nil
			}
		}
		// Remember, remember...
		visited[h] = &visit{addr, typ, seen}
	}
	switch dst.Kind() {
	case reflect.Struct:
		for i, n := 0, dst.NumField(); i < n; i++ {
			if err := deepMerge(dst.Field(i), src.Field(i), visited, depth+1); err != nil {
				return err
			}
		}
	case reflect.Map:
		for _, key := range src.MapKeys() {
			srcElement := src.MapIndex(key)
			if !srcElement.IsValid() {
				continue
			}
			dstElement := dst.MapIndex(key)
			switch reflect.TypeOf(srcElement.Interface()).Kind() {
			case reflect.Struct:
				fallthrough
			case reflect.Map:
				if err := deepMerge(dstElement, srcElement, visited, depth+1); err != nil {
					return err
				}
			default:
				dst.SetMapIndex(key, srcElement)
			}
			if !dstElement.IsValid() {
				dst.SetMapIndex(key, srcElement)
			}
		}
	case reflect.Interface:
		if err := deepMerge(dst.Elem(), src.Elem(), visited, depth+1); err != nil {
			return err
		}
	default:
		if dst.CanSet() && isEmptyValue(dst) {
			dst.Set(src)
		}
	}
	return nil
}