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 {
