From 58d8b98ad6dad346632f678f0ebc166efa393311 Mon Sep 17 00:00:00 2001 From: Christophe Henry Date: Tue, 15 Oct 2024 10:56:24 +0200 Subject: [PATCH 01/11] Expose convertCharset convenience function to controller Allow to convert from UTF-8 to whatever encoding the device supports --- res/controllers/engine-api.d.ts | 29 +++++++++++ .../legacy/controllerscriptenginelegacy.cpp | 6 ++- .../controllerscriptinterfacelegacy.cpp | 50 +++++++++++++++++++ .../legacy/controllerscriptinterfacelegacy.h | 17 +++++++ .../controllerscriptenginelegacy_test.cpp | 37 ++++++++++++++ 5 files changed, 137 insertions(+), 2 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index f406a745a01..b753f35f060 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -301,4 +301,33 @@ declare namespace engine { * SoftStart with low factors would take a while until sound is audible. [default = 1.0] */ function softStart(deck: number, activate: boolean, factor?: number): void; + + enum WellKnownCharsets { + Latin1, + ISO_8859_1, + Latin9, + ISO_8859_15, + UCS2, + ISO_10646_UCS_2 + } + + /** + * Converts a string into another charset. + * + * This function is useful to display text on a device that does not make use of UTF-8. + * Available charset names are listed here: http://www.iana.org/assignments/character-sets/character-sets.xhtml. + * Characters that are unsupported by target charset will be transformed to null character (0x00). + * @param targetCharset The charset to encode the string into. + * @param value The string to encode + * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error. + */ + function convertCharset(targetCharset: string, value: string): ArrayBuffer + + /** + * Version of {@link engine.convertCharset} to use with {@link engine.WellKnownCharsets}. + * @param targetCharset The charset to encode the string into. + * @param value The string to encode + * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error. + */ + function convertCharset(targetCharset: WellKnownCharsets, value: string): ArrayBuffer } diff --git a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp index 805cc90012e..f1d7ad607a4 100644 --- a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp @@ -338,8 +338,10 @@ bool ControllerScriptEngineLegacy::initialize() { ControllerScriptInterfaceLegacy* legacyScriptInterface = new ControllerScriptInterfaceLegacy(this, m_logger); - engineGlobalObject.setProperty( - "engine", m_pJSEngine->newQObject(legacyScriptInterface)); + auto engine = m_pJSEngine->newQObject(legacyScriptInterface); + auto meta = m_pJSEngine->newQMetaObject(&ControllerScriptInterfaceLegacy::staticMetaObject); + engine.setProperty("WellKnownCharsets", meta); + engineGlobalObject.setProperty("engine", m_pJSEngine->newQObject(legacyScriptInterface)); #ifdef MIXXX_USE_QML if (m_bQmlMode) { diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 2093cb7ffca..6cd04b4c531 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1,5 +1,10 @@ #include "controllerscriptinterfacelegacy.h" +#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) +#include +#else +#include +#endif #include #include "control/controlobject.h" @@ -1052,3 +1057,48 @@ void ControllerScriptInterfaceLegacy::softStart(int deck, bool activate, double // activate the ramping in scratchProcess() m_ramp[deck] = true; } + +QByteArray ControllerScriptInterfaceLegacy::convertCharset( + const ControllerScriptInterfaceLegacy::WellKnownCharsets targetCharset, + const QString& value) { + switch (targetCharset) { + case WellKnownCharsets::Latin1: + case WellKnownCharsets::ISO_8859_1: + return convertCharset(QStringLiteral("ISO-8859-1"), value); + case WellKnownCharsets::Latin9: + case WellKnownCharsets::ISO_8859_15: + return convertCharset(QStringLiteral("ISO-8859-15"), value); + case WellKnownCharsets::UCS2: + case WellKnownCharsets::ISO_10646_UCS_2: + return convertCharset(QStringLiteral("ISO-10646-UCS-2"), value); + default: + m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unknown charset specified")); + return QByteArray(); + } +} + +QByteArray ControllerScriptInterfaceLegacy::convertCharset( + const QString& targetCharset, const QString& value) { + QByteArray encoderNameArray = targetCharset.toUtf8(); +#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) + auto* pCodec = QTextCodec::codecForName(encoderNameArray); + if (!pCodec) { + m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); + return QByteArray(); + } + return pCodec->makeEncoder(QTextCodec::Flag::ConvertInvalidToNull)->fromUnicode(value); +#else +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + QAnyStringView encoderName = QAnyStringView(encoderNameArray); +#else + const char* encoderName = encoderNameArray.constData(); +#endif + QStringEncoder fromUtf16 = QStringEncoder( + encoderName, QStringEncoder::Flag::ConvertInvalidToNull); + if (!fromUtf16.isValid()) { + m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); + return QByteArray(); + } + return fromUtf16(value); +#endif +} diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h index b83ca2fa296..c2f1dbbb46e 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h @@ -17,6 +17,16 @@ class ConfigKey; class ControllerScriptInterfaceLegacy : public QObject { Q_OBJECT public: + enum class WellKnownCharsets { + Latin1, + ISO_8859_1, + Latin9, + ISO_8859_15, + UCS2, + ISO_10646_UCS_2 + }; + Q_ENUM(WellKnownCharsets) + ControllerScriptInterfaceLegacy(ControllerScriptEngineLegacy* m_pEngine, const RuntimeLoggingCategory& logger); @@ -72,6 +82,13 @@ class ControllerScriptInterfaceLegacy : public QObject { const double rate = -10.0); Q_INVOKABLE void softStart(const int deck, bool activate, double factor = 1.0); + Q_INVOKABLE QByteArray convertCharset( + const ControllerScriptInterfaceLegacy::WellKnownCharsets + targetCharset, + const QString& value); + + Q_INVOKABLE QByteArray convertCharset(const QString& targetCharset, const QString& value); + bool removeScriptConnection(const ScriptConnection& conn); /// Execute a ScriptConnection's JS callback void triggerScriptConnection(const ScriptConnection& conn); diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index aa88263fc63..cd5c9650b2f 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -658,6 +658,43 @@ TEST_F(ControllerScriptEngineLegacyTest, connectionExecutesWithCorrectThisObject EXPECT_DOUBLE_EQ(1.0, pass->get()); } +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUndefinedOnUnknownCharset) { + const auto result = evaluate("engine.convertCharset('NULL', 'Hello!')"); + + EXPECT_EQ(qjsvalue_cast(result), QByteArrayLiteral("")); +} + +template +QByteArray intByteArray(const char (&array)[N]) { + return QByteArray(array, N); +} + +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueWellKnown) { + const auto result = evaluate( + "engine.convertCharset(engine.WellKnownCharsets.Latin9, 'Hello!')"); + + // ISO-8859-15 ecoded 'Hello!' + EXPECT_EQ(qjsvalue_cast(result), + intByteArray({0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21})); +} + +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset) { + const auto result = evaluate("engine.convertCharset('ISO-8859-15', 'Hello!')"); + + // ISO-8859-15 ecoded 'Hello!' + EXPECT_EQ(qjsvalue_cast(result), + intByteArray({0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21})); +} + +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { + auto result = qjsvalue_cast( + evaluate("engine.convertCharset('ISO-8859-15', 'مايأ نامز')")); + + EXPECT_EQ(result, + intByteArray( + {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00})); +} + #ifdef MIXXX_USE_QML class MockScreenRender : public ControllerRenderingEngine { public: From d131d1c540c0ee522a2e436d8beab37d574d6d11 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:45:58 +0100 Subject: [PATCH 02/11] simplify ControllerScriptInterfaceLegacy::convertCharset --- res/controllers/engine-api.d.ts | 6 +- .../controllerscriptinterfacelegacy.cpp | 9 ++- .../controllerscriptenginelegacy_test.cpp | 58 +++++++++++++++---- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index b753f35f060..2314fc2d8a6 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -319,15 +319,13 @@ declare namespace engine { * Characters that are unsupported by target charset will be transformed to null character (0x00). * @param targetCharset The charset to encode the string into. * @param value The string to encode - * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error. + * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error or unavailable charset. */ function convertCharset(targetCharset: string, value: string): ArrayBuffer /** - * Version of {@link engine.convertCharset} to use with {@link engine.WellKnownCharsets}. - * @param targetCharset The charset to encode the string into. * @param value The string to encode - * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error. + * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error or unavailable charset. */ function convertCharset(targetCharset: WellKnownCharsets, value: string): ArrayBuffer } diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 6cd04b4c531..3a2dd8b0bba 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1079,18 +1079,21 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( QByteArray ControllerScriptInterfaceLegacy::convertCharset( const QString& targetCharset, const QString& value) { - QByteArray encoderNameArray = targetCharset.toUtf8(); #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) + QByteArray encoderNameArray = targetCharset.toUtf8(); auto* pCodec = QTextCodec::codecForName(encoderNameArray); if (!pCodec) { m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); return QByteArray(); } - return pCodec->makeEncoder(QTextCodec::Flag::ConvertInvalidToNull)->fromUnicode(value); + return std::unique_ptr( + pCodec->makeEncoder(QTextCodec::Flag::ConvertInvalidToNull)) + ->fromUnicode(value); #else #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) - QAnyStringView encoderName = QAnyStringView(encoderNameArray); + QAnyStringView encoderName = QAnyStringView(targetCharset); #else + QByteArray encoderNameArray = targetCharset.toUtf8(); const char* encoderName = encoderNameArray.constData(); #endif QStringEncoder fromUtf16 = QStringEncoder( diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index cd5c9650b2f..1b5e4c48a81 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -12,6 +14,7 @@ #include "control/controlobject.h" #include "control/controlpotmeter.h" +#include "controllers/scripting/legacy/controllerscriptinterfacelegacy.h" #ifdef MIXXX_USE_QML #include @@ -661,12 +664,7 @@ TEST_F(ControllerScriptEngineLegacyTest, connectionExecutesWithCorrectThisObject TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUndefinedOnUnknownCharset) { const auto result = evaluate("engine.convertCharset('NULL', 'Hello!')"); - EXPECT_EQ(qjsvalue_cast(result), QByteArrayLiteral("")); -} - -template -QByteArray intByteArray(const char (&array)[N]) { - return QByteArray(array, N); + EXPECT_EQ(qjsvalue_cast(result), QByteArrayView("")); } TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueWellKnown) { @@ -675,7 +673,7 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueWellKnown) { // ISO-8859-15 ecoded 'Hello!' EXPECT_EQ(qjsvalue_cast(result), - intByteArray({0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21})); + QByteArrayView::fromArray({'\x48', '\x65', '\x6c', '\x6c', '\x6f', '\x21'})); } TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset) { @@ -683,7 +681,7 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset // ISO-8859-15 ecoded 'Hello!' EXPECT_EQ(qjsvalue_cast(result), - intByteArray({0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21})); + QByteArrayView::fromArray({'\x48', '\x65', '\x6c', '\x6c', '\x6f', '\x21'})); } TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { @@ -691,8 +689,48 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { evaluate("engine.convertCharset('ISO-8859-15', 'مايأ نامز')")); EXPECT_EQ(result, - intByteArray( - {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00})); + QByteArrayView::fromArray( + {'\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00', '\x00'})); +} + +#define COMPLICATEDSTRINGLITERAL "Hello, 世界! שלום! こんにちは! 안녕하세요! 😊" + +static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownCharsets charset) { + // the expected length after conversion of COMPLICATEDSTRINGLITERAL + using enum ControllerScriptInterfaceLegacy::WellKnownCharsets; + switch (charset) { + case Latin9: + case ISO_8859_15: + return 32; + case Latin1: + case ISO_8859_1: + return 33; + case UCS2: + case ISO_10646_UCS_2: + return 68; + } + // unreachable (TODO assert false?) + return 0; +} + +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetAllWellKnownCharsets) { + QMetaEnum charsetEnumEntry = QMetaEnum::fromType< + ControllerScriptInterfaceLegacy::WellKnownCharsets>(); + + for (int i = 0; i < charsetEnumEntry.keyCount(); ++i) { + QString key = charsetEnumEntry.key(i); + auto enumValue = + static_cast( + charsetEnumEntry.value(i)); + QString source = QStringLiteral( + "engine.convertCharset(engine.WellKnownCharsets.%1, " + "'" COMPLICATEDSTRINGLITERAL "')") + .arg(key); + auto result = qjsvalue_cast(evaluate(source)); + EXPECT_EQ(result.size(), convertedCharsetForString(enumValue)) + << "Unexpected length of converted string for encoding: '" + << key.toStdString() << "'"; + } } #ifdef MIXXX_USE_QML From 57007c866b4268267713b73ce5cd93f0d688a729 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:34:46 +0100 Subject: [PATCH 03/11] feat: add a couple more encodings to enum, don't throw on invalid codec --- res/controllers/engine-api.d.ts | 8 ++++++-- .../controllerscriptinterfacelegacy.cpp | 19 +++++++++++++------ .../legacy/controllerscriptinterfacelegacy.h | 6 +++++- .../controllerscriptenginelegacy_test.cpp | 6 ++++++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index 2314fc2d8a6..d83bfa649e2 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -303,12 +303,16 @@ declare namespace engine { function softStart(deck: number, activate: boolean, factor?: number): void; enum WellKnownCharsets { + US_ASCII, Latin1, ISO_8859_1, Latin9, ISO_8859_15, - UCS2, - ISO_10646_UCS_2 + UCS2, // with prepended Byte-Order-Mark + ISO_10646_UCS_2, // with prepended Byte-Order-Mark + UTF_8, + UTF_16BE, + UTF_16LE, } /** diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 3a2dd8b0bba..4b344e2537d 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1062,6 +1062,8 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( const ControllerScriptInterfaceLegacy::WellKnownCharsets targetCharset, const QString& value) { switch (targetCharset) { + case WellKnownCharsets::US_ASCII: + return convertCharset(QStringLiteral("US-ASCII"), value); case WellKnownCharsets::Latin1: case WellKnownCharsets::ISO_8859_1: return convertCharset(QStringLiteral("ISO-8859-1"), value); @@ -1071,10 +1073,15 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( case WellKnownCharsets::UCS2: case WellKnownCharsets::ISO_10646_UCS_2: return convertCharset(QStringLiteral("ISO-10646-UCS-2"), value); - default: - m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unknown charset specified")); - return QByteArray(); - } + case WellKnownCharsets::UTF_8: + return convertCharset(QStringLiteral("UTF-8"), value); + case WellKnownCharsets::UTF_16BE: + return convertCharset(QStringLiteral("UTF-16BE"), value); + case WellKnownCharsets::UTF_16LE: + return convertCharset(QStringLiteral("UTF-16LE"), value); + } + m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unknown charset specified")); + return QByteArray(); } QByteArray ControllerScriptInterfaceLegacy::convertCharset( @@ -1083,7 +1090,7 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( QByteArray encoderNameArray = targetCharset.toUtf8(); auto* pCodec = QTextCodec::codecForName(encoderNameArray); if (!pCodec) { - m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); + qCWarning(m_logger) << "Unable to open encoder"; return QByteArray(); } return std::unique_ptr( @@ -1099,7 +1106,7 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( QStringEncoder fromUtf16 = QStringEncoder( encoderName, QStringEncoder::Flag::ConvertInvalidToNull); if (!fromUtf16.isValid()) { - m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); + qCWarning(m_logger) << "Unable to open encoder"; return QByteArray(); } return fromUtf16(value); diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h index c2f1dbbb46e..69659143961 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h @@ -18,12 +18,16 @@ class ControllerScriptInterfaceLegacy : public QObject { Q_OBJECT public: enum class WellKnownCharsets { + US_ASCII, Latin1, ISO_8859_1, Latin9, ISO_8859_15, UCS2, - ISO_10646_UCS_2 + ISO_10646_UCS_2, + UTF_8, + UTF_16BE, + UTF_16LE, }; Q_ENUM(WellKnownCharsets) diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index 1b5e4c48a81..def738cc997 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -699,12 +699,18 @@ static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownC // the expected length after conversion of COMPLICATEDSTRINGLITERAL using enum ControllerScriptInterfaceLegacy::WellKnownCharsets; switch (charset) { + case US_ASCII: case Latin9: case ISO_8859_15: return 32; case Latin1: case ISO_8859_1: return 33; + case UTF_8: + return 63; + case UTF_16BE: + case UTF_16LE: + return 66; case UCS2: case ISO_10646_UCS_2: return 68; From 01b80a540ccbcaae9827c535326cfb3cd019bbce Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:37:05 +0100 Subject: [PATCH 04/11] fix: don't convert invalid chars to null Returning part of a usable result instead of nullbytes since those likely terminate the string early or even corrupt the underlying binary message format the buffer is embedded in. --- .../scripting/legacy/controllerscriptinterfacelegacy.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 4b344e2537d..a4acba774cf 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1093,9 +1093,7 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( qCWarning(m_logger) << "Unable to open encoder"; return QByteArray(); } - return std::unique_ptr( - pCodec->makeEncoder(QTextCodec::Flag::ConvertInvalidToNull)) - ->fromUnicode(value); + return std::unique_ptr(pCodec->makeEncoder())->fromUnicode(value); #else #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) QAnyStringView encoderName = QAnyStringView(targetCharset); @@ -1103,8 +1101,7 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( QByteArray encoderNameArray = targetCharset.toUtf8(); const char* encoderName = encoderNameArray.constData(); #endif - QStringEncoder fromUtf16 = QStringEncoder( - encoderName, QStringEncoder::Flag::ConvertInvalidToNull); + QStringEncoder fromUtf16 = QStringEncoder(encoderName); if (!fromUtf16.isValid()) { qCWarning(m_logger) << "Unable to open encoder"; return QByteArray(); From f8767248d5506d326bef39069d538a322dca9d67 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:48:04 +0100 Subject: [PATCH 05/11] fix: test --- .../controllerscriptinterfacelegacy.cpp | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index a4acba774cf..4b32cdbe76e 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1063,38 +1063,29 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( const QString& value) { switch (targetCharset) { case WellKnownCharsets::US_ASCII: - return convertCharset(QStringLiteral("US-ASCII"), value); + return convertCharsetInternal(QStringLiteral("US-ASCII"), value); case WellKnownCharsets::Latin1: case WellKnownCharsets::ISO_8859_1: - return convertCharset(QStringLiteral("ISO-8859-1"), value); + return convertCharsetInternal(QStringLiteral("ISO-8859-1"), value); case WellKnownCharsets::Latin9: case WellKnownCharsets::ISO_8859_15: - return convertCharset(QStringLiteral("ISO-8859-15"), value); + return convertCharsetInternal(QStringLiteral("ISO-8859-15"), value); case WellKnownCharsets::UCS2: case WellKnownCharsets::ISO_10646_UCS_2: - return convertCharset(QStringLiteral("ISO-10646-UCS-2"), value); + return convertCharsetInternal(QStringLiteral("ISO-10646-UCS-2"), value); case WellKnownCharsets::UTF_8: - return convertCharset(QStringLiteral("UTF-8"), value); + return convertCharsetInternal(QStringLiteral("UTF-8"), value); case WellKnownCharsets::UTF_16BE: - return convertCharset(QStringLiteral("UTF-16BE"), value); + return convertCharsetInternal(QStringLiteral("UTF-16BE"), value); case WellKnownCharsets::UTF_16LE: - return convertCharset(QStringLiteral("UTF-16LE"), value); + return convertCharsetInternal(QStringLiteral("UTF-16LE"), value); } m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unknown charset specified")); return QByteArray(); } -QByteArray ControllerScriptInterfaceLegacy::convertCharset( +QByteArray ControllerScriptInterfaceLegacy::convertCharsetInternal( const QString& targetCharset, const QString& value) { -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) - QByteArray encoderNameArray = targetCharset.toUtf8(); - auto* pCodec = QTextCodec::codecForName(encoderNameArray); - if (!pCodec) { - qCWarning(m_logger) << "Unable to open encoder"; - return QByteArray(); - } - return std::unique_ptr(pCodec->makeEncoder())->fromUnicode(value); -#else #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) QAnyStringView encoderName = QAnyStringView(targetCharset); #else @@ -1103,9 +1094,8 @@ QByteArray ControllerScriptInterfaceLegacy::convertCharset( #endif QStringEncoder fromUtf16 = QStringEncoder(encoderName); if (!fromUtf16.isValid()) { - qCWarning(m_logger) << "Unable to open encoder"; + m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unable to open encoder")); return QByteArray(); } return fromUtf16(value); -#endif } From e2c74a9a3dc8d3d883bab8f22441b540ac032383 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:48:24 +0100 Subject: [PATCH 06/11] align closer with upstream --- .../scripting/legacy/controllerscriptinterfacelegacy.h | 5 +++-- src/test/controllerscriptenginelegacy_test.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h index 69659143961..6184723780f 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h @@ -91,8 +91,6 @@ class ControllerScriptInterfaceLegacy : public QObject { targetCharset, const QString& value); - Q_INVOKABLE QByteArray convertCharset(const QString& targetCharset, const QString& value); - bool removeScriptConnection(const ScriptConnection& conn); /// Execute a ScriptConnection's JS callback void triggerScriptConnection(const ScriptConnection& conn); @@ -105,6 +103,9 @@ class ControllerScriptInterfaceLegacy : public QObject { const QString& name, const QJSValue& callback, bool skipSuperseded = false); + + QByteArray convertCharsetInternal(const QString& targetCharset, const QString& value); + QHash m_controlCache; ControlObjectScript* getControlObjectScript(const QString& group, const QString& name); diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index def738cc997..9d48025e681 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -687,10 +687,10 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { auto result = qjsvalue_cast( evaluate("engine.convertCharset('ISO-8859-15', 'مايأ نامز')")); - + char sub = '\x1A'; // ASCII/Latin9 SUB character EXPECT_EQ(result, QByteArrayView::fromArray( - {'\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00', '\x00'})); + {sub, sub, sub, sub, '\x20', sub, sub, sub, sub})); } #define COMPLICATEDSTRINGLITERAL "Hello, 世界! שלום! こんにちは! 안녕하세요! 😊" From e2d6ab22a27cd474f74ad68e0035199aa85e5f77 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:44:59 +0100 Subject: [PATCH 07/11] feat: add more sensible WellKnownCharsets --- res/controllers/engine-api.d.ts | 35 ++++++++--- .../controllerscriptinterfacelegacy.cpp | 62 ++++++++++++++----- .../legacy/controllerscriptinterfacelegacy.h | 32 +++++++--- .../controllerscriptenginelegacy_test.cpp | 46 +++++++++----- 4 files changed, 128 insertions(+), 47 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index d83bfa649e2..fc04584d19f 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -303,16 +303,31 @@ declare namespace engine { function softStart(deck: number, activate: boolean, factor?: number): void; enum WellKnownCharsets { - US_ASCII, - Latin1, - ISO_8859_1, - Latin9, - ISO_8859_15, - UCS2, // with prepended Byte-Order-Mark - ISO_10646_UCS_2, // with prepended Byte-Order-Mark - UTF_8, - UTF_16BE, - UTF_16LE, + ASCII, // American Standard Code for Information Interchange (7-Bit) + UTF_8, // Unicode Transformation Format (8-Bit) + UTF_16LE, // UTF-16 for Little-Endian devices (ARM, x86) + UTF_16BE, // UTF-16 for Big-Endian devices (MIPS, PPC) + UTF_32LE, // UTF-32 for Little-Endian devices (ARM, x86) + UTF_32BE, // UTF-32 for Big-Endian devices (MIPS, PPC) + CentralEurope, // Windows_1250 which includes all characters of ISO_8859_2 + Cyrillic, // Windows_1251 which includes all characters of ISO_8859_5 + Latin1, // Windows_1252 which includes all characters of ISO_8859_1 + Greek, // Windows_1253 which includes all characters of ISO_8859_7 + Turkish, // Windows_1254 which includes all characters of ISO_8859_9 + Hebrew, // Windows_1255 which includes all characters of ISO_8859_8 + Arabic, // Windows_1256 which includes all characters of ISO_8859_6 + Baltic, // Windows_1257 which includes all characters of ISO_8859_13 + Vietnamese, // Windows_1258 which includes all characters of ISO_8859_14 + Latin9, // ISO_8859_15 + Shift_JIS, // Japanese Industrial Standard (JIS X 0208) + EUC_JP, // Extended Unix Code for Japanese + EUC_KR, // Extended Unix Code for Korean + Big5_HKSCS, // Includes all characters of Big5 and the Hong Kong Supplementary Character Set (HKSCS) + KOI8_U, // Includes all characters of KOI8_R for Russian language and adds Ukrainian language characters + UCS2, // Universal Character Set (2-Byte) ISO_10646 + SCSU, // Standard Compression Scheme for Unicode + BOCU_1, // Binary Ordered Compression for Unicode + CESU_8 // Compatibility Encoding Scheme for UTF-16 (8-Bit) } /** diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 4b32cdbe76e..62e6aa511b5 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1061,24 +1061,58 @@ void ControllerScriptInterfaceLegacy::softStart(int deck, bool activate, double QByteArray ControllerScriptInterfaceLegacy::convertCharset( const ControllerScriptInterfaceLegacy::WellKnownCharsets targetCharset, const QString& value) { + using enum WellKnownCharsets; switch (targetCharset) { - case WellKnownCharsets::US_ASCII: + case ASCII: return convertCharsetInternal(QStringLiteral("US-ASCII"), value); - case WellKnownCharsets::Latin1: - case WellKnownCharsets::ISO_8859_1: - return convertCharsetInternal(QStringLiteral("ISO-8859-1"), value); - case WellKnownCharsets::Latin9: - case WellKnownCharsets::ISO_8859_15: - return convertCharsetInternal(QStringLiteral("ISO-8859-15"), value); - case WellKnownCharsets::UCS2: - case WellKnownCharsets::ISO_10646_UCS_2: - return convertCharsetInternal(QStringLiteral("ISO-10646-UCS-2"), value); - case WellKnownCharsets::UTF_8: + case UTF_8: return convertCharsetInternal(QStringLiteral("UTF-8"), value); - case WellKnownCharsets::UTF_16BE: - return convertCharsetInternal(QStringLiteral("UTF-16BE"), value); - case WellKnownCharsets::UTF_16LE: + case UTF_16LE: return convertCharsetInternal(QStringLiteral("UTF-16LE"), value); + case UTF_16BE: + return convertCharsetInternal(QStringLiteral("UTF-16BE"), value); + case UTF_32LE: + return convertCharsetInternal(QStringLiteral("UTF-32LE"), value); + case UTF_32BE: + return convertCharsetInternal(QStringLiteral("UTF-32BE"), value); + case CentralEurope: + return convertCharsetInternal(QStringLiteral("windows-1250"), value); + case Cyrillic: + return convertCharsetInternal(QStringLiteral("windows-1251"), value); + case Latin1: + return convertCharsetInternal(QStringLiteral("windows-1252"), value); + case Greek: + return convertCharsetInternal(QStringLiteral("windows-1253"), value); + case Turkish: + return convertCharsetInternal(QStringLiteral("windows-1254"), value); + case Hebrew: + return convertCharsetInternal(QStringLiteral("windows-1255"), value); + case Arabic: + return convertCharsetInternal(QStringLiteral("windows-1256"), value); + case Baltic: + return convertCharsetInternal(QStringLiteral("windows-1257"), value); + case Vietnamese: + return convertCharsetInternal(QStringLiteral("windows-1258"), value); + case Latin9: + return convertCharsetInternal(QStringLiteral("ISO-8859-15"), value); + case Shift_JIS: + return convertCharsetInternal(QStringLiteral("Shift_JIS"), value); + case EUC_JP: + return convertCharsetInternal(QStringLiteral("EUC-JP"), value); + case EUC_KR: + return convertCharsetInternal(QStringLiteral("EUC-KR"), value); + case Big5_HKSCS: + return convertCharsetInternal(QStringLiteral("Big5-HKSCS"), value); + case KOI8_U: + return convertCharsetInternal(QStringLiteral("KOI8-U"), value); + case UCS2: + return convertCharsetInternal(QStringLiteral("ISO-10646-UCS-2"), value); + case SCSU: + return convertCharsetInternal(QStringLiteral("SCSU"), value); + case BOCU_1: + return convertCharsetInternal(QStringLiteral("BOCU-1"), value); + case CESU_8: + return convertCharsetInternal(QStringLiteral("CESU-8"), value); } m_pScriptEngineLegacy->logOrThrowError(QStringLiteral("Unknown charset specified")); return QByteArray(); diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h index 6184723780f..48cd1a700d7 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h @@ -17,17 +17,35 @@ class ConfigKey; class ControllerScriptInterfaceLegacy : public QObject { Q_OBJECT public: + // NOTE: these enumerator names are exposed to the JS engine! Removal/Changing of + // any name is likely breaking. Only add more and only remove enumerators if + // they're broken to begin with. enum class WellKnownCharsets { - US_ASCII, + ASCII, + UTF_8, + UTF_16LE, + UTF_16BE, + UTF_32LE, + UTF_32BE, + CentralEurope, + Cyrillic, Latin1, - ISO_8859_1, + Greek, + Turkish, + Hebrew, + Arabic, + Baltic, + Vietnamese, Latin9, - ISO_8859_15, + Shift_JIS, + EUC_JP, + EUC_KR, + Big5_HKSCS, + KOI8_U, UCS2, - ISO_10646_UCS_2, - UTF_8, - UTF_16BE, - UTF_16LE, + SCSU, + BOCU_1, + CESU_8 }; Q_ENUM(WellKnownCharsets) diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index 9d48025e681..1e0d9e587d2 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -661,12 +661,6 @@ TEST_F(ControllerScriptEngineLegacyTest, connectionExecutesWithCorrectThisObject EXPECT_DOUBLE_EQ(1.0, pass->get()); } -TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUndefinedOnUnknownCharset) { - const auto result = evaluate("engine.convertCharset('NULL', 'Hello!')"); - - EXPECT_EQ(qjsvalue_cast(result), QByteArrayView("")); -} - TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueWellKnown) { const auto result = evaluate( "engine.convertCharset(engine.WellKnownCharsets.Latin9, 'Hello!')"); @@ -699,23 +693,43 @@ static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownC // the expected length after conversion of COMPLICATEDSTRINGLITERAL using enum ControllerScriptInterfaceLegacy::WellKnownCharsets; switch (charset) { - case US_ASCII: - case Latin9: - case ISO_8859_15: - return 32; - case Latin1: - case ISO_8859_1: - return 33; case UTF_8: return 63; - case UTF_16BE: case UTF_16LE: + case UTF_16BE: return 66; + case UTF_32LE: + case UTF_32BE: + return 128; + case ASCII: + case CentralEurope: + case Cyrillic: + case Latin1: + case Greek: + case Turkish: + case Hebrew: + case Arabic: + case Baltic: + case Vietnamese: + case Latin9: + case KOI8_U: + return 32; + case Shift_JIS: + case EUC_JP: + case EUC_KR: + case Big5_HKSCS: + return 49; case UCS2: - case ISO_10646_UCS_2: return 68; + case SCSU: + return 51; + case BOCU_1: + return 53; + case CESU_8: + return 65; } - // unreachable (TODO assert false?) + // unreachable, but gtest does not offer a way to assert this here. + // returning 0 will almost certainly also result in a failure. return 0; } From e0943990d661f8f1fb7836fa6772767c2acab267 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 1 Dec 2024 19:01:57 +0100 Subject: [PATCH 08/11] refactor: replace irrelevant test with more meaningfull --- .../controllerscriptenginelegacy_test.cpp | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index 1e0d9e587d2..618513ba9b4 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -661,32 +661,48 @@ TEST_F(ControllerScriptEngineLegacyTest, connectionExecutesWithCorrectThisObject EXPECT_DOUBLE_EQ(1.0, pass->get()); } -TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueWellKnown) { - const auto result = evaluate( - "engine.convertCharset(engine.WellKnownCharsets.Latin9, 'Hello!')"); - - // ISO-8859-15 ecoded 'Hello!' - EXPECT_EQ(qjsvalue_cast(result), - QByteArrayView::fromArray({'\x48', '\x65', '\x6c', '\x6c', '\x6f', '\x21'})); -} TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset) { - const auto result = evaluate("engine.convertCharset('ISO-8859-15', 'Hello!')"); + const auto result = evaluate( + "engine.convertCharset(engine.WellKnownCharsets.Latin9, 'Hello!')"); - // ISO-8859-15 ecoded 'Hello!' EXPECT_EQ(qjsvalue_cast(result), QByteArrayView::fromArray({'\x48', '\x65', '\x6c', '\x6c', '\x6f', '\x21'})); } TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { auto result = qjsvalue_cast( - evaluate("engine.convertCharset('ISO-8859-15', 'مايأ نامز')")); + evaluate("engine.convertCharset(engine.WellKnownCharsets.Latin9, 'مايأ نامز')")); char sub = '\x1A'; // ASCII/Latin9 SUB character EXPECT_EQ(result, QByteArrayView::fromArray( {sub, sub, sub, sub, '\x20', sub, sub, sub, sub})); } +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetMultiByteEncoding) { + auto result = qjsvalue_cast( + evaluate("engine.convertCharset(engine.WellKnownCharsets.UTF_16LE, 'مايأ نامز')")); + EXPECT_EQ(result, + QByteArrayView::fromArray({'\x45', + '\x06', + '\x27', + '\x06', + '\x4A', + '\x06', + '\x23', + '\x06', + '\x20', + '\x00', + '\x46', + '\x06', + '\x27', + '\x06', + '\x45', + '\x06', + '\x32', + '\x06'})); +} + #define COMPLICATEDSTRINGLITERAL "Hello, 世界! שלום! こんにちは! 안녕하세요! 😊" static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownCharsets charset) { From d07e6293b04368a1147cc757eb6b7caa0f09a7a5 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Sun, 1 Dec 2024 19:04:46 +0100 Subject: [PATCH 09/11] fix: remove private API doc --- res/controllers/engine-api.d.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index fc04584d19f..99c0482d825 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -332,18 +332,9 @@ declare namespace engine { /** * Converts a string into another charset. - * - * This function is useful to display text on a device that does not make use of UTF-8. - * Available charset names are listed here: http://www.iana.org/assignments/character-sets/character-sets.xhtml. - * Characters that are unsupported by target charset will be transformed to null character (0x00). - * @param targetCharset The charset to encode the string into. - * @param value The string to encode - * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error or unavailable charset. - */ - function convertCharset(targetCharset: string, value: string): ArrayBuffer - - /** + * * @param value The string to encode + * @param targetCharset The charset to encode the string into. * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error or unavailable charset. */ function convertCharset(targetCharset: WellKnownCharsets, value: string): ArrayBuffer From 424111a2cf6b02abbde49a8ffe7604bf4576d863 Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:47:52 +0100 Subject: [PATCH 10/11] fix: remove unnecessary include --- .../scripting/legacy/controllerscriptinterfacelegacy.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index 62e6aa511b5..b63108a2d13 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1,10 +1,6 @@ #include "controllerscriptinterfacelegacy.h" -#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) -#include -#else #include -#endif #include #include "control/controlobject.h" From 3101effca788106fab958b2628d9ff946bc9e27c Mon Sep 17 00:00:00 2001 From: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:31:20 +0100 Subject: [PATCH 11/11] refactor: rename `WellKnownCharsets` to `Charset` --- res/controllers/engine-api.d.ts | 4 ++-- .../legacy/controllerscriptenginelegacy.cpp | 2 +- .../legacy/controllerscriptinterfacelegacy.cpp | 4 ++-- .../legacy/controllerscriptinterfacelegacy.h | 6 +++--- src/test/controllerscriptenginelegacy_test.cpp | 18 +++++++++--------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/res/controllers/engine-api.d.ts b/res/controllers/engine-api.d.ts index 99c0482d825..ee7cd92fd61 100644 --- a/res/controllers/engine-api.d.ts +++ b/res/controllers/engine-api.d.ts @@ -302,7 +302,7 @@ declare namespace engine { */ function softStart(deck: number, activate: boolean, factor?: number): void; - enum WellKnownCharsets { + enum Charset { ASCII, // American Standard Code for Information Interchange (7-Bit) UTF_8, // Unicode Transformation Format (8-Bit) UTF_16LE, // UTF-16 for Little-Endian devices (ARM, x86) @@ -337,5 +337,5 @@ declare namespace engine { * @param targetCharset The charset to encode the string into. * @returns The converted String as an array of bytes. Will return an empty buffer on conversion error or unavailable charset. */ - function convertCharset(targetCharset: WellKnownCharsets, value: string): ArrayBuffer + function convertCharset(targetCharset: Charset, value: string): ArrayBuffer } diff --git a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp index f1d7ad607a4..e8bcf81c408 100644 --- a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp @@ -340,7 +340,7 @@ bool ControllerScriptEngineLegacy::initialize() { auto engine = m_pJSEngine->newQObject(legacyScriptInterface); auto meta = m_pJSEngine->newQMetaObject(&ControllerScriptInterfaceLegacy::staticMetaObject); - engine.setProperty("WellKnownCharsets", meta); + engine.setProperty("Charset", meta); engineGlobalObject.setProperty("engine", m_pJSEngine->newQObject(legacyScriptInterface)); #ifdef MIXXX_USE_QML diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp index b63108a2d13..611f9b26f95 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.cpp @@ -1055,9 +1055,9 @@ void ControllerScriptInterfaceLegacy::softStart(int deck, bool activate, double } QByteArray ControllerScriptInterfaceLegacy::convertCharset( - const ControllerScriptInterfaceLegacy::WellKnownCharsets targetCharset, + const ControllerScriptInterfaceLegacy::Charset targetCharset, const QString& value) { - using enum WellKnownCharsets; + using enum Charset; switch (targetCharset) { case ASCII: return convertCharsetInternal(QStringLiteral("US-ASCII"), value); diff --git a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h index 48cd1a700d7..76e44f72e6a 100644 --- a/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h +++ b/src/controllers/scripting/legacy/controllerscriptinterfacelegacy.h @@ -20,7 +20,7 @@ class ControllerScriptInterfaceLegacy : public QObject { // NOTE: these enumerator names are exposed to the JS engine! Removal/Changing of // any name is likely breaking. Only add more and only remove enumerators if // they're broken to begin with. - enum class WellKnownCharsets { + enum class Charset { ASCII, UTF_8, UTF_16LE, @@ -47,7 +47,7 @@ class ControllerScriptInterfaceLegacy : public QObject { BOCU_1, CESU_8 }; - Q_ENUM(WellKnownCharsets) + Q_ENUM(Charset) ControllerScriptInterfaceLegacy(ControllerScriptEngineLegacy* m_pEngine, const RuntimeLoggingCategory& logger); @@ -105,7 +105,7 @@ class ControllerScriptInterfaceLegacy : public QObject { Q_INVOKABLE void softStart(const int deck, bool activate, double factor = 1.0); Q_INVOKABLE QByteArray convertCharset( - const ControllerScriptInterfaceLegacy::WellKnownCharsets + const ControllerScriptInterfaceLegacy::Charset targetCharset, const QString& value); diff --git a/src/test/controllerscriptenginelegacy_test.cpp b/src/test/controllerscriptenginelegacy_test.cpp index 618513ba9b4..ab7ff36b72b 100644 --- a/src/test/controllerscriptenginelegacy_test.cpp +++ b/src/test/controllerscriptenginelegacy_test.cpp @@ -664,7 +664,7 @@ TEST_F(ControllerScriptEngineLegacyTest, connectionExecutesWithCorrectThisObject TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset) { const auto result = evaluate( - "engine.convertCharset(engine.WellKnownCharsets.Latin9, 'Hello!')"); + "engine.convertCharset(engine.Charset.Latin9, 'Hello!')"); EXPECT_EQ(qjsvalue_cast(result), QByteArrayView::fromArray({'\x48', '\x65', '\x6c', '\x6c', '\x6f', '\x21'})); @@ -672,7 +672,7 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetCorrectValueStringCharset TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { auto result = qjsvalue_cast( - evaluate("engine.convertCharset(engine.WellKnownCharsets.Latin9, 'مايأ نامز')")); + evaluate("engine.convertCharset(engine.Charset.Latin9, 'مايأ نامز')")); char sub = '\x1A'; // ASCII/Latin9 SUB character EXPECT_EQ(result, QByteArrayView::fromArray( @@ -681,7 +681,7 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetUnsupportedChars) { TEST_F(ControllerScriptEngineLegacyTest, convertCharsetMultiByteEncoding) { auto result = qjsvalue_cast( - evaluate("engine.convertCharset(engine.WellKnownCharsets.UTF_16LE, 'مايأ نامز')")); + evaluate("engine.convertCharset(engine.Charset.UTF_16LE, 'مايأ نامز')")); EXPECT_EQ(result, QByteArrayView::fromArray({'\x45', '\x06', @@ -705,9 +705,9 @@ TEST_F(ControllerScriptEngineLegacyTest, convertCharsetMultiByteEncoding) { #define COMPLICATEDSTRINGLITERAL "Hello, 世界! שלום! こんにちは! 안녕하세요! 😊" -static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownCharsets charset) { +static int convertedCharsetForString(ControllerScriptInterfaceLegacy::Charset charset) { // the expected length after conversion of COMPLICATEDSTRINGLITERAL - using enum ControllerScriptInterfaceLegacy::WellKnownCharsets; + using enum ControllerScriptInterfaceLegacy::Charset; switch (charset) { case UTF_8: return 63; @@ -749,17 +749,17 @@ static int convertedCharsetForString(ControllerScriptInterfaceLegacy::WellKnownC return 0; } -TEST_F(ControllerScriptEngineLegacyTest, convertCharsetAllWellKnownCharsets) { +TEST_F(ControllerScriptEngineLegacyTest, convertCharsetAllCharset) { QMetaEnum charsetEnumEntry = QMetaEnum::fromType< - ControllerScriptInterfaceLegacy::WellKnownCharsets>(); + ControllerScriptInterfaceLegacy::Charset>(); for (int i = 0; i < charsetEnumEntry.keyCount(); ++i) { QString key = charsetEnumEntry.key(i); auto enumValue = - static_cast( + static_cast( charsetEnumEntry.value(i)); QString source = QStringLiteral( - "engine.convertCharset(engine.WellKnownCharsets.%1, " + "engine.convertCharset(engine.Charset.%1, " "'" COMPLICATEDSTRINGLITERAL "')") .arg(key); auto result = qjsvalue_cast(evaluate(source));