From 3dc3f040de0dd50bbf97a5461d5cccffa0f45ca3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 30 Aug 2024 14:44:40 +0700 Subject: [PATCH] feat(core): implement loading KMX from blob - split keyboard loading into loading KMX file into blob and then loading the keyboard processor from the blob. - deprecate `km_core_keyboard_load` - move file access next to deprecated method. This is now the only place that loads a file in Core; unit tests have some more places that load files. - introduce GTest and add unit tests for loading from blob Cherry-picked from `epic/web-core` branch. Cherry-Pick-Commit: 1deaa323ada28a6212da06d76ef886abc9c1335c Cherry-Pick-Commit: 59019cc8b79242de3c1e2a1703083f1b89d792d7 Cherry-Pick-Commit: bc4645836838e37e696f49fa6f342e548635a91a Cherry-Pick-Commit: d06aa29956227dd3277dee32fe36a94e0828f102 Cherry-Pick-Commit: 1c88166f6eea3ebb27bb5bdd05c4704ea6afb4b3 Cherry-Pick-Commit: 069cd21ecde94730ba16cfef91a8f37a225bdcd7 Cherry-Pick-Commit: 052ae2ec35e1756eebc15c691c3d690685272638 Cherry-Pick-Commit: 11a2a3ba3a3e1bd58583438ca054f290836fcae2 Part-of: #11293 Part-of: #8093 --- core/include/keyman/keyman_core_api.h | 66 ++++++++- core/include/keyman/keyman_core_api_bits.h | 5 +- core/src/keyboard.cpp | 7 +- core/src/keyboard.hpp | 5 +- core/src/km_core_keyboard_api.cpp | 119 +++++++++++++--- core/src/kmx/kmx_file.cpp | 92 +++++-------- core/src/kmx/kmx_processevent.h | 4 +- core/src/kmx/kmx_processor.cpp | 29 +++- core/src/kmx/kmx_processor.hpp | 4 +- core/src/ldml/ldml_processor.cpp | 52 +++---- core/src/ldml/ldml_processor.hpp | 9 +- core/src/meson.build | 32 +++-- core/src/mock/mock_processor.cpp | 24 +++- core/src/mock/mock_processor.hpp | 10 +- core/src/util_normalize_table_generator.cpp | 1 - core/subprojects/.gitignore | 1 + core/subprojects/gtest.wrap | 16 +++ .../tests/unit/km_core_keyboard_api.tests.cpp | 128 ++++++++++++++++++ .../unit/kmnkbd/action_set_api.tests.cpp | 5 +- .../unit/kmnkbd/actions_get_api.tests.cpp | 4 +- .../unit/kmnkbd/actions_normalize.tests.cpp | 4 +- core/tests/unit/kmnkbd/debug_api.tests.cpp | 5 +- core/tests/unit/kmnkbd/keyboard_api.tests.cpp | 8 +- core/tests/unit/kmnkbd/state_api.tests.cpp | 5 +- .../unit/kmnkbd/state_context_api.tests.cpp | 11 +- core/tests/unit/kmx/kmx.cpp | 4 +- .../unit/kmx/kmx_external_event.tests.cpp | 4 +- core/tests/unit/kmx/kmx_imx.tests.cpp | 7 +- core/tests/unit/kmx/kmx_key_list.tests.cpp | 4 +- .../unit/ldml/context_normalization.tests.cpp | 4 +- core/tests/unit/ldml/core_ldml_min.tests.cpp | 4 +- core/tests/unit/ldml/ldml.cpp | 4 +- core/tests/unit/ldml/ldml_test_source.cpp | 6 +- core/tests/unit/ldml/meson.build | 5 +- core/tests/unit/load_kmx_file.cpp | 34 +++++ core/tests/unit/load_kmx_file.hpp | 14 ++ core/tests/unit/meson.build | 30 +++- linux/debian/libkeymancore2.symbols | 3 +- 38 files changed, 579 insertions(+), 190 deletions(-) create mode 100644 core/subprojects/gtest.wrap create mode 100644 core/tests/unit/km_core_keyboard_api.tests.cpp create mode 100644 core/tests/unit/load_kmx_file.cpp create mode 100644 core/tests/unit/load_kmx_file.hpp diff --git a/core/include/keyman/keyman_core_api.h b/core/include/keyman/keyman_core_api.h index 328965e876..3c41182bab 100644 --- a/core/include/keyman/keyman_core_api.h +++ b/core/include/keyman/keyman_core_api.h @@ -1007,7 +1007,11 @@ Provides read-only information about a keyboard. typedef struct { km_core_cu const * version_string; km_core_cu const * id; + + // TODO-web-core: Deprecate this field (#12497) + // KMN_DEPRECATED km_core_path_name folder_path; + km_core_option_item const * default_options; } km_core_keyboard_attrs; @@ -1022,7 +1026,7 @@ typedef struct { : Keyman keyboard ID string. `folder_path` -: Path to the unpacked folder containing the keyboard and associated resources. +: Path to the unpacked folder containing the keyboard and associated resources (deprecated). `default_options` : Set of default values for any options included in the keyboard. @@ -1096,12 +1100,16 @@ typedef struct { ## Description +DEPRECATED: use [km_core_keyboard_load_from_blob] instead. + Parse and load keyboard from the supplied path and a pointer to the loaded keyboard -into the out paramter. +into the out parameter. ## Specification ```c */ +// TODO-web-core: Deprecate this function (#12497) +// KMN_DEPRECATED_API KMN_API km_core_status km_core_keyboard_load(km_core_path_name kb_path, @@ -1140,6 +1148,60 @@ km_core_keyboard_load(km_core_path_name kb_path, ------------------------------------------------------------------------------- +# km_core_keyboard_load_from_blob() + +## Description + +Parse and load keyboard from the supplied blob and a pointer to the loaded keyboard +into the out paramter. + +## Specification + +```c */ +KMN_API +km_core_status km_core_keyboard_load_from_blob(const km_core_path_name kb_name, + const void* blob, + const size_t blob_size, + km_core_keyboard** keyboard); + +/* +``` + +## Parameters + +`kb_name` +: a string with the name of the keyboard. + +`blob` +: a byte array containing the content of a KMX/KMX+ file. + +`blob_size` +: a size_t variable with the size of the blob in bytes. + +`keyboard` +: A pointer to result variable: A pointer to the opaque keyboard + object returned by the Processor. This memory must be freed with a + call to [km_core_keyboard_dispose]. + +## Returns + +`KM_CORE_STATUS_OK` +: On success. + +`KM_CORE_STATUS_NO_MEM` +: In the event an internal memory allocation fails. + +`KM_CORE_STATUS_IO_ERROR` +: In the event the keyboard file is unparseable for any reason + +`KM_CORE_STATUS_INVALID_ARGUMENT` +: In the event `keyboard` is null. + +`KM_CORE_STATUS_OS_ERROR` +: Bit 31 (high bit) set, bits 0-30 are an OS-specific error code. + +------------------------------------------------------------------------------- + # km_core_keyboard_dispose() ## Description diff --git a/core/include/keyman/keyman_core_api_bits.h b/core/include/keyman/keyman_core_api_bits.h index e00f4698a8..bd1f519bff 100644 --- a/core/include/keyman/keyman_core_api_bits.h +++ b/core/include/keyman/keyman_core_api_bits.h @@ -23,7 +23,6 @@ #define _kmn_unused(x) UNUSED_ ## x __attribute__((__unused__)) #else #define _kmn_unused(x) UNUSED_ ## x - #endif #if defined _WIN32 || defined __CYGWIN__ @@ -36,7 +35,7 @@ #undef _kmn_static_flag #else // How MSVC sepcifies function level attributes adn deprecation #define _kmn_and - #define _kmn_tag_fn(a) __declspec(a) + #define _kmn_tag_fn(a) __declspec(a) #define _kmn_deprecated_flag deprecated #endif #define _kmn_export_flag dllexport @@ -48,6 +47,8 @@ #define _KM_CORE_EXT_SEPARATOR ('.') #endif +#define KMN_DEPRECATED _kmn_tag_fn(_kmn_deprecated_flag) + #if defined KM_CORE_LIBRARY_STATIC #define KMN_API _kmn_tag_fn(_kmn_static_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_static_flag) diff --git a/core/src/keyboard.cpp b/core/src/keyboard.cpp index 2c3a0c11b2..0f104f9422 100644 --- a/core/src/keyboard.cpp +++ b/core/src/keyboard.cpp @@ -17,18 +17,16 @@ void keyboard_attributes::render() // Make attributes point to the stored values above. id = _keyboard_id.c_str(); version_string = _version_string.c_str(); - folder_path = _folder_path.c_str(); default_options = _default_opts.data(); } keyboard_attributes::keyboard_attributes(std::u16string const & kbid, std::u16string const & version, - path_type const & path, options_store const &opts) : _keyboard_id(kbid), _version_string(version), - _folder_path(path), + _folder_path(""), _default_opts(opts) { // Ensure that the default_options array will be properly terminated. @@ -40,7 +38,7 @@ keyboard_attributes::keyboard_attributes(std::u16string const & kbid, keyboard_attributes::keyboard_attributes(keyboard_attributes &&rhs) : _keyboard_id(std::move(rhs._keyboard_id)), _version_string(std::move(rhs._version_string)), - _folder_path(std::move(rhs._folder_path)), + _folder_path(""), _default_opts(std::move(rhs._default_opts)) { rhs.id = rhs.version_string = nullptr; @@ -58,7 +56,6 @@ json & km::core::operator << (json & j, km::core::keyboard_attributes const & kb { j << json::object << "id" << kb.id - << "folder" << kb._folder_path << "version" << kb.version_string << "rules" << json::array << json::close; diff --git a/core/src/keyboard.hpp b/core/src/keyboard.hpp index 142bf40e86..2ca7118d87 100644 --- a/core/src/keyboard.hpp +++ b/core/src/keyboard.hpp @@ -26,6 +26,7 @@ namespace core { std::u16string _keyboard_id; std::u16string _version_string; + // unused and deprecated core::path _folder_path; std::vector