Пример #1
0
func arrayEncoder(typ reflect.Type) (typeEncoder, error) {
	al := typ.Len()
	etyp := typ.Elem()
	switch etyp.Kind() {
	case reflect.Int8, reflect.Uint8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64:
		// Take advantage of the fast path in Write
		return func(enc *encoder, p unsafe.Pointer) error {
			v := reflect.NewAt(typ, p).Elem().Slice(0, al)
			return Write(enc, enc.order, v.Interface())
		}, nil
	}
	eenc, err := makeEncoder(etyp)
	if err != nil {
		return nil, err
	}
	s := etyp.Size()
	return func(enc *encoder, p unsafe.Pointer) error {
		for ii := 0; ii < al; ii++ {
			if err := eenc(enc, p); err != nil {
				return err
			}
			p = unsafe.Pointer(uintptr(p) + s)
		}
		return nil
	}, nil
}
Пример #2
0
func decodeArray(t reflect.Type) interface{} {
	slType := reflect.SliceOf(t.Elem())
	slDec := getTypeDecoder(slType)
	_, ok := slDec.(decodeFunc)
	l := t.Len()
	return decodeReflectFunc(func(dec *Decoder, v reflect.Value) error {
		p := v.UnsafeAddr()
		var err error
		if ok {
			slice := reflect.SliceHeader{
				Len: l, Cap: l,
				Data: p,
			}
			err = (slDec.(decodeFunc))(dec, unsafe.Pointer(&slice))
			if slice.Len != l {
				return ErrorIncorrectLength{l, slice.Len}
			}
		} else {
			slice := v.Slice(0, v.Len())
			ptr := reflect.New(slType)
			ptr.Elem().Set(slice)
			err = (slDec.(decodeReflectFunc))(dec, ptr.Elem())
			if slice.Len() != l {
				return ErrorIncorrectLength{l, slice.Len()}
			}
		}
		return err
	})
}
Пример #3
0
// formFromGoType returns a suitable FITS TFORM string from a reflect.Type
func formFromGoType(rt reflect.Type, htype HDUType) string {
	hdr := ""
	var t reflect.Type
	switch rt.Kind() {
	case reflect.Array:
		hdr = fmt.Sprintf("%d", rt.Len())
		t = rt.Elem()
	case reflect.Slice:
		hdr = "Q"
		t = rt.Elem()
	default:
		t = rt
	}

	dict, ok := g_gotype2FITS[t.Kind()]
	if !ok {
		return ""
	}

	form, ok := dict[htype]
	if !ok {
		return ""
	}

	return hdr + form
}
Пример #4
0
func sizeof(t reflect.Type) (int, error) {
	switch t.Kind() {
	case reflect.Array:
		n, err := sizeof(t.Elem())
		if err != nil {
			return 0, err
		}
		return t.Len() * n, nil

	case reflect.Struct:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s, err := sizeof(t.Field(i).Type)
			if err != nil {
				return 0, err
			}
			sum += s
		}
		return sum, nil

	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
		return int(t.Size()), nil
	}
	return 0, errors.New("invalid type " + t.String())
}
Пример #5
0
func sliceDecoder(typ reflect.Type) (typeDecoder, error) {
	switch typ.Elem().Kind() {
	case reflect.Int8, reflect.Uint8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64:
		// Take advantage of the fast path in Read
		if typ.Kind() == reflect.Slice {
			return func(dec *decoder, v reflect.Value) error {
				return Read(dec, dec.order, v.Interface())
			}, nil
		}
		// Array
		al := typ.Len()
		return func(dec *decoder, v reflect.Value) error {
			// Value must be addressable when we reach this point
			return Read(dec, dec.order, v.Slice(0, al).Interface())
		}, nil
	}
	edec, err := makeDecoder(typ.Elem())
	if err != nil {
		return nil, err
	}
	return func(dec *decoder, v reflect.Value) error {
		sl := v.Len()
		for ii := 0; ii < sl; ii++ {
			if err := edec(dec, v.Index(ii)); err != nil {
				return err
			}
		}
		return nil
	}, nil
}
Пример #6
0
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
func sizeof(t reflect.Type) int {
	switch t.Kind() {
	case reflect.Array:
		if s := sizeof(t.Elem()); s >= 0 {
			return s * t.Len()
		}

	case reflect.Struct:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s := sizeof(t.Field(i).Type)
			if s < 0 {
				return -1
			}
			sum += s
		}
		return sum

	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
		return int(t.Size())
	}

	return -1
}
Пример #7
0
func evalCompositeLitArrayOrSlice(ctx *Ctx, t reflect.Type, lit *CompositeLit, env *Env) (*reflect.Value, bool, error) {

	v := reflect.New(t).Elem()

	var curKey uint64 = 0
	var size uint64 = 0
	if t.Kind() == reflect.Array {
		size = uint64(t.Len())
	} else {
		// Check all keys are valid and calculate slice size.
		// Elements with key are placed at the keyed position.
		// Elements without are placed one after the previous.
		// For example, []int{1, 2:1, 1} -> [1, 0, 1, 1]
		for _, elt := range lit.Elts {
			if kv, ok := elt.(*KeyValueExpr); !ok {
				size += 1
			} else if k, ok := kv.Key.(*BasicLit); !ok || k.Kind != token.INT {
				return nil, false, ErrArrayKey

				// The limit of 2^31 elements is infered from the go implementation
				// The actual limit is "largest value representable by an int"
			} else if i, err := strconv.ParseUint(k.Value, 0, 31); err != nil {
				return nil, false, ErrArrayKey
			} else if !(i < size) {
				size = i + 1
			}
		}
		// Allocate the slice
		v.Set(reflect.MakeSlice(t, int(size), int(size)))
	}

	// Fill the array or slice, the reflect interface is identical for both
	for _, elt := range lit.Elts {
		var expr ast.Expr
		if kv, ok := elt.(*KeyValueExpr); !ok {
			expr = elt
		} else {
			// We know this expression to be valid from above.
			curKey, _ = strconv.ParseUint(kv.Key.(*BasicLit).Value, 0, 31)
			expr = kv.Value
		}

		if !(curKey < size) {
			return nil, false, ErrArrayIndexOutOfBounds{t, curKey}
		}

		// Evaluate and set the element
		elem := v.Index(int(curKey))
		if values, typed, err := EvalExpr(ctx, expr.(Expr), env); err != nil {
			return nil, false, err
		} else if value, err := expectSingleValue(ctx, *values, elt); err != nil {
			return nil, false, err
		} else if err := setTypedValue(elem, value, typed); err != nil {
			return nil, false, err
		}
		curKey += 1
	}
	return &v, true, nil
}
Пример #8
0
// Return the string that should be used to refer to the supplied type within
// the given package. The output is not guaranteed to be pretty, and should be
// run through a tool like gofmt afterward.
//
// For example, a pointer to an io.Reader may be rendered as "*Reader" or
// "*io.Reader" depending on whether the package path is "io" or not.
func typeString(
	t reflect.Type,
	pkgPath string) (s string) {
	// Is this type named? If so we use its name, possibly with a package prefix.
	//
	// Examples:
	//
	//     int
	//     string
	//     error
	//     gcs.Bucket
	//
	if t.Name() != "" {
		if t.PkgPath() == pkgPath {
			s = t.Name()
		} else {
			s = t.String()
		}

		return
	}

	// This type is unnamed. Recurse.
	switch t.Kind() {
	case reflect.Array:
		s = fmt.Sprintf("[%d]%s", t.Len(), typeString(t.Elem(), pkgPath))

	case reflect.Chan:
		s = fmt.Sprintf("%s %s", t.ChanDir(), typeString(t.Elem(), pkgPath))

	case reflect.Func:
		s = typeString_Func(t, pkgPath)

	case reflect.Interface:
		s = typeString_Interface(t, pkgPath)

	case reflect.Map:
		s = fmt.Sprintf(
			"map[%s]%s",
			typeString(t.Key(), pkgPath),
			typeString(t.Elem(), pkgPath))

	case reflect.Ptr:
		s = fmt.Sprintf("*%s", typeString(t.Elem(), pkgPath))

	case reflect.Slice:
		s = fmt.Sprintf("[]%s", typeString(t.Elem(), pkgPath))

	case reflect.Struct:
		s = typeString_Struct(t, pkgPath)

	default:
		log.Panicf("Unhandled kind %v for type: %v", t.Kind(), t)
	}

	return
}
Пример #9
0
func (s *Shader) assignPrimitive(ptr unsafe.Pointer, typ reflect.Type, u gl.UniformLocation) bool {
	switch typ.Kind() {
	// basic primitives
	case reflect.Int:
		u.Uniform1i(*(*int)(ptr))
	case reflect.Int32:
		u.Uniform1i(int(*(*int32)(ptr)))
	case reflect.Float32:
		u.Uniform1f(*(*float32)(ptr))
	// arrays represent vectors or matrices
	case reflect.Array:
		size := typ.Len()
		elemtyp := typ.Elem()
		switch elemtyp.Kind() {
		case reflect.Int32:
			switch size {
			case 2:
				slice := (*(*[2]int32)(ptr))[:]
				u.Uniform2iv(1, slice)
			case 3:
				slice := (*(*[3]int32)(ptr))[:]
				u.Uniform3iv(1, slice)
			case 4:
				slice := (*(*[4]int32)(ptr))[:]
				u.Uniform4iv(1, slice)
			default:
				return false
			}
		case reflect.Float32:
			switch size {
			case 2:
				slice := (*(*[2]float32)(ptr))[:]
				u.Uniform2fv(1, slice)
			case 3:
				slice := (*(*[3]float32)(ptr))[:]
				u.Uniform3fv(1, slice)
			case 4:
				slice := (*(*[4]float32)(ptr))[:]
				u.Uniform4fv(1, slice)
			case 9:
				matptr := (*[9]float32)(ptr)
				u.UniformMatrix3f(false, matptr)
			case 16:
				matptr := (*[16]float32)(ptr)
				u.UniformMatrix4f(false, matptr)
			default:
				return false
			}
		default:
			return false
		}
	default:
		return false
	}
	return true
}
Пример #10
0
func getArrayDims(dt reflect.Type) []int {
	result := []int{}
	if dt.Kind() == reflect.Array {
		result = append(result, dt.Len())
		for _, dim := range getArrayDims(dt.Elem()) {
			result = append(result, dim)
		}
	}
	return result
}
Пример #11
0
func reifyArray(
	opts fieldOptions,
	to reflect.Value, tTo reflect.Type,
	val value,
) (reflect.Value, Error) {
	arr := castArr(val)
	if len(arr) != tTo.Len() {
		ctx := val.Context()
		return reflect.Value{}, raiseArraySize(ctx, val.meta(), len(arr), tTo.Len())
	}
	return reifyDoArray(opts, to, tTo.Elem(), val, arr)
}
Пример #12
0
//获取t对应的类型信息,不支持slice, function, map, pointer, interface, channel
//如果parentIdx的长度>0,则表示t是strut中的字段的类型信息, t为字段对应的类型
func getKeyInfoByParent(t reflect.Type, parent *keyInfo, parentIdx []int) (ki *keyInfo, err error) {
	ki = &keyInfo{}
	//判断是否实现了hasher接口
	if t.Implements(hasherT) {
		ki.isHasher = true
		return
	}
	ki.kind = t.Kind()

	if _, ok := engM[ki.kind]; ok {
		//简单类型,不需要再分解元素类型的信息
		ki.index = parentIdx
	} else {
		//some types can be used as key, we can use equals to test
		switch ki.kind {
		case reflect.Chan, reflect.Slice, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface:
			err = NonSupportKey
		case reflect.Struct:
			if parent == nil {
				//parent==nil表示t不是一个嵌套的struct,所以这里需要初始化fields
				parent = ki
				ki.fields = make([]*keyInfo, 0, t.NumField())
			}
			for i := 0; i < t.NumField(); i++ {
				f := t.Field(i)
				//skip unexported field,
				if len(f.PkgPath) > 0 {
					continue
				}

				idx := make([]int, len(parentIdx), len(parentIdx)+1)
				copy(idx, parentIdx)
				idx = append(idx, i)
				if fi, e := getKeyInfoByParent(f.Type, parent, idx); e != nil {
					err = e
					return
				} else {
					//fi.index = i
					parent.fields = append(ki.fields, fi)
				}
			}
		case reflect.Array:
			if ki.elementInfo, err = getKeyInfo(t.Elem()); err != nil {
				return
			}
			ki.size = t.Len()
			ki.index = parentIdx
		}
	}

	return

}
Пример #13
0
func ValType(t reflect.Type) (decl string) {
	switch k := t.Kind(); k {
	case reflect.Struct:
		decl = "struct {\n"
		for i, ed := 0, t.NumField(); i < ed; i++ {
			ft := t.Field(i)
			if ft.Tag != "-" || ft.Tag.Get("goval") == "-" {
				s := ft.Name + " " + ValType(ft.Type)
				if ft.Tag != "" {
					s += " `" + strings.Replace("`", "\\`", string(ft.Tag), -1) + "`"
				}
				decl += indent(s) + "\n"
			}
		}
		decl += "}"
	case reflect.Array:
		decl = "[" + strconv.Itoa(t.Len()) + "]" + Val(t.Elem())
	case reflect.Slice:
		decl = "[]" + Val(t.Elem())
	case reflect.Chan:
		switch t.ChanDir() {
		case reflect.RecvDir:
			decl = "<-chan "
		case reflect.SendDir:
			decl = "chan<- "
		case reflect.BothDir:
			decl = "chan "
		default:
			panic("Didn't expect a dir other than send, recieve or both.")
		}
		decl += Val(t.Elem())
	case reflect.Map:
		decl = "map[" + ValType(t.Key()) + "]" + ValType(t.Elem())
	case reflect.Ptr:
		decl = "*" + ValType(t.Elem())
	case reflect.Interface:
		decl = "interface {\n"
		for i, ed := 0, t.NumMethod(); i < ed; i++ {
			ft := t.Method(i)
			s := ft.Name + FormatFuncArguments(ft.Type)
			decl += indent(s) + "\n"
		}
		decl += "}"
	case reflect.Func:
		decl = "func" + FormatFuncArguments(t)
	default:
		return k.String()
	}

	return
}
Пример #14
0
func sizeof(t reflect.Type) int {
	switch t := t.(type) {
	case *reflect.ArrayType:
		n := sizeof(t.Elem())
		if n < 0 {
			return -1
		}
		return t.Len() * n

	case *reflect.StructType:
		sum := 0
		for i, n := 0, t.NumField(); i < n; i++ {
			s := sizeof(t.Field(i).Type)
			if s < 0 {
				return -1
			}
			sum += s
		}
		return sum

	case *reflect.Uint8Type:
		return 1
	case *reflect.Uint16Type:
		return 2
	case *reflect.Uint32Type:
		return 4
	case *reflect.Uint64Type:
		return 8
	case *reflect.Int8Type:
		return 1
	case *reflect.Int16Type:
		return 2
	case *reflect.Int32Type:
		return 4
	case *reflect.Int64Type:
		return 8
	case *reflect.Float32Type:
		return 4
	case *reflect.Float64Type:
		return 8
	}
	return -1
}
Пример #15
0
func encodeArray(t reflect.Type) interface{} {
	//Cheat by turning the array into a slice
	slEnc := getTypeEncoder(reflect.SliceOf(t.Elem()))
	l := t.Len()
	_, ok := slEnc.(encodeFunc)
	return encodeReflectFunc(func(enc *Encoder, v reflect.Value) error {
		if ok {
			slice := reflect.SliceHeader{ //Convert to slice
				Data: v.UnsafeAddr(),
				Len:  l,
				Cap:  l,
			}
			encF := slEnc.(encodeFunc)
			return encF(enc, unsafe.Pointer(&slice))
		} else {
			encF := slEnc.(encodeReflectFunc)
			return encF(enc, v.Slice(0, v.Len()))
		}
	})
}
Пример #16
0
func evalIntIndex(ctx *Ctx, intExpr ast.Expr, env *Env, containerType reflect.Type) (int, error) {
	if is, typed, err := EvalExpr(ctx, intExpr.(Expr), env); err != nil {
		return -1, err
	} else if is == nil {
		// XXX temporary error until typed evaluation of nil
		return -1, errors.New("Cannot index nil type")
	} else if i, err := expectSingleValue(ctx, *is, intExpr); err != nil {
		return -1, err

		// XXX This untyped constant conversion is not correct, the index must evaluate exactly
		// to an integer.
		// a[2*0.5] is legal, a[2*0.4] is not.
		//
		// There is also the constraint that constant expressions such as "abc"[10] must be
		// in range. Fix both when constant expressions are correctly handled
	} else if !typed && i.Type().ConvertibleTo(reflect.TypeOf(int(0))) {
		result := int(i.Convert(reflect.TypeOf(int(0))).Int())
		if 0 <= result && (containerType.Kind() != reflect.Array || result < containerType.Len()) {
			return result, nil
		}
		return -1, ErrInvalidIndex{at(ctx, intExpr), reflect.ValueOf(result), containerType}
	} else {
		var result int
		switch i.Type().Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			result = int(i.Int())
			if result >= 0 {
				return result, nil
			}
			return -1, ErrInvalidIndex{at(ctx, intExpr), reflect.ValueOf(result), containerType}
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			result = int(i.Uint())
			if result >= 0 {
				return result, nil
			}
			return -1, ErrInvalidIndex{at(ctx, intExpr), reflect.ValueOf(result), containerType}
		default:
			return -1, ErrInvalidIndex{at(ctx, intExpr), i, containerType}
		}
	}
}
Пример #17
0
func NewMesh(attrs interface{}, indicies []uint32) *Mesh {
	mesh := new(Mesh)
	mesh.Attrs = attrs
	mesh.Indicies = indicies
	gl33.GenVertexArrays(1, &mesh.vao)
	gl33.BindVertexArray(mesh.vao)
	attrsValue := reflect.ValueOf(attrs)
	mesh.vertexBO = NewBuffer(gl33.ARRAY_BUFFER, gl33.STATIC_DRAW, attrs)
	vertexSpec := attrsValue.Type().Elem()
	if vertexSpec.Kind() != reflect.Struct && vertexSpec.Kind() != reflect.Array {
		panic("attrs is not a slice of structs or arrays")
	}
	var num int
	if vertexSpec.Kind() == reflect.Struct {
		num = vertexSpec.NumField()
	} else {
		num = vertexSpec.Len()
	}
	for i, offset := 0, uintptr(0); i < num; i++ {
		var field reflect.Type
		var type_ gl33.Enum
		var dimensions int
		if vertexSpec.Kind() == reflect.Struct {
			field = vertexSpec.Field(i).Type
		} else {
			field = vertexSpec.Elem()
		}
		if field.Kind() == reflect.Array {
			type_ = glType(field.Elem().Kind())
			dimensions = field.Len()
		} else {
			type_ = glType(field.Kind())
			dimensions = 1
		}
		setupAttrib(gl33.Uint(i), type_, dimensions, offset, int(vertexSpec.Size()))
		offset += field.Size()
	}
	mesh.indexBO = NewBuffer(gl33.ELEMENT_ARRAY_BUFFER, gl33.STATIC_DRAW, indicies)
	return mesh
}
Пример #18
0
// GetName of a type.
func (opts *GenOpts) GetName(t reflect.Type) string {
	name := t.Name()
	if name != "" {
		pkg, _ := packageAndName(t)
		// Handle the case the type is in the package we are generating code for.
		if pkg == "" || pkg == opts.PkgName {
			return name
		}
		return fmt.Sprintf("%s.%s", pkg, name)
	}
	switch t.Kind() {
	case reflect.Ptr:
		return fmt.Sprintf("*%s", opts.GetName(t.Elem()))
	case reflect.Map:
		return fmt.Sprintf("map[%s]%s", opts.GetName(t.Key()), opts.GetName(t.Elem()))
	case reflect.Slice:
		return fmt.Sprintf("[]%s", opts.GetName(t.Elem()))
	case reflect.Chan:
		return fmt.Sprintf("%s %s", t.ChanDir().String(), opts.GetName(t.Elem()))
	case reflect.Array:
		return fmt.Sprintf("[%d]%s", t.Len(), opts.GetName(t.Elem()))
	case reflect.Func:
		inputs := make([]string, t.NumIn())
		for i := range inputs {
			inputs[i] = opts.GetName(t.In(i))
		}
		outputs := make([]string, t.NumOut())
		for i := range outputs {
			outputs[i] = opts.GetName(t.Out(i))
		}
		out := strings.Join(outputs, ", ")
		if len(outputs) > 1 {
			out = fmt.Sprintf("(%s)", out)
		}
		return fmt.Sprintf("func (%s) %s", strings.Join(inputs, ", "), out)
	default:
		return t.String()
	}
}
Пример #19
0
// getType return the textual type name of given type that can be used in generated code.
func (g *Generator) getType(t reflect.Type) string {
	if t.Name() == "" {
		switch t.Kind() {
		case reflect.Ptr:
			return "*" + g.getType(t.Elem())
		case reflect.Slice:
			return "[]" + g.getType(t.Elem())
		case reflect.Array:
			return "[" + strconv.Itoa(t.Len()) + "]" + g.getType(t.Elem())
		case reflect.Map:
			return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
		}
	}

	if t.Name() == "" || t.PkgPath() == "" {
		return t.String()
	} else if t.PkgPath() == g.pkgPath {
		return t.Name()
	}
	// TODO: unnamed structs.
	return g.pkgAlias(t.PkgPath()) + "." + t.Name()
}
Пример #20
0
func sliceEncoder(typ reflect.Type) (typeEncoder, error) {
	switch typ.Elem().Kind() {
	case reflect.Int8, reflect.Uint8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64:
		// Take advantage of the fast path in Write
		if typ.Kind() == reflect.Slice {
			return func(enc *encoder, v reflect.Value) error {
				return Write(enc, enc.order, v.Interface())
			}, nil
		}
		// Array
		al := typ.Len()
		eenc, _ := makeEncoder(typ.Elem())
		return func(enc *encoder, v reflect.Value) error {
			if v.CanAddr() {
				return Write(enc, enc.order, v.Slice(0, al).Interface())
			}
			for ii := 0; ii < al; ii++ {
				if err := eenc(enc, v.Index(ii)); err != nil {
					return err
				}
			}
			return nil
		}, nil
	}
	eenc, err := makeEncoder(typ.Elem())
	if err != nil {
		return nil, err
	}
	return func(enc *encoder, v reflect.Value) error {
		sl := v.Len()
		for ii := 0; ii < sl; ii++ {
			if err := eenc(enc, v.Index(ii)); err != nil {
				return err
			}
		}
		return nil
	}, nil
}
Пример #21
0
func checkCompositeLitArrayOrSlice(lit *CompositeLit, t reflect.Type, env Env) (*CompositeLit, []error) {
	var errs, moreErrs []error
	eltT := t.Elem()
	maxIndex, curIndex := -1, 0
	outOfBounds := false
	length := -1
	if t.Kind() == reflect.Array {
		length = t.Len()
	}
	used := make(map[int]bool, len(lit.Elts))
	// Check all keys are valid and calculate array or slice length.
	// Elements with key are placed at the keyed position.
	// Elements without are placed in the next position.
	// For example, []int{1, 2:1, 1} -> [1, 0, 1, 1]
	for i := range lit.Elts {
		var value ast.Expr
		var key Expr
		var avalue *Expr
		skipIndexChecks := false
		kv, ok := lit.CompositeLit.Elts[i].(*ast.KeyValueExpr)
		if !ok {
			avalue, value = &lit.Elts[i], lit.CompositeLit.Elts[i]
		} else {
			akv := &KeyValueExpr{KeyValueExpr: kv}
			lit.Elts[i] = akv
			avalue, value = &akv.Value, kv.Value
			// Check the array key
			var index int
			key, index, ok, moreErrs = checkArrayIndex(kv.Key, env)
			if !ok || moreErrs != nil {
				// NOTE[crc] Haven't checked the gc implementation, but
				// from experimentation it seems that only undefined
				// idents are reported. This filter should perhaps be part
				// of checkArrayIndex
				for _, err := range moreErrs {
					if _, ok := err.(ErrUndefined); ok {
						errs = append(errs, err)
					}
				}
				errs = append(errs, ErrBadArrayKey{key})
				// Don't include this element in index calculations
				curIndex -= 1
				skipIndexChecks = true
			} else {
				lit.indices = append(lit.indices, struct{ pos, index int }{i, index})
				curIndex = index
			}
		}
		// finally check the value
		v, moreErrs := checkArrayValue(value, eltT, env)
		*avalue = v

		// These errors slide in before the check errors, but we need v
		if !skipIndexChecks {
			if maxIndex < curIndex {
				maxIndex = curIndex
			}
			if !outOfBounds && length != -1 && curIndex >= length {
				outOfBounds = true
				errs = append(errs, ErrArrayKeyOutOfBounds{v, t, curIndex})
			}
			// has this index been used already
			if used[curIndex] {
				errs = append(errs, ErrDuplicateArrayKey{key, curIndex})
			}
			used[curIndex] = true
		}

		// Add the check errors
		if moreErrs != nil {
			errs = append(errs, moreErrs...)
		}

		curIndex += 1
	}
	lit.indices = append(lit.indices, struct{ pos, index int }{-1, -1})
	if length == -1 {
		lit.length = maxIndex + 1
	} else {
		lit.length = length
	}
	return lit, errs
}
Пример #22
0
func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
	log.Info(Fmt("writeReflectJSON(%v, %v, %v, %v, %v)", rv, rt, w, n, err))

	// Get typeInfo
	typeInfo := GetTypeInfo(rt)

	if rt.Kind() == reflect.Interface {
		if rv.IsNil() {
			// XXX ensure that typeByte 0 is reserved.
			WriteTo([]byte("null"), w, n, err)
			return
		}
		crv := rv.Elem()  // concrete reflection value
		crt := crv.Type() // concrete reflection type
		if typeInfo.IsRegisteredInterface {
			// See if the crt is registered.
			// If so, we're more restrictive.
			_, ok := typeInfo.TypeToByte[crt]
			if !ok {
				switch crt.Kind() {
				case reflect.Ptr:
					*err = errors.New(Fmt("Unexpected pointer type %v for registered interface %v. "+
						"Was it registered as a value receiver rather than as a pointer receiver?", crt, rt.Name()))
				case reflect.Struct:
					*err = errors.New(Fmt("Unexpected struct type %v for registered interface %v. "+
						"Was it registered as a pointer receiver rather than as a value receiver?", crt, rt.Name()))
				default:
					*err = errors.New(Fmt("Unexpected type %v for registered interface %v. "+
						"If this is intentional, please register it.", crt, rt.Name()))
				}
				return
			}
		} else {
			// We support writing unsafely for convenience.
		}
		// We don't have to write the typeByte here,
		// the writeReflectJSON() call below will write it.
		writeReflectJSON(crv, crt, w, n, err)
		return
	}

	if rt.Kind() == reflect.Ptr {
		// Dereference pointer
		rv, rt = rv.Elem(), rt.Elem()
		typeInfo = GetTypeInfo(rt)
		if !rv.IsValid() {
			// For better compatibility with other languages,
			// as far as tendermint/wire is concerned,
			// pointers to nil values are the same as nil.
			WriteTo([]byte("null"), w, n, err)
			return
		}
		// continue...
	}

	// Write Byte
	if typeInfo.Byte != 0x00 {
		WriteTo([]byte(Fmt("[%v,", typeInfo.Byte)), w, n, err)
		defer WriteTo([]byte("]"), w, n, err)
	}

	// All other types
	switch rt.Kind() {
	case reflect.Array:
		elemRt := rt.Elem()
		length := rt.Len()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Bytearray
			bytearray := reflect.ValueOf(make([]byte, length))
			reflect.Copy(bytearray, rv)
			WriteTo([]byte(Fmt("\"%X\"", bytearray.Interface())), w, n, err)
		} else {
			WriteTo([]byte("["), w, n, err)
			// Write elems
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				writeReflectJSON(elemRv, elemRt, w, n, err)
				if i < length-1 {
					WriteTo([]byte(","), w, n, err)
				}
			}
			WriteTo([]byte("]"), w, n, err)
		}

	case reflect.Slice:
		elemRt := rt.Elem()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Byteslices
			byteslice := rv.Bytes()
			WriteTo([]byte(Fmt("\"%X\"", byteslice)), w, n, err)
		} else {
			WriteTo([]byte("["), w, n, err)
			// Write elems
			length := rv.Len()
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				writeReflectJSON(elemRv, elemRt, w, n, err)
				if i < length-1 {
					WriteTo([]byte(","), w, n, err)
				}
			}
			WriteTo([]byte("]"), w, n, err)
		}

	case reflect.Struct:
		if rt == timeType {
			// Special case: time.Time
			t := rv.Interface().(time.Time).UTC()
			str := t.Format(iso8601)
			jsonBytes, err_ := json.Marshal(str)
			if err_ != nil {
				*err = err_
				return
			}
			WriteTo(jsonBytes, w, n, err)
		} else {
			WriteTo([]byte("{"), w, n, err)
			wroteField := false
			for _, fieldInfo := range typeInfo.Fields {
				i, fieldType, opts := fieldInfo.unpack()
				fieldRv := rv.Field(i)
				if wroteField {
					WriteTo([]byte(","), w, n, err)
				} else {
					wroteField = true
				}
				WriteTo([]byte(Fmt("\"%v\":", opts.JSONName)), w, n, err)
				writeReflectJSON(fieldRv, fieldType, w, n, err)
			}
			WriteTo([]byte("}"), w, n, err)
		}

	case reflect.String:
		fallthrough
	case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
		fallthrough
	case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
		fallthrough
	case reflect.Bool:
		jsonBytes, err_ := json.Marshal(rv.Interface())
		if err_ != nil {
			*err = err_
			return
		}
		WriteTo(jsonBytes, w, n, err)

	default:
		PanicSanity(Fmt("Unknown field type %v", rt.Kind()))
	}

}
Пример #23
0
// Contract: Caller must ensure that rt is supported
// (e.g. is recursively composed of supported native types, and structs and slices.)
// rv and rt refer to the object we're unmarhsaling into, whereas o is the result of naiive json unmarshal (map[string]interface{})
func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *error) {

	// Get typeInfo
	typeInfo := GetTypeInfo(rt)

	if rt.Kind() == reflect.Interface {
		if !typeInfo.IsRegisteredInterface {
			// There's no way we can read such a thing.
			*err = errors.New(Fmt("Cannot read unregistered interface type %v", rt))
			return
		}
		if o == nil {
			return // nil
		}
		typeByte, _, err_ := readByteJSON(o)
		if err_ != nil {
			*err = err_
			return
		}
		crt, ok := typeInfo.ByteToType[typeByte]
		if !ok {
			*err = errors.New(Fmt("Byte %X not registered for interface %v", typeByte, rt))
			return
		}
		crv := reflect.New(crt).Elem()
		readReflectJSON(crv, crt, o, err)
		rv.Set(crv) // NOTE: orig rv is ignored.
		return
	}

	if rt.Kind() == reflect.Ptr {
		if o == nil {
			return // nil
		}
		// Create new struct if rv is nil.
		if rv.IsNil() {
			newRv := reflect.New(rt.Elem())
			rv.Set(newRv)
			rv = newRv
		}
		// Dereference pointer
		rv, rt = rv.Elem(), rt.Elem()
		typeInfo = GetTypeInfo(rt)
		// continue...
	}

	// Read Byte prefix
	if typeInfo.Byte != 0x00 {
		typeByte, rest, err_ := readByteJSON(o)
		if err_ != nil {
			*err = err_
			return
		}
		if typeByte != typeInfo.Byte {
			*err = errors.New(Fmt("Expected Byte of %X but got %X", typeInfo.Byte, byte(typeByte)))
			return
		}
		o = rest
	}

	switch rt.Kind() {
	case reflect.Array:
		elemRt := rt.Elem()
		length := rt.Len()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Bytearrays
			oString, ok := o.(string)
			if !ok {
				*err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o)))
				return
			}
			buf, err_ := hex.DecodeString(oString)
			if err_ != nil {
				*err = err_
				return
			}
			if len(buf) != length {
				*err = errors.New(Fmt("Expected bytearray of length %v but got %v", length, len(buf)))
				return
			}
			log.Info("Read bytearray", "bytes", buf)
			reflect.Copy(rv, reflect.ValueOf(buf))
		} else {
			oSlice, ok := o.([]interface{})
			if !ok {
				*err = errors.New(Fmt("Expected array of %v but got type %v", rt, reflect.TypeOf(o)))
				return
			}
			if len(oSlice) != length {
				*err = errors.New(Fmt("Expected array of length %v but got %v", length, len(oSlice)))
				return
			}
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				readReflectJSON(elemRv, elemRt, oSlice[i], err)
			}
			log.Info(Fmt("Read %v-array", elemRt), "length", length)
		}

	case reflect.Slice:
		elemRt := rt.Elem()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Byteslices
			oString, ok := o.(string)
			if !ok {
				*err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o)))
				return
			}
			byteslice, err_ := hex.DecodeString(oString)
			if err_ != nil {
				*err = err_
				return
			}
			log.Info("Read byteslice", "bytes", byteslice)
			rv.Set(reflect.ValueOf(byteslice))
		} else {
			// Read length
			oSlice, ok := o.([]interface{})
			if !ok {
				*err = errors.New(Fmt("Expected array of %v but got type %v", rt, reflect.TypeOf(o)))
				return
			}
			length := len(oSlice)
			log.Info(Fmt("Read length: %v", length))
			sliceRv := reflect.MakeSlice(rt, length, length)
			// Read elems
			for i := 0; i < length; i++ {
				elemRv := sliceRv.Index(i)
				readReflectJSON(elemRv, elemRt, oSlice[i], err)
			}
			rv.Set(sliceRv)
		}

	case reflect.Struct:
		if rt == timeType {
			// Special case: time.Time
			str, ok := o.(string)
			if !ok {
				*err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o)))
				return
			}
			log.Info(Fmt("Read time: %v", str))
			t, err_ := time.Parse(iso8601, str)
			if err_ != nil {
				*err = err_
				return
			}
			rv.Set(reflect.ValueOf(t))
		} else {
			oMap, ok := o.(map[string]interface{})
			if !ok {
				*err = errors.New(Fmt("Expected map but got type %v", reflect.TypeOf(o)))
				return
			}
			// TODO: ensure that all fields are set?
			// TODO: disallow unknown oMap fields?
			for _, fieldInfo := range typeInfo.Fields {
				i, fieldType, opts := fieldInfo.unpack()
				value, ok := oMap[opts.JSONName]
				if !ok {
					continue // Skip missing fields.
				}
				fieldRv := rv.Field(i)
				readReflectJSON(fieldRv, fieldType, value, err)
			}
		}

	case reflect.String:
		str, ok := o.(string)
		if !ok {
			*err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o)))
			return
		}
		log.Info(Fmt("Read string: %v", str))
		rv.SetString(str)

	case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
		num, ok := o.(float64)
		if !ok {
			*err = errors.New(Fmt("Expected numeric but got type %v", reflect.TypeOf(o)))
			return
		}
		log.Info(Fmt("Read num: %v", num))
		rv.SetInt(int64(num))

	case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint:
		num, ok := o.(float64)
		if !ok {
			*err = errors.New(Fmt("Expected numeric but got type %v", reflect.TypeOf(o)))
			return
		}
		if num < 0 {
			*err = errors.New(Fmt("Expected unsigned numeric but got %v", num))
			return
		}
		log.Info(Fmt("Read num: %v", num))
		rv.SetUint(uint64(num))

	case reflect.Bool:
		bl, ok := o.(bool)
		if !ok {
			*err = errors.New(Fmt("Expected boolean but got type %v", reflect.TypeOf(o)))
			return
		}
		log.Info(Fmt("Read boolean: %v", bl))
		rv.SetBool(bl)

	default:
		PanicSanity(Fmt("Unknown field type %v", rt.Kind()))
	}
}
Пример #24
0
// rv: the reflection value of the thing to write
// rt: the type of rv as declared in the container, not necessarily rv.Type().
func writeReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, w io.Writer, n *int64, err *error) {

	// Get typeInfo
	typeInfo := GetTypeInfo(rt)

	if rt.Kind() == reflect.Interface {
		if rv.IsNil() {
			// XXX ensure that typeByte 0 is reserved.
			WriteByte(0x00, w, n, err)
			return
		}
		crv := rv.Elem()  // concrete reflection value
		crt := crv.Type() // concrete reflection type
		if typeInfo.IsRegisteredInterface {
			// See if the crt is registered.
			// If so, we're more restrictive.
			_, ok := typeInfo.TypeToByte[crt]
			if !ok {
				switch crt.Kind() {
				case reflect.Ptr:
					*err = errors.New(Fmt("Unexpected pointer type %v for registered interface %v. "+
						"Was it registered as a value receiver rather than as a pointer receiver?", crt, rt.Name()))
				case reflect.Struct:
					*err = errors.New(Fmt("Unexpected struct type %v for registered interface %v. "+
						"Was it registered as a pointer receiver rather than as a value receiver?", crt, rt.Name()))
				default:
					*err = errors.New(Fmt("Unexpected type %v for registered interface %v. "+
						"If this is intentional, please register it.", crt, rt.Name()))
				}
				return
			}
		} else {
			// We support writing unsafely for convenience.
		}
		// We don't have to write the typeByte here,
		// the writeReflectBinary() call below will write it.
		writeReflectBinary(crv, crt, opts, w, n, err)
		return
	}

	if rt.Kind() == reflect.Ptr {
		// Dereference pointer
		rv, rt = rv.Elem(), rt.Elem()
		typeInfo = GetTypeInfo(rt)
		if !rv.IsValid() {
			// For better compatibility with other languages,
			// as far as tendermint/wire is concerned,
			// pointers to nil values are the same as nil.
			WriteByte(0x00, w, n, err)
			return
		}
		if typeInfo.Byte == 0x00 {
			WriteByte(0x01, w, n, err)
			// continue...
		} else {
			// continue...
		}
	}

	// Write type byte
	if typeInfo.Byte != 0x00 {
		WriteByte(typeInfo.Byte, w, n, err)
	}

	// All other types
	switch rt.Kind() {
	case reflect.Array:
		elemRt := rt.Elem()
		length := rt.Len()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Bytearrays
			if rv.CanAddr() {
				byteslice := rv.Slice(0, length).Bytes()
				WriteTo(byteslice, w, n, err)
			} else {
				buf := make([]byte, length)
				reflect.Copy(reflect.ValueOf(buf), rv)
				WriteTo(buf, w, n, err)
			}
		} else {
			// Write elems
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				writeReflectBinary(elemRv, elemRt, opts, w, n, err)
			}
		}

	case reflect.Slice:
		elemRt := rt.Elem()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Byteslices
			byteslice := rv.Bytes()
			WriteByteSlice(byteslice, w, n, err)
		} else {
			// Write length
			length := rv.Len()
			WriteVarint(length, w, n, err)
			// Write elems
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				writeReflectBinary(elemRv, elemRt, opts, w, n, err)
			}
		}

	case reflect.Struct:
		if rt == timeType {
			// Special case: time.Time
			WriteTime(rv.Interface().(time.Time), w, n, err)
		} else {
			for _, fieldInfo := range typeInfo.Fields {
				i, fieldType, opts := fieldInfo.unpack()
				fieldRv := rv.Field(i)
				writeReflectBinary(fieldRv, fieldType, opts, w, n, err)
			}
		}

	case reflect.String:
		WriteString(rv.String(), w, n, err)

	case reflect.Int64:
		if opts.Varint {
			WriteVarint(int(rv.Int()), w, n, err)
		} else {
			WriteInt64(rv.Int(), w, n, err)
		}

	case reflect.Int32:
		WriteInt32(int32(rv.Int()), w, n, err)

	case reflect.Int16:
		WriteInt16(int16(rv.Int()), w, n, err)

	case reflect.Int8:
		WriteInt8(int8(rv.Int()), w, n, err)

	case reflect.Int:
		WriteVarint(int(rv.Int()), w, n, err)

	case reflect.Uint64:
		if opts.Varint {
			WriteUvarint(uint(rv.Uint()), w, n, err)
		} else {
			WriteUint64(rv.Uint(), w, n, err)
		}

	case reflect.Uint32:
		WriteUint32(uint32(rv.Uint()), w, n, err)

	case reflect.Uint16:
		WriteUint16(uint16(rv.Uint()), w, n, err)

	case reflect.Uint8:
		WriteUint8(uint8(rv.Uint()), w, n, err)

	case reflect.Uint:
		WriteUvarint(uint(rv.Uint()), w, n, err)

	case reflect.Bool:
		if rv.Bool() {
			WriteUint8(uint8(1), w, n, err)
		} else {
			WriteUint8(uint8(0), w, n, err)
		}

	default:
		PanicSanity(Fmt("Unknown field type %v", rt.Kind()))
	}
}
Пример #25
0
// Contract: Caller must ensure that rt is supported
// (e.g. is recursively composed of supported native types, and structs and slices.)
func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Reader, n *int64, err *error) {

	// Get typeInfo
	typeInfo := GetTypeInfo(rt)

	if rt.Kind() == reflect.Interface {
		if !typeInfo.IsRegisteredInterface {
			// There's no way we can read such a thing.
			*err = errors.New(Fmt("Cannot read unregistered interface type %v", rt))
			return
		}
		typeByte := ReadByte(r, n, err)
		if *err != nil {
			return
		}
		if typeByte == 0x00 {
			return // nil
		}
		crt, ok := typeInfo.ByteToType[typeByte]
		if !ok {
			*err = errors.New(Fmt("Unexpected type byte %X for type %v", typeByte, rt))
			return
		}
		crv := reflect.New(crt).Elem()
		r = NewPrefixedReader([]byte{typeByte}, r)
		readReflectBinary(crv, crt, opts, r, n, err)
		rv.Set(crv) // NOTE: orig rv is ignored.
		return
	}

	if rt.Kind() == reflect.Ptr {
		typeByte := ReadByte(r, n, err)
		if *err != nil {
			return
		}
		if typeByte == 0x00 {
			return // nil
		}
		// Create new if rv is nil.
		if rv.IsNil() {
			newRv := reflect.New(rt.Elem())
			rv.Set(newRv)
			rv = newRv
		}
		// Dereference pointer
		rv, rt = rv.Elem(), rt.Elem()
		typeInfo = GetTypeInfo(rt)
		if typeInfo.Byte != 0x00 {
			r = NewPrefixedReader([]byte{typeByte}, r)
		} else if typeByte != 0x01 {
			*err = errors.New(Fmt("Unexpected type byte %X for ptr of untyped thing", typeByte))
			return
		}
		// continue...
	}

	// Read Byte prefix
	if typeInfo.Byte != 0x00 {
		typeByte := ReadByte(r, n, err)
		if typeByte != typeInfo.Byte {
			*err = errors.New(Fmt("Expected Byte of %X but got %X", typeInfo.Byte, typeByte))
			return
		}
	}

	switch rt.Kind() {
	case reflect.Array:
		elemRt := rt.Elem()
		length := rt.Len()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Bytearrays
			buf := make([]byte, length)
			ReadFull(buf, r, n, err)
			if *err != nil {
				return
			}
			log.Info("Read bytearray", "bytes", buf)
			reflect.Copy(rv, reflect.ValueOf(buf))
		} else {
			for i := 0; i < length; i++ {
				elemRv := rv.Index(i)
				readReflectBinary(elemRv, elemRt, opts, r, n, err)
				if *err != nil {
					return
				}
				if MaxBinaryReadSize < *n {
					*err = ErrBinaryReadSizeOverflow
					return
				}
			}
			log.Info(Fmt("Read %v-array", elemRt), "length", length)
		}

	case reflect.Slice:
		elemRt := rt.Elem()
		if elemRt.Kind() == reflect.Uint8 {
			// Special case: Byteslices
			byteslice := ReadByteSlice(r, n, err)
			log.Info("Read byteslice", "bytes", byteslice)
			rv.Set(reflect.ValueOf(byteslice))
		} else {
			var sliceRv reflect.Value
			// Read length
			length := ReadVarint(r, n, err)
			log.Info(Fmt("Read length: %v", length))
			sliceRv = reflect.MakeSlice(rt, 0, 0)
			// read one ReflectSliceChunk at a time and append
			for i := 0; i*ReflectSliceChunk < length; i++ {
				l := MinInt(ReflectSliceChunk, length-i*ReflectSliceChunk)
				tmpSliceRv := reflect.MakeSlice(rt, l, l)
				for j := 0; j < l; j++ {
					elemRv := tmpSliceRv.Index(j)
					readReflectBinary(elemRv, elemRt, opts, r, n, err)
					if *err != nil {
						return
					}
					if MaxBinaryReadSize < *n {
						*err = ErrBinaryReadSizeOverflow
						return
					}
				}
				sliceRv = reflect.AppendSlice(sliceRv, tmpSliceRv)
			}

			rv.Set(sliceRv)
		}

	case reflect.Struct:
		if rt == timeType {
			// Special case: time.Time
			t := ReadTime(r, n, err)
			log.Info(Fmt("Read time: %v", t))
			rv.Set(reflect.ValueOf(t))
		} else {
			for _, fieldInfo := range typeInfo.Fields {
				i, fieldType, opts := fieldInfo.unpack()
				fieldRv := rv.Field(i)
				readReflectBinary(fieldRv, fieldType, opts, r, n, err)
			}
		}

	case reflect.String:
		str := ReadString(r, n, err)
		log.Info(Fmt("Read string: %v", str))
		rv.SetString(str)

	case reflect.Int64:
		if opts.Varint {
			num := ReadVarint(r, n, err)
			log.Info(Fmt("Read num: %v", num))
			rv.SetInt(int64(num))
		} else {
			num := ReadInt64(r, n, err)
			log.Info(Fmt("Read num: %v", num))
			rv.SetInt(int64(num))
		}

	case reflect.Int32:
		num := ReadUint32(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetInt(int64(num))

	case reflect.Int16:
		num := ReadUint16(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetInt(int64(num))

	case reflect.Int8:
		num := ReadUint8(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetInt(int64(num))

	case reflect.Int:
		num := ReadVarint(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetInt(int64(num))

	case reflect.Uint64:
		if opts.Varint {
			num := ReadVarint(r, n, err)
			log.Info(Fmt("Read num: %v", num))
			rv.SetUint(uint64(num))
		} else {
			num := ReadUint64(r, n, err)
			log.Info(Fmt("Read num: %v", num))
			rv.SetUint(uint64(num))
		}

	case reflect.Uint32:
		num := ReadUint32(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetUint(uint64(num))

	case reflect.Uint16:
		num := ReadUint16(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetUint(uint64(num))

	case reflect.Uint8:
		num := ReadUint8(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetUint(uint64(num))

	case reflect.Uint:
		num := ReadVarint(r, n, err)
		log.Info(Fmt("Read num: %v", num))
		rv.SetUint(uint64(num))

	case reflect.Bool:
		num := ReadUint8(r, n, err)
		log.Info(Fmt("Read bool: %v", num))
		rv.SetBool(num > 0)

	default:
		PanicSanity(Fmt("Unknown field type %v", rt.Kind()))
	}
}
Пример #26
0
func typeFromType(t reflect.Type) (Type, error) {
	// Hack workaround for https://golang.org/issue/3853.
	// This explicit check should not be necessary.
	if t == byteType {
		return PredeclaredType("byte"), nil
	}

	if imp := t.PkgPath(); imp != "" {
		return &NamedType{
			Package: imp,
			Type:    t.Name(),
		}, nil
	}

	// only unnamed or predeclared types after here

	// Lots of types have element types. Let's do the parsing and error checking for all of them.
	var elemType Type
	switch t.Kind() {
	case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
		var err error
		elemType, err = typeFromType(t.Elem())
		if err != nil {
			return nil, err
		}
	}

	switch t.Kind() {
	case reflect.Array:
		return &ArrayType{
			Len:  t.Len(),
			Type: elemType,
		}, nil
	case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String:
		return PredeclaredType(t.Kind().String()), nil
	case reflect.Chan:
		var dir ChanDir
		switch t.ChanDir() {
		case reflect.RecvDir:
			dir = RecvDir
		case reflect.SendDir:
			dir = SendDir
		}
		return &ChanType{
			Dir:  dir,
			Type: elemType,
		}, nil
	case reflect.Func:
		in, variadic, out, err := funcArgsFromType(t)
		if err != nil {
			return nil, err
		}
		return &FuncType{
			In:       in,
			Out:      out,
			Variadic: variadic,
		}, nil
	case reflect.Interface:
		// Two special interfaces.
		if t.NumMethod() == 0 {
			return PredeclaredType("interface{}"), nil
		}
		if t == errorType {
			return PredeclaredType("error"), nil
		}
	case reflect.Map:
		kt, err := typeFromType(t.Key())
		if err != nil {
			return nil, err
		}
		return &MapType{
			Key:   kt,
			Value: elemType,
		}, nil
	case reflect.Ptr:
		return &PointerType{
			Type: elemType,
		}, nil
	case reflect.Slice:
		return &ArrayType{
			Len:  -1,
			Type: elemType,
		}, nil
	case reflect.Struct:
		if t.NumField() == 0 {
			return PredeclaredType("struct{}"), nil
		}
	}

	// TODO: Struct, UnsafePointer
	return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind())
}
Пример #27
0
func new_dataTypeFromType(t reflect.Type) *DataType {

	var dt *DataType = nil

	switch t.Kind() {

	case reflect.Int:
		dt = T_NATIVE_INT // FIXME: .Copy() instead ?

	case reflect.Int8:
		dt = T_NATIVE_INT8

	case reflect.Int16:
		dt = T_NATIVE_INT16

	case reflect.Int32:
		dt = T_NATIVE_INT32

	case reflect.Int64:
		dt = T_NATIVE_INT64

	case reflect.Uint:
		dt = T_NATIVE_UINT // FIXME: .Copy() instead ?

	case reflect.Uint8:
		dt = T_NATIVE_UINT8

	case reflect.Uint16:
		dt = T_NATIVE_UINT16

	case reflect.Uint32:
		dt = T_NATIVE_UINT32

	case reflect.Uint64:
		dt = T_NATIVE_UINT64

	case reflect.Float32:
		dt = T_NATIVE_FLOAT

	case reflect.Float64:
		dt = T_NATIVE_DOUBLE

	case reflect.String:
		dt = T_GO_STRING
		//dt = T_C_S1

	case reflect.Array:
		elem_type := new_dataTypeFromType(t.Elem())
		n := t.Len()
		dims := []int{n}
		adt, err := NewArrayType(elem_type, dims)
		if err != nil {
			panic(err)
		}
		dt, err = adt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Slice:
		elem_type := new_dataTypeFromType(t.Elem())
		vlen_dt, err := NewVarLenType(elem_type)
		if err != nil {
			panic(err)
		}
		dt, err = vlen_dt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Struct:
		sz := int(t.Size())
		hdf_dt, err := CreateDataType(T_COMPOUND, sz)
		if err != nil {
			panic(err)
		}
		cdt := &CompType{*hdf_dt}
		n := t.NumField()
		for i := 0; i < n; i++ {
			f := t.Field(i)
			var field_dt *DataType = nil
			field_dt = new_dataTypeFromType(f.Type)
			offset := int(f.Offset + 0)
			if field_dt == nil {
				panic(fmt.Sprintf("pb with field [%d-%s]", i, f.Name))
			}
			field_name := string(f.Tag)
			if len(field_name) == 0 {
				field_name = f.Name
			}
			err = cdt.Insert(field_name, offset, field_dt)
			if err != nil {
				panic(fmt.Sprintf("pb with field [%d-%s]: %s", i, f.Name, err))
			}
		}
		cdt.Lock()
		dt, err = cdt.Copy()
		if err != nil {
			panic(err)
		}

	case reflect.Ptr:
		panic("sorry, pointers not yet supported")

	default:
		panic(fmt.Sprintf("unhandled kind (%d)", t.Kind()))
	}

	return dt
}
Пример #28
0
func ctype_from_gotype(rt reflect.Type) Type {
	var t Type

	switch rt.Kind() {
	case reflect.Int:
		t = C_int

	case reflect.Int8:
		t = C_int8

	case reflect.Int16:
		t = C_int16

	case reflect.Int32:
		t = C_int32

	case reflect.Int64:
		t = C_int64

	case reflect.Uint:
		t = C_uint

	case reflect.Uint8:
		t = C_uint8

	case reflect.Uint16:
		t = C_uint16

	case reflect.Uint32:
		t = C_uint32

	case reflect.Uint64:
		t = C_uint64

	case reflect.Float32:
		t = C_float

	case reflect.Float64:
		t = C_double

	case reflect.Array:
		et := ctype_from_gotype(rt.Elem())
		ct, err := NewArrayType(rt.Len(), et)
		if err != nil {
			panic("ffi: " + err.Error())
		}
		ct.set_gotype(rt)
		t = ct

	case reflect.Ptr:
		et := ctype_from_gotype(rt.Elem())
		ct, err := NewPointerType(et)
		if err != nil {
			panic("ffi: " + err.Error())
		}
		t = ct

	case reflect.Slice:
		et := ctype_from_gotype(rt.Elem())
		ct, err := NewSliceType(et)
		if err != nil {
			panic("ffi: " + err.Error())
		}
		ct.set_gotype(rt)
		t = ct

	case reflect.Struct:
		fields := make([]Field, rt.NumField())
		for i := 0; i < rt.NumField(); i++ {
			field := rt.Field(i)
			fields[i] = Field{
				Name: field.Name,
				Type: ctype_from_gotype(field.Type),
			}
		}
		ct, err := NewStructType(rt.Name(), fields)
		if err != nil {
			panic("ffi: " + err.Error())
		}
		ct.set_gotype(rt)
		t = ct

	case reflect.String:
		panic("unimplemented")
	default:
		panic("unhandled kind [" + rt.Kind().String() + "]")
	}

	return t
}
Пример #29
0
// TypeFromNative converts a regular Go type into a the corresponding
// interpreter Type.
func TypeFromNative(t reflect.Type) Type {
	if et, ok := evalTypes[t]; ok {
		return et
	}

	var nt *NamedType
	if t.Name() != "" {
		name := t.PkgPath() + "·" + t.Name()
		nt = &NamedType{token.Position{}, name, nil, true, make(map[string]Method)}
		evalTypes[t] = nt
	}

	var et Type
	switch t := t.(type) {
	case *reflect.BoolType:
		et = BoolType
	case *reflect.FloatType:
		switch t.Kind() {
		case reflect.Float32:
			et = Float32Type
		case reflect.Float64:
			et = Float64Type
		case reflect.Float:
			et = FloatType
		}
	case *reflect.IntType:
		switch t.Kind() {
		case reflect.Int16:
			et = Int16Type
		case reflect.Int32:
			et = Int32Type
		case reflect.Int64:
			et = Int64Type
		case reflect.Int8:
			et = Int8Type
		case reflect.Int:
			et = IntType
		}
	case *reflect.UintType:
		switch t.Kind() {
		case reflect.Uint16:
			et = Uint16Type
		case reflect.Uint32:
			et = Uint32Type
		case reflect.Uint64:
			et = Uint64Type
		case reflect.Uint8:
			et = Uint8Type
		case reflect.Uint:
			et = UintType
		case reflect.Uintptr:
			et = UintptrType
		}
	case *reflect.StringType:
		et = StringType
	case *reflect.ArrayType:
		et = NewArrayType(int64(t.Len()), TypeFromNative(t.Elem()))
	case *reflect.ChanType:
		log.Panicf("%T not implemented", t)
	case *reflect.FuncType:
		nin := t.NumIn()
		// Variadic functions have DotDotDotType at the end
		variadic := t.DotDotDot()
		if variadic {
			nin--
		}
		in := make([]Type, nin)
		for i := range in {
			in[i] = TypeFromNative(t.In(i))
		}
		out := make([]Type, t.NumOut())
		for i := range out {
			out[i] = TypeFromNative(t.Out(i))
		}
		et = NewFuncType(in, variadic, out)
	case *reflect.InterfaceType:
		log.Panicf("%T not implemented", t)
	case *reflect.MapType:
		log.Panicf("%T not implemented", t)
	case *reflect.PtrType:
		et = NewPtrType(TypeFromNative(t.Elem()))
	case *reflect.SliceType:
		et = NewSliceType(TypeFromNative(t.Elem()))
	case *reflect.StructType:
		n := t.NumField()
		fields := make([]StructField, n)
		for i := 0; i < n; i++ {
			sf := t.Field(i)
			// TODO(austin) What to do about private fields?
			fields[i].Name = sf.Name
			fields[i].Type = TypeFromNative(sf.Type)
			fields[i].Anonymous = sf.Anonymous
		}
		et = NewStructType(fields)
	case *reflect.UnsafePointerType:
		log.Panicf("%T not implemented", t)
	default:
		log.Panicf("unexpected reflect.Type: %T", t)
	}

	if nt != nil {
		if _, ok := et.(*NamedType); !ok {
			nt.Complete(et)
			et = nt
		}
	}

	nativeTypes[et] = t
	evalTypes[t] = et

	return et
}
Пример #30
0
func writeType(buf *bytes.Buffer, ptrs int, t reflect.Type) {
	parens := ptrs > 0
	switch t.Kind() {
	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
		parens = true
	}

	if parens {
		buf.WriteRune('(')
		for i := 0; i < ptrs; i++ {
			buf.WriteRune('*')
		}
	}

	switch t.Kind() {
	case reflect.Ptr:
		if ptrs == 0 {
			// This pointer was referenced from within writeType (e.g., as part of
			// rendering a list), and so hasn't had its pointer asterisk accounted
			// for.
			buf.WriteRune('*')
		}
		writeType(buf, 0, t.Elem())

	case reflect.Interface:
		if n := t.Name(); n != "" {
			buf.WriteString(t.String())
		} else {
			buf.WriteString("interface{}")
		}

	case reflect.Array:
		buf.WriteRune('[')
		buf.WriteString(strconv.FormatInt(int64(t.Len()), 10))
		buf.WriteRune(']')
		writeType(buf, 0, t.Elem())

	case reflect.Slice:
		if t == reflect.SliceOf(t.Elem()) {
			buf.WriteString("[]")
			writeType(buf, 0, t.Elem())
		} else {
			// Custom slice type, use type name.
			buf.WriteString(t.String())
		}

	case reflect.Map:
		if t == reflect.MapOf(t.Key(), t.Elem()) {
			buf.WriteString("map[")
			writeType(buf, 0, t.Key())
			buf.WriteRune(']')
			writeType(buf, 0, t.Elem())
		} else {
			// Custom map type, use type name.
			buf.WriteString(t.String())
		}

	default:
		buf.WriteString(t.String())
	}

	if parens {
		buf.WriteRune(')')
	}
}