Beispiel #1
0
func validateBitType(sqlType string, goType reflect.Type) bool {
	bits := 0
	if n, err := fmt.Sscanf(sqlType, "bit(%d)", &bits); err != nil {
		return false
	} else if n != 1 {
		return false
	}
	requiredBits := []int{8, 16, 32, 64}
	i := sort.SearchInts(requiredBits, bits)
	if i >= len(requiredBits) {
		return false
	}
	bits = requiredBits[i]
	switch goType.Kind() {
	case reflect.Int, reflect.Uint:
		fallthrough
	case reflect.Int8, reflect.Uint8:
		fallthrough
	case reflect.Int16, reflect.Uint16:
		fallthrough
	case reflect.Int32, reflect.Uint32:
		fallthrough
	case reflect.Int64, reflect.Uint64:
		return bits == goType.Bits()
	}
	return false
}
Beispiel #2
0
func makeUnsignedSinglePacker(typ reflect.Type, ilsb uint64, width uint8) packer {
	firstByte := ilsb / 8
	lsb := uint8(ilsb % 8)
	canOverflow := width != uint8(typ.Bits())
	maxVal := (uint64(1) << width) - 1
	switch {
	case lsb+width <= 8:
		if canOverflow {
			return func(b []byte, field reflect.Value) {
				u := field.Uint()
				if u > maxVal {
					panic(Error{fmt.Errorf("gopack: value out of range: max %v; got %v", maxVal, u)})
				}
				b[firstByte] |= byte(u << lsb)
			}
		} else {
			return func(b []byte, field reflect.Value) {
				b[firstByte] |= byte(field.Uint() << lsb)
			}
		}
	case lsb+width <= 16:
		if canOverflow {
			return func(b []byte, field reflect.Value) {
				u := field.Uint()
				if u > maxVal {
					panic(Error{fmt.Errorf("gopack: value out of range: max %v; got %v", maxVal, u)})
				}
				*(*uint16)(unsafe.Pointer(&b[firstByte])) |= uint16(u << lsb)
			}
		} else {
			return func(b []byte, field reflect.Value) {
				*(*uint16)(unsafe.Pointer(&b[firstByte])) |= uint16(field.Uint() << lsb)
			}
		}
Beispiel #3
0
func validateIntType(bits int, sqlType string, goType reflect.Type) bool {
	if strings.HasSuffix(sqlType, " unsigned") {
		switch goType.Kind() {
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			return bits == goType.Bits()
		}
	} else {
		switch goType.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			return bits == goType.Bits()
		}
	}
	return false
}
// makeMapKeyFromString takes the key type for a map, and a string
// representing the key, it then tries to convert the string
// representation into a value of the correct type.
func makeMapKeyFromString(mapKeyType reflect.Type, pointer string) (reflect.Value, bool) {
	valp := reflect.New(mapKeyType)
	val := reflect.Indirect(valp)
	switch mapKeyType.Kind() {
	case reflect.String:
		return reflect.ValueOf(pointer), true
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		iv, err := strconv.ParseInt(pointer, 10, mapKeyType.Bits())
		if err == nil {
			val.SetInt(iv)
			return val, true
		}
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
		iv, err := strconv.ParseUint(pointer, 10, mapKeyType.Bits())
		if err == nil {
			val.SetUint(iv)
			return val, true
		}
	case reflect.Float32, reflect.Float64:
		fv, err := strconv.ParseFloat(pointer, mapKeyType.Bits())
		if err == nil {
			val.SetFloat(fv)
			return val, true
		}
	}

	return reflect.ValueOf(nil), false
}
Beispiel #5
0
Datei: gl.go Projekt: extrame/gl
func toCtype(data interface{}) (p unsafe.Pointer, t C.GLenum, ts int, s uintptr) {
	v := reflect.ValueOf(data)
	var et reflect.Type
	switch v.Type().Kind() {
	case reflect.Slice, reflect.Array:
		if !v.IsNil() {
			p = unsafe.Pointer(v.Index(0).UnsafeAddr())
			s = uintptr(v.Len())
		}
		et = v.Type().Elem()
	default:
		panic("not a pointer or slice")
	}
	switch et.Kind() {
	case reflect.Uint8:
		t = UNSIGNED_BYTE
	case reflect.Int8:
		t = BYTE
	case reflect.Uint16:
		t = UNSIGNED_SHORT
	case reflect.Int16:
		t = SHORT
	case reflect.Uint32:
		t = UNSIGNED_INT
	case reflect.Int32:
		t = INT
	case reflect.Float32:
		t = FLOAT
	case reflect.Float64:
		t = DOUBLE
	default:
		panic("unknown type: " + reflect.TypeOf(v).String())
	}
	ts = et.Bits() / 8
	s *= uintptr(et.Bits() / 8)

	return
}
Beispiel #6
0
// Append value to target or return a new value of type typ.
func appendValue(typ reflect.Type, target reflect.Value, value string) (result reflect.Value, err error) {
	if target.IsValid() {
		typ = target.Type()
	}
	if typ.Kind() == reflect.Interface {
		typ = reflect.TypeOf([]string{})
	}
	switch typ.Kind() {
	case reflect.Bool:
		if parsed, err2 := strconv.ParseBool(value); err2 != nil {
			err = &UnmarshalTypeError{Value: value, Type: typ}
		} else if target.IsValid() && target.CanSet() {
			target.SetBool(parsed)
		} else {
			result = reflect.ValueOf(parsed)
		}
	case reflect.Float32, reflect.Float64:
		if parsed, err2 := strconv.ParseFloat(value, typ.Bits()); err2 != nil {
			err = &UnmarshalTypeError{Value: value, Type: typ}
		} else if target.IsValid() && target.CanSet() {
			target.SetFloat(parsed)
		} else {
			switch typ.Kind() {
			case reflect.Float32:
				result = reflect.ValueOf(float32(parsed))
			default:
				result = reflect.ValueOf(parsed)
			}
		}
	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
		if parsed, err2 := strconv.ParseInt(value, 10, typ.Bits()); err2 != nil {
			err = &UnmarshalTypeError{Value: value, Type: typ}
		} else if target.IsValid() && target.CanSet() {
			target.SetInt(parsed)
		} else {
			switch typ.Kind() {
			case reflect.Int:
				result = reflect.ValueOf(int(parsed))
			case reflect.Int16:
				result = reflect.ValueOf(int16(parsed))
			case reflect.Int32:
				result = reflect.ValueOf(int32(parsed))
			default:
				result = reflect.ValueOf(parsed)
			}
		}
	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if parsed, err2 := strconv.ParseUint(value, 10, typ.Bits()); err2 != nil {
			err = &UnmarshalTypeError{Value: value, Type: typ}
		} else if target.IsValid() && target.CanSet() {
			target.SetUint(parsed)
		} else {
			switch typ.Kind() {
			case reflect.Uint:
				result = reflect.ValueOf(uint(parsed))
			case reflect.Uint16:
				result = reflect.ValueOf(uint16(parsed))
			case reflect.Uint32:
				result = reflect.ValueOf(uint32(parsed))
			default:
				result = reflect.ValueOf(parsed)
			}
		}
	case reflect.Ptr:
		result = reflect.New(typ.Elem())
		var elem reflect.Value
		if elem, err = appendValue(typ.Elem(), elem, value); err == nil {
			result.Elem().Set(elem)
		}
	case reflect.String:
		result = reflect.ValueOf(value)
	case reflect.Slice:
		var next reflect.Value
		next, err = appendValue(typ.Elem(), next, value)
		if err == nil && next.IsValid() {
			result = target
			if result.IsValid() && result.Type().Kind() == reflect.Interface {
				result = reflect.ValueOf(result.Interface())
			}
			if !result.IsValid() {
				result = reflect.MakeSlice(typ, 0, 4)
			}
			result = reflect.Append(result, next)
		}
	default:
		err = &UnmarshalTypeError{
			Value: value,
			Type:  typ,
		}
	}
	return
}
Beispiel #7
0
// Convert an untyped constant to a typed constant. If the types from and to are
// incompatible, ErrBadConstConversion is returned along with an invalid value.
// If the types were compatible but other errors are present, such as integer
// overflows or floating truncations, the conversion will continue and a valid
// value will be returned. Therefore, if a valid value is returned, the const
// type is assignable to the reflect.Type. This can be checked using
//
//  reflect.Value(constValue).IsValid()
//
func convertConstToTyped(from ConstType, c constValue, to reflect.Type, isTypeCast bool, expr Expr) (
	constValue, []error) {
	v := hackedNew(to).Elem()

	switch from.(type) {
	case ConstShiftedIntType:
		switch to.Kind() {
		case reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
			return constValue{}, []error{ErrBadConstConversion{expr, from, to}}
		}
		return convertConstToTyped(ConstInt, c, to, isTypeCast, expr)
	case ConstIntType, ConstRuneType, ConstFloatType, ConstComplexType:
		underlying := reflect.Value(c).Interface().(*ConstNumber)
		switch to.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			var errs []error
			i, truncation, overflow := underlying.Value.Int(to.Bits())
			if truncation {
				errs = append(errs, ErrTruncatedConstant{expr, ConstInt, underlying})
			}
			if overflow {
				errs = append(errs, ErrOverflowedConstant{expr, from, to, underlying})
			}
			// For some reason, the errors produced are "complex -> int" then "complex -> real"
			_, truncation = underlying.Value.Real()
			if truncation {
				errs = append(errs, ErrTruncatedConstant{expr, ConstFloat, underlying})
			}
			v.SetInt(i)
			return constValue(v), errs

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			var errs []error
			u, truncation, overflow := underlying.Value.Uint(to.Bits())
			if truncation {
				errs = append(errs, ErrTruncatedConstant{expr, ConstInt, underlying})
			}
			if overflow {
				errs = append(errs, ErrOverflowedConstant{expr, from, to, underlying})
			}
			// For some reason, the erros produced are "complex -> int" then "complex -> real"
			_, truncation = underlying.Value.Real()
			if truncation {
				errs = append(errs, ErrTruncatedConstant{expr, ConstFloat, underlying})
			}
			v.SetUint(u)
			return constValue(v), errs

		case reflect.Float32, reflect.Float64:
			var errs []error
			f, truncation, _ := underlying.Value.Float64()
			if truncation {
				errs = []error{ErrTruncatedConstant{expr, ConstFloat, underlying}}
			}
			v.SetFloat(f)
			return constValue(v), errs

		case reflect.Complex64, reflect.Complex128:
			cmplx, _ := underlying.Value.Complex128()
			v.SetComplex(cmplx)
			return constValue(v), nil

		// string(97) is legal, equivalent of string('a'), but this
		// conversion is not automatic. "abc" + 10 is illegal.
		case reflect.String:
			if isTypeCast && from.IsIntegral() {
				i, _, overflow := underlying.Value.Int(32)
				if overflow {
					err := ErrOverflowedConstant{expr, from, ConstString, underlying}
					return constValue{}, []error{err}
				}
				v.SetString(string(i))
				return constValue(v), nil
			}

		// consts can satisfy the empty interface only
		case reflect.Interface:
			if to == emptyInterface {
				to = underlying.Type.DefaultPromotion()
				cv, _ := convertConstToTyped(from, c, to, isTypeCast, expr)
				v.Set(reflect.Value(cv).Convert(emptyInterface))
				return constValue(v), nil
			}
		}

	case ConstStringType:
		if to.Kind() == reflect.String {
			v.SetString(reflect.Value(c).String())
			return constValue(v), nil
		} else if to == emptyInterface {
			v.Set(reflect.Value(c).Convert(emptyInterface))
			return constValue(v), nil
		} else if isTypeCast && to == byteSlice || to == runeSlice {
			v = reflect.Value(c).Convert(to)
			return constValue(v), nil
		}

	case ConstBoolType:
		if to.Kind() == reflect.Bool {
			v.SetBool(reflect.Value(c).Bool())
			return constValue(v), nil
		} else if to == emptyInterface {
			v.Set(reflect.Value(c).Convert(emptyInterface))
			return constValue(v), nil
		}

	case ConstNilType:
		// Unfortunately there is no reflect.Type.CanNil()
		if isNillable(to) {
			// v is already nil
			return constValue(v), nil
		}
	}

	return constValue{}, []error{ErrBadConstConversion{expr, from, to}}
}
Beispiel #8
0
func getNumberSize(typ reflect.Type) string {
	return fmt.Sprintf("%d", typ.Bits())
}
Beispiel #9
0
func convertConstToTyped(ctx *Ctx, from ConstType, c constValue, to reflect.Type, expr Expr) (
	constValue, []error) {

	v := hackedNew(to).Elem()

	switch from.(type) {
	case ConstIntType, ConstRuneType, ConstFloatType, ConstComplexType:
		underlying := reflect.Value(c).Interface().(*ConstNumber)
		switch to.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			var errs []error
			i, truncation, overflow := underlying.Value.Int(to.Bits())
			if truncation {
				errs = append(errs, ErrTruncatedConstant{at(ctx, expr), ConstInt, underlying})
			}
			if overflow {
				errs = append(errs, ErrOverflowedConstant{at(ctx, expr), from, to, underlying})
			}
			// For some reason, the erros produced are "complex -> int" then "complex -> real"
			_, truncation = underlying.Value.Real()
			if truncation {
				errs = append(errs, ErrTruncatedConstant{at(ctx, expr), ConstFloat, underlying})
			}
			v.SetInt(i)
			return constValue(v), errs

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			var errs []error
			u, truncation, overflow := underlying.Value.Uint(to.Bits())
			if truncation {
				errs = append(errs, ErrTruncatedConstant{at(ctx, expr), ConstInt, underlying})
			}
			if overflow {
				errs = append(errs, ErrOverflowedConstant{at(ctx, expr), from, to, underlying})
			}
			// For some reason, the erros produced are "complex -> int" then "complex -> real"
			_, truncation = underlying.Value.Real()
			if truncation {
				errs = append(errs, ErrTruncatedConstant{at(ctx, expr), ConstFloat, underlying})
			}
			v.SetUint(u)
			return constValue(v), errs

		case reflect.Float32, reflect.Float64:
			var errs []error
			f, truncation, _ := underlying.Value.Float64()
			if truncation {
				errs = []error{ErrTruncatedConstant{at(ctx, expr), ConstFloat, underlying}}
			}
			v.SetFloat(f)
			return constValue(v), errs

		case reflect.Complex64, reflect.Complex128:
			cmplx, _ := underlying.Value.Complex128()
			v.SetComplex(cmplx)
			return constValue(v), nil

		// string(97) is legal, equivalent of string('a')
		case reflect.String:
			if from.IsIntegral() {
				i, _, overflow := underlying.Value.Int(32)
				if overflow {
					err := ErrOverflowedConstant{at(ctx, expr), from, ConstString, underlying}
					return constValue{}, []error{err}
				}
				v.SetString(string(i))
				return constValue(v), nil
			}
		}
	case ConstStringType:
		if v.Type().Kind() == reflect.String {
			v.SetString(reflect.Value(c).String())
			return constValue(v), nil
		}

	case ConstBoolType:
		if to.Kind() == reflect.Bool {
			v.SetBool(reflect.Value(c).Bool())
			return constValue(v), nil
		}

	case ConstNilType:
		// Unfortunately there is no reflect.Type.CanNil()
		switch to.Kind() {
		case reflect.Chan, reflect.Func, reflect.Interface,
			reflect.Map, reflect.Ptr, reflect.Slice:

			// v is already nil
			return constValue(v), nil
		}
	}

	return constValue{}, []error{ErrBadConstConversion{at(ctx, expr), from, to, reflect.Value(c)}}
}
Beispiel #10
0
func (v *Value) ToRealNumber(nv json.Number, valueType reflect.Type) interface{} {
	switch valueType.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		n, err := strconv.ParseInt(string(nv), 10, 64)
		if err != nil {
			return fmt.Errorf("Can not use number %v as %s patch failure err: %v", nv, valueType, err)
		}
		switch k := valueType.Kind(); k {
		default:
			panic(&reflect.ValueError{"Transform to int failure, err: %v", valueType.Kind()})
		case reflect.Int:
			return int(n)
		case reflect.Int8:
			return int8(n)
		case reflect.Int16:
			return int16(n)
		case reflect.Int32:
			return int32(n)
		case reflect.Int64:
			return n
		}
		return n

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		n, err := strconv.ParseUint(string(nv), 10, 64)
		if err != nil {
			return fmt.Errorf("Can not use number %v as %s patch failure err: %v", nv, valueType, err)
		}
		switch k := valueType.Kind(); k {
		default:
			panic(&reflect.ValueError{"Transform to uint failure, err: %v", valueType.Kind()})
		case reflect.Uint:
			return uint(n)
		case reflect.Uint8:
			return uint8(n)
		case reflect.Uint16:
			return uint16(n)
		case reflect.Uint32:
			return uint32(n)
		case reflect.Uint64:
			return n
		case reflect.Uintptr:
			return uintptr(n)
		}
		return n

	case reflect.Float32, reflect.Float64:
		n, err := strconv.ParseFloat(string(nv), valueType.Bits())
		if err != nil {
			return fmt.Errorf("Can not use number %v as %s patch failure err: %v", valueType, valueType, err)
		}
		switch k := valueType.Kind(); k {
		default:
			panic(&reflect.ValueError{"Transform to float failure, err: %v", valueType.Kind()})
		case reflect.Float32:
			return int32(n)
		case reflect.Float64:
			return n
		}
		return n

	default:
		return fmt.Errorf("Can not use use value %v to patch %s type", valueType, valueType.Kind())
	}
	return nil
}
Beispiel #11
0
func traverse(v reflect.Value, t reflect.Type) (match bool) {
	switch v.Kind() {
	case reflect.Map:
		// TODO: Logic here bit messy, needs cleaning
		// Idea: fieldNames are must, omitEmpty means that JSON can't have zero val-
		// ues in golang sense for such fields because fields with omit and empty
		// values will not be present in resulting json
		fieldNames, omitEmpty := getJSONFieldNames(t)
		if len(fieldNames) != len(v.MapKeys()) {
			return false
		}
		for _, key := range v.MapKeys() {
			must := fieldNames[key.String()]
			omit := omitEmpty[key.String()]
			value := v.MapIndex(key).Interface()
			if must == "" && omit == "" {
				return false
			}
			if omit != "" {
				if value == nil || isZero(reflect.ValueOf(value)) {
					return false
				}
				must = omit
			}
			f, _ := t.FieldByName(must)
			ok := traverse(reflect.ValueOf(value), f.Type)
			if !ok {
				return false
			}
		}
	case reflect.Slice:
		if t.Kind() != reflect.Slice {
			return false
		}
		trueType := t.Elem()
		for i := 0; i < v.Len(); i++ {
			ok := traverse(reflect.ValueOf(v.Index(i).Interface()), trueType)
			if !ok {
				return false
			}
		}

	case reflect.Bool:
		return t.Kind() == reflect.Bool
	case reflect.String:
		// If number
		var number json.Number
		if v.Type() == reflect.TypeOf(number) {
			switch t.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				_, err := strconv.ParseInt(v.String(), 10, t.Bits())
				return err == nil
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				_, err := strconv.ParseUint(v.String(), 10, t.Bits())
				return err == nil
			case reflect.Float32, reflect.Float64:
				_, err := strconv.ParseFloat(v.String(), t.Bits())
				return err == nil
			default:
				return false
			}
		}
		return t.Kind() == reflect.String

	}
	return true
}
Beispiel #12
0
// getParser returns back a FieldParser instance for the given type
func getParser(t reflect.Type, k reflect.Kind) (parser *fieldParser) {
	switch k {
	case reflect.String:
		parser = &fieldParser{
			Parse: func(v string) (interface{}, error) {
				return v, nil
			},
			Set: func(f *reflect.Value, v interface{}) {
				f.SetString(v.(string))
			},
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		parser = &fieldParser{
			Parse: func(v string) (interface{}, error) {
				intValue, err := strconv.ParseInt(v, 0, t.Bits())
				if err != nil {
					return nil, err
				}

				return intValue, nil
			},
			Set: func(f *reflect.Value, v interface{}) {
				f.SetInt(v.(int64))
			},
		}
	case reflect.Bool:
		parser = &fieldParser{
			Parse: func(v string) (interface{}, error) {
				boolValue, err := strconv.ParseBool(v)
				if err != nil {
					return nil, err
				}
				return boolValue, nil
			},
			Set: func(f *reflect.Value, v interface{}) {
				f.SetBool(v.(bool))
			},
		}

	case reflect.Float32, reflect.Float64:
		parser = &fieldParser{
			Parse: func(v string) (interface{}, error) {
				floatValue, err := strconv.ParseFloat(v, t.Bits())
				if err != nil {
					return nil, err
				}
				return floatValue, nil
			},
			Set: func(f *reflect.Value, v interface{}) {
				f.SetFloat(v.(float64))
			},
		}
	case reflect.Slice:
		parser = &fieldParser{
			Parse: func(v string) (interface{}, error) {
				elemType := t.Elem()
				parser := getParser(elemType, elemType.Kind())
				strValues := strings.Split(v, ",")

				slice := reflect.MakeSlice(reflect.SliceOf(elemType), 0, 0)
				for i := range strValues {
					value, err := parser.Parse(strValues[i])
					if err != nil {
						return nil, err
					}

					itmValue := reflect.ValueOf(value)
					itmValue = itmValue.Convert(elemType)

					slice = reflect.Append(slice, itmValue)
				}
				return slice.Interface(), nil
			},
			Set: func(f *reflect.Value, v interface{}) {
				f.Set(reflect.ValueOf(v))
			},
		}
	}
	return
}
Beispiel #13
0
// unmarshallString parses string s to in vto
func unmarshallString(vto reflect.Value, tto reflect.Type, s string) error {

	// custom handlers for non-builtin types:
	switch tto.String() {

	case "time.Duration":
		d, e := time.ParseDuration(s)
		if e != nil {
			return e
		}
		vto.Set(reflect.ValueOf(d))
		return nil
	}

	// handle builtin types:
	switch vto.Kind() {

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:

		ival, err := strconv.ParseInt(s, 10, tto.Bits())

		if err != nil {
			// try again looking for B/K/M/G/T
			ival, err = getBytes(s, err)
			if err != nil {
				return err
			}
		}

		vto.SetInt(ival)
		return nil

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:

		uval, err := strconv.ParseUint(s, 10, tto.Bits())

		if err != nil {

			// try again looking for B/K/M/G/T
			ival, e := getBytes(s, err)
			if e != nil {
				return e
			}
			uval = uint64(ival)

		}

		vto.SetUint(uval)
		return nil

	case reflect.Float32, reflect.Float64:

		fval, err := strconv.ParseFloat(s, tto.Bits())

		if err != nil {
			return err
		}

		vto.SetFloat(fval)
		return nil
	}

	return fmt.Errorf("don't know how to unmarshall string to %v\n", tto)
}