From 9d630ab930f83252e75d6e66e2912cbe75ca253f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 8 Jan 2013 21:48:22 +0100 Subject: [PATCH] Fix std::string support for v8. --- Lib/javascript/jsc/std_string.i | 8 +- Lib/javascript/v8/javascriptstrings.swg | 5 +- Lib/javascript/v8/std_string.i | 106 +++++++++++++----------- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i index d1ac12ef9..a23396fe6 100755 --- a/Lib/javascript/jsc/std_string.i +++ b/Lib/javascript/jsc/std_string.i @@ -1,12 +1,10 @@ /* ----------------------------------------------------------------------------- * std_string.i * - * Typemaps for std::string and const std::string& - * These are mapped to a JSCore String and are passed around by value. + * Typemaps for const std::string&. + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; * - * To use non-const std::string references use the following %apply. Note - * that they are passed by value. - * %apply const std::string & {std::string &}; * ----------------------------------------------------------------------------- */ %{ diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg index e955bee3a..69b6836a8 100644 --- a/Lib/javascript/v8/javascriptstrings.swg +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -2,7 +2,7 @@ /* ------------------------------------------------------------ * utility methods for char strings * ------------------------------------------------------------ */ -%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +%fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") { SWIGINTERN int SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) { @@ -47,9 +47,6 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size) if (carray) { if (size > INT_MAX) { // TODO: handle extra long strings - //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - //return pchar_descriptor ? - // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); return v8::Undefined(); } else { v8::Handle js_str = v8::String::New(carray, size); diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i index 0d6143319..d9221627f 100755 --- a/Lib/javascript/v8/std_string.i +++ b/Lib/javascript/v8/std_string.i @@ -1,68 +1,74 @@ /* ----------------------------------------------------------------------------- * std_string.i * - * Typemaps for std::string and const std::string& - * These are mapped to a JSCore String and are passed around by value. + * Typemaps for std::string and const std::string&. + * + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; * - * To use non-const std::string references use the following %apply. Note - * that they are passed by value. - * %apply const std::string & {std::string &}; * ----------------------------------------------------------------------------- */ %{ #include %} +%fragment("SWIGV8_valueToString", "header", fragment="SWIG_AsCharPtrAndSize") { +std::string* SWIGV8_valueToStringPtr(v8::Handle val) { + int alloc; + size_t size; + char* chars; + int res = SWIG_AsCharPtrAndSize(val, &chars, &size, &alloc); + + if(res != SWIG_OK) { + v8::ThrowException(v8::Exception::TypeError(v8::String::New("Could not convert to string."))); + return 0; + } + + // copies the data (again) + std::string *str = new std::string(chars); + + if (alloc) delete[] chars; + + return str; +} +} + +%fragment("SWIGV8_stringToValue", "header", fragment="SWIG_FromCharPtrAndSize") { +v8::Handle SWIGV8_stringToValue(const std::string &str) { + return SWIG_FromCharPtrAndSize(str.c_str(), str.length()); +} +} + namespace std { + %naturalvar string; -%naturalvar string; + class string; -class string; + %typemap(in, fragment="SWIGV8_valueToString") string (std::string* tmp) + %{ + tmp = SWIGV8_valueToStringPtr($input); + $1 = *tmp; + delete tmp; + %} -// string + %typemap(in, fragment="SWIGV8_valueToString") const string & + %{ + $1 = SWIGV8_valueToStringPtr($input); + %} + + %typemap(freearg) const string & + %{ + delete $1; + %} -%typemap(in) string -%{ - if(!$input->IsString()) { - // TODO: Throw exception? - return NULL; - } + %typemap(out, fragment="SWIGV8_stringToValue") string + %{ + $result = SWIGV8_stringToValue($1); + %} - size_t $1_strsize = js_str->Utf8Length(); - char* 1_cstr = new char[1_strsize]; - js_str->WriteUtf8(1_cstr, 1_strsize); - $1 = std::string($1_cstr); -%} - -%typemap(out) string %{ - $result = v8::String::New($1.c_str(), $1.size()); -%} - -%typemap(freearg) string -%{%} - -// const string & -%typemap(in) const string & -%{ - - if(!$input->IsString()) { - // TODO: Throw exception? - return NULL; - } - - size_t $1_strsize = js_str->Utf8Length(); - char* 1_cstr = new char[1_strsize]; - js_str->WriteUtf8(1_cstr, 1_strsize); - $1 = newstd::string($1_cstr); -%} - -%typemap(out) const string & %{ - $result = v8::String::New($1.c_str(), $1.size()); -%} - -%typemap(freearg) const string & //TODO: Not working: A memory leak -%{ free($1_cstr); %} - -//%typemap(typecheck) const string & = char *; + %typemap(out, fragment="SWIGV8_stringToValue") const string & + %{ + $result = SWIGV8_stringToValue($1); + %} }