// 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()) }
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 }
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() }