コード例 #1
0
ファイル: encode.go プロジェクト: carriercomm/os
func (e *Encoder) emitAddrMarshaler(tag string, v reflect.Value) {
	if !v.CanAddr() {
		e.marshal(tag, v, false)
		return
	}

	va := v.Addr()
	if va.IsNil() {
		e.emitNil()
		return
	}

	m := v.Interface().(Marshaler)
	t, val, err := m.MarshalYAML()
	if err != nil {
		panic(err)
	}

	if val == nil {
		e.emitNil()
		return
	}

	e.marshal(t, reflect.ValueOf(val), false)
}
コード例 #2
0
ファイル: decode.go プロジェクト: shitfSign/gosproto
func decodeInt(val *uint16, data []byte, sf *SprotoField, v reflect.Value) error {
	var n uint64
	if val != nil {
		n = uint64(*val)
	} else {
		switch len(data) {
		case 0:
			n = 0
		case 4:
			n = uint64(readUint32(data))
		case 8:
			n = readUint64(data)
		default:
			return fmt.Errorf("sproto: malformed integer data for field %s", sf.Name)
		}
	}
	e := v.Type().Elem()
	v.Addr().Elem().Set(reflect.New(e))
	switch e.Kind() {
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		v.Elem().SetInt(int64(n))
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
		v.Elem().SetUint(n)
	}
	return nil
}
コード例 #3
0
ファイル: parsers.go プロジェクト: rymis/parse
func (par *parserParser) ParseValue(ctx *parseContext, valueOf reflect.Value, location int, err *Error) int {
	var v Parser
	if par.ptr {
		v = valueOf.Addr().Interface().(Parser)
	} else {
		if valueOf.Kind() == reflect.Ptr {
			valueOf = reflect.New(valueOf.Type().Elem())
		}
		v = valueOf.Interface().(Parser)
	}

	l, e := v.ParseValue(ctx.str, location)
	if e != nil {
		switch ev := e.(type) {
		case Error:
			err.Location = ev.Location
			err.Message = ev.Message
			err.Str = ev.Str
			return -1
		}
		err.Location = location
		err.Message = e.Error()
		return -1
	}

	location = l
	if location > len(ctx.str) {
		panic("Invalid parser")
	}

	return location
}
コード例 #4
0
ファイル: encode.go プロジェクト: eswdd/bosun
func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) {
	if indir == 0 {
		v = rv.Interface()
	} else if indir == -1 {
		// If a non-pointer was passed to Encode(), then that value is not addressable.
		// Take addr if addresable, else copy value to an addressable value.
		if rv.CanAddr() {
			v = rv.Addr().Interface()
		} else {
			rv2 := reflect.New(rv.Type())
			rv2.Elem().Set(rv)
			v = rv2.Interface()
			// fmt.Printf("rv.Type: %v, rv2.Type: %v, v: %v\n", rv.Type(), rv2.Type(), v)
		}
	} else {
		for j := int8(0); j < indir; j++ {
			if rv.IsNil() {
				f.ee.EncodeNil()
				return
			}
			rv = rv.Elem()
		}
		v = rv.Interface()
	}
	return v, true
}
コード例 #5
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
}
コード例 #6
0
ファイル: decode.go プロジェクト: newthinker/samples
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)
}
コード例 #7
0
ファイル: scan.go プロジェクト: rjp/crud
func (scan *Scan) ScanToStruct(rows *sql.Rows, record reflect.Value) error {
	columns, err := rows.Columns()
	if err != nil {
		return err
	}

	values := make([]interface{}, len(columns))

	for i, column := range columns {
		var field reflect.Value

		fieldName := scan.SQLColumnDict[column]

		if scan.ToPointers {
			field = record.Elem().FieldByName(fieldName)
		} else {
			field = record.FieldByName(fieldName)
		}

		if field.IsValid() {
			values[i] = field.Addr().Interface()
		} else {
			values[i] = &values[i]
		}
	}

	return rows.Scan(values...)
}
コード例 #8
0
ファイル: opts.go プロジェクト: CaptainIlu/cloud-torrent
func (o *Opts) addCmd(sf reflect.StructField, val reflect.Value) {

	if o.arglist != nil {
		o.errorf("argslists and commands cannot be used together")
		return
	}

	//requires address
	switch sf.Type.Kind() {
	case reflect.Ptr:
		//if nil ptr, auto-create new struct
		if val.IsNil() {
			ptr := reflect.New(val.Type().Elem())
			val.Set(ptr)
		}
	case reflect.Struct:
		val = val.Addr()
	}

	name := sf.Tag.Get("name")
	if name == "" || name == "!" {
		name = camel2dash(sf.Name) //default to struct field name
	}
	// log.Printf("define cmd: %s =====", subname)
	sub := fork(o, val)
	sub.name = name
	sub.help = sf.Tag.Get("help")
	o.cmds[name] = sub
}
コード例 #9
0
ファイル: exec.go プロジェクト: jmcadden/EbbRT-gcc
// validateType guarantees that the value is valid and assignable to the type.
func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
	if !value.IsValid() {
		switch typ.Kind() {
		case reflect.Interface, reflect.Ptr, reflect.Chan, reflect.Map, reflect.Slice, reflect.Func:
			// An untyped nil interface{}. Accept as a proper nil value.
			// TODO: Can we delete the other types in this list? Should we?
			value = reflect.Zero(typ)
		default:
			s.errorf("invalid value; expected %s", typ)
		}
	}
	if !value.Type().AssignableTo(typ) {
		// Does one dereference or indirection work? We could do more, as we
		// do with method receivers, but that gets messy and method receivers
		// are much more constrained, so it makes more sense there than here.
		// Besides, one is almost always all you need.
		switch {
		case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
			value = value.Elem()
		case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
			value = value.Addr()
		default:
			s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
		}
	}
	return value
}
コード例 #10
0
ファイル: converter.go プロジェクト: MohamedFAhmed/heapster
// 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)
}
コード例 #11
0
ファイル: converter.go プロジェクト: MohamedFAhmed/heapster
// convert recursively copies sv into dv, calling an appropriate conversion function if
// one is registered.
func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
	dt, st := dv.Type(), sv.Type()
	// Apply default values.
	if fv, ok := c.defaultingFuncs[st]; ok {
		if c.Debug != nil {
			c.Debug.Logf("Applying defaults for '%v'", st)
		}
		args := []reflect.Value{sv.Addr()}
		fv.Call(args)
	}

	// Convert sv to dv.
	if fv, ok := c.conversionFuncs[typePair{st, dt}]; ok {
		if c.Debug != nil {
			c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
		}
		return c.callCustom(sv, dv, fv, scope)
	}
	if fv, ok := c.generatedConversionFuncs[typePair{st, dt}]; ok {
		if c.Debug != nil {
			c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
		}
		return c.callCustom(sv, dv, fv, scope)
	}

	return c.defaultConvert(sv, dv, scope)
}
コード例 #12
0
ファイル: sitef.go プロジェクト: beoran/woe
func (me Record) GetValue(key string, value reflect.Value) (err error) {
	/*stringer, ok := value.Interface().(fmt.Stringer)
	  if ok {
	      me.Gut(key, stringer.String())
	      return
	  }*/
	monolog.Debug("GetValue: %s %v", key, value)

	switch value.Kind() {
	case reflect.Int, reflect.Int32, reflect.Int64:
		value.SetInt(int64(me.GetIntDefault(key, 0)))
	case reflect.Uint, reflect.Uint32, reflect.Uint64:
		value.SetUint(uint64(me.GetIntDefault(key, 0)))
	case reflect.Float32, reflect.Float64:
		f, err := me.GetFloat(key)
		if err != nil {
			return err
		}
		value.SetFloat(f)
	case reflect.String:
		s, ok := me.MayGet(key)
		if !ok {
			return fmt.Errorf("Could not get string for key %s", key)
		}
		value.SetString(s)
	case reflect.Struct:
		me.GetStruct(key+".", value.Addr().Interface())
	default:
		monolog.Warning("Don't know what to do with %v", value)
	}
	return nil
}
コード例 #13
0
ファイル: text.go プロジェクト: ContiGuy/conti-gui
// isAny reports whether sv is a google.protobuf.Any message
func isAny(sv reflect.Value) bool {
	type wkt interface {
		XXX_WellKnownType() string
	}
	t, ok := sv.Addr().Interface().(wkt)
	return ok && t.XXX_WellKnownType() == "Any"
}
コード例 #14
0
ファイル: reify.go プロジェクト: fedelemantuano/beats
func reifyInto(opts *options, to reflect.Value, from *Config) Error {
	to = chaseValuePointers(to)

	if to, ok := tryTConfig(to); ok {
		return mergeConfig(opts, to.Addr().Interface().(*Config), from)
	}

	tTo := chaseTypePointers(to.Type())
	k := tTo.Kind()

	switch k {
	case reflect.Map:
		return reifyMap(opts, to, from)
	case reflect.Struct:
		return reifyStruct(opts, to, from)
	case reflect.Slice, reflect.Array:
		fopts := fieldOptions{opts: opts, tag: tagOptions{}, validators: nil}
		v, err := reifyMergeValue(fopts, to, cfgSub{from})
		if err != nil {
			return err
		}
		to.Set(v)
		return nil
	}

	return raiseInvalidTopLevelType(to.Interface())
}
コード例 #15
0
ファイル: util_db.go プロジェクト: fishedee/fishgo
func (this *databaseImplement) autoMapType(v reflect.Value) *core.Table {
	t := v.Type()
	table := core.NewEmptyTable()
	if tb, ok := v.Interface().(tableName); ok {
		table.Name = tb.TableName()
	} else {
		if v.CanAddr() {
			if tb, ok = v.Addr().Interface().(tableName); ok {
				table.Name = tb.TableName()
			}
		}
		if table.Name == "" {
			table.Name = this.TableMapper.Obj2Table(t.Name())
		}
	}
	table.Type = t
	for i := 0; i < t.NumField(); i++ {
		tag := t.Field(i).Tag
		ormTagStr := tag.Get("xorm")
		if ormTagStr == "-" || ormTagStr == "<-" {
			continue
		}
		col := &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
			IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]bool)}
		col.Name = this.ColumnMapper.Obj2Table(t.Field(i).Name)
		table.AddColumn(col)
	}
	return table
}
コード例 #16
0
ファイル: field.go プロジェクト: arunk-s/libaudit-go
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
}
コード例 #17
0
ファイル: marshal.go プロジェクト: dongzerun/RationalDb
func EncodeStructContent(buf *bytes2.ChunkedWriter, val reflect.Value) {
	// check the Marshaler interface on T
	if marshaler, ok := val.Interface().(Marshaler); ok {
		marshaler.MarshalBson(buf)
		return
	}
	// check the Marshaler interface on *T
	if val.CanAddr() {
		if marshaler, ok := val.Addr().Interface().(Marshaler); ok {
			marshaler.MarshalBson(buf)
			return
		}
	}

	lenWriter := NewLenWriter(buf)
	t := val.Type()
	for i := 0; i < t.NumField(); i++ {
		key := t.Field(i).Name

		// NOTE(szopa): Ignore private fields (copied from
		// encoding/json). Yes, it feels like a hack.
		if t.Field(i).PkgPath != "" {
			continue
		}
		encodeField(buf, key, val.Field(i))
	}
	buf.WriteByte(0)
	lenWriter.RecordLen()
}
コード例 #18
0
ファイル: mvc.go プロジェクト: aresLove/revel
// This is a helper that initializes (zeros) a new app controller value.
// Generally, everything is set to its zero value, except:
// 1. Embedded controller pointers are newed up.
// 2. The rev.Controller embedded type is set to the value provided.
// Returns a value representing a pointer to the new app controller.
func initNewAppController(appControllerType reflect.Type, c *Controller) reflect.Value {
	// It might be a multi-level embedding, so we have to create new controllers
	// at every level of the hierarchy.
	// ASSUME: the first field in each type is the way up to rev.Controller.
	appControllerPtr := reflect.New(appControllerType)
	ptr := appControllerPtr
	for {
		var (
			embeddedField     reflect.Value = ptr.Elem().Field(0)
			embeddedFieldType reflect.Type  = embeddedField.Type()
		)

		// Check if it's the controller.
		if embeddedFieldType == controllerType {
			embeddedField.Set(reflect.ValueOf(c).Elem())
			break
		} else if embeddedFieldType == controllerPtrType {
			embeddedField.Set(reflect.ValueOf(c))
			break
		}

		// If the embedded field is a pointer, then instantiate an object and set it.
		// (If it's not a pointer, then it's already initialized)
		if embeddedFieldType.Kind() == reflect.Ptr {
			embeddedField.Set(reflect.New(embeddedFieldType.Elem()))
			ptr = embeddedField
		} else {
			ptr = embeddedField.Addr()
		}
	}
	return appControllerPtr
}
コード例 #19
0
ファイル: exec.go プロジェクト: bibbyflyaway/go
// validateType guarantees that the value is valid and assignable to the type.
func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
	if !value.IsValid() {
		if typ == nil || canBeNil(typ) {
			// An untyped nil interface{}. Accept as a proper nil value.
			return reflect.Zero(typ)
		}
		s.errorf("invalid value; expected %s", typ)
	}
	if typ != nil && !value.Type().AssignableTo(typ) {
		if value.Kind() == reflect.Interface && !value.IsNil() {
			value = value.Elem()
			if value.Type().AssignableTo(typ) {
				return value
			}
			// fallthrough
		}
		// Does one dereference or indirection work? We could do more, as we
		// do with method receivers, but that gets messy and method receivers
		// are much more constrained, so it makes more sense there than here.
		// Besides, one is almost always all you need.
		switch {
		case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
			value = value.Elem()
			if !value.IsValid() {
				s.errorf("dereference of nil pointer of type %s", typ)
			}
		case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
			value = value.Addr()
		default:
			s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
		}
	}
	return value
}
コード例 #20
0
ファイル: decode.go プロジェクト: kezhuw/toml
func indirectValue(v reflect.Value) (encoding.TextUnmarshaler, reflect.Value) {
	if v.Kind() != reflect.Ptr && v.CanAddr() {
		v = v.Addr()
	}
	var u encoding.TextUnmarshaler
	for {
		if v.Kind() == reflect.Interface && !v.IsNil() {
			e := v.Elem()
			if e.Kind() == reflect.Ptr && !e.IsNil() {
				v = e
				continue
			}
		}
		if v.Kind() != reflect.Ptr {
			break
		}
		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		if v.NumMethod() > 0 {
			// TOML has native Datetime support, while time.Time implements
			// encoding.TextUnmarshaler. For native Datetime, we need settable
			// time.Time struct, so continue here.
			if i, ok := v.Interface().(encoding.TextUnmarshaler); ok {
				u = i
			}
		}
		v = v.Elem()
	}
	return u, v
}
コード例 #21
0
ファイル: encode.go プロジェクト: eswdd/bosun
func (f encFnInfo) ext(rv reflect.Value) {
	// if this is a struct|array and it was addressable, then pass the address directly (not the value)
	if k := rv.Kind(); (k == reflect.Struct || k == reflect.Array) && rv.CanAddr() {
		rv = rv.Addr()
	}
	f.ee.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e)
}
コード例 #22
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
}
コード例 #23
0
ファイル: decode.go プロジェクト: nsf/libtorgo
func (d *decoder) parse_unmarshaler(v reflect.Value) bool {
	m, ok := v.Interface().(Unmarshaler)
	if !ok {
		// T doesn't work, try *T
		if v.Kind() != reflect.Ptr && v.CanAddr() {
			m, ok = v.Addr().Interface().(Unmarshaler)
			if ok {
				v = v.Addr()
			}
		}
	}
	if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
		if d.read_one_value() {
			err := m.UnmarshalBencode(d.buf.Bytes())
			d.buf.Reset()
			if err != nil {
				panic(&UnmarshalerError{v.Type(), err})
			}
			return true
		}
		d.buf.Reset()
	}

	return false
}
コード例 #24
0
ファイル: encode.go プロジェクト: MG-RAST/Shock
func (f *encFnInfo) binaryMarshal(rv reflect.Value) {
	var bm binaryMarshaler
	if f.ti.mIndir == 0 {
		bm = rv.Interface().(binaryMarshaler)
	} else if f.ti.mIndir == -1 {
		bm = rv.Addr().Interface().(binaryMarshaler)
	} else {
		for j, k := int8(0), f.ti.mIndir; j < k; j++ {
			if rv.IsNil() {
				f.ee.encodeNil()
				return
			}
			rv = rv.Elem()
		}
		bm = rv.Interface().(binaryMarshaler)
	}
	// debugf(">>>> binaryMarshaler: %T", rv.Interface())
	bs, fnerr := bm.MarshalBinary()
	if fnerr != nil {
		panic(fnerr)
	}
	if bs == nil {
		f.ee.encodeNil()
	} else {
		f.ee.encodeStringBytes(c_RAW, bs)
	}
}
コード例 #25
0
ファイル: scope.go プロジェクト: RichardKnop/example-api
func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) {
	// Only get address from non-pointer
	if reflectValue.CanAddr() && reflectValue.Kind() != reflect.Ptr {
		reflectValue = reflectValue.Addr()
	}

	if methodValue := reflectValue.MethodByName(methodName); methodValue.IsValid() {
		switch method := methodValue.Interface().(type) {
		case func():
			method()
		case func(*Scope):
			method(scope)
		case func(*DB):
			newDB := scope.NewDB()
			method(newDB)
			scope.Err(newDB.Error)
		case func() error:
			scope.Err(method())
		case func(*Scope) error:
			scope.Err(method(scope))
		case func(*DB) error:
			newDB := scope.NewDB()
			scope.Err(method(newDB))
			scope.Err(newDB.Error)
		default:
			scope.Err(fmt.Errorf("unsupported function %v", methodName))
		}
	}
}
コード例 #26
0
ファイル: decoder.go プロジェクト: joamaki/gorethink
// 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
}
コード例 #27
0
ファイル: flat.go プロジェクト: hanjin8307/circuit
func unflattenValue(v reflect.Value, t reflect.Type) reflect.Value {
	// When t is an Interface, we can't do much, since we don't know the
	// original (unflattened) type of the value placed in v, so we just nop it.
	if t.Kind() == reflect.Interface {
		return v
	}
	// v can be invalid, if it holds the nil value for pointer type
	if !v.IsValid() {
		return v
	}
	// Make sure v is indeed flat
	if v.Kind() == reflect.Ptr {
		panic("unflattening non-flat value")
	}
	// Add a *, one at a time
	for t.Kind() == reflect.Ptr {
		if v.CanAddr() {
			v = v.Addr()
		} else {
			pw := reflect.New(v.Type())
			pw.Elem().Set(v)
			v = pw
		}
		t = t.Elem()
	}
	return v
}
コード例 #28
0
ファイル: network.go プロジェクト: cgravill/antha
func (n *Graph) getPort(procName, portName string,
	extractFromPM func(portMapper, string) reflect.Value) (reflect.Value, error) {

	proc, found := n.procs[procName]
	var port reflect.Value
	if !found {
		return port, errors.New("name '" + procName + "' not found")
	}
	v := reflect.ValueOf(proc).Elem()
	if !v.CanSet() {
		return port, errors.New(procName + " is not settable")
	}
	var net reflect.Value
	if v.Type().Name() == "Graph" {
		net = v
	} else {
		net = v.FieldByName("Graph")
	}
	if net.IsValid() {
		// Port is a net
		if pm, isPm := net.Addr().Interface().(portMapper); isPm {
			port = extractFromPM(pm, portName)
		}
	} else {
		// Port is a proc
		port = v.FieldByName(portName)
	}

	return port, nil
}
コード例 #29
0
ファイル: validate.go プロジェクト: emosbaugh/libyaml-1
func getCurrentContainer(current reflect.Value) *Container {
	if !current.CanAddr() {
		return nil
	}
	currentContainer, _ := current.Addr().Interface().(*Container)
	return currentContainer
}
コード例 #30
0
ファイル: decode.go プロジェクト: NorgannasAddOns/go-anyproto
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
}