From e93cb80d26c98f84ec7936c19af598f9897217a2 Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Sat, 12 Aug 2017 00:18:10 +0200 Subject: [PATCH] Fix converstion of ByteArray and String --- common-rust/src/types.rs | 39 ++++++++---- .../rust_qt_binding_generator.cpp | 3 +- src/tmp.cpp | 3 +- tests/rust_object/src/types.rs | 41 +++++++++---- tests/rust_object_types/src/types.rs | 33 ++++++---- tests/test_object_rust.cpp | 3 +- tests/test_object_types.cpp | 61 ++++++++++++++++--- tests/test_object_types_rust.cpp | 3 +- 8 files changed, 135 insertions(+), 51 deletions(-) diff --git a/common-rust/src/types.rs b/common-rust/src/types.rs index 41077a3..c416ff5 100644 --- a/common-rust/src/types.rs +++ b/common-rust/src/types.rs @@ -85,8 +85,8 @@ enum VariantType { #[repr(C)] pub struct QVariant<'a> { - type_: c_uint, - len: c_int, + type_: VariantType, + value: c_int, data: *const uint8_t, phantom: PhantomData<&'a u8>, } @@ -96,9 +96,22 @@ impl<'a> QVariant<'a> { self.type_ as u32 } pub fn convert(&self) -> Variant { - match (self.type_) { - 10 => { - Variant::String(String::new()) + match self.type_ { + VariantType::Bool => { + Variant::Bool(self.value != 0) + }, + VariantType::String => { + let data = unsafe { + let d = self.data as *const uint16_t; + slice::from_raw_parts(d, self.value as usize) + }; + Variant::String(String::from_utf16_lossy(data)) + } + VariantType::ByteArray => { + let data = unsafe { + slice::from_raw_parts(self.data, self.value as usize) + }; + Variant::ByteArray(Vec::from(data)) } _ => Variant::None } @@ -111,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> { Variant::None => { QVariant { data: null(), - len: 0, - type_: VariantType::Invalid as c_uint, + value: 0, + type_: VariantType::Invalid, phantom: PhantomData, } } Variant::Bool(v) => { QVariant { data: null(), - len: v as c_int, - type_: VariantType::Bool as c_uint, + value: v as c_int, + type_: VariantType::Bool, phantom: PhantomData, } } Variant::String(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::String as c_uint, + value: v.len() as c_int, + type_: VariantType::String, phantom: PhantomData, } } Variant::ByteArray(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::ByteArray as c_uint, + value: v.len() as c_int, + type_: VariantType::ByteArray, phantom: PhantomData, } } diff --git a/rust_qt_binding_generator/rust_qt_binding_generator.cpp b/rust_qt_binding_generator/rust_qt_binding_generator.cpp index b2b6c63..ba85aa9 100644 --- a/rust_qt_binding_generator/rust_qt_binding_generator.cpp +++ b/rust_qt_binding_generator/rust_qt_binding_generator.cpp @@ -457,8 +457,9 @@ namespace { }; QVariant variant(const qvariant_t& v) { switch (v.type) { - case QVariant::Bool: return QVariant((bool)v.value); case QVariant::String: return QString::fromUtf8(static_cast(v.data), v.value); + case QVariant::Bool: return QVariant((bool)v.value); + case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value)); default:; } return QVariant(); diff --git a/src/tmp.cpp b/src/tmp.cpp index 910d0c9..2ab363e 100644 --- a/src/tmp.cpp +++ b/src/tmp.cpp @@ -43,8 +43,9 @@ namespace { }; QVariant variant(const qvariant_t& v) { switch (v.type) { - case QVariant::Bool: return QVariant((bool)v.value); case QVariant::String: return QString::fromUtf8(static_cast(v.data), v.value); + case QVariant::Bool: return QVariant((bool)v.value); + case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value)); default:; } return QVariant(); diff --git a/tests/rust_object/src/types.rs b/tests/rust_object/src/types.rs index 180ae6e..c416ff5 100644 --- a/tests/rust_object/src/types.rs +++ b/tests/rust_object/src/types.rs @@ -85,8 +85,8 @@ enum VariantType { #[repr(C)] pub struct QVariant<'a> { - type_: c_uint, - len: c_int, + type_: VariantType, + value: c_int, data: *const uint8_t, phantom: PhantomData<&'a u8>, } @@ -96,8 +96,25 @@ impl<'a> QVariant<'a> { self.type_ as u32 } pub fn convert(&self) -> Variant { - // TODO - Variant::None + match self.type_ { + VariantType::Bool => { + Variant::Bool(self.value != 0) + }, + VariantType::String => { + let data = unsafe { + let d = self.data as *const uint16_t; + slice::from_raw_parts(d, self.value as usize) + }; + Variant::String(String::from_utf16_lossy(data)) + } + VariantType::ByteArray => { + let data = unsafe { + slice::from_raw_parts(self.data, self.value as usize) + }; + Variant::ByteArray(Vec::from(data)) + } + _ => Variant::None + } } } @@ -107,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> { Variant::None => { QVariant { data: null(), - len: 0, - type_: VariantType::Invalid as c_uint, + value: 0, + type_: VariantType::Invalid, phantom: PhantomData, } } Variant::Bool(v) => { QVariant { data: null(), - len: v as c_int, - type_: VariantType::Bool as c_uint, + value: v as c_int, + type_: VariantType::Bool, phantom: PhantomData, } } Variant::String(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::String as c_uint, + value: v.len() as c_int, + type_: VariantType::String, phantom: PhantomData, } } Variant::ByteArray(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::ByteArray as c_uint, + value: v.len() as c_int, + type_: VariantType::ByteArray, phantom: PhantomData, } } diff --git a/tests/rust_object_types/src/types.rs b/tests/rust_object_types/src/types.rs index b8ca403..c416ff5 100644 --- a/tests/rust_object_types/src/types.rs +++ b/tests/rust_object_types/src/types.rs @@ -85,8 +85,8 @@ enum VariantType { #[repr(C)] pub struct QVariant<'a> { - type_: c_uint, - len: c_int, + type_: VariantType, + value: c_int, data: *const uint8_t, phantom: PhantomData<&'a u8>, } @@ -97,13 +97,22 @@ impl<'a> QVariant<'a> { } pub fn convert(&self) -> Variant { match self.type_ { - 10 => { + VariantType::Bool => { + Variant::Bool(self.value != 0) + }, + VariantType::String => { let data = unsafe { let d = self.data as *const uint16_t; - slice::from_raw_parts(d, self.len as usize) + slice::from_raw_parts(d, self.value as usize) }; Variant::String(String::from_utf16_lossy(data)) } + VariantType::ByteArray => { + let data = unsafe { + slice::from_raw_parts(self.data, self.value as usize) + }; + Variant::ByteArray(Vec::from(data)) + } _ => Variant::None } } @@ -115,32 +124,32 @@ impl<'a> From<&'a Variant> for QVariant<'a> { Variant::None => { QVariant { data: null(), - len: 0, - type_: VariantType::Invalid as c_uint, + value: 0, + type_: VariantType::Invalid, phantom: PhantomData, } } Variant::Bool(v) => { QVariant { data: null(), - len: v as c_int, - type_: VariantType::Bool as c_uint, + value: v as c_int, + type_: VariantType::Bool, phantom: PhantomData, } } Variant::String(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::String as c_uint, + value: v.len() as c_int, + type_: VariantType::String, phantom: PhantomData, } } Variant::ByteArray(ref v) => { QVariant { data: v.as_ptr(), - len: v.len() as c_int, - type_: VariantType::ByteArray as c_uint, + value: v.len() as c_int, + type_: VariantType::ByteArray, phantom: PhantomData, } } diff --git a/tests/test_object_rust.cpp b/tests/test_object_rust.cpp index e55ff2f..9589b43 100644 --- a/tests/test_object_rust.cpp +++ b/tests/test_object_rust.cpp @@ -43,8 +43,9 @@ namespace { }; QVariant variant(const qvariant_t& v) { switch (v.type) { - case QVariant::Bool: return QVariant((bool)v.value); case QVariant::String: return QString::fromUtf8(static_cast(v.data), v.value); + case QVariant::Bool: return QVariant((bool)v.value); + case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value)); default:; } return QVariant(); diff --git a/tests/test_object_types.cpp b/tests/test_object_types.cpp index 6361284..200cde6 100644 --- a/tests/test_object_types.cpp +++ b/tests/test_object_types.cpp @@ -1,29 +1,52 @@ #include "test_object_types_rust.h" #include #include -#include -class TestRustObject : public QObject +class TestRustObjectTypes : public QObject { Q_OBJECT private slots: - void testConstructor(); - void testStringGetter(); - void testStringSetter(); + void testInvalid(); + void testBool(); + void testString(); + void testByteArray(); }; -void TestRustObject::testConstructor() +void TestRustObjectTypes::testInvalid() { + // GIVEN Person person; + const QVariant userName; + QSignalSpy spy(&person, &Person::userNameChanged); + + // WHEN + person.setUserName(userName); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(person.userName().type(), userName.type()); + QCOMPARE(person.userName(), userName); } -void TestRustObject::testStringGetter() +void TestRustObjectTypes::testBool() { + // GIVEN Person person; - person.setUserName("Konqi"); + const QVariant userName(true); + QSignalSpy spy(&person, &Person::userNameChanged); + + // WHEN + person.setUserName(userName); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(person.userName().type(), userName.type()); + QCOMPARE(person.userName(), userName); } -void TestRustObject::testStringSetter() +void TestRustObjectTypes::testString() { // GIVEN Person person; @@ -40,5 +63,23 @@ void TestRustObject::testStringSetter() QCOMPARE(person.userName(), userName); } -QTEST_MAIN(TestRustObject) +void TestRustObjectTypes::testByteArray() +{ + // GIVEN + Person person; + const char data[10] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9}; + const QVariant userName(QByteArray(data, 10)); + QSignalSpy spy(&person, &Person::userNameChanged); + + // WHEN + person.setUserName(userName); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(spy.count(), 1); + QCOMPARE(person.userName().type(), userName.type()); + QCOMPARE(person.userName(), userName); +} + +QTEST_MAIN(TestRustObjectTypes) #include "test_object_types.moc" diff --git a/tests/test_object_types_rust.cpp b/tests/test_object_types_rust.cpp index 11f5ffe..3376375 100644 --- a/tests/test_object_types_rust.cpp +++ b/tests/test_object_types_rust.cpp @@ -43,8 +43,9 @@ namespace { }; QVariant variant(const qvariant_t& v) { switch (v.type) { - case QVariant::Bool: return QVariant((bool)v.value); case QVariant::String: return QString::fromUtf8(static_cast(v.data), v.value); + case QVariant::Bool: return QVariant((bool)v.value); + case QVariant::ByteArray: return QVariant(QByteArray(v.data, v.value)); default:; } return QVariant();