include/static/unoembindhelpers/PrimaryBindings.hxx |   23 +++++++++++++++++++-
 static/source/unoembindhelpers/PrimaryBindings.cxx  |    3 +-
 2 files changed, 24 insertions(+), 2 deletions(-)

New commits:
commit 72056edca078dd010368de15d03321a60c6d5cdd
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Wed Feb 7 14:47:54 2024 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Thu Feb 8 09:30:22 2024 +0100

    Embind: Allow UNO sequences to be constructed from JS arrays
    
    ...though
    
    > let seq = new Module.uno_Sequence_string(["foo", "bar", "baz"]);
    > // ...
    > delete seq;
    
    is still ugly.
    
    And Embind only allows for overload resolution by number of parameters, not 
by
    their type, so using the original sequence constructor had to be changed to
    
    > let seq = new Module.uno_Sequence_string(3, Module.uno_Sequence.FromSize);
    > seq.set(0, "foo");
    > seq.set(1, "bar");
    > seq.set(2, "baz");
    > // ...
    > delete seq;
    
    Change-Id: If26ff4a485ba16b65cf24b6fe729d379c733c473
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163097
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/include/static/unoembindhelpers/PrimaryBindings.hxx 
b/include/static/unoembindhelpers/PrimaryBindings.hxx
index 61efaf01153b..4df301277cc9 100644
--- a/include/static/unoembindhelpers/PrimaryBindings.hxx
+++ b/include/static/unoembindhelpers/PrimaryBindings.hxx
@@ -11,6 +11,8 @@
 
 #include <sal/config.h>
 
+#include <cstdint>
+#include <limits>
 #include <stdexcept>
 
 #include <emscripten/bind.h>
@@ -36,6 +38,11 @@ enum class uno_Reference
     FromAny
 };
 
+enum class uno_Sequence
+{
+    FromSize
+};
+
 template <typename T> struct UnoInOutParam
 {
     UnoInOutParam() {}
@@ -72,7 +79,21 @@ void checkSequenceAccess(css::uno::Sequence<T> const& 
sequence, sal_Int32 index)
 template <typename T> void registerSequence(char const* name)
 {
     emscripten::class_<css::uno::Sequence<T>>(name)
-        .constructor(+[](sal_Int32 size) {
+        .constructor(+[](emscripten::val const& members) {
+            auto const len = members["length"].as<std::uint32_t>();
+            if (len > std::numeric_limits<sal_Int32>::max())
+            {
+                throw std::length_error("JavaScript array length too large for 
C++ UNO sequence");
+            }
+            css::uno::Sequence<T> seq(len);
+            auto const p = seq.getArray();
+            for (std::uint32_t i = 0; i != len; ++i)
+            {
+                p[i] = members[i].as<T>();
+            }
+            return seq;
+        })
+        .constructor(+[](sal_Int32 size, [[maybe_unused]] uno_Sequence) {
             checkSequenceSize(size);
             return css::uno::Sequence<T>(size);
         })
diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx 
b/static/source/unoembindhelpers/PrimaryBindings.cxx
index fe3b6e29908f..ee4998988c19 100644
--- a/static/source/unoembindhelpers/PrimaryBindings.cxx
+++ b/static/source/unoembindhelpers/PrimaryBindings.cxx
@@ -46,9 +46,10 @@ Reference<css::frame::XModel> getCurrentModelFromViewSh()
 
 EMSCRIPTEN_BINDINGS(PrimaryBindings)
 {
-    // Reference bits
     enum_<unoembindhelpers::uno_Reference>("uno_Reference")
         .value("FromAny", unoembindhelpers::uno_Reference::FromAny);
+    enum_<unoembindhelpers::uno_Sequence>("uno_Sequence")
+        .value("FromSize", unoembindhelpers::uno_Sequence::FromSize);
 
     // Any
     class_<Any>("Any").constructor(+[](const val& rObject, const TypeClass& 
rUnoType) -> Any {

Reply via email to