예제 #1
0
파일: encode.go 프로젝트: 2thetop/go
func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	pe.elemEnc(e, v.Elem(), opts)
}
예제 #2
0
func defaultReturnHandler() ReturnHandler {
	return func(ctx *Context, vals []reflect.Value) {
		rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
		resp := rv.Interface().(http.ResponseWriter)
		var respVal reflect.Value
		if len(vals) > 1 && vals[0].Kind() == reflect.Int {
			resp.WriteHeader(int(vals[0].Int()))
			respVal = vals[1]
		} else if len(vals) > 0 {
			respVal = vals[0]

			if isError(respVal) {
				err := respVal.Interface().(error)
				if err != nil {
					ctx.internalServerError(ctx, err)
				}
				return
			} else if canDeref(respVal) {
				if respVal.IsNil() {
					return // Ignore nil error
				}
			}
		}
		if canDeref(respVal) {
			respVal = respVal.Elem()
		}
		if isByteSlice(respVal) {
			resp.Write(respVal.Bytes())
		} else {
			resp.Write([]byte(respVal.String()))
		}
	}
}
예제 #3
0
// Validates that if a value is provided for a field, that value must be at
// least a minimum length.
func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error {
	minStr := f.Tag.Get("min")
	if minStr == "" {
		return nil
	}
	min, _ := strconv.ParseInt(minStr, 10, 64)

	kind := fvalue.Kind()
	if kind == reflect.Ptr {
		if fvalue.IsNil() {
			return nil
		}
		fvalue = fvalue.Elem()
	}

	switch fvalue.Kind() {
	case reflect.String:
		if int64(fvalue.Len()) < min {
			return fmt.Errorf("field too short, minimum length %d", min)
		}
	case reflect.Slice, reflect.Map:
		if fvalue.IsNil() {
			return nil
		}
		if int64(fvalue.Len()) < min {
			return fmt.Errorf("field too short, minimum length %d", min)
		}

		// TODO min can also apply to number minimum value.

	}
	return nil
}
예제 #4
0
파일: encode.go 프로젝트: ossrs/go-oryx-lib
func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	pe.elemEnc(e, v.Elem(), quoted)
}
예제 #5
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
}
예제 #6
0
func decodeMessage(chunk []byte, st *SprotoType, v reflect.Value) (int, error) {
	var total int
	var tags []Tag
	var err error
	if total, tags, err = decodeHeader(chunk); err != nil {
		return 0, err
	}

	for _, tag := range tags {
		var used int
		var data []byte
		if tag.Val == nil {
			if used, data, err = readChunk(chunk[total:]); err != nil {
				return 0, err
			}
			total += used
		}
		sf := st.FieldByTag(int(tag.Tag))
		if sf == nil {
			fmt.Fprintf(os.Stderr, "sproto<%s>: unknown tag %d\n", st.Name, tag.Tag)
			continue
		}
		v1 := v.Elem().FieldByIndex(sf.index)
		if err = sf.dec(tag.Val, data, sf, v1); err != nil {
			return 0, err
		}
	}
	return total, nil
}
예제 #7
0
func encodeField(w io.Writer, f reflect.Value) error {
	if f.Type() == timeType {
		return encodeTime(w, f)
	}

	switch f.Kind() {
	case reflect.Uint8:
		fallthrough
	case reflect.Uint16:
		fallthrough
	case reflect.Uint32:
		fallthrough
	case reflect.Uint64:
		fallthrough
	case reflect.Int64:
		fallthrough
	case reflect.Int32:
		fallthrough
	case reflect.Int16:
		fallthrough
	case reflect.Int8:
		return binary.Write(w, byteOrder, f.Interface())
	case reflect.String:
		return encodeStrField(w, f)
	case reflect.Slice:
		return encodeArray(w, f)
	case reflect.Interface:
		return encodeField(w, f.Elem())
	default:
		panic(fmt.Sprintf("unimplemented kind %v", f))
	}
}
예제 #8
0
func getFields(v reflect.Value, tagName string) []*Field {
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	t := v.Type()

	var fields []*Field

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if tag := field.Tag.Get(tagName); tag == "-" {
			continue
		}

		f := &Field{
			field: field,
			value: v.FieldByName(field.Name),
		}

		fields = append(fields, f)

	}

	return fields
}
예제 #9
0
func assertValid(vObj reflect.Value) error {
	if !vObj.IsValid() {
		return nil
	}

	if obj, ok := vObj.Interface().(interface {
		AssertValid() error
	}); ok && !(vObj.Kind() == reflect.Ptr && vObj.IsNil()) {
		if err := obj.AssertValid(); err != nil {
			return err
		}
	}

	switch vObj.Kind() {
	case reflect.Ptr:
		return assertValid(vObj.Elem())
	case reflect.Struct:
		return assertStructValid(vObj)
	case reflect.Slice:
		for i := 0; i < vObj.Len(); i++ {
			if err := assertValid(vObj.Index(i)); err != nil {
				return err
			}
		}
	}

	return nil
}
예제 #10
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)
	}
}
예제 #11
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
}
예제 #12
0
파일: encoder.go 프로젝트: Chao-Jia/skycoin
func DeserializeToValue(r io.Reader, dsize int, dst reflect.Value) error {

	//fmt.Printf("*A1 v is type %s \n", data.Type().String() )		//this is the type of the value

	var v reflect.Value
	switch dst.Kind() {
	case reflect.Ptr:
		v = dst.Elem()
	case reflect.Slice:
		v = dst
	case reflect.Struct:

	default:
		return errors.New("binary.Read: invalid type " + reflect.TypeOf(dst).String())
	}

	//fmt.Printf("*A2 v is type %s \n", v.Type().String() )		//this is the type of the value

	d1 := &decoder{buf: make([]byte, dsize)}
	if _, err := io.ReadFull(r, d1.buf); err != nil {
		return err
	}

	return d1.value(v)
}
예제 #13
0
파일: encoder.go 프로젝트: Chao-Jia/skycoin
// Returns number of bytes used and an error if deserialization failed
func DeserializeRawToValue(in []byte, dst reflect.Value) (int, error) {
	var v reflect.Value
	switch dst.Kind() {
	case reflect.Ptr:
		v = dst.Elem()
	case reflect.Slice:
		v = dst
	case reflect.Struct:
	default:
		return 0, errors.New("binary.Read: invalid type " + reflect.TypeOf(dst).String())
	}

	inlen := len(in)
	d1 := &decoder{buf: make([]byte, inlen)}
	copy(d1.buf, in)

	//check if can deserialize
	d2 := &decoder{buf: make([]byte, inlen)}
	copy(d2.buf, d1.buf)
	if d2.dchk(v) != 0 {
		return 0, errors.New("Deserialization failed")
	}

	err := d1.value(v)
	return inlen - len(d1.buf), err
}
예제 #14
0
func (c *FlatMapConfig) flatten(result map[string]interface{}, prefix string, v reflect.Value) error {
	var err error

	if v.Kind() == reflect.Interface {
		v = v.Elem()
	}

	// Set as type interface
	// https://golang.org/pkg/reflect/#Kind
	switch v.Kind() {
	case reflect.Bool:
		result[c.keyDelim+prefix] = v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
		result[c.keyDelim+prefix] = v.Int()
	case reflect.String:
		result[c.keyDelim+prefix] = v.String()
	case reflect.Map:
		err = c.flattenMap(result, prefix, v)
	case reflect.Slice, reflect.Array:
		err = c.flattenSlice(result, prefix, v)
	default:
		err = fmt.Errorf("Unknown primitive type found for value: '%q'", v)
	}

	return err
}
예제 #15
0
func (enc *encoder) writeStruct(val reflect.Value) {
	for val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface {
		val = val.Elem()
	}
	if val.Kind() != reflect.Struct {
		enc.error(&UnsupportedValueError{Value: val, Message: "expect a struct"})
	}
	marker := &MStruct{}
	if err := enc.proto.WriteStructBegin(enc.writer, marker); err != nil {
		enc.error(err)
	}
	for _, ef := range encodeFields(val.Type()).fields {
		field := val.Type().Field(ef.i)
		fieldValue := val.Field(ef.i)

		if isEmptyValue(fieldValue) {
			continue
		}

		mfield := &MField{Name: field.Name, Type: ef.fieldType, ID: ef.id}
		if err := enc.proto.WriteFieldBegin(enc.writer, mfield); err != nil {
			enc.error(err)
		}
		enc.writeValue(fieldValue, ef.fieldType)
	}
	enc.proto.WriteFieldStop(enc.writer)
}
예제 #16
0
파일: coerce.go 프로젝트: kyledj/qlbridge
func convertToFloat64(depth int, v reflect.Value) (float64, bool) {
	if v.Kind() == reflect.Interface {
		v = v.Elem()
	}
	switch v.Kind() {
	case reflect.Float32, reflect.Float64:
		return v.Float(), true
	case reflect.Int16, reflect.Int8, reflect.Int, reflect.Int32, reflect.Int64:
		return float64(v.Int()), true
	case reflect.String:
		s := v.String()
		var f float64
		var err error
		if strings.HasPrefix(s, "0x") {
			f, err = strconv.ParseFloat(s, 64)
		} else {
			f, err = strconv.ParseFloat(s, 64)
		}
		if err == nil {
			return float64(f), true
		}
		if depth == 0 {
			s = intStrReplacer.Replace(s)
			rv := reflect.ValueOf(s)
			return convertToFloat64(1, rv)
		}
	case reflect.Slice:
		// Should we grab first one?  Or Error?
		//u.Warnf("ToFloat() but is slice?: %T first=%v", v, v.Index(0))
		return convertToFloat64(0, v.Index(0))
	default:
		//u.Warnf("Cannot convert type?  %v", v.Kind())
	}
	return math.NaN(), false
}
예제 #17
0
파일: encoder.go 프로젝트: erkl/binn
func (pe *pointerEncoder) encode(b []byte, v reflect.Value) []byte {
	if v.IsNil() {
		return append(b, 0x10)
	} else {
		return pe.encodeElem(b, v.Elem())
	}
}
예제 #18
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
}
예제 #19
0
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
}
예제 #20
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...)
}
예제 #21
0
파일: encode.go 프로젝트: ossrs/go-oryx-lib
func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	e.reflectValue(v.Elem())
}
예제 #22
0
파일: db.go 프로젝트: seacoastboy/goku
// scan the value by fields, and set to v
func rawScanStruct(v reflect.Value, fields []string, scanner rowScaner) (err error) {
	if v.IsNil() {
		e := fmt.Sprintf("struct can not be nil, but got %#v", v.Interface())
		return errors.New(e)
	}
	dest := make([]interface{}, len(fields))
	for v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// Loop over column names and find field in s to bind to
	// based on column name. all returned columns must match
	// a field in the s struct
	for x, fieldName := range fields {
		f := v.FieldByName(fieldName)
		if f == zeroVal {
			e := fmt.Sprintf("Scanner: No field %s in type %s",
				fieldName, v.Type())
			return errors.New(e)
		} else {
			dest[x] = f.Addr().Interface()
		}
	}

	err = scanner.Scan(dest...)
	return
}
예제 #23
0
func testSetNilMapsToEmpties(curr reflect.Value) {
	actualCurrValue := curr
	if curr.Kind() == reflect.Ptr {
		actualCurrValue = curr.Elem()
	}

	switch actualCurrValue.Kind() {
	case reflect.Map:
		for _, mapKey := range actualCurrValue.MapKeys() {
			currMapValue := actualCurrValue.MapIndex(mapKey)
			testSetNilMapsToEmpties(currMapValue)
		}

	case reflect.Struct:
		for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ {
			currFieldValue := actualCurrValue.Field(fieldIndex)

			if currFieldValue.Kind() == reflect.Map && currFieldValue.IsNil() {
				newValue := reflect.MakeMap(currFieldValue.Type())
				currFieldValue.Set(newValue)
			} else {
				testSetNilMapsToEmpties(currFieldValue.Addr())
			}
		}

	}

}
예제 #24
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
}
예제 #25
0
파일: swalker.go 프로젝트: yuroyoro/swalker
func unwrap(v *reflect.Value) *reflect.Value {
	if v.Kind() == reflect.Interface {
		org := v.Elem() //  Get rid of the wrapping interface
		return &org
	}
	return v
}
예제 #26
0
파일: encode.go 프로젝트: eswdd/bosun
func (f encFnInfo) kInterface(rv reflect.Value) {
	if rv.IsNil() {
		f.ee.EncodeNil()
		return
	}
	f.e.encodeValue(rv.Elem(), encFn{})
}
예제 #27
0
파일: option.go 프로젝트: chzyer/flagly
func GetMethod(s reflect.Value, name string) reflect.Value {
	method := s.MethodByName(name)
	if !method.IsValid() {
		method = s.Elem().MethodByName(name)
	}
	return method
}
예제 #28
0
파일: encode.go 프로젝트: eswdd/bosun
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) {
LOOP:
	for {
		switch rv.Kind() {
		case reflect.Ptr, reflect.Interface:
			if rv.IsNil() {
				e.e.EncodeNil()
				return
			}
			rv = rv.Elem()
			continue LOOP
		case reflect.Slice, reflect.Map:
			if rv.IsNil() {
				e.e.EncodeNil()
				return
			}
		case reflect.Invalid, reflect.Func:
			e.e.EncodeNil()
			return
		}
		break
	}

	return rv, true
}
예제 #29
0
파일: starexpr.go 프로젝트: raff/eval
func evalStarExpr(ctx *Ctx, starExpr *StarExpr, env *Env) (*reflect.Value, bool, error) {
	// return nil, false, errors.New("Star expressions not done yet")
	var cexpr Expr
	var errs []error
	if cexpr, errs = CheckExpr(ctx, starExpr.X, env); len(errs) != 0 {
		for _, cerr := range errs {
			fmt.Printf("%v\n", cerr)
		}
		return nil, false, errors.New("Something wrong checking * expression")
	}

	xs, _, err := EvalExpr(ctx, cexpr, env)
	if err != nil {
		return nil, false, err
	} else if xs == nil {
		// XXX temporary error until typed evaluation of nil
		return nil, false, errors.New("Cannot dereferece nil type")
	}

	var x reflect.Value
	if x, err = expectSingleValue(ctx, *xs, starExpr.X); err != nil {
		return nil, false, err
	}

	switch x.Type().Kind() {
	case reflect.Interface, reflect.Ptr:
		val := x.Elem()
		return &val, true, nil
	default:
		return nil, true, ErrInvalidIndirect{x.Type()}
	}
}
예제 #30
0
파일: encode.go 프로젝트: 2thetop/go
func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	e.reflectValue(v.Elem(), opts)
}