Пример #1
0
// returns the size of a type, works only for TypeExact
func TypeSize(ti *gi.TypeInfo, flags TypeFlags) int {
	ptrsize := int(unsafe.Sizeof(unsafe.Pointer(nil)))
	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			return ptrsize
		}
		panic("Non-pointer void type is not supported")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME, gi.TYPE_TAG_GLIST,
		gi.TYPE_TAG_GSLIST, gi.TYPE_TAG_GHASH:
		return ptrsize
	case gi.TYPE_TAG_ARRAY:
		size := ti.ArrayFixedSize()
		if size != -1 {
			return size * TypeSize(ti.ParamType(0), flags)
		}
		return ptrsize
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		return TypeSizeForInterface(ti.Interface(), flags)
	default:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		return TypeSizeForTag(tag, flags)
	}
	panic("unreachable: " + ti.Tag().String())
}
Пример #2
0
func TypeNeedsWrapper(ti *gi.TypeInfo) bool {
	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			return false
		}
		panic("Non-pointer void type is not supported")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME, gi.TYPE_TAG_GLIST,
		gi.TYPE_TAG_GSLIST, gi.TYPE_TAG_GHASH:
		return true
	case gi.TYPE_TAG_ARRAY:
		size := ti.ArrayFixedSize()
		if size != -1 {
			return TypeNeedsWrapper(ti.ParamType(0))
		}
		return true
	case gi.TYPE_TAG_ERROR:
		panic("not implemented")
	case gi.TYPE_TAG_INTERFACE:
		switch ti.Interface().Type() {
		case gi.INFO_TYPE_CALLBACK, gi.INFO_TYPE_ENUM, gi.INFO_TYPE_FLAGS,
			gi.INFO_TYPE_STRUCT, gi.INFO_TYPE_UNION:
			return false
		}
		return true
	}
	return false
}
Пример #3
0
func SimpleCgoType(ti *gi.TypeInfo, flags TypeFlags) string {
	tag := ti.Tag()
	switch tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			return "unsafe.Pointer"
		}
		panic("Non-pointer void type is not supported")
	case gi.TYPE_TAG_INTERFACE:
		bi := ti.Interface()
		switch bi.Type() {
		case gi.INFO_TYPE_ENUM, gi.INFO_TYPE_FLAGS:
			ei := gi.ToEnumInfo(bi)
			return GoTypeForTag(ei.StorageType(), flags|TypeExact)
		case gi.INFO_TYPE_STRUCT:
			ns := bi.Namespace()
			nm := bi.Name()
			fullnm := strings.ToLower(ns) + "." + nm
			if _, ok := GConfig.Sys.DisguisedTypes[fullnm]; ok {
				return "unsafe.Pointer"
			}
		}
	}
	if !strings.HasPrefix(CgoType(ti, flags), "*") {
		return GoTypeForTag(tag, flags|TypeExact)
	}
	return "unsafe.Pointer"
}
Пример #4
0
func simple_cgo_type(ti *gi.TypeInfo, flags type_flags) string {
	tag := ti.Tag()
	switch tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			return "unsafe.Pointer"
		}
		panic("Non-pointer void type is not supported")
	case gi.TYPE_TAG_INTERFACE:
		bi := ti.Interface()
		switch bi.Type() {
		case gi.INFO_TYPE_ENUM, gi.INFO_TYPE_FLAGS:
			ei := gi.ToEnumInfo(bi)
			return go_type_for_tag(ei.StorageType(), flags|type_exact)
		case gi.INFO_TYPE_STRUCT:
			ns := bi.Namespace()
			nm := bi.Name()
			fullnm := strings.ToLower(ns) + "." + nm
			if config.is_disguised(fullnm) {
				return "unsafe.Pointer"
			}
		}
	}
	if !strings.HasPrefix(cgo_type(ti, flags), "*") {
		return go_type_for_tag(tag, flags|type_exact)
	}
	return "unsafe.Pointer"
}
Пример #5
0
func CgoType(ti *gi.TypeInfo, flags TypeFlags) string {
	var out bytes.Buffer

	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			out.WriteString("unsafe.Pointer")
			break
		}
		panic("Non-pointer void type is not supported in cgo")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME:
		out.WriteString("*C.char")
	case gi.TYPE_TAG_ARRAY:
		switch ti.ArrayType() {
		case gi.ARRAY_TYPE_C:
			out.WriteString("*")
			out.WriteString(CgoType(ti.ParamType(0), flags))
		case gi.ARRAY_TYPE_ARRAY:
			out.WriteString("*C.GArray")
		case gi.ARRAY_TYPE_PTR_ARRAY:
			out.WriteString("*C.GPtrArray")
		case gi.ARRAY_TYPE_BYTE_ARRAY:
			out.WriteString("*C.GByteArray")
		}
	case gi.TYPE_TAG_GLIST:
		out.WriteString("*C.GList")
	case gi.TYPE_TAG_GSLIST:
		out.WriteString("*C.GSList")
	case gi.TYPE_TAG_GHASH:
		out.WriteString("*C.GHashTable")
	case gi.TYPE_TAG_ERROR:
		out.WriteString("*C.GError")
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		out.WriteString(CgoTypeForInterface(ti.Interface(), flags))
	default:
		if ti.IsPointer() {
			out.WriteString("*")
		}
		out.WriteString(CgoTypeForTag(tag, flags))
	}

	return out.String()
}
Пример #6
0
func CType(ti *gi.TypeInfo, flags TypeFlags) string {
	var out bytes.Buffer

	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			out.WriteString("void*")
			break
		}
		out.WriteString("void")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME:
		out.WriteString("char*")
	case gi.TYPE_TAG_ARRAY:
		switch ti.ArrayType() {
		case gi.ARRAY_TYPE_C:
			out.WriteString(CType(ti.ParamType(0), flags))
			out.WriteString("*")
		case gi.ARRAY_TYPE_ARRAY:
			out.WriteString("GArray*")
		case gi.ARRAY_TYPE_PTR_ARRAY:
			out.WriteString("GPtrArray*")
		case gi.ARRAY_TYPE_BYTE_ARRAY:
			out.WriteString("GByteArray*")
		}
	case gi.TYPE_TAG_GLIST:
		out.WriteString("GList*")
	case gi.TYPE_TAG_GSLIST:
		out.WriteString("GSList*")
	case gi.TYPE_TAG_GHASH:
		out.WriteString("GHashTable*")
	case gi.TYPE_TAG_ERROR:
		out.WriteString("GError*")
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		out.WriteString(CTypeForInterface(ti.Interface(), flags))
	default:
		out.WriteString(CTypeForTag(tag, flags))
		if ti.IsPointer() {
			out.WriteString("*")
		}
	}

	return out.String()
}
Пример #7
0
func GoToCgo(ti *gi.TypeInfo, arg0, arg1 string, flags ConvFlags) string {
	var out bytes.Buffer
	printf := PrinterTo(&out)

	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			printf("%s = unsafe.Pointer(%s)", arg1, arg0)
			break
		}
		printf("<ERROR: void>")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME:
		printf("%s = _GoStringToGString(%s)", arg1, arg0)
		if flags&ConvOwnEverything == 0 {
			printf("\ndefer C.free(unsafe.Pointer(%s))", arg1)
		}
	case gi.TYPE_TAG_ARRAY:
		switch ti.ArrayType() {
		case gi.ARRAY_TYPE_C:
			var nelem string
			if ti.IsZeroTerminated() {
				nelem = fmt.Sprintf("(len(%s) + 1)", arg0)
			} else {
				nelem = fmt.Sprintf("len(%s)", arg0)
			}

			// alloc memory
			printf("%s = (%s)(C.malloc(C.size_t(int(unsafe.Sizeof(*%s)) * %s)))\n",
				arg1, CgoType(ti, TypeNone), arg1, nelem)
			printf("defer C.free(unsafe.Pointer(%s))\n", arg1)

			// convert elements
			printf("for i, e := range %s {\n", arg0)
			array := CgoArrayToGoArray(ti.ParamType(0), arg1)
			conv := GoToCgo(ti.ParamType(0), "e", array+"[i]", flags)
			printf(PrintLinesWithIndent(conv))
			printf("}")

			// write a trailing zero if necessary (TODO: buggy)
			if ti.IsZeroTerminated() {
				printf("\n%s[len(%s)] = nil", array, arg0)
			}

		}
	case gi.TYPE_TAG_GLIST:
	case gi.TYPE_TAG_GSLIST:
	case gi.TYPE_TAG_GHASH:
	case gi.TYPE_TAG_ERROR:
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= ConvPointer
		}
		printf(GoToCgoForInterface(ti.Interface(), arg0, arg1, flags))
	default:
		if ti.IsPointer() {
			flags |= ConvPointer
		}
		printf(GoToCgoForTag(tag, arg0, arg1, flags))
	}

	return out.String()
}
Пример #8
0
func CgoToGo(ti *gi.TypeInfo, arg1, arg2 string, flags ConvFlags) string {
	var out bytes.Buffer
	printf := PrinterTo(&out)

	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			printf("%s = %s", arg2, arg1)
			break
		}
		printf("<ERROR: void>")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME:
		printf("%s = C.GoString(%s)", arg2, arg1)
		if flags&ConvOwnEverything != 0 {
			printf("\nC.g_free(unsafe.Pointer(%s))", arg1)
		}
	case gi.TYPE_TAG_ARRAY:
		switch ti.ArrayType() {
		case gi.ARRAY_TYPE_C:
			// array was allocated already at this point
			printf("for i := range %s {\n", arg2)
			array := CgoArrayToGoArray(ti.ParamType(0), arg1)
			conv := CgoToGo(ti.ParamType(0),
				array+"[i]", arg2+"[i]", flags)
			printf(PrintLinesWithIndent(conv))
			printf("}")
		}
	case gi.TYPE_TAG_GLIST:
		ptype := ti.ParamType(0)
		printf("for iter := (*_GList)(unsafe.Pointer(%s)); iter != nil; iter = iter.next {\n", arg1)
		elt := fmt.Sprintf("(%s)(iter.data)",
			ForcePointer(CgoType(ptype, TypeReturn|TypeListMember)))
		printf("\tvar elt %s\n", GoType(ptype, TypeReturn|TypeListMember))
		conv := CgoToGo(ptype, elt, "elt", flags|ConvListMember)
		printf(PrintLinesWithIndent(conv))
		printf("\t%s = append(%s, elt)\n", arg2, arg2)
		printf("}")
	case gi.TYPE_TAG_GSLIST:
		ptype := ti.ParamType(0)
		printf("for iter := (*_GSList)(unsafe.Pointer(%s)); iter != nil; iter = iter.next {\n", arg1)
		elt := fmt.Sprintf("(%s)(iter.data)",
			ForcePointer(CgoType(ptype, TypeReturn|TypeListMember)))
		printf("\tvar elt %s\n", GoType(ptype, TypeReturn|TypeListMember))
		conv := CgoToGo(ptype, elt, "elt", flags|ConvListMember)
		printf(PrintLinesWithIndent(conv))
		printf("\t%s = append(%s, elt)\n", arg2, arg2)
		printf("}")
	case gi.TYPE_TAG_GHASH:
	case gi.TYPE_TAG_ERROR:
		printf("if %s != nil {\n", arg1)
		printf("\t%s = errors.New(C.GoString(((*_GError)(unsafe.Pointer(%s))).message))\n", arg2, arg1)
		printf("\tC.g_error_free(%s)\n", arg1)
		printf("}\n")
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= ConvPointer
		}
		printf(CgoToGoForInterface(ti.Interface(), arg1, arg2, flags))
	default:
		if ti.IsPointer() {
			flags |= ConvPointer
		}
		printf(CgoToGoForTag(tag, arg1, arg2, flags))
	}

	return out.String()
}
Пример #9
0
func GoType(ti *gi.TypeInfo, flags TypeFlags) string {
	var out bytes.Buffer

	switch tag := ti.Tag(); tag {
	case gi.TYPE_TAG_VOID:
		if ti.IsPointer() {
			out.WriteString("unsafe.Pointer")
			break
		}
		panic("Non-pointer void type is not supported")
	case gi.TYPE_TAG_UTF8, gi.TYPE_TAG_FILENAME:
		if flags&TypeExact != 0 {
			out.WriteString("unsafe.Pointer")
		} else {
			out.WriteString("string")
		}
	case gi.TYPE_TAG_ARRAY:
		size := ti.ArrayFixedSize()
		if size != -1 {
			fmt.Fprintf(&out, "[%d]", size)
		} else {
			if flags&TypeExact != 0 {
				out.WriteString("unsafe.Pointer")
			} else {
				out.WriteString("[]")
			}
		}
		out.WriteString(GoType(ti.ParamType(0), flags))
	case gi.TYPE_TAG_GLIST:
		if flags&TypeExact != 0 {
			out.WriteString("unsafe.Pointer")
		} else {
			out.WriteString("[]")
			out.WriteString(GoType(ti.ParamType(0), flags|TypeListMember))
		}
	case gi.TYPE_TAG_GSLIST:
		if flags&TypeExact != 0 {
			out.WriteString("unsafe.Pointer")
		} else {
			out.WriteString("[]")
			out.WriteString(GoType(ti.ParamType(0), flags|TypeListMember))
		}
	case gi.TYPE_TAG_GHASH:
		if flags&TypeExact != 0 {
			out.WriteString("unsafe.Pointer")
		} else {
			out.WriteString("map[")
			out.WriteString(GoType(ti.ParamType(0), flags))
			out.WriteString("]")
			out.WriteString(GoType(ti.ParamType(1), flags))
		}
	case gi.TYPE_TAG_ERROR:
		// not used?
		out.WriteString("error")
	case gi.TYPE_TAG_INTERFACE:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		out.WriteString(GoTypeForInterface(ti.Interface(), flags))
	default:
		if ti.IsPointer() {
			flags |= TypePointer
		}
		out.WriteString(GoTypeForTag(tag, flags))
	}

	return out.String()
}