static/source/unoembindhelpers/PrimaryBindings.cxx |   43 +++++++++++++++++++++
 udkapi/org/libreoffice/embindtest/XTest.idl        |    4 +
 unotest/source/embindtest/embindtest.cxx           |   24 +++++++++++
 unotest/source/embindtest/embindtest.js            |   16 +++++++
 4 files changed, 87 insertions(+)

New commits:
commit 41feb036b44ffefca898f44ed95a2129d779da59
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Thu Feb 29 08:54:08 2024 +0100
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Thu Feb 29 16:19:19 2024 +0100

    Some minimal Embind support for UNO type
    
    ...which should be rare enough in practical use that it should be 
sufficient to
    only have toString-functionality for instances mapped from C++ to JS, but no
    constructor for new instances on the JS side.  (The natural choice for the
    latter would be a mapping of the C++
    
    >     inline Type( TypeClass eTypeClass, const ::rtl::OUString & rTypeName 
);
    
    constructor, but which requires a mapping for the css::uno::TypeClass UNOIDL
    enum, which is only provided "later" through CustomTarget_static/unoembind, 
so
    would at least conceptually be a bit dirty.)
    
    This Embind mapping treats css::uno::Type as a smart pointer for the 
underlying
    typelib_TypeDescriptionReference, to benefit from the fallback garbage
    collection (in more recent Emscripten versions, at least) for smart 
pointers,
    obviating the need to call .delete() on each instance mapped to JS.
    
    Change-Id: Ic113967c264c28641dfd1fe159012c85519f4a9b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164140
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>

diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx 
b/static/source/unoembindhelpers/PrimaryBindings.cxx
index 186e3ee88057..50048a97ada6 100644
--- a/static/source/unoembindhelpers/PrimaryBindings.cxx
+++ b/static/source/unoembindhelpers/PrimaryBindings.cxx
@@ -12,17 +12,41 @@
 #include <emscripten.h>
 #include <emscripten/bind.h>
 
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Type.hxx>
 #include <comphelper/processfactory.hxx>
+#include <rtl/string.hxx>
+#include <rtl/textcvt.h>
+#include <rtl/textenc.h>
+#include <rtl/ustring.hxx>
 #include <sal/log.hxx>
 #include <sfx2/viewsh.hxx>
 #include <static/unoembindhelpers/PrimaryBindings.hxx>
+#include <typelib/typedescription.h>
 
 #include <cstdint>
+#include <string>
 #include <typeinfo>
 
 using namespace emscripten;
 using namespace css::uno;
 
