diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index caac7696a5..395683d043 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -1211,8 +1211,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" @@ -3732,8 +3735,11 @@ set_source_files_properties( "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index 6f1d681359..70dde5ca09 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -1538,6 +1538,15 @@ true + + true + + + true + + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 7029bfed70..76dce8451d 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -2272,6 +2272,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 47e9214d09..73191b956a 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -1538,6 +1538,15 @@ true + + true + + + true + + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index 32e0c670d3..f9c09729b3 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -2272,6 +2272,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 49ac3d972f..11540368ed 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -1070,8 +1070,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" @@ -3274,8 +3277,11 @@ set_source_files_properties( "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index e0c4545c40..b0be6a8ecb 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -1357,6 +1357,15 @@ true + + true + + + true + + + true + true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index fad4989f63..8a6aeab3d4 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -1948,6 +1948,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 35aaefb72f..67c51dbb6a 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -1103,8 +1103,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" @@ -3460,8 +3463,11 @@ set_source_files_properties( "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index f3bdde7465..fa6b36b5ad 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -1365,6 +1365,15 @@ true + + true + + + true + + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 0fe8b36cd1..e6804e8cd7 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -2023,6 +2023,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index ffc939e0b7..e928a8a358 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -1365,6 +1365,15 @@ true + + true + + + true + + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index d45df19419..efa8516045 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -2023,6 +2023,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj index 4a9a026217..07366eb352 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj @@ -391,6 +391,15 @@ true + + true + + + true + + + true + true diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters index 62ed01bcd4..d7c6eba364 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters @@ -373,6 +373,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 179362384d..615876fb03 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -1074,8 +1074,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" @@ -3358,8 +3361,11 @@ set_source_files_properties( "../../../../../modules/juce_core/text/juce_CharacterFunctions.h" "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF8_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF16_test.cpp" "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" + "../../../../../modules/juce_core/text/juce_CharPointer_UTF32_test.cpp" "../../../../../modules/juce_core/text/juce_Identifier.cpp" "../../../../../modules/juce_core/text/juce_Identifier.h" "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 376f5b0c44..21ddf0af4f 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -1357,6 +1357,15 @@ true + + true + + + true + + + true + true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 442642a432..8dfcb4fc88 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -1978,6 +1978,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index c2ab74e706..cf7123264a 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -508,6 +508,15 @@ true + + true + + + true + + + true + true diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index 65ecd8be7b..f1096edf0e 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -826,6 +826,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj index 60528b4ce6..c08062d0bc 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj @@ -508,6 +508,15 @@ true + + true + + + true + + + true + true diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters index 5d29a07652..04aa8b1112 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters @@ -826,6 +826,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index e231c78418..ee652babf7 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -1373,6 +1373,15 @@ true + + true + + + true + + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index fac0ff7ff9..4e021c4aeb 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -2044,6 +2044,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index e33bb5e735..d3ac59a4de 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -1373,6 +1373,15 @@ true + + true + + + true + + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 679ddd5d78..258e625d23 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -2044,6 +2044,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj index 3ef5abd964..32cf266d79 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj @@ -1356,6 +1356,15 @@ true + + true + + + true + + + true + true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters index 68b921b926..64f6fa7ab4 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters @@ -1975,6 +1975,15 @@ JUCE Modules\juce_core\text + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + + + JUCE Modules\juce_core\text + JUCE Modules\juce_core\text diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index 569ee83710..a61a55d0d2 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -295,6 +295,9 @@ #include "containers/juce_FixedSizeFunction_test.cpp" #include "javascript/juce_JSONSerialisation_test.cpp" #include "memory/juce_SharedResourcePointer_test.cpp" + #include "text/juce_CharPointer_UTF8_test.cpp" + #include "text/juce_CharPointer_UTF16_test.cpp" + #include "text/juce_CharPointer_UTF32_test.cpp" #if JUCE_MAC || JUCE_IOS #include "native/juce_ObjCHelpers_mac_test.mm" #endif diff --git a/modules/juce_core/text/juce_CharPointer_ASCII.h b/modules/juce_core/text/juce_CharPointer_ASCII.h index 4f8fc0c011..c62f108a43 100644 --- a/modules/juce_core/text/juce_CharPointer_ASCII.h +++ b/modules/juce_core/text/juce_CharPointer_ASCII.h @@ -366,7 +366,7 @@ public: /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((unsigned int) character) < (unsigned int) 128; + return CharacterFunctions::isAscii (character); } /** Returns true if this data contains a valid string in this encoding. */ diff --git a/modules/juce_core/text/juce_CharPointer_UTF16.h b/modules/juce_core/text/juce_CharPointer_UTF16.h index 1b588c8bdd..7a0f82243d 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF16.h +++ b/modules/juce_core/text/juce_CharPointer_UTF16.h @@ -438,35 +438,32 @@ public: /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - auto n = (uint32) character; - return n < 0x10ffff && (n < 0xd800 || n > 0xdfff); + return CharacterFunctions::isNonSurrogateCodePoint (character); } /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) + static bool isValidString (const CharType* codeUnits, int maxBytesToRead) { - maxBytesToRead /= (int) sizeof (CharType); + const auto maxCodeUnitsToRead = (size_t) maxBytesToRead / sizeof (CharType); - while (--maxBytesToRead >= 0 && *dataToTest != 0) + for (size_t codeUnitIndex = 0; codeUnitIndex < maxCodeUnitsToRead; ++codeUnitIndex) { - auto n = (uint32) (uint16) *dataToTest++; + const auto c = toCodePoint (codeUnits[codeUnitIndex]); - if (n >= 0xd800) - { - if (n > 0x10ffff) - return false; + if (c == 0) + return true; - if (n <= 0xdfff) - { - if (n > 0xdc00) - return false; + if (canRepresent (c)) + continue; - auto nextChar = (uint32) (uint16) *dataToTest++; + if (! CharacterFunctions::isHighSurrogate (c)) + return false; - if (nextChar < 0xdc00 || nextChar > 0xdfff) - return false; - } - } + if (++codeUnitIndex >= maxCodeUnitsToRead) + return false; + + if (! CharacterFunctions::isLowSurrogate (toCodePoint (codeUnits[codeUnitIndex]))) + return false; } return true; @@ -527,6 +524,16 @@ private: return n; } + + static inline uint32 toUint32 (CharType c) noexcept + { + return (uint32) (uint16) c; + } + + static inline juce_wchar toCodePoint (CharType c) noexcept + { + return (juce_wchar) toUint32 (c); + } }; } // namespace juce diff --git a/modules/juce_core/text/juce_CharPointer_UTF16_test.cpp b/modules/juce_core/text/juce_CharPointer_UTF16_test.cpp new file mode 100644 index 0000000000..defbfd8733 --- /dev/null +++ b/modules/juce_core/text/juce_CharPointer_UTF16_test.cpp @@ -0,0 +1,118 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +class CharPointer_UTF16Test final : public UnitTest +{ +public: + CharPointer_UTF16Test() : UnitTest { "CharPointer_UTF16Test", UnitTestCategories::text } {} + + void runTest() final + { + const auto toCharType = [] (const std::vector& str) + { + return reinterpret_cast (str.data()); + }; + + const auto getNumBytes = [] (const auto& str) + { + return (int) (sizeof (CharPointer_UTF16::CharType) * str.size()); + }; + + beginTest ("String validation - empty string / null-terminator"); + { + const std::vector string { 0x0 }; + expect (CharPointer_UTF16::isValidString (string.data(), getNumBytes (string))); + } + + beginTest ("String validation - ascii"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x21, 0x0 }; // Test! + expect (CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - 2-byte code points"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x20ac, 0x0 }; // Test€ + expect (CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - surrogate pairs"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0xd83d, 0xde03, 0x0 }; // TestđŸ˜ƒ + expect (CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - high-surrogate without a low-surrogate"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0xd83d, 0x0 }; + expect (! CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - low-surrogate without a high-surrogate"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0xde03, 0x0 }; + expect (! CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - characters after a null terminator are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x0, 0xde03 }; + expect (CharPointer_UTF16::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - characters exceeding max bytes are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0xde03 }; + expect (CharPointer_UTF16::isValidString (toCharType (string), 8)); + } + + beginTest ("String validation - all unicode characters"); + { + for (uint32_t c = 0; c < 0x110000; ++c) + { + std::array string = {}; + CharPointer_UTF16 utf16 { string.data() }; + utf16.write ((juce_wchar) c); + expect (CharPointer_UTF16::isValidString (string.data(), 4) == CharPointer_UTF32::canRepresent ((juce_wchar) c)); + } + } + } +}; + +static CharPointer_UTF16Test charPointer_UTF16Test; + +} // namespace juce diff --git a/modules/juce_core/text/juce_CharPointer_UTF32.h b/modules/juce_core/text/juce_CharPointer_UTF32.h index bfe1ad43b6..2eabf0b12c 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF32.h +++ b/modules/juce_core/text/juce_CharPointer_UTF32.h @@ -357,17 +357,24 @@ public: /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((uint32) character) < (uint32) 0x10ffff; + return CharacterFunctions::isNonSurrogateCodePoint (character); } /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) + static bool isValidString (const CharType* codeUnits, int maxBytesToRead) { - maxBytesToRead /= (int) sizeof (CharType); + const auto maxCodeUnitsToRead = (size_t) maxBytesToRead / sizeof (CharType); - while (--maxBytesToRead >= 0 && *dataToTest != 0) - if (! canRepresent (*dataToTest++)) + for (size_t codeUnitIndex = 0; codeUnitIndex < maxCodeUnitsToRead; ++codeUnitIndex) + { + const auto c = codeUnits[codeUnitIndex]; + + if (c == 0) + return true; + + if (! canRepresent (c)) return false; + } return true; } diff --git a/modules/juce_core/text/juce_CharPointer_UTF32_test.cpp b/modules/juce_core/text/juce_CharPointer_UTF32_test.cpp new file mode 100644 index 0000000000..b46788c459 --- /dev/null +++ b/modules/juce_core/text/juce_CharPointer_UTF32_test.cpp @@ -0,0 +1,108 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +class CharPointer_UTF32Test final : public UnitTest +{ +public: + CharPointer_UTF32Test() : UnitTest { "CharPointer_UTF32", UnitTestCategories::text } {} + + void runTest() final + { + const auto toCharType = [] (const std::vector& str) + { + return reinterpret_cast (str.data()); + }; + + const auto getNumBytes = [] (const auto& str) + { + return (int) (sizeof (CharPointer_UTF32::CharType) * str.size()); + }; + + beginTest ("String validation - empty string / null-terminator"); + { + const std::vector string { 0x0 }; + expect (CharPointer_UTF32::isValidString (string.data(), getNumBytes (string))); + } + + beginTest ("String validation - ascii"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x21, 0x0 }; // Test! + expect (CharPointer_UTF32::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - 2-byte code points"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x20ac, 0x0 }; // Test€ + expect (CharPointer_UTF32::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - maximum code point"); + { + const std::vector string1 { 0x54, 0x65, 0x73, 0x74, 0x10ffff, 0x0 }; + expect (CharPointer_UTF32::isValidString (toCharType (string1), getNumBytes (string1))); + + const std::vector string2 { 0x54, 0x65, 0x73, 0x74, 0x110000, 0x0 }; + expect (! CharPointer_UTF32::isValidString (toCharType (string2), getNumBytes (string2))); + } + + beginTest ("String validation - characters after a null terminator are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x0, 0x110000 }; + expect (CharPointer_UTF32::isValidString (toCharType (string), getNumBytes (string))); + } + + beginTest ("String validation - characters exceeding max bytes are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x110000 }; + expect (CharPointer_UTF32::isValidString (toCharType (string), 8)); + } + + beginTest ("String validation - surrogate code points are invalid"); + { + const std::vector highSurrogate { 0xd800 }; + expect (! CharPointer_UTF32::isValidString (toCharType (highSurrogate), getNumBytes (highSurrogate))); + + const std::vector lowSurrogate { 0xdfff }; + expect (! CharPointer_UTF32::isValidString (toCharType (lowSurrogate), getNumBytes (lowSurrogate))); + } + } +}; + + +static CharPointer_UTF32Test charPointer_UTF32Test; + +} // namespace juce diff --git a/modules/juce_core/text/juce_CharPointer_UTF8.h b/modules/juce_core/text/juce_CharPointer_UTF8.h index ca06656805..a13ff2cb7b 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF8.h +++ b/modules/juce_core/text/juce_CharPointer_UTF8.h @@ -497,45 +497,80 @@ public: /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((uint32) character) < (uint32) 0x10ffff; + return CharacterFunctions::isNonSurrogateCodePoint (character); } /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) + static bool isValidString (const CharType* codeUnits, int maxBytesToRead) { - while (--maxBytesToRead >= 0 && *dataToTest != 0) + const auto maxCodeUnitsToRead = (size_t) maxBytesToRead / sizeof (CharType); + + for (size_t codeUnitIndex = 0; codeUnitIndex < maxCodeUnitsToRead; ++codeUnitIndex) { - auto byte = (signed char) *dataToTest++; + const auto firstByte = (uint8_t) codeUnits[codeUnitIndex]; - if (byte < 0) + if (firstByte == 0) + return true; + + if (CharacterFunctions::isAscii ((juce_wchar) firstByte)) + continue; + + auto numExtraBytes = [&] { - int bit = 0x40; - int numExtraValues = 0; + if (firstByte < 0xc0) + return 0; - while ((byte & bit) != 0) - { - if (bit < 8) - return false; + if (firstByte < 0xe0) + return 1; - ++numExtraValues; - bit >>= 1; + if (firstByte < 0xf0) + return 2; - if (bit == 8 && (numExtraValues > maxBytesToRead - || *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff)) - return false; - } + if (firstByte <= 0xf4) + return 3; - if (numExtraValues == 0) + return 0; + }(); + + if (numExtraBytes == 0) + return false; + + auto bytes = (uint32_t) firstByte; + + while (numExtraBytes--) + { + if (++codeUnitIndex >= maxCodeUnitsToRead) return false; - maxBytesToRead -= numExtraValues; - if (maxBytesToRead < 0) - return false; - - while (--numExtraValues >= 0) - if ((*dataToTest++ & 0xc0) != 0x80) - return false; + bytes <<= 8; + bytes |= (uint32_t) (uint8_t) codeUnits[codeUnitIndex]; } + + if (constexpr uint32_t firstTwoByteCodePoint = 0xc280; bytes < firstTwoByteCodePoint) + return false; + + if (constexpr uint32_t lastTwoByteCodePoint = 0xdfbf; bytes <= lastTwoByteCodePoint) + continue; + + if (constexpr uint32_t firstThreeByteCodePoint = 0xe0a080; bytes < firstThreeByteCodePoint) + return false; + + if (constexpr uint32_t firstSurrogateCodePoint = 0xeda080; bytes < firstSurrogateCodePoint) + continue; + + if (constexpr uint32_t lastSurrogateCodePoint = 0xedbfbf; bytes <= lastSurrogateCodePoint) + return false; + + if (constexpr uint32_t lastThreeByteCodePoint = 0xefbfbf; bytes <= lastThreeByteCodePoint) + continue; + + if (constexpr uint32_t firstFourByteCodePoint = 0xf0908080; bytes < firstFourByteCodePoint) + return false; + + if (constexpr uint32_t lastFourByteCodePoint = 0xf48fbfbf; bytes <= lastFourByteCodePoint) + continue; + + return false; } return true; diff --git a/modules/juce_core/text/juce_CharPointer_UTF8_test.cpp b/modules/juce_core/text/juce_CharPointer_UTF8_test.cpp new file mode 100644 index 0000000000..c6fbe592db --- /dev/null +++ b/modules/juce_core/text/juce_CharPointer_UTF8_test.cpp @@ -0,0 +1,91 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +class CharPointer_UTF8Test final : public UnitTest +{ +public: + CharPointer_UTF8Test() : UnitTest { "CharPointer_UTF8", UnitTestCategories::text } {} + + void runTest() final + { + beginTest ("String validation - empty string / null-terminator"); + { + const std::vector string { 0x0 }; + expect (CharPointer_UTF8::isValidString (string.data(), (int) string.size())); + } + + beginTest ("String validation - ascii"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x21, 0x0 }; // Test! + expect (CharPointer_UTF8::isValidString (string.data(), (int) string.size())); + } + + beginTest ("String validation - continuation characters are invalid when not proceeded by the correct bytes"); + { + const std::vector string { -1 }; + expect (! CharPointer_UTF8::isValidString (string.data(), (int) string.size())); + } + + beginTest ("String validation - characters after a null terminator are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, 0x0, -1 }; + expect (CharPointer_UTF8::isValidString (string.data(), (int) string.size())); + } + + beginTest ("String validation - characters exceeding max bytes are ignored"); + { + const std::vector string { 0x54, 0x65, 0x73, 0x74, -1 }; + expect (CharPointer_UTF8::isValidString (string.data(), 4)); + } + + beginTest ("String validation - all unicode characters"); + { + for (uint32_t c = 0; c < 0x110000; ++c) + { + std::array string = {}; + CharPointer_UTF8 utf8 { string.data() }; + utf8.write ((juce_wchar) c); + expect (CharPointer_UTF8::isValidString (string.data(), (int) string.size()) == CharPointer_UTF32::canRepresent ((juce_wchar) c)); + } + } + } +}; + + +static CharPointer_UTF8Test charPointer_UTF8Test; + +} // namespace juce diff --git a/modules/juce_core/text/juce_CharacterFunctions.h b/modules/juce_core/text/juce_CharacterFunctions.h index aadb6a62e5..fde96a0563 100644 --- a/modules/juce_core/text/juce_CharacterFunctions.h +++ b/modules/juce_core/text/juce_CharacterFunctions.h @@ -150,6 +150,70 @@ public: /** Converts a byte of Windows 1252 codepage to unicode. */ static juce_wchar getUnicodeCharFromWindows1252Codepage (uint8 windows1252Char) noexcept; + /** Returns true if a unicode code point is part of the basic multilingual plane. + + @see isAscii, isNonSurrogateCodePoint + */ + static constexpr bool isPartOfBasicMultilingualPlane (juce_wchar character) noexcept + { + return (uint32) character < 0x10000; + } + + /** Returns true if a unicode code point is in the range os ASCII characters. + + @see isAsciiControlCharacter, isPartOfBasicMultilingualPlane + */ + static constexpr bool isAscii (juce_wchar character) noexcept + { + return (uint32) character < 128; + } + + /** Returns true if a unicode code point is in the range of ASCII control characters. + + @see isAscii + */ + static constexpr bool isAsciiControlCharacter (juce_wchar character) noexcept + { + return (uint32) character < 32; + } + + /** Returns true if a unicode code point is in the range of UTF-16 surrogate code units. + + @see isHighSurrogate, isLowSurrogate + */ + static constexpr bool isSurrogate (juce_wchar character) noexcept + { + const auto n = (uint32) character; + return 0xd800 <= n && n <= 0xdfff; + } + + /** Returns true if a unicode code point is in the range of UTF-16 high surrogate code units. + + @see isLowSurrogate, isSurrogate + */ + static constexpr bool isHighSurrogate (juce_wchar character) noexcept + { + const auto n = (uint32) character; + return 0xd800 <= n && n <= 0xdbff; + } + + /** Returns true if a unicode code point is in the range of UTF-16 low surrogate code units. + + @see isHighSurrogate, isSurrogate + */ + static constexpr bool isLowSurrogate (juce_wchar character) noexcept + { + const auto n = (uint32) character; + return 0xdc00 <= n && n <= 0xdfff; + } + + /** Returns true if a unicode code point is in the range of valid unicode code points. */ + static constexpr bool isNonSurrogateCodePoint (juce_wchar character) noexcept + { + const auto n = (uint32) character; + return n <= 0x10ffff && ! isSurrogate (character); + } + //============================================================================== /** Parses a character string to read a floating-point number. Note that this will advance the pointer that is passed in, leaving it at