예제 #1
0
파일: reader.go 프로젝트: moxian/go-iproto
func (sw *TReader) structAuto(r *marshal.Reader, v reflect.Value) {
	if !v.CanSet() {
		sw.structFixed(r, v)
		return
	}
	l := r.IntUint32()
	flds := sw.Reader.Flds
	switch sw.Tail {
	/*case NoTail:
	if l < len(flds) {
		r.Err = fmt.Errorf("Wrong field count: expect %d, got %d", len(flds), l)
		return
	}*/
	case Tail, TailSplit:
		if l < len(flds)-1 {
			break
			/*r.Err = fmt.Errorf("Wrong field count: expect at least %d, got %d", len(flds)-1, l)
			return*/
		}
		tail := l - len(flds) + 1
		last := flds[len(flds)-1]
		if sw.Tail == TailSplit {
			llast := len(last.Flds)
			tail /= llast
		}
		last.TReader.SetCount(v.Field(last.I), tail)
	}
	sw.structRead(r, l, v)
}
예제 #2
0
파일: types.go 프로젝트: fcavani/monlite
//AnySettableValue find if exist one value that you can set.
func AnySettableValue(val reflect.Value) bool {
	switch val.Kind() {
	case reflect.Array:
		for i := 0; i < val.Type().Len(); i++ {
			if AnySettableValue(val.Index(i)) {
				return true
			}
		}
	case reflect.Interface:
		return AnySettableValue(val.Elem())
	case reflect.Map:
		for _, key := range val.MapKeys() {
			if AnySettableValue(val.MapIndex(key)) {
				return true
			}
		}
	case reflect.Ptr:
		return AnySettableValue(val.Elem())
	case reflect.Slice:
		for i := 0; i < val.Len(); i++ {
			if AnySettableValue(val.Index(i)) {
				return true
			}
		}
	case reflect.Struct:
		for i := 0; i < val.Type().NumField(); i++ {
			if AnySettableValue(val.Field(i)) {
				return true
			}
		}
	default:
		return val.CanSet()
	}
	return false
}
예제 #3
0
func (d *decodeState) indirect(v reflect.Value, decodingNull bool) 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()))
		}
		v = v.Elem()
	}
	return v
}
예제 #4
0
func (q *queryDecoder) decodeValue(output reflect.Value, prefix string, tag reflect.StructTag) error {
	if !q.containsPrefix(prefix) {
		return nil
	}

	if output.Kind() == reflect.Ptr {
		if output.IsNil() {
			output.Set(reflect.New(output.Type().Elem()))
		}
	}
	output = elemOf(output)

	if !output.CanSet() {
		panic("can't set " + prefix)
	}

	switch getFieldType(tag, output.Kind()) {
	case "structure":
		return q.decodeStruct(output, prefix)
	case "list":
		return q.decodeList(output, prefix, tag)
	case "map":
		return q.decodeMap(output, prefix, tag)
	default:
		return q.decodeScalar(output, prefix)
	}
}
예제 #5
0
파일: fuzz.go 프로젝트: nyaxt/kubernetes
// tryCustom searches for custom handlers, and returns true iff it finds a match
// and successfully randomizes v.
func (f Fuzzer) tryCustom(v reflect.Value) bool {
	doCustom, ok := f.customFuzz[v.Type()]
	if !ok {
		return false
	}

	switch v.Kind() {
	case reflect.Ptr:
		if v.IsNil() {
			if !v.CanSet() {
				return false
			}
			v.Set(reflect.New(v.Type().Elem()))
		}
	case reflect.Map:
		if v.IsNil() {
			if !v.CanSet() {
				return false
			}
			v.Set(reflect.MakeMap(v.Type()))
		}
	default:
		return false
	}

	doCustom(v)
	return true
}
예제 #6
0
func setUint(rv reflect.Value, u uint64) error {
	switch rv.Kind() {
	case reflect.Ptr:
		if rv.IsNil() {
			if rv.CanSet() {
				rv.Set(reflect.New(rv.Type().Elem()))
				// fall through to set indirect below
			} else {
				return fmt.Errorf("trying to put uint into unsettable nil ptr")
			}
		}
		return setUint(reflect.Indirect(rv), u)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if rv.OverflowUint(u) {
			return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String())
		}
		rv.SetUint(u)
		return nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if (u == 0xffffffffffffffff) || rv.OverflowInt(int64(u)) {
			return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String())
		}
		rv.SetInt(int64(u))
		return nil
	case reflect.Interface:
		rv.Set(reflect.ValueOf(u))
		return nil
	default:
		return fmt.Errorf("cannot assign uint into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv)
	}
}
예제 #7
0
// callCustom calls 'custom' with sv & dv. custom must be a conversion function.
func (c *Converter) callCustom(sv, dv, custom reflect.Value, scope *scope) error {
	if !sv.CanAddr() {
		sv2 := reflect.New(sv.Type())
		sv2.Elem().Set(sv)
		sv = sv2
	} else {
		sv = sv.Addr()
	}
	if !dv.CanAddr() {
		if !dv.CanSet() {
			return scope.errorf("can't addr or set dest.")
		}
		dvOrig := dv
		dv := reflect.New(dvOrig.Type())
		defer func() { dvOrig.Set(dv) }()
	} else {
		dv = dv.Addr()
	}
	args := []reflect.Value{sv, dv, reflect.ValueOf(scope)}
	ret := custom.Call(args)[0].Interface()
	// This convolution is necessary because nil interfaces won't convert
	// to errors.
	if ret == nil {
		return nil
	}
	return ret.(error)
}
예제 #8
0
파일: reflector.go 프로젝트: hoffoo/skini
// Checks if field can be modified and
// field kind matches give kind.
func isFieldModifiable(field *reflect.Value, name string, kind reflect.Kind) (err error) {
	if !field.IsValid() {
		return fmt.Errorf("error, field not valid: %s", name)
	}
	if !field.CanSet() {
		return fmt.Errorf("error, field cannot be set: %s", name)
	}

	if field.Kind() != kind {
		switch kind {
		case reflect.String:
			return fmt.Errorf("error, field must be string: %s", name)

		case reflect.Slice:
			return fmt.Errorf("error, field must be slice: %s", name)

		case reflect.Map:
			return fmt.Errorf("error, field must be map: %s", name)

		default:
			return fmt.Errorf("error, not yet supported type for field: %s", name)
		}
	}
	return
}
예제 #9
0
파일: merge.go 프로젝트: contiv/volplugin
func setValueWithType(field *reflect.Value, val string) error {
	if !field.CanSet() {
		return errored.Errorf("Cannot set value %q for struct element %q", val, field.Kind().String())
	}

	// navigate the kinds using the reflect types. fallthrough until we can get
	// at a convertible type. If nothing is applicable, error out.
	switch field.Kind() {
	case reflect.Int:
		fallthrough
	case reflect.Int32:
		return castInt32(field, val)
	case reflect.Int64:
		return castInt64(field, val)
	case reflect.Uint:
		fallthrough
	case reflect.Uint32:
		return castUint32(field, val)
	case reflect.Uint64:
		return castUint64(field, val)
	case reflect.Bool:
		return castBool(field, val)
	case reflect.Ptr:
		return castPtr(field, val)
	case reflect.String:
		return castString(field, val)
	}

	return errored.Errorf("Could not find appropriate type %q", field.Kind().String())
}
예제 #10
0
파일: util.go 프로젝트: iizotop/kmg
func (t getElemByStringEditorabler) SaveByPath(v *reflect.Value, path Path, value string) (err error) {
	if len(path) == 0 {
		return nil
	}
	ev, et, err := t.GetElemByString(*v, path[0])
	if err != nil {
		return err
	}
	oEv := ev
	err = et.SaveByPath(&oEv, path[1:], value)
	if err != nil {
		return err
	}

	//not change this type
	if oEv == ev {
		return nil
	}
	if v.CanSet() {
		return nil
	}
	output := reflect.New(t.GetReflectType()).Elem()
	output.Set(*v)
	*v = output
	ev, _, err = t.GetElemByString(*v, path[0])
	if err != nil {
		return err
	}
	ev.Set(oEv)
	return nil
}
예제 #11
0
// setValue decodes a YAML value from node into the value field,
// filtering out the fields not listed in the supportedYamlTags map.
func setValue(node yaml.Node, fieldType reflect.Type, field reflect.Value, supportedYamlTags map[string]bool) error {
	if !field.CanSet() {
		return fmt.Errorf("Unable to set the value [%v] for the field [%v] of kind [%v]", node, field, field.Kind())
	}

	// invoke custom unmarshaler if implemented, else proceed with best-effort parsing using reflections
	if field.CanAddr() {
		if u, ok := field.Addr().Interface().(Unmarshaler); ok {
			return u.UnmarshalYAML(func(val interface{}) error {
				return unmarshal(node, val, supportedYamlTags)
			})
		}
	}

	switch field.Kind() {
	case reflect.String, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
		return unmarshalScalar(node, field, supportedYamlTags)
	case reflect.Slice:
		return unmarshalSlice(node, field, supportedYamlTags)
	case reflect.Struct:
		return unmarshalStruct(node, fieldType, field, supportedYamlTags)
	case reflect.Map:
		return unmarshalMap(node, field, supportedYamlTags)
	case reflect.Ptr:
		fieldValue := reflect.New(fieldType.Elem())
		if err := setValue(node, fieldType.Elem(), fieldValue.Elem(), supportedYamlTags); err != nil {
			return err
		}
		field.Set(fieldValue)
		return nil
	// TODO, case reflect.Interface:
	default:
		return fmt.Errorf("Cannot setValue for the field [%v] of kind [%v]. Undefined operation.", field, field.Kind())
	}
}
예제 #12
0
파일: util.go 프로젝트: iizotop/kmg
//can not pass through map
func passThougthDeleteByPath(t GetElemByStringAndReflectTypeGetterInterface, v *reflect.Value, path Path) (err error) {
	ev, et, err := t.GetElemByString(*v, path[0])
	if err != nil {
		return err
	}
	oEv := ev
	err = et.DeleteByPath(&oEv, path[1:])
	if err != nil {
		return err
	}
	if oEv == ev {
		return
	}
	if v.CanSet() {
		return
	}
	output := reflect.New(t.GetReflectType()).Elem()
	output.Set(*v)
	*v = output
	ev, _, err = t.GetElemByString(*v, path[0])
	if err != nil {
		return err
	}
	ev.Set(oEv)
	return nil
}
예제 #13
0
func unmarshalValue(value reflect.Value, settable reflect.Value) error {
	if !settable.CanSet() {
		return fmt.Errorf("Value is not settable")
	}

	if settable.Kind() == reflect.Ptr {
		// If a nil pointer, allocate a new object to unmarshal into
		if settable.IsNil() {
			newPtr := reflect.New(settable.Type().Elem())
			settable.Set(newPtr)
		}
		// We want unmarshal into the pointed value
		settable = settable.Elem()
	}

	val := value.Interface()

	switch value.Kind() {
	case reflect.Float64:
		return unmarshalNumber(val.(float64), settable)
	case reflect.Bool:
		return unmarshalBoolean(val.(bool), settable)
	case reflect.String:
		return unmarshalString(val.(string), settable)
	case reflect.Map:
		return unmarshalStruct(val.(map[string]interface{}), settable)
	case reflect.Slice:
		return unmarshalSlice(val.([]interface{}), settable)
	default:
		panic(fmt.Sprintf("Unexpected unmarshal type: %s", value.Kind()))
	}
}
예제 #14
0
파일: decode.go 프로젝트: jagregory/pq
// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
func (d *decodeState) indirect(v reflect.Value, decodingNull bool) 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() && (!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()))
		}
		v = v.Elem()
	}
	return v
}
예제 #15
0
파일: parse.go 프로젝트: alexflint/go-arg
// parse a value as the appropriate type and store it in the struct
func setSlice(dest reflect.Value, values []string) error {
	if !dest.CanSet() {
		return fmt.Errorf("field is not writable")
	}

	var ptr bool
	elem := dest.Type().Elem()
	if elem.Kind() == reflect.Ptr {
		ptr = true
		elem = elem.Elem()
	}

	// Truncate the dest slice in case default values exist
	if !dest.IsNil() {
		dest.SetLen(0)
	}

	for _, s := range values {
		v := reflect.New(elem)
		if err := setScalar(v.Elem(), s); err != nil {
			return err
		}
		if !ptr {
			v = v.Elem()
		}
		dest.Set(reflect.Append(dest, v))
	}
	return nil
}
예제 #16
0
func (d *Decoder) DecodeArrayReflect(v reflect.Value) error {
	count := int(d.ParseUnsigned())
	t := v.Type()
	itemType := t.Elem()
	if !v.CanSet() {
		d.err = fmt.Errorf("Cannot set array element")
		return d.err
	}
	v.Set(reflect.MakeSlice(reflect.SliceOf(itemType), count, count))
	for i := 0; i < count; i++ {
		item := v.Index(i)
		itemType := item.Type()
		if item.Kind() == reflect.Ptr {
			item = item.Elem()
			itemType := itemType.Elem()
			if !item.IsValid() {
				item = reflect.New(itemType)
			}
		}
		if itemType.Kind() == reflect.Ptr {
			d.DecodeReflect(item.Elem())
		} else {
			d.DecodeReflect(item)
		}
		v.Index(i).Set(item)
		if d.err != nil {
			return d.err
		}
	}
	return d.err
}
예제 #17
0
파일: parameter.go 프로젝트: vmware/vic
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
	sz := len(data)
	if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil {
		return errors.Required(p.Name, p.parameter.In)
	}

	defVal := reflect.Zero(target.Type())
	if defaultValue != nil {
		defVal = reflect.ValueOf(defaultValue)
	}

	if !target.CanSet() {
		return nil
	}
	if sz == 0 {
		target.Set(defVal)
		return nil
	}

	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], hasKey); err != nil {
			return err
		}
	}

	target.Set(value)

	return nil
}
예제 #18
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)
		}
	}
}
예제 #19
0
// tryCustom searches for custom handlers, and returns true iff it finds a match
// and successfully randomizes v.
func (f *Fuzzer) tryCustom(v reflect.Value) bool {
	doCustom, ok := f.fuzzFuncs[v.Type()]
	if !ok {
		return false
	}

	switch v.Kind() {
	case reflect.Ptr:
		if v.IsNil() {
			if !v.CanSet() {
				return false
			}
			v.Set(reflect.New(v.Type().Elem()))
		}
	case reflect.Map:
		if v.IsNil() {
			if !v.CanSet() {
				return false
			}
			v.Set(reflect.MakeMap(v.Type()))
		}
	default:
		return false
	}

	doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{
		f:    f,
		Rand: f.r,
	})})
	return true
}
예제 #20
0
func fillStructWithMap(dst interface{}, src map[string]interface{}) error {
	log.Printf("fillStructWithMap(%+v, %+v)", dst, src)
	var (
		ok bool
		sv reflect.Value
	)
	t := reflect.TypeOf(dst)
	v := reflect.ValueOf(dst)
	if t.Kind() == reflect.Ptr {
		v = reflect.Indirect(v)
		t = v.Type()
	}
	log.Printf(" t=%s k=%s", t, t.Kind())
	for key, val := range src {
		if _, ok = t.FieldByName(key); !ok {
			key = strings.Title(key)
			if _, ok = t.FieldByName(key); !ok {
				log.Printf("unknown key %s", key)
				continue
			}
		}
		sv = v.FieldByName(key)
		if !sv.CanSet() {
			log.Printf("cannot set value of %#v (%s)", sv, key)
		}
		sv.Set(reflect.ValueOf(val))
	}
	return nil
}
예제 #21
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))
		}
	}
}
func parseAndSet(target reflect.Value, val string) error {
	if !target.CanSet() {
		return fmt.Errorf("Cannot set %v to %v", target, val)
	}
	switch kind := target.Type().Kind(); kind {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		intVal, err := strconv.ParseInt(val, 10, 64)
		if err == nil {
			target.SetInt(intVal)
		}
		return err
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		intVal, err := strconv.ParseUint(val, 10, 64)
		if err == nil {
			target.SetUint(intVal)
		}
		return err
	case reflect.Float32, reflect.Float64:
		floatVal, err := strconv.ParseFloat(val, 64)
		if err == nil {
			target.SetFloat(floatVal)
		}
		return err
	case reflect.String:
		target.SetString(val)
		return nil
	}
	return fmt.Errorf("Field %v has type %v, cannot set to %v", target, target.Type(), val)
}
예제 #23
0
파일: flagst.go 프로젝트: idkfa/flagst
// parseFlags - register receiver struct fields as flag receivers and parse arguments
func parseFlags(receiver interface{}, args []string) (err error) {
	ptr := reflect.ValueOf(receiver)
	if ptr.Kind() != reflect.Ptr {
		return errors.New("Receiver passed by value, not by reference")
	}
	structVal := ptr.Elem()
	if structVal.Kind() != reflect.Struct {
		return errors.New("Receiver is not a struct")
	}
	structType := structVal.Type()
	flagSet := newflagSet()
	for i := 0; i < structType.NumField(); i++ {
		var fieldVal reflect.Value
		if fieldVal = structVal.Field(i); fieldVal.CanSet() == false {
			continue
		}
		structField := structType.Field(i)
		var ff *fieldFlag
		if ff, err = newFieldFlag(&structField, &fieldVal); err != nil {
			return
		}
		flagSet.Var(ff)
	}
	return flagSet.Parse(args)
}
예제 #24
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
}
예제 #25
0
파일: decode_value.go 프로젝트: anmic/pg
func decodeBoolValue(v reflect.Value, b []byte) error {
	if !v.CanSet() {
		return errorf("pg: Decode(nonsettable %s)", v.Type())
	}
	v.SetBool(len(b) == 1 && b[0] == 't')
	return nil
}
예제 #26
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

}
예제 #27
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
}
예제 #28
0
func (d *Decoder) decodeNull(v reflect.Value) error {
	if v.IsValid() && v.CanSet() {
		v.Set(reflect.Zero(v.Type()))
	}

	return nil
}
예제 #29
0
파일: type.go 프로젝트: feyeleanor/raw
//	Uses reflect.Set to create a copy of an existing value.
//	This will only work if the value being copied is *settable* according to the language specification.
//	A struct{} type with unexported fields is never *settable* via reflection.
//	If the value cannot be copied then nil is returned.
//
func Duplicate(value reflect.Value) (r interface{}) {
	if value.CanSet() {
		ptr := reflect.New(value.Type()).Elem()
		ptr.Set(value)
		r = ptr.Interface()
	}
	return
}
예제 #30
0
func (vk *GenericInvoker) convert2struct(v, r reflect.Value, rt reflect.Type) (err error) {
	var (
		fv, mv reflect.Value
		ft     reflect.StructField
		key    string
	)
	kind := v.Kind()

	if !(kind == reflect.Map || kind == reflect.Struct) {
		err = fmt.Errorf("Only Map/Struct not %v convertible to struct", v.Kind().String())
		return
	}
	for i := 0; i < r.NumField(); i++ {
		if fv = r.Field(i); !fv.CanSet() {
			continue
		}

		var converted reflect.Value

		ft = rt.Field(i)
		switch kind {
		case reflect.Map:
			if ft.Anonymous {
				converted, err = vk.convert(v, ft.Type)
				break
			}
			// json tags
			if key = ft.Tag.Get("json"); key != "" {
				key = strings.Trim(key, "\"")
				keys := strings.Split(key, ",")
				key = keys[0]
				if key == "-" {
					key = ""
				}
			}
			if key == "" {
				key = ft.Name
			}
			if mv = v.MapIndex(reflect.ValueOf(key)); !mv.IsValid() {
				err = fmt.Errorf("Invalid value returned from map by key: %v", ft)
				break
			}

			converted, err = vk.convert(mv, fv.Type())
		case reflect.Struct:
			converted = v.FieldByName(ft.Name)
		}

		if err != nil {
			return err
		}

		fv.Set(converted)
	}

	return err
}