Skip to content

Commit bdc1a21

Browse files
committed
Improve C# string input performance
Encode input strings directly to UTF8 unmanaged memory instead of managed byte array. Apply string typemap to `void* callback_data`
1 parent 7488a84 commit bdc1a21

4 files changed

Lines changed: 24 additions & 19 deletions

File tree

swig/csharp/apps/GDALTestUtf8.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22

33
using OSGeo.GDAL;
4+
using OSGeo.OSR;
45

56
namespace testapp
67
{

swig/include/csharp/csharp_strings.i

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,6 @@ static CSharpUtf8StringHelperCallback SWIG_csharp_string_callback = NULL;
101101

102102
return unmanagedString;
103103
}
104-
105-
public static byte[] StringToUtf8Bytes(string str)
106-
{
107-
if (str == null)
108-
return null;
109-
110-
int bytecount = System.Text.Encoding.UTF8.GetByteCount(str);
111-
byte[] bytes = new byte[bytecount + 1];
112-
System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, bytes, 0);
113-
return bytes;
114-
}
115104
%}
116105

117106
%insert(runtime) %{
@@ -129,18 +118,35 @@ SWIGEXPORT void SWIGSTDCALL RegisterUtf8StringCallback_$module(CSharpUtf8StringH
129118

130119
/* Changing csin and imtype typemaps for string types defined by SWIG in csharp.swg */
131120

132-
%typemap(imtype, out="IntPtr") (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) "byte[]"
121+
%typemap(cstype) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) "string"
122+
%typemap(imtype) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) "IntPtr"
133123

134124
%typemap(in) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) %{
135125
$1 = ($1_ltype)$input;
136126
%}
137127

138-
%typemap(out) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string)
139-
%{
128+
%typemap(out) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) %{
140129
$result = SWIG_csharp_string_callback((const char *)$1);
141130
%}
142131

143-
%typemap(csin) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) "$modulePINVOKE.StringToUtf8Bytes($csinput)"
132+
%typemap(csin,
133+
pre=" IntPtr temp$csinput = $modulePINVOKE.StringToUtf8Unmanaged($csinput);",
134+
post=" Marshal.FreeHGlobal(temp$csinput);",
135+
cshin="$csinput"
136+
) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string)
137+
"temp$csinput"
138+
139+
%typemap(csvarin, excode=SWIGEXCODE2) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) %{
140+
/* %typemap(csvarin) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string) */
141+
set {
142+
IntPtr temp$csinput = $modulePINVOKE.StringToUtf8Unmanaged($csinput);
143+
try {
144+
$imcall;$excode
145+
}
146+
finally {
147+
Marshal.FreeHGlobal(temp$csinput);
148+
}
149+
} %}
144150

145151
%typemap(csout, excode=SWIGEXCODE) (char *), (char *&), (char[ANY]), (char[]), (const char *utf8_string)
146152
{

swig/include/csharp/ogr_csharp.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ DEFINE_EXTERNAL_CLASS(GDALMajorObjectShadow, OSGeo.GDAL.MajorObject)
7171
return new $csclassname(wkbGeometryType.wkbUnknown, null, 0, IntPtr.Zero, gml);
7272
}
7373

74-
public Geometry(wkbGeometryType type) : this(OgrPINVOKE.new_Geometry((int)type, null, 0, IntPtr.Zero, null), true, null) {
74+
public Geometry(wkbGeometryType type) : this(OgrPINVOKE.new_Geometry((int)type, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero), true, null) {
7575
if (OgrPINVOKE.SWIGPendingException.Pending) throw OgrPINVOKE.SWIGPendingException.Retrieve();
7676
}
7777
}

swig/include/csharp/typemaps_csharp.i

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,7 @@ CSHARP_OBJECT_ARRAYS_PINNED(GDALRasterBandShadow, Band)
600600
return ret;
601601
} %}
602602
%typemap(in) (GDALProgressFunc callback) %{ $1 = ($1_ltype)$input; %}
603-
%typemap(imtype) (void* callback_data) "string"
604-
%typemap(cstype) (void* callback_data) "string"
605-
%typemap(csin) (void* callback_data) "$csinput"
603+
%apply (const char *utf8_string) {(void* callback_data)};
606604

607605
%ignore SWIGTYPE_p_GDALProgressFunc;
608606

0 commit comments

Comments
 (0)