blob: 0be3ca1f7ff2fe6584107d5293935899eae4a138 [file] [log] [blame]
// Test the goin and goout typemaps for directors.
%module(directors="1") go_director_inout
%include <std_string.i>
%{
#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,fragment="AllocateString") RetStruct
%{
$result = Swig_AllocateString($1.str.data(), $1.str.length());
%}
%typemap(goout,fragment="CopyString") RetStruct
%{
$result = GoRetStruct{Str: swigCopyString($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,fragment="AllocateString") MyStruct
%{
$input = Swig_AllocateString($1.str.data(), $1.str.length());
%}
%typemap(godirectorin,fragment="CopyString") MyStruct
%{
if err := json.Unmarshal([]byte(swigCopyString($input)), &$result); err != nil {
panic(err)
}
%}
%typemap(out,fragment="AllocateString") MyStruct
%{
$result = Swig_AllocateString($1.str.data(), $1.str.length());
%}
%typemap(goout,fragment="CopyString") MyStruct
%{
$result = swigCopyString($input)
%}
%typemap(in) MyStruct
%{
$1.str.assign($input.p, $input.n);
%}
%typemap(directorin) std::string & (_gostring_ temp) {
$input = &temp;
temp.p = (char *) $1.data();
temp.n = $1.size();
}
%typemap(directorargout) std::string & {
_gostring_ *tmp = $input;
$1.assign(tmp->p, tmp->p + tmp->n);
}
%inline %{
// Helper functions for converting string arrays
#include <stdlib.h>
void *alloc_ptr_array(unsigned int len)
{
return calloc(len, sizeof(void *));
}
void set_ptr_array(void *ain, unsigned int pos, void *val)
{
void **a = (void **) ain;
a[pos] = val;
}
void *get_ptr_array(void *ain, unsigned int pos)
{
void **a = (void **) ain;
return a[pos];
}
void free_ptr_array(void *ain)
{
void **a = (void **) ain;
unsigned int i;
if (!a)
return;
for (i = 0; a[i]; i++) {
free(a[i]);
}
free(a);
}
char *uintptr_to_string(void *in)
{
return (char *) in;
}
void *string_to_uintptr(char *in)
{
return strdup(in);
}
%}
// These typemaps convert between an array of strings in Go and a
// const char** that is NULL terminated in C++.
%typemap(gotype) (const char * const *) "[]string"
%typemap(imtype) (const char * const *) "uintptr"
%typemap(goin) (const char * const *) {
if $input == nil || len($input) == 0 {
$result = 0
} else {
$result = Alloc_ptr_array(uint(len($input) + 1))
defer func() {
Free_ptr_array($result)
}()
var i uint
for i = 0; i < uint(len($input)); i++ {
Set_ptr_array($result, i, String_to_uintptr($input[i]))
}
}
}
%typemap(in) (const char * const *) {
$1 = (char **) $input;
}
%typemap(godirectorin) (const char * const *) {
if ($input == 0) {
$result = nil
} else {
var i uint
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
}
if i == 0 {
$result = nil
} else {
$result = make([]string, i)
for i = 0; ; i++ {
var v uintptr = Get_ptr_array($input, i)
if v == 0 {
break
}
$result[i] = Uintptr_to_string(v)
}
}
}
}
%feature("director") MyClass;
%inline
%{
class MyClass {
public:
virtual ~MyClass() {}
virtual RetStruct Adjust(MyStruct s) {
RetStruct r;
r.str = s.str;
return r;
}
void CallS4(const char * const *strarray);
virtual void S1(std::string s);
virtual void S2(std::string& s) = 0;
virtual void S3(std::string* s) = 0;
virtual void S4(const char * const *strarray);
virtual int S5(const std::string* s);
};
void MyClass::S1(std::string s) {
throw "Base S1 called!";
}
void MyClass::S4(const char * const *strarray) {
throw "Base S4 called!";
}
void MyClass::CallS4(const char * const *strarray) {
this->S4(strarray);
}
int MyClass::S5(const std::string* s) {
if (s) {
return (*s)[0];
} else {
return 0;
}
}
%}