[Go] Add imtype, goin, goout, godirectorin, and godirectorout

typemaps, to support writing Go code to convert between types.
This commit is contained in:
Ian Lance Taylor 2014-09-05 17:54:19 -07:00
commit 1addbb46a8
9 changed files with 744 additions and 101 deletions

View file

@ -24,6 +24,10 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES = \
go_inout \
go_director_inout
include $(srcdir)/../common.mk
.SUFFIXES: .cpptest .ctest .multicpptest

View file

@ -0,0 +1,32 @@
package main
import (
wrap "./go_director_inout"
)
type GoMyClass struct {}
func (p *GoMyClass) Adjust(m map[string]interface{}) wrap.GoRetStruct {
s := ""
for k, v := range m {
s += k + "," + v.(string) + ";"
}
return wrap.GoRetStruct{s}
}
func main() {
a := wrap.NewDirectorMyClass(&GoMyClass{})
m := map[string]interface{}{
"first": "second",
}
s := a.Adjust(m)
if s.Str != "first,second;" {
panic(s)
}
a = wrap.NewDirectorMyClass(nil)
s = a.Adjust(m)
if s.Str != `{"first":"second"}` {
panic(s.Str)
}
}

View file

@ -0,0 +1,35 @@
package main
import (
"encoding/json"
"fmt"
"reflect"
"./go_inout"
)
type S struct {
A int
B string
C float64
}
func (p *S) MarshalJSON() ([]byte, error) {
return json.Marshal(*p)
}
func main() {
v := &S{12, "hi", 34.5}
m := go_inout.Same(v)
want := map[string]interface{}{
// The type of A changes from int to float64 because
// JSON has no ints.
"A": float64(12),
"B": "hi",
"C": 34.5,
}
if !reflect.DeepEqual(m, want) {
fmt.Println("got", m, "want", want)
panic(m)
}
}

View file

@ -0,0 +1,121 @@
// Test the goin and goout typemaps for directors.
%module(directors="1") go_director_inout
%{
#include <string>
%}
%inline
%{
struct MyStruct {
std::string str;
};
struct RetStruct {
std::string str;
};
%}
%go_import("encoding/json")
%insert(go_header)
%{
type GoRetStruct struct {
Str string
}
%}
%typemap(gotype) RetStruct "GoRetStruct"
%typemap(imtype) RetStruct "string"
%typemap(goin) RetStruct
%{
$result = $input.Str
%}
%typemap(in) RetStruct
%{
$result.str.assign($input.p, $input.n);
%}
%typemap(out) RetStruct
%{
$result = _swig_makegostring($1.str.data(), $1.str.length());
%}
%typemap(goout) RetStruct
%{
$result = GoRetStruct{Str: $input}
%}
%typemap(godirectorout) RetStruct
%{
$result = $input.Str
%}
%typemap(directorout) RetStruct
%{
$result.str.assign($input.p, $input.n);
%}
%typemap(godirectorin) RetStruct
%{
%}
%typemap(gotype) MyStruct "map[string]interface{}"
%typemap(imtype) MyStruct "string"
%typemap(goin) MyStruct
%{
if b, err := json.Marshal($input); err != nil {
panic(err)
} else {
$result = string(b)
}
%}
%typemap(directorin) MyStruct
%{
$input = _swig_makegostring($1.str.data(), $1.str.length());
%}
%typemap(out) MyStruct
%{
$result = _swig_makegostring($1.str.data(), $1.str.length());
%}
%typemap(godirectorin) MyStruct
%{
if err := json.Unmarshal([]byte($input), &$result); err != nil {
panic(err)
}
%}
%typemap(in) MyStruct
%{
$1.str.assign($input.p, $input.n);
%}
%feature("director") MyClass;
%inline
%{
class MyClass {
public:
virtual ~MyClass() {}
virtual RetStruct Adjust(MyStruct s) {
RetStruct r;
r.str = s.str;
return r;
}
};
%}

View file

@ -0,0 +1,79 @@
// Test the goin and goout typemaps.
%module go_inout
%{
#include <string>
%}
%inline
%{
struct MyStruct {
std::string str;
};
struct RetStruct {
std::string str;
};
%}
// Write a typemap that calls C++ by converting in and out of JSON.
%go_import("encoding/json")
%insert(go_header)
%{
type In json.Marshaler
%}
%typemap(gotype) MyStruct "In"
%typemap(imtype) MyStruct "string"
%typemap(goin) MyStruct
%{
{
b, err := $input.MarshalJSON()
if err != nil {
panic(err)
}
$result = string(b)
}
%}
%typemap(in) MyStruct
%{
$1.str.assign($input.p, $input.n);
%}
%typemap(gotype) RetStruct "map[string]interface{}"
%typemap(imtype) RetStruct "string"
%typemap(out) RetStruct
%{
$result = _swig_makegostring($1.str.data(), $1.str.length());
%}
%typemap(goout) RetStruct
%{
if err := json.Unmarshal([]byte($1), &$result); err != nil {
panic(err)
}
%}
%inline
%{
RetStruct Same(MyStruct s)
{
RetStruct r;
r.str = s.str;
return r;
}
%}