# Copyright (c) 2023 M.J.N. Corino, The Netherlands # # This software is released under the MIT license. ### # wxRuby3 Common typemap definitions ### require_relative '../core/mapping' module WXRuby3 module Typemap # Deals with GetDataHere and SetData module DataObjectData include Typemap::Module define do # For wxDataObject::GetDataHere: the ruby method is passed the DataFormat # for the sought data, and should return either a string containing the # data, or nil if the data cannot be provided for some reason. map 'const wxDataFormat &format, void *buf' do # this is needed for this and all other mappings add_header '#include <wx/dataobj.h>' map_in from: {type: 'Wx::DataFormat', index: 0}, temp: 'std::unique_ptr<char[]> data_buf, size_t data_size', code: <<~__CODE void* argp$argnum = NULL; if ( TYPE($input) == T_DATA ) { if (SWIG_IsOK(SWIG_ConvertPtr($input, &argp$argnum, $1_descriptor, 0)) && argp$argnum) { $1 = reinterpret_cast< $1_basetype * >(argp$argnum); } } if (!argp$argnum) { rb_raise(rb_eTypeError, "Expected Wx::DataFormat instance."); } data_size = arg1->GetDataSize(*$1); data_buf = std::make_unique<char[]>(data_size); $2 = data_buf.get (); __CODE # ignore C defined return value entirely (also affects directorout) map_out ignore: 'bool' map_argout as: {type: 'String', index: 1}, code: <<~__CODE if (result) { $result = rb_utf8_str_new( (const char*)data_buf$argnum.get(), data_size$argnum); } else $result = Qnil; __CODE # convert the dataformat and ignore the buffer pointer for now map_directorin code: '$input = SWIG_NewPointerObj(SWIG_as_voidptr(&$1), SWIGTYPE_p_wxDataFormat, 0);' map_directorargout code: <<~__CODE if (RTEST(result)) { if (TYPE(result) == T_STRING) { memcpy(buf, StringValuePtr(result), RSTRING_LEN(result) ); c_result = true; } else { Swig::DirectorTypeMismatchException::raise(swig_get_self(), "$symname", rb_eTypeError, "get_data_here should return a string, or nil on failure"); } } else c_result = false; __CODE end # For SetData: the data contents to be set upon the data object is # passed in as a Ruby string; the ruby method should return a true # value if the data could be set successfully, or false/nil if it could # not. This string is marked as tainted. map 'size_t len, const void* buf' do map_in from: {type: 'String', index: 1}, code: <<~__CODE if (RTEST($input) && TYPE($input) == T_STRING) { $1 = RSTRING_LEN($input); $2 = (void*)StringValuePtr($input); } else { $1 = 0; $2 = NULL; } __CODE map_directorin code: '$input = rb_utf8_str_new( (const char *)buf, len );' map_typecheck precedence: 'pointer', code: '$1 = (TYPE($input) == T_STRING);' end end # define end # DataObjectData end # Typemap end # WXRuby3