diff options
Diffstat (limited to 'Lib/csharp/std_wstring.i')
-rw-r--r-- | Lib/csharp/std_wstring.i | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i index 162b90e80..c7fef41a5 100644 --- a/Lib/csharp/std_wstring.i +++ b/Lib/csharp/std_wstring.i @@ -2,7 +2,9 @@ * std_wstring.i * * Typemaps for std::wstring and const std::wstring& - * These are mapped to a C# String and are passed around by value. + * std::wstring is mapped to a C# Unicode string (UTF16) and is passed around by value. + * std::wstring support includes wchar_t as a 2 byte type (Windows) and a 4 byte type + * (most Unix systems). * * To use non-const std::wstring references use the following %apply. Note * that they are passed by value. @@ -15,6 +17,28 @@ #include <string> %} +%fragment("Swig_csharp_UTF16ToWString", "header") %{ +/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */ +static std::wstring Swig_csharp_UTF16ToWString(const unsigned short *str) { + if (sizeof(wchar_t) == 2) { + return std::wstring((wchar_t *)str); + } else { + const unsigned short *pBegin(str); + const unsigned short *ptr(pBegin); + + while (*ptr != 0) + ++ptr; + + std::wstring result; + result.reserve(ptr - pBegin); + while(pBegin != ptr) + result.push_back(*pBegin++); + + return result; + } +} +%} + namespace std { %naturalvar wstring; @@ -22,31 +46,33 @@ namespace std { class wstring; // wstring -%typemap(ctype, out="void *") wstring "wchar_t *" +%typemap(ctype, out="void *") wstring "unsigned short *" %typemap(imtype, inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", - outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]" + outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", + directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", + directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]" ) wstring "string" %typemap(cstype) wstring "string" %typemap(csdirectorin) wstring "$iminput" %typemap(csdirectorout) wstring "$cscall" -%typemap(in, canthrow=1) wstring +%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") wstring %{ if (!$input) { SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0); return $null; } - $1.assign($input); %} -%typemap(out) wstring %{ $result = SWIG_csharp_wstring_callback($1.c_str()); %} + $1 = Swig_csharp_UTF16ToWString($input); %} +%typemap(out) wstring %{ $result = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %} -%typemap(directorout, canthrow=1) wstring +%typemap(directorout, canthrow=1) wstring %{ if (!$input) { SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0); return $null; } - $result.assign($input); %} + $result = Swig_csharp_UTF16ToWString($input); %} -%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %} +%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %} %typemap(csin) wstring "$csinput" %typemap(csout, excode=SWIGEXCODE) wstring { @@ -57,29 +83,30 @@ class wstring; %typemap(typecheck) wstring = wchar_t *; %typemap(throws, canthrow=1) wstring -%{ std::string message($1.begin(), $1.end()); - SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str()); +%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size()); return $null; %} // const wstring & -%typemap(ctype, out="void *") const wstring & "wchar_t *" +%typemap(ctype, out="void *") const wstring & "unsigned short *" %typemap(imtype, inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", - outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]" + outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", + directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", + directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]" ) const wstring & "string" %typemap(cstype) const wstring & "string" %typemap(csdirectorin) const wstring & "$iminput" %typemap(csdirectorout) const wstring & "$cscall" -%typemap(in, canthrow=1) const wstring & +%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") const wstring & %{ if (!$input) { SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0); return $null; } - std::wstring $1_str($input); + std::wstring $1_str(Swig_csharp_UTF16ToWString($input)); $1 = &$1_str; %} -%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_callback($1->c_str()); %} +%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_with_length_callback($1->data(), (int)$1->size()); %} %typemap(csin) const wstring & "$csinput" %typemap(csout, excode=SWIGEXCODE) const wstring & { @@ -94,10 +121,10 @@ class wstring; } /* possible thread/reentrant code problem */ static std::wstring $1_str; - $1_str = $input; + $1_str = Swig_csharp_UTF16ToWString($input); $result = &$1_str; %} -%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %} +%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %} %typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{ set { @@ -112,8 +139,7 @@ class wstring; %typemap(typecheck) const wstring & = wchar_t *; %typemap(throws, canthrow=1) const wstring & -%{ std::string message($1.begin(), $1.end()); - SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str()); +%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size()); return $null; %} } |