diff options
Diffstat (limited to 'Lib/ruby/rubywstrings.swg')
-rw-r--r-- | Lib/ruby/rubywstrings.swg | 92 |
1 files changed, 39 insertions, 53 deletions
diff --git a/Lib/ruby/rubywstrings.swg b/Lib/ruby/rubywstrings.swg index b6dd937a5..7da6f4bf2 100644 --- a/Lib/ruby/rubywstrings.swg +++ b/Lib/ruby/rubywstrings.swg @@ -1,71 +1,57 @@ /* ----------------------------------------------------------------------------- * rubywstrings.swg * - * Currently, Ruby does not support Unicode or WChar properly, so these - * are still treated as char arrays for now. - * There are other libraries available that add support to this in - * ruby including WString, FXString, etc. - * ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------ * utility methods for wchar_t strings * ------------------------------------------------------------ */ -%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize") { +%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") { SWIGINTERN int SWIG_AsWCharPtrAndSize(VALUE obj, wchar_t **cptr, size_t *psize, int *alloc) { - return SWIG_AsCharPtrAndSize( obj, (char**)cptr, psize, alloc); -// VALUE tmp = 0; -// bool ok = false; -// if ( TYPE(obj) == T_STRING ) { -// if (cptr) { -// obj = tmp = SWIG_Unicode_FromObject(obj); -// ok = true; -// } -// } -// if (ok) { -// Py_ssize_t len = PyUnicode_GetSize(obj); -// rb_notimplement(); -// if (cptr) { -// *cptr = %new_array(len + 1, wchar_t); -// SWIG_Unicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len); -// (*cptr)[len] = 0; -// } -// if (psize) *psize = (size_t) len + 1; -// if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; -// return SWIG_OK; -// } else { -// swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); -// if (pwchar_descriptor) { -// void * vptr = 0; -// if (SWIG_ConvertPtr(obj, &vptr, pwchar_descriptor, 0) == SWIG_OK) { -// if (cptr) *cptr = (wchar_t *)vptr; -// if (psize) *psize = vptr ? (wcslen((wchar_t *)vptr) + 1) : 0; -// return SWIG_OK; -// } -// } -// } -// return SWIG_TypeError; + rb_encoding* wstr_enc = swig_ruby_wstring_encoding; + + if (TYPE(obj) == T_STRING) { + VALUE rstr = rb_str_conv_enc(obj, rb_enc_get(obj), wstr_enc); + wchar_t* cstr = (wchar_t*) StringValuePtr(rstr); + size_t size = RSTRING_LEN(rstr) / sizeof(wchar_t) + 1; + + if ( RSTRING_LEN(rstr) % sizeof(wchar_t) != 0 ) { + rb_raise(rb_eRuntimeError, + "The length of the byte sequence of converted string is not a multiplier of sizeof(wchar_t). Invalid byte sequence is given. Or invalid SWIG_RUBY_WSTRING_ENCODING is given when compiling this binding."); + } + if (cptr && alloc) { + *alloc = SWIG_NEWOBJ; + *cptr = %new_array(size, wchar_t); + memmove(*cptr, cstr, RSTRING_LEN(rstr)); + } + if (psize) *psize = size; + + return SWIG_OK; + } else { + return SWIG_TypeError; + } } } -%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize") { +%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") { SWIGINTERNINLINE VALUE SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size) { - return SWIG_FromCharPtrAndSize( (const char*)carray, size); -// if (carray) { -// if (size > INT_MAX) { -// swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); -// return pwchar_descriptor ? -// SWIG_NewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : Qnil; -// } else { -// return SWIG_Unicode_FromWideChar(carray, %numeric_cast(size,int)); -// } -// } else { -// return Qnil; -// } + rb_encoding* wstr_enc = swig_ruby_wstring_encoding; + rb_encoding* rb_enc = swig_ruby_internal_encoding; + + if (carray && size <= LONG_MAX/sizeof(wchar_t)) { + VALUE rstr = rb_str_new( (const char*)carray, %numeric_cast(size*sizeof(wchar_t),long) ); + rb_encoding* new_enc = rb_default_internal_encoding(); + + rb_enc_associate(rstr, wstr_enc); + if ( !new_enc ) { + new_enc = rb_enc; + } + return rb_str_conv_enc(rstr, wstr_enc, new_enc); + } else { + return Qnil; + } } } |