+template <> struct emscripten::smart_ptr_trait<css::uno::Type>
+{
+    using PointerType = css::uno::Type;
+    using element_type = typelib_TypeDescriptionReference;
+    static typelib_TypeDescriptionReference* get(css::uno::Type const& ptr)
+    {
+        return ptr.getTypeLibType();
+    }
+    static sharing_policy get_sharing_policy() { return 
sharing_policy::INTRUSIVE; }
+    static css::uno::Type* share(typelib_TypeDescriptionReference* v)
+    {
+        return new css::uno::Type(v);
+    }
+    static css::uno::Type* construct_null() { return new css::uno::Type(); }
+};
+
 EM_JS(void, jsRegisterChar, (std::type_info const* raw),
 // clang-format off
 {
@@ -110,6 +134,18 @@ EM_JS(void, jsRegisterString, (std::type_info const* raw),
 
 namespace
 {
+OString toUtf8(OUString const& string)
+{
+    OString s;
+    if (!string.convertToString(&s, RTL_TEXTENCODING_UTF8,
+                                RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+                                    | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+    {
+        throw css::uno::RuntimeException("cannot convert OUString to UTF-8");
+    }
+    return s;
+}
+
 template <typename T> void registerInOutParam(char const* name)
 {
     
class_<unoembindhelpers::UnoInOutParam<T>>(name).constructor().constructor<T>().property(
@@ -135,6 +171,13 @@ EMSCRIPTEN_BINDINGS(PrimaryBindings)
     enum_<unoembindhelpers::uno_Sequence>("uno_Sequence")
         .value("FromSize", unoembindhelpers::uno_Sequence::FromSize);
 
+    emscripten::class_<typelib_TypeDescriptionReference>("uno_Type")
+        .smart_ptr<css::uno::Type>("uno_Type$")
+        .function("toString", +[](css::uno::Type const& self) {
+            auto const name = toUtf8(self.getTypeName());
+            return std::string(name.getStr(), name.getLength());
+        });
+
     // Any
     class_<Any>("Any").constructor(+[](const val& rObject, const TypeClass& 
rUnoType) -> Any {
         switch (rUnoType)
diff --git a/udkapi/org/libreoffice/embindtest/XTest.idl 
b/udkapi/org/libreoffice/embindtest/XTest.idl
index f64a3857e863..2ddfb41f2ead 100644
--- a/udkapi/org/libreoffice/embindtest/XTest.idl
+++ b/udkapi/org/libreoffice/embindtest/XTest.idl
@@ -34,6 +34,8 @@ interface XTest {
     boolean isChar([in] char value);
     string getString();
     boolean isString([in] string value);
+    type getType();
+    boolean isType([in] type value);
     Enum getEnum();
     boolean isEnum([in] Enum value);
     Struct getStruct();
@@ -62,6 +64,8 @@ interface XTest {
     boolean isSequenceChar([in] sequence<char> value);
     sequence<string> getSequenceString();
     boolean isSequenceString([in] sequence<string> value);
+    sequence<type> getSequenceType();
+    boolean isSequenceType([in] sequence<type> value);
     sequence<sequence<string> > getSequenceSequenceString();
     boolean isSequenceSequenceString([in] sequence<sequence<string> > value);
     sequence<Enum> getSequenceEnum();
diff --git a/unotest/source/embindtest/embindtest.cxx 
b/unotest/source/embindtest/embindtest.cxx
index 2a9cdfc4de3a..8b131cd9f376 100644
--- a/unotest/source/embindtest/embindtest.cxx
+++ b/unotest/source/embindtest/embindtest.cxx
@@ -10,6 +10,8 @@
 #include <sal/config.h>
 
 #include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <cppu/unotype.hxx>
 #include <cppuhelper/implbase.hxx>
 #include <cppuhelper/weak.hxx>
 #include <org/libreoffice/embindtest/Struct.hpp>
@@ -76,6 +78,13 @@ public:
 
     sal_Bool SAL_CALL isString(OUString const& value) override { return value 
== u"hä"; }
 
+    css::uno::Type SAL_CALL getType() override { return 
cppu::UnoType<sal_Int32>::get(); }
+
+    sal_Bool SAL_CALL isType(css::uno::Type const& value) override
+    {
+        return value == cppu::UnoType<sal_Int32>::get();
+    }
+
     org::libreoffice::embindtest::Enum SAL_CALL getEnum() override
     {
         return org::libreoffice::embindtest::Enum_E_2;
@@ -213,6 +222,21 @@ public:
         return value == css::uno::Sequence<OUString>{ u"foo"_ustr, 
u"barr"_ustr, u"bazzz"_ustr };
     }
 
+    css::uno::Sequence<css::uno::Type> SAL_CALL getSequenceType() override
+    {
+        return { cppu::UnoType<sal_Int32>::get(), cppu::UnoType<void>::get(),
+                 
cppu::UnoType<css::uno::Sequence<org::libreoffice::embindtest::Enum>>::get() };
+    }
+
+    sal_Bool SAL_CALL isSequenceType(css::uno::Sequence<css::uno::Type> const& 
value) override
+    {
+        return value
+               == css::uno::Sequence<css::uno::Type>{
+                      cppu::UnoType<sal_Int32>::get(), 
cppu::UnoType<void>::get(),
+                      
cppu::UnoType<css::uno::Sequence<org::libreoffice::embindtest::Enum>>::get()
+                  };
+    }
+
     css::uno::Sequence<css::uno::Sequence<OUString>> SAL_CALL 
getSequenceSequenceString() override
     {
         return { {}, { u"foo"_ustr, u"barr"_ustr }, { u"baz"_ustr } };
diff --git a/unotest/source/embindtest/embindtest.js 
b/unotest/source/embindtest/embindtest.js
index 1978c9cc4ec7..422c1c1a421f 100644
--- a/unotest/source/embindtest/embindtest.js
+++ b/unotest/source/embindtest/embindtest.js
@@ -84,6 +84,12 @@ Module.addOnPostRun(function() {
         console.assert(v === 'hä');
         console.assert(test.isString(v));
     }
+    {
+        let v = test.getType();
+        console.log(v);
+        console.assert(v.toString() === 'long');
+        console.assert(test.isType(v));
+    }
     {
         let v = test.getEnum();
         console.log(v);
@@ -218,6 +224,16 @@ Module.addOnPostRun(function() {
         console.assert(test.isSequenceString(v));
         v.delete();
     }
+    {
+        let v = test.getSequenceType();
+        console.log(v);
+        console.assert(v.size() === 3);
+        console.assert(v.get(0).toString() === 'long');
+        console.assert(v.get(1).toString() === 'void');
+        console.assert(v.get(2).toString() === 
'[]org.libreoffice.embindtest.Enum');
+        console.assert(test.isSequenceType(v));
+        v.delete();
+    }
     {
         let v = test.getSequenceSequenceString();
         console.log(v);

Reply via email to