/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include template struct emscripten::smart_ptr_trait> { using PointerType = css::uno::Reference; using element_type = T; static T* get(css::uno::Reference const& ptr) { return ptr.get(); } static sharing_policy get_sharing_policy() { return sharing_policy::INTRUSIVE; } static css::uno::Reference* share(T* v) { return new css::uno::Reference(v); } static css::uno::Reference* construct_null() { return new css::uno::Reference(); } }; namespace unoembindhelpers { namespace detail { void registerUnoType(css::uno::Type const& type, std::type_info const* id); } enum class uno_Sequence { FromSize }; template struct UnoInOutParam { UnoInOutParam() {} UnoInOutParam(T the_value) : value(the_value) { } T get() const { return value; } void set(T the_value) { value = the_value; } T value; }; inline void checkSequenceSize(sal_Int32 size) { if (size < 0) { throw std::invalid_argument("negative size"); } } template void checkSequenceAccess(css::uno::Sequence const& sequence, sal_Int32 index) { if (index < 0 || index >= sequence.getLength()) { throw std::out_of_range("index out of bounds"); } } template void registerUnoType() { detail::registerUnoType(cppu::UnoType::get(), &typeid(T)); } template void registerSequence(char const* name) { emscripten::class_>(name) .constructor(+[](emscripten::val const& members) { auto const len = members["length"].as(); if (len > std::numeric_limits::max()) { throw std::length_error("JavaScript array length too large for C++ UNO sequence"); } css::uno::Sequence seq(len); auto const p = seq.getArray(); for (std::uint32_t i = 0; i != len; ++i) { p[i] = members[i].as(); } return seq; }) .constructor(+[](sal_Int32 size, [[maybe_unused]] uno_Sequence) { checkSequenceSize(size); return css::uno::Sequence(size); }) .function("resize", +[](css::uno::Sequence& self, sal_Int32 size) { checkSequenceSize(size); self.realloc(size); }) .function("size", &css::uno::Sequence::getLength) .function("get", +[](css::uno::Sequence const& self, sal_Int32 index) -> T const& { checkSequenceAccess(self, index); return self[index]; }) .function("set", +[](css::uno::Sequence& self, sal_Int32 index, T const& value) { checkSequenceAccess(self, index); self.getArray()[index] = value; }); registerUnoType>(); } template void registerInOutParameter(char const* name) { emscripten::class_>(name).constructor().template constructor().property( "val", &UnoInOutParam::get, &UnoInOutParam::set); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */