From 5bcb96b56124597e1c7d674550168d4f885aa514 Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Wed, 2 May 2018 17:02:07 +0200 Subject: [PATCH] Convert test_object_list --- src/cpp.cpp | 20 ++++++++- src/rust.cpp | 75 ++++++++++++++++++++++---------- tests/rust_list/src/interface.rs | 67 ++++++++++------------------ tests/test_list_rust.cpp | 23 +++------- 4 files changed, 98 insertions(+), 87 deletions(-) diff --git a/src/cpp.cpp b/src/cpp.cpp index fd8bd9b..6370ff9 100644 --- a/src/cpp.cpp +++ b/src/cpp.cpp @@ -174,6 +174,14 @@ void writeModelGetterSetter(QTextStream& cpp, const QString& index, cpp << " } else\n"; } QString val = QString("value.value<%1>()").arg(ip.type.name); + if (ip.type.isComplex()) { + cpp << QString(" const %1 s = %2;").arg(ip.type.name, val); + if (ip.type.name == "QString") { + val = "s.utf16(), s.length()"; + } else { + val = "s.data(), s.length()"; + } + } cpp << QString(" set = %1_set_data_%2(m_d%3, %4);") .arg(lcname, snakeCase(ip.name), idx, val) << endl; if (o.type == ObjectType::List) { @@ -215,8 +223,16 @@ void writeCppModel(QTextStream& cpp, const Object& o) { .arg(o.name, lcname, snakeCase(ip.name), cppSetType(ip), indexDecl); } if (ip.write) { - cpp << QString(" bool %2_set_data_%3(%1::Private*%5, %4);") - .arg(o.name, lcname, snakeCase(ip.name), ip.type.cSetType, indexDecl) << endl; + if (ip.type.name == "QString") { + cpp << QString(" bool %2_set_data_%3(%1::Private*%4, const ushort* s, int len);") + .arg(o.name, lcname, snakeCase(ip.name), indexDecl) << endl; + } else if (ip.type.name == "QByteArray") { + cpp << QString(" bool %2_set_data_%3(%1::Private*%4, const char* s, int len);") + .arg(o.name, lcname, snakeCase(ip.name), indexDecl) << endl; + } else { + cpp << QString(" bool %2_set_data_%3(%1::Private*%5, %4);") + .arg(o.name, lcname, snakeCase(ip.name), ip.type.cSetType, indexDecl) << endl; + } if (ip.optional) { cpp << QString(" bool %2_set_data_%3_none(%1::Private*%4);") .arg(o.name, lcname, snakeCase(ip.name), indexDecl) << endl; diff --git a/src/rust.cpp b/src/rust.cpp index a34c3d6..41448d9 100644 --- a/src/rust.cpp +++ b/src/rust.cpp @@ -370,7 +370,7 @@ pub extern "C" fn %2_get( let s: *const c_char = v.as_ptr() as (*const c_char); set(p, s, v.len() as c_int); } -)").arg(o.name, base, snakeCase(p.name), p.type.name, p.rustByValue ?"&" :""); +)").arg(o.name, base, snakeCase(p.name)); if (p.write && p.type.name == "QString") { r << QString(R"( #[no_mangle] @@ -406,8 +406,7 @@ pub extern "C" fn %2_get( set(p, s, v.len() as c_int); } } -)").arg(o.name, base, snakeCase(p.name), p.type.name, - p.rustByValue ?"&" :""); +)").arg(o.name, base, snakeCase(p.name)); if (p.write && p.type.name == "QString") { r << QString(R"( #[no_mangle] @@ -603,49 +602,76 @@ pub unsafe extern "C" fn %2_row(ptr: *const %1, item: usize) -> c_int { if (ip.type.isComplex() && !ip.optional) { r << QString(R"( #[no_mangle] -pub unsafe extern "C" fn %2_data_%3( +pub extern "C" fn %2_data_%3( ptr: *const %1%5, - d: *mut c_void, - set: fn(*mut c_void, %4), + d: *mut QString, + set: fn(*mut QString, *const c_char, len: c_int), ) { - let data = (&*ptr).%3(%6); - set(d, (%7data).into()); + let o = unsafe { & *ptr }; + let data = o.%3(%6); + let s: *const c_char = data.as_ptr() as (*const c_char); + set(d, s, data.len() as i32); } -)").arg(o.name, lcname, snakeCase(ip.name), ip.type.name, indexDecl, index, - ip.rustByValue ?"&" :""); - } else if (ip.type.isComplex()) { +)").arg(o.name, lcname, snakeCase(ip.name), indexDecl, index); + } else if (ip.type.name == "QString") { r << QString(R"( #[no_mangle] -pub unsafe extern "C" fn %2_data_%3( +pub extern "C" fn %2_data_%3( ptr: *const %1%5, - d: *mut c_void, - set: fn(*mut c_void, %4), + d: *mut QString, + set: fn(*mut QString, *const c_char, len: c_int), ) { - let data = (&*ptr).%3(%6); + let o = unsafe { &mut *ptr }; + let data = o.%3(%6); if let Some(data) = data { - set(d, %4::from(&data)); + let s: *const c_char = data.as_ptr() as (*const c_char); + set(d, s, data.len()); } } )").arg(o.name, lcname, snakeCase(ip.name), ip.type.name, indexDecl, index); } else { r << QString(R"( #[no_mangle] -pub unsafe extern "C" fn %2_data_%3(ptr: *const %1%5) -> %4 { - (&*ptr).%3(%6).into() +pub extern "C" fn %2_data_%3(ptr: *const %1%5) -> %4 { + let o = unsafe { &mut *ptr }; + o.%3(%6).into() } )").arg(o.name, lcname, snakeCase(ip.name), rustCType(ip), indexDecl, index); } if (ip.write) { QString val = "v"; - QString type = ip.type.rustType; - if (ip.type.isComplex()) { - val = val + ".convert()"; - type = ip.type.name == "QString" ? "QStringIn" : ip.type.name; - } if (ip.optional) { val = "Some(" + val + ")"; } - r << QString(R"( + if (ip.type.name == "QString") { + r << QString(R"( +#[no_mangle] +pub extern "C" fn %2_set_data_%3( + ptr: *mut %1%4, + s: *const c_ushort, len: c_int, +) -> bool { + let o = unsafe { &mut *ptr }; + let mut v = String::new(); + set_string_from_utf16(&mut v, s, len); + o.set_%3(%5, %6) +} +)").arg(o.name, lcname, snakeCase(ip.name), indexDecl, index, val); + } else if (ip.type.name == "QByteArray") { + r << QString(R"( +#[no_mangle] +pub extern "C" fn %2_set_data_%3( + ptr: *mut %1%4, + s: *const c_char, len: c_int, +) -> bool { + let o = unsafe { &mut *ptr }; + let mut v = Vec::new(); + set_string_from_utf16(&mut v, s, len); + o.set_%3(%5, %6) +} +)").arg(o.name, lcname, snakeCase(ip.name), indexDecl, index, val); + } else { + const QString type = ip.type.rustType; + r << QString(R"( #[no_mangle] pub unsafe extern "C" fn %2_set_data_%3( ptr: *mut %1%4, @@ -654,6 +680,7 @@ pub unsafe extern "C" fn %2_set_data_%3( (&mut *ptr).set_%3(%5, %7) } )").arg(o.name, lcname, snakeCase(ip.name), indexDecl, index, type, val); + } } if (ip.write && ip.optional) { r << QString(R"( diff --git a/tests/rust_list/src/interface.rs b/tests/rust_list/src/interface.rs index 5fe7fbb..af00e77 100644 --- a/tests/rust_list/src/interface.rs +++ b/tests/rust_list/src/interface.rs @@ -1,8 +1,9 @@ /* generated by rust_qt_binding_generator */ #![allow(unknown_lints)] #![allow(mutex_atomic, needless_pass_by_value)] -use libc::{c_int, c_void, uint8_t, uint16_t}; +use libc::{c_char, c_ushort, c_int, c_void, uint8_t, uint16_t}; use std::slice; +use std::char::decode_utf16; use std::sync::{Arc, Mutex}; use std::ptr::null; @@ -36,42 +37,17 @@ where } -#[repr(C)] -pub struct QString { - data: *const uint8_t, - len: c_int, +pub enum QString {} + +fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) { + let utf16 = unsafe { slice::from_raw_parts(str, len as usize) }; + let characters = decode_utf16(utf16.iter().cloned()) + .into_iter() + .map(|r| r.unwrap()); + s.clear(); + s.extend(characters); } -#[repr(C)] -pub struct QStringIn { - data: *const uint16_t, - len: c_int, -} - -impl QStringIn { - fn convert(&self) -> String { - let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) }; - String::from_utf16_lossy(data) - } -} - -impl<'a> From<&'a str> for QString { - fn from(string: &'a str) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} - -impl<'a> From<&'a String> for QString { - fn from(string: &'a String) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} #[repr(C)] @@ -223,19 +199,24 @@ pub unsafe extern "C" fn persons_sort( } #[no_mangle] -pub unsafe extern "C" fn persons_data_user_name( +pub extern "C" fn persons_data_user_name( ptr: *const Persons, row: c_int, - d: *mut c_void, - set: fn(*mut c_void, QString), + d: *mut QString, + set: fn(*mut QString, *const c_char, len: c_int), ) { - let data = (&*ptr).user_name(row as usize); - set(d, (data).into()); + let o = unsafe { & *ptr }; + let data = o.user_name(row as usize); + let s: *const c_char = data.as_ptr() as (*const c_char); + set(d, s, data.len() as i32); } #[no_mangle] -pub unsafe extern "C" fn persons_set_data_user_name( +pub extern "C" fn persons_set_data_user_name( ptr: *mut Persons, row: c_int, - v: QStringIn, + s: *const c_ushort, len: c_int, ) -> bool { - (&mut *ptr).set_user_name(row as usize, v.convert()) + let o = unsafe { &mut *ptr }; + let mut v = String::new(); + set_string_from_utf16(&mut v, s, len); + o.set_user_name(row as usize, v) } diff --git a/tests/test_list_rust.cpp b/tests/test_list_rust.cpp index 37341d4..b43fdfa 100644 --- a/tests/test_list_rust.cpp +++ b/tests/test_list_rust.cpp @@ -15,22 +15,9 @@ namespace { } }; - struct qstring_t { - private: - const void* data; - int len; - public: - qstring_t(const QString& v): - data(static_cast(v.utf16())), - len(v.size()) { - } - operator QString() const { - return QString::fromUtf8(static_cast(data), len); - } - }; - typedef void (*qstring_set)(QString*, qstring_t*); - void set_qstring(QString* v, qstring_t* val) { - *v = *val; + typedef void (*qstring_set)(QString* val, const char* utf8, int nbytes); + void set_qstring(QString* val, const char* utf8, int nbytes) { + *val = QString::fromUtf8(utf8, nbytes); } struct qmodelindex_t { @@ -40,7 +27,7 @@ namespace { } extern "C" { void persons_data_user_name(const Persons::Private*, int, QString*, qstring_set); - bool persons_set_data_user_name(Persons::Private*, int, qstring_t); + bool persons_set_data_user_name(Persons::Private*, int, const ushort* s, int len); void persons_sort(Persons::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder); int persons_row_count(const Persons::Private*); @@ -124,7 +111,7 @@ QVariant Persons::userName(int row) const bool Persons::setUserName(int row, const QVariant& value) { bool set = false; - set = persons_set_data_user_name(m_d, row, value.value()); + const QString s = value.value(); set = persons_set_data_user_name(m_d, row, s.utf16(), s.length()); if (set) { QModelIndex index = createIndex(row, 0, row); emit dataChanged(index, index);