Преглед на файлове

Merge branch 'rc-2023.2.0' of public/ls-standard-library into master

patrick-christopher.mattulat преди 1 година
родител
ревизия
4904188daf
променени са 100 файла, в които са добавени 2956 реда и са изтрити 476 реда
  1. 163 34
      CMakeLists.txt
  2. 25 31
      README.md
  3. BIN
      doc/section-pair-2023-standard.odt
  4. 3 1
      include/ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp
  5. 3 1
      include/ls-std/core/evaluator/NullPointerEvaluator.hpp
  6. 4 2
      include/ls-std/core/exception/Exception.hpp
  7. 31 0
      include/ls-std/core/exception/NotImplementedException.hpp
  8. 39 0
      include/ls-std/core/interface/IJniApi.hpp
  9. 42 0
      include/ls-std/core/jni/JniApi.hpp
  10. 57 0
      include/ls-std/core/jni/JniClass.hpp
  11. 43 0
      include/ls-std/core/jni/JniClassParameter.hpp
  12. 41 0
      include/ls-std/core/jni/JniMethod.hpp
  13. 55 0
      include/ls-std/core/jni/JniReturnValue.hpp
  14. 9 1
      include/ls-std/io/logging/Logger.hpp
  15. 19 0
      include/ls-std/ls-std-core-jni.hpp
  16. 2 1
      include/ls-std/ls-std-core.hpp
  17. 15 0
      include/ls-std/ls-std-time-jni.hpp
  18. 16 1
      include/ls-std/ls-std-time.hpp
  19. 53 0
      include/ls-std/time/common/DateParameter.hpp
  20. 38 0
      include/ls-std/time/common/DateParameterMapper.hpp
  21. 30 0
      include/ls-std/time/common/jni/JniDateParameterMapper.hpp
  22. 29 0
      include/ls-std/time/system-time/IClock.hpp
  23. 30 0
      include/ls-std/time/system-time/PosixClock.hpp
  24. 41 0
      include/ls-std/time/system-time/SystemTime.hpp
  25. 35 0
      include/ls-std/time/system-time/SystemTimeParameter.hpp
  26. 29 0
      include/ls-std/time/system-time/WindowsClock.hpp
  27. 21 0
      include/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h
  28. 24 0
      include/ls-std/time/type/DateParameterTypes.hpp
  29. 2 2
      source/ls-std/core/LibraryVersion.cpp
  30. 23 3
      source/ls-std/core/evaluator/NullPointerArgumentEvaluator.cpp
  31. 19 1
      source/ls-std/core/evaluator/NullPointerEvaluator.cpp
  32. 2 13
      source/ls-std/core/exception/EventNotHandledException.cpp
  33. 2 13
      source/ls-std/core/exception/EventNotSubscribedException.cpp
  34. 15 3
      source/ls-std/core/exception/Exception.cpp
  35. 2 13
      source/ls-std/core/exception/FileNotFoundException.cpp
  36. 2 13
      source/ls-std/core/exception/FileOperationException.cpp
  37. 2 13
      source/ls-std/core/exception/IllegalArgumentException.cpp
  38. 2 13
      source/ls-std/core/exception/IllegalArithmeticOperationException.cpp
  39. 2 13
      source/ls-std/core/exception/IncompleteJsonException.cpp
  40. 2 13
      source/ls-std/core/exception/IndexOutOfBoundsException.cpp
  41. 33 0
      source/ls-std/core/exception/NotImplementedException.cpp
  42. 2 13
      source/ls-std/core/exception/NullPointerException.cpp
  43. 16 0
      source/ls-std/core/interface/IJniApi.cpp
  44. 73 0
      source/ls-std/core/jni/JniApi.cpp
  45. 203 0
      source/ls-std/core/jni/JniClass.cpp
  46. 49 0
      source/ls-std/core/jni/JniClassParameter.cpp
  47. 55 0
      source/ls-std/core/jni/JniMethod.cpp
  48. 96 0
      source/ls-std/core/jni/JniReturnValue.cpp
  49. 3 3
      source/ls-std/io/File.cpp
  50. 48 4
      source/ls-std/io/logging/Logger.cpp
  51. 2 2
      source/ls-std/io/section-pair/validator/SectionPairIdentifierValidator.cpp
  52. 2 2
      source/ls-std/io/section-pair/validator/SectionPairValueValidator.cpp
  53. 90 0
      source/ls-std/time/common/DateParameter.cpp
  54. 56 0
      source/ls-std/time/common/DateParameterMapper.cpp
  55. 35 0
      source/ls-std/time/common/jni/JniDateParameterMapper.cpp
  56. 16 0
      source/ls-std/time/system-time/IClock.cpp
  57. 28 0
      source/ls-std/time/system-time/PosixClock.cpp
  58. 65 0
      source/ls-std/time/system-time/SystemTime.cpp
  59. 29 0
      source/ls-std/time/system-time/SystemTimeParameter.cpp
  60. 26 0
      source/ls-std/time/system-time/WindowsClock.cpp
  61. 69 0
      source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp
  62. 2 8
      test/cases/boxing/BooleanTest.cpp
  63. 2 8
      test/cases/boxing/DoubleTest.cpp
  64. 2 8
      test/cases/boxing/FloatTest.cpp
  65. 2 8
      test/cases/boxing/IntegerTest.cpp
  66. 2 8
      test/cases/boxing/LongTest.cpp
  67. 2 8
      test/cases/boxing/StringTest.cpp
  68. 2 8
      test/cases/core/ClassTest.cpp
  69. 2 8
      test/cases/core/ConditionalFunctionExecutorTest.cpp
  70. 3 9
      test/cases/core/LibraryVersionTest.cpp
  71. 2 8
      test/cases/core/VersionTest.cpp
  72. 2 8
      test/cases/core/evaluator/EmptyStringArgumentEvaluatorTest.cpp
  73. 2 8
      test/cases/core/evaluator/IndexOutOfBoundsEvaluatorTest.cpp
  74. 49 9
      test/cases/core/evaluator/NullPointerArgumentEvaluatorTest.cpp
  75. 49 9
      test/cases/core/evaluator/NullPointerEvaluatorTest.cpp
  76. 2 8
      test/cases/core/exception/EventNotHandledExceptionTest.cpp
  77. 2 8
      test/cases/core/exception/EventNotSubscribedExceptionTest.cpp
  78. 2 8
      test/cases/core/exception/ExceptionMessageTest.cpp
  79. 2 8
      test/cases/core/exception/FileNotFoundExceptionTest.cpp
  80. 2 8
      test/cases/core/exception/FileOperationExceptionTest.cpp
  81. 2 8
      test/cases/core/exception/IllegalArgumentExceptionTest.cpp
  82. 2 8
      test/cases/core/exception/IllegalArithmeticOperationExceptionTest.cpp
  83. 2 8
      test/cases/core/exception/IncompleteJsonExceptionTest.cpp
  84. 2 8
      test/cases/core/exception/IndexOutOfBoundsExceptionTest.cpp
  85. 72 0
      test/cases/core/exception/NotImplementedExceptionTest.cpp
  86. 2 8
      test/cases/core/exception/NullPointerExceptionTest.cpp
  87. 50 0
      test/cases/core/jni/JniApiTest.cpp
  88. 77 0
      test/cases/core/jni/JniClassParameterTest.cpp
  89. 369 0
      test/cases/core/jni/JniClassTest.cpp
  90. 114 0
      test/cases/core/jni/JniMethodTest.cpp
  91. 137 0
      test/cases/core/jni/JniReturnValueTest.cpp
  92. 2 8
      test/cases/encoding/Base64Test.cpp
  93. 2 8
      test/cases/event/EventHandlerTest.cpp
  94. 2 8
      test/cases/event/EventManagerTest.cpp
  95. 2 8
      test/cases/event/EventTest.cpp
  96. 2 8
      test/cases/event/NarratorTest.cpp
  97. 2 8
      test/cases/event/serialization/SerializableJsonEventTest.cpp
  98. 2 8
      test/cases/io/FileOutputStreamTest.cpp
  99. 2 8
      test/cases/io/FileReaderTest.cpp
  100. 10 8
      test/cases/io/FileTest.cpp

+ 163 - 34
CMakeLists.txt

@@ -11,7 +11,7 @@
 ##########################################################
 
 cmake_minimum_required(VERSION 3.17)
-project(ls-std VERSION 2023.1.0)
+project(ls-std VERSION 2023.2.0)
 
 set(MODULE_NAME_BOXING ls-std-boxing)
 set(MODULE_NAME_CORE ls-std-core)
@@ -32,6 +32,7 @@ option(LS_STD_BUILD_WITH_TESTS "Build project with tests..." OFF)
 option(LS_STD_BUILD_WITH_SUPPORTED_COMPILER "Build project with supported compiler only..." ON)
 option(LS_STD_BUILD_STATIC "Build ls-std static library..." ON)
 option(LS_STD_BUILD_SHARED "Build ls-std shared library..." OFF)
+option(LS_STD_BUILD_WITH_JNI "Build ls-std shared library with JNI..." OFF)
 
 set(TARGET_COUNTER 0)
 
@@ -57,6 +58,19 @@ if (TARGET_COUNTER EQUAL 0)
     return()
 endif ()
 
+##########################################################
+# JNI flag check
+##########################################################
+
+if (${LS_STD_BUILD_WITH_JNI})
+    if (${LS_STD_BUILD_SHARED})
+        message("${PROJECT_NAME}: build with JNI support...")
+    else ()
+        message("${PROJECT_NAME}: [Error] JNI support requires shared build goal!")
+        return()
+    endif ()
+endif ()
+
 ##########################################################
 # Compiler Settings
 ##########################################################
@@ -70,7 +84,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 # Compiler Support
 ##########################################################
 
-if(${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
+if (${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
     message("${PROJECT_NAME}: build with compiler support...")
 
     # define supported compilers
@@ -80,11 +94,27 @@ if(${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
             ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang OR
             ${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang)
         message("${PROJECT_NAME}: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} is supported...")
-    else()
+    else ()
         message("${PROJECT_NAME}: [Error] ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} is not supported... terminated!")
         return()
     endif ()
-endif()
+endif ()
+
+######################################################
+# Find Packages
+######################################################
+
+if (${LS_STD_BUILD_WITH_JNI})
+    if (DEFINED ENV{JAVA_HOME})
+        message("JAVA_HOME found in '$ENV{JAVA_HOME}' location...")
+    else ()
+        message("[Error] JAVA_HOME not found!")
+        return()
+    endif ()
+
+    message("${PROJECT_NAME}: finding JNI package in '$ENV{JAVA_HOME}'...")
+    find_package(JNI REQUIRED)
+endif ()
 
 ######################################################
 # Include Directories
@@ -92,6 +122,12 @@ endif()
 
 message("${PROJECT_NAME}: Adding include directories...")
 
+if (${LS_STD_BUILD_WITH_JNI})
+    include_directories(${JAVA_INCLUDE_PATH})
+    include_directories(${JAVA_INCLUDE_PATH2})
+    include_directories(${JAVA_AWT_INCLUDE_PATH})
+endif ()
+
 if (${LS_STD_BUILD_WITH_TESTS})
     include_directories(${CMAKE_CURRENT_SOURCE_DIR}/test)
     include_directories(${CMAKE_CURRENT_LIST_DIR}/test/lib/${GOOGLE_TEST_MODULE}/googletest/include)
@@ -141,6 +177,7 @@ set(SOURCE_FILES_CORE
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/IllegalArithmeticOperationException.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/IncompleteJsonException.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/IndexOutOfBoundsException.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/NotImplementedException.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/NullPointerException.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IBoxing.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IEncoding.cpp
@@ -157,6 +194,14 @@ set(SOURCE_FILES_CORE
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/LibraryVersion.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/Version.cpp)
 
+set(SOURCE_FILES_CORE_JNI
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IJniApi.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniApi.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniClass.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniClassParameter.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniMethod.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniReturnValue.cpp)
+
 set(SOURCE_FILES_ENCODING
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/encoding/Base64.cpp)
 
@@ -218,8 +263,30 @@ set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/StorableFile.cpp)
 
 set(SOURCE_FILES_TIME
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/DateParameter.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/DateParameterMapper.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/IClock.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/SystemTime.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/SystemTimeParameter.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/Date.cpp)
 
+set(SOURCE_FILES_LINUX_TIME)
+set(SOURCE_FILES_WINDOWS_TIME)
+
+if (UNIX OR APPLE)
+    message("${MODULE_NAME_TIME}: Add UNIX files for time module...")
+    set(SOURCE_FILES_LINUX_TIME
+            ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/PosixClock.cpp)
+else (WIN32)
+    message("${MODULE_NAME_TIME}: Add Windows files for time module...")
+    set(SOURCE_FILES_WINDOWS_TIME
+            ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/WindowsClock.cpp)
+endif ()
+
+set(SOURCE_FILES_TIME_JNI
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/jni/JniDateParameterMapper.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp)
+
 ####################################################################################################################
 ####################################################################################################################
 ####################################################################################################################
@@ -251,6 +318,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/IllegalArithmeticOperationExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/IncompleteJsonExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/IndexOutOfBoundsExceptionTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/NotImplementedExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/NullPointerExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/ClassTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/ConditionalFunctionExecutorTest.cpp
@@ -259,6 +327,14 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/ClassWrapper.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/MathOddValidator.cpp)
 
+    set(UNIT_TEST_FILES_CORE_JNI
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniApiTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniClassParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniClassTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniMethodTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniReturnValueTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/jni/MockJniApi.cpp)
+
     set(UNIT_TEST_FILES_ENCODING
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/encoding/Base64Test.cpp)
 
@@ -335,7 +411,12 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/JsonTest.cpp)
 
     set(UNIT_TEST_FILES_TIME
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/DateTest.cpp)
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/common/DateParameterMapperTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/common/DateParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/system-time/SystemTimeParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/system-time/SystemTimeTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/DateTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/time/system-time/MockClock.cpp)
 endif ()
 
 ####################################################################################################################
@@ -360,8 +441,13 @@ endif ()
 ##########################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${MODULE_NAME_CORE}: Building unit tests...")
-    add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_CORE}: Building unit tests with JNI support...")
+        add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE} ${UNIT_TEST_FILES_CORE_JNI})
+    else ()
+        message("${MODULE_NAME_CORE}: Building unit tests...")
+        add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE})
+    endif ()
 endif ()
 
 ##########################################################
@@ -407,16 +493,30 @@ endif ()
 ##########################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${PROJECT_NAME}: Building unit tests...")
-    add_executable(${PROJECT_NAME}-unit-test
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
-            ${UNIT_TEST_FILES_BOXING}
-            ${UNIT_TEST_FILES_CORE}
-            ${UNIT_TEST_FILES_ENCODING}
-            ${UNIT_TEST_FILES_EVENT}
-            ${UNIT_TEST_FILES_IO}
-            ${UNIT_TEST_FILES_SERIALIZATION}
-            ${UNIT_TEST_FILES_TIME})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${PROJECT_NAME}: Building unit tests with JNI support...")
+        add_executable(${PROJECT_NAME}-unit-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_CORE_JNI}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    else ()
+        message("${PROJECT_NAME}: Building unit tests...")
+        add_executable(${PROJECT_NAME}-unit-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -460,17 +560,32 @@ endif ()
 ####################################################################################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${PROJECT_NAME}: Building all tests...")
-    add_executable(${PROJECT_NAME}-test
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
-            ${UNIT_TEST_FILES_BOXING}
-            ${UNIT_TEST_FILES_CORE}
-            ${UNIT_TEST_FILES_ENCODING}
-            ${UNIT_TEST_FILES_EVENT}
-            ${UNIT_TEST_FILES_IO}
-            ${INTEGRATION_TEST_FILES_IO}
-            ${UNIT_TEST_FILES_SERIALIZATION}
-            ${UNIT_TEST_FILES_TIME})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${PROJECT_NAME}: Building all tests...")
+        add_executable(${PROJECT_NAME}-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_CORE_JNI}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${INTEGRATION_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    else ()
+        message("${PROJECT_NAME}: Building all tests with JNI support...")
+        add_executable(${PROJECT_NAME}-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${INTEGRATION_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -510,8 +625,14 @@ if (${LS_STD_BUILD_STATIC})
 endif ()
 
 if (${LS_STD_BUILD_SHARED})
-    add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE})
-    set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_CORE}: building with JNI...")
+        add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE} ${SOURCE_FILES_CORE_JNI})
+        set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    else ()
+        add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE})
+        set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    endif ()
 endif ()
 
 ##########################################################
@@ -577,14 +698,21 @@ endif ()
 message("${PROJECT_NAME}: Building ${MODULE_NAME_TIME} library version ${PROJECT_VERSION}...")
 
 if (${LS_STD_BUILD_STATIC})
-    add_library("${MODULE_NAME_TIME}" STATIC ${SOURCE_FILES_TIME})
+    add_library("${MODULE_NAME_TIME}" STATIC ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME})
     set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
 endif ()
 
 if (${LS_STD_BUILD_SHARED})
-    add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME})
-    target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
-    set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_TIME}: building with JNI...")
+        add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME} ${SOURCE_FILES_TIME_JNI})
+        target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
+        set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    else ()
+        add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME})
+        target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
+        set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -669,6 +797,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
     message("${MODULE_NAME_TIME}: Linking libraries for unit test application...")
     target_link_libraries(${MODULE_NAME_TIME}-unit-test
             gtest
+            gmock
             gtest_main
             "${MODULE_NAME_TIME}"
             "${MODULE_NAME_CORE}")

+ 25 - 31
README.md

@@ -1,4 +1,4 @@
-# Lynar Studios - Standard Library 2023.1.0 #
+# Lynar Studios - Standard Library 2023.2.0 #
 
 This is a cross-platform standard library written in C++ offering functionalities you would usually miss in C++'s standard template library (STL), especially if you would search for cross-platform implementations.  
 This library has been tested on __Windows__, __Linux__ and __MacOS__ systems.
@@ -34,33 +34,26 @@ A __Date__ class comes with this submodule, which you can use to represent a dat
 
 #### Features ####
 
-- __AppleClang__ compiler is now officially supported
-- exceptions provided by __core__ submodule now offer a constructor for passing dedicated messages
-- evaluators have been added, which can check a state of variables and throw a dedicated exception in a single line and
-  more convenient way
-- a section-pair file standard has been implemented and is provided via __ls-std-io__ module, a definition of this
-  standard can be found in the libraries __doc__ folder
-- a base Exception class has been added, which provides basic reflection functionality - all existing library exceptions
-  inherit from this class now
+- added NotImplementedException class, which can be thrown in case a method is provided, but not implemented
+- a JNI class is now available, wrapping C-like JNI functionalities, which can be found in __ls-std-core__ module - in
+  order to use this feature the CMake option __LS_STD_BUILD_WITH_JNI__ has to be enabled - please note, that this
+  feature is experimental and incomplete
+- a SystemTime class has been added to the library's time module for setting the local system time
+- Logger class is now configurable to silent log level or timestamp output
 
 #### Improvements ####
 
-- __logic__ module has been removed from this library and can now be found in __ls-game-tool-kit__ library
-- __core.utils__ module has been removed from this library to provide more clean implementations where it's needed
-- the complexity of source files has been reduced by declaring usages of namespaces at the file beginning sections
-  instead of using those in every definition implementation, this overall improves the readability of the libraries
-  source files
-- a new naming convention for files and directories has been introduced, where underscores were replaced by dashes
-  entirely
-- fetching the library version can now be achieved by using a dedicated __LibraryVersion__ class - the usage of a static function for this purpose has been removed completely
-- missing nodiscard attributes have been added to library classes
-- rename "types" folder in __core__ submodule to stick to naming convention
-- key-value file standard has been removed from this library and is replaced by section-pair file standard
+- made test constructors public and reduced test setup overhead
+- added missing __nodiscard__ attributes to test package
+- made __Exception__ base class abstract, which prevents it from being instantiated
+- __NullPointerEvaluator__ & __NullPointerArgumentEvaluator__ now except raw pointers
+- Section-Pair identifiers can now have a length of 64 characters
+- Section-Pair values can now have a length of 512 characters
+- exceptions for creation of files or directories have been improved and now show the absolute file path
 
 #### Fixes ####
 
-- potential memory leaks have been resolved by strictly splitting prototypes and implementation project-wide, which enabled the usage of virtual or overridden destructors
-- memory leaks inside exception test suite have been fixed
+- no comment
 
 ---
 ### Documentation ###
@@ -77,15 +70,15 @@ This software is licensed and uses MIT-license. You can find a __LICENSE.MIT__ f
 
 Building this library would result into providing binaries for each library module and CLI tool: 
 
-| binary              | type                       |
-|---------------------|----------------------------|
-| __cli-base64__      | CLI executable             |
-| __ls-std-boxing__   | library (static / dynamic) |
-| __ls-std-core__     | library (static / dynamic) |
-| __ls-std-encoding__ | library (static / dynamic) |
-| __ls-std-event__    | library (static / dynamic) |
-| __ls-std-io__       | library (static / dynamic) |
-| __ls-std-time__     | library (static / dynamic) |
+| binary              | type                       | dependency                   |
+|---------------------|----------------------------|------------------------------|
+| __cli-base64__      | CLI executable             | ls-std-encoding, ls-std-core |
+| __ls-std-boxing__   | library (static / dynamic) | ls-std-core                  |
+| __ls-std-core__     | library (static / dynamic) | ---                          |
+| __ls-std-encoding__ | library (static / dynamic) | ls-std-core                  |
+| __ls-std-event__    | library (static / dynamic) | ls-std-core                  |
+| __ls-std-io__       | library (static / dynamic) | ls-std-core                  |
+| __ls-std-time__     | library (static / dynamic) | ls-std-core                  |
 
 #### Prerequisites ####
 
@@ -125,6 +118,7 @@ Alternatively, the CMake project generation can be controlled by providing libra
 | __LS_STD_BUILD_WITH_SUPPORTED_COMPILER__ | ON            | This flag enforces the usage of supported compilers, only.<br/>For usage of an unsupported toolchain, set this flag to __OFF__.                      |
 | __LS_STD_BUILD_STATIC__                  | ON            | This flag indicates, that all library modules should be built as static goals.  <br/>Please note, that __LS_STD_BUILD_SHARED__ has to be turned off. |
 | __LS_STD_BUILD_SHARED__                  | OFF           | This flag indicates, that all library modules should be built as shared goals.  <br/>Please note, that __LS_STD_BUILD_STATIC__ has to be turned off. |
+| __LS_STD_BUILD_WITH_JNI__                | OFF           | This flag enables the build of JNI dependencies.  <br/>Please note, that __LS_STD_BUILD_SHARED__ has to be turned on.                                |
 
 To use one or more of these flags, you'd have to adjust previous command, like:
 

BIN
doc/section-pair-2023-standard.odt


+ 3 - 1
include/ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-07
 *
 * */
 
@@ -21,6 +21,8 @@ namespace ls::std::core
   {
     public:
 
+      explicit NullPointerArgumentEvaluator(const void *_rawArgument);
+      explicit NullPointerArgumentEvaluator(const void *_rawArgument, ::std::string _message);
       explicit NullPointerArgumentEvaluator(const ::std::shared_ptr<void> &_argument);
       explicit NullPointerArgumentEvaluator(const ::std::shared_ptr<void> &_argument, ::std::string _message);
       ~NullPointerArgumentEvaluator() noexcept override;

+ 3 - 1
include/ls-std/core/evaluator/NullPointerEvaluator.hpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-04
 *
 * */
 
@@ -21,6 +21,8 @@ namespace ls::std::core
   {
     public:
 
+      explicit NullPointerEvaluator(const void *_rawArgument);
+      explicit NullPointerEvaluator(const void *_rawArgument, ::std::string _message);
       explicit NullPointerEvaluator(const ::std::shared_ptr<void> &_argument);
       explicit NullPointerEvaluator(const ::std::shared_ptr<void> &_argument, ::std::string _message);
       ~NullPointerEvaluator() noexcept override;

+ 4 - 2
include/ls-std/core/exception/Exception.hpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-22
-* Changed:         2023-02-22
+* Changed:         2023-03-28
 *
 * */
 
@@ -24,12 +24,14 @@ namespace ls::std::core
       ~Exception() noexcept override;
 
       [[nodiscard]] ::std::string getName() const;
-      [[nodiscard]] const char *what() const noexcept override;
+      [[nodiscard]] const char *what() const noexcept override = 0;
 
     protected:
 
       ::std::string message{};
       ::std::string name{};
+
+      [[nodiscard]] const char *_getIdentifiedMessage(const ::std::string &_defaultMessage) const;
   };
 }
 

+ 31 - 0
include/ls-std/core/exception/NotImplementedException.hpp

@@ -0,0 +1,31 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-27
+* Changed:         2023-03-27
+*
+* */
+
+#ifndef LS_STD_NOT_IMPLEMENTED_EXCEPTION_HPP
+#define LS_STD_NOT_IMPLEMENTED_EXCEPTION_HPP
+
+#include "Exception.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::core
+{
+  class LS_STD_DYNAMIC_GOAL NotImplementedException : public ls::std::core::Exception
+  {
+    public:
+
+      NotImplementedException();
+      explicit NotImplementedException(::std::string _message);
+      ~NotImplementedException() noexcept override;
+
+      [[nodiscard]] const char *what() const noexcept override;
+  };
+}
+
+#endif

+ 39 - 0
include/ls-std/core/interface/IJniApi.hpp

@@ -0,0 +1,39 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_I_JNI_API_HPP
+#define LS_STD_I_JNI_API_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::core::experimental::interface_type
+{
+  class LS_STD_DYNAMIC_GOAL IJniApi
+  {
+    public:
+
+      IJniApi();
+      virtual ~IJniApi();
+
+      virtual jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jchar callCharMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jint callIntMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jlong callLongMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jshort callShortMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jclass findClass(const ::std::string &_classPath) = 0;
+      virtual jmethodID getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature) = 0;
+  };
+}
+
+#endif

+ 42 - 0
include/ls-std/core/jni/JniApi.hpp

@@ -0,0 +1,42 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_API_HPP
+#define LS_STD_JNI_API_HPP
+
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniApi : public ls::std::core::experimental::interface_type::IJniApi
+  {
+    public:
+
+      explicit JniApi(JNIEnv *_environment);
+      ~JniApi() noexcept override;
+
+      jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) override;
+      jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) override;
+      jchar callCharMethod(jobject _javaObject, jmethodID _methodId) override;
+      jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) override;
+      jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) override;
+      jint callIntMethod(jobject _javaObject, jmethodID _methodId) override;
+      jlong callLongMethod(jobject _javaObject, jmethodID _methodId) override;
+      jshort callShortMethod(jobject _javaObject, jmethodID _methodId) override;
+      jclass findClass(const ::std::string &_classPath) override;
+      jmethodID getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature) override;
+
+    private:
+
+      JNIEnv *environment{};
+  };
+}
+
+#endif

+ 57 - 0
include/ls-std/core/jni/JniClass.hpp

@@ -0,0 +1,57 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_CLASS_HPP
+#define LS_STD_JNI_CLASS_HPP
+
+#include "JniClassParameter.hpp"
+#include "JniMethod.hpp"
+#include "JniReturnValue.hpp"
+#include <jni.h>
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniClass
+  {
+    public:
+
+      explicit JniClass(const ::std::shared_ptr<ls::std::core::experimental::JniClassParameter> &_parameter, const ::std::string &_path);
+      virtual ~JniClass();
+
+      [[nodiscard]] ls::std::core::experimental::JniReturnValue callMethod(const ::std::string &_methodIdentifier);
+      [[nodiscard]] bool hasMethod(const ::std::string &_methodIdentifier);
+      bool load();                                                                                    // nodiscard is optional here
+      bool loadMethod(const ::std::string &_methodIdentifier, const ::std::string &_methodSignature); // nodiscard is optional here
+
+    private:
+
+      jclass javaClass{};
+      ::std::unordered_map<::std::string, ls::std::core::experimental::JniMethod> methods{};
+      ::std::shared_ptr<ls::std::core::experimental::JniClassParameter> parameter{};
+      ::std::string path{};
+
+      void _callBooleanMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callByteMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callCharMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callDoubleMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callFloatMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callIntMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callLongMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callShortMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _createJniApi();
+      [[nodiscard]] bool _hasMethod(const ::std::string &_methodIdentifier);
+  };
+}
+
+#endif

+ 43 - 0
include/ls-std/core/jni/JniClassParameter.hpp

@@ -0,0 +1,43 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_CLASS_PARAMETER_HPP
+#define LS_STD_JNI_CLASS_PARAMETER_HPP
+
+#include <jni.h>
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+#include <string>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniClassParameter
+  {
+    public:
+
+      JniClassParameter();
+      ~JniClassParameter();
+
+      [[nodiscard]] JNIEnv *getJavaEnvironment();
+      [[nodiscard]] jobject getJavaObject();
+      [[nodiscard]] ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> getJniApi();
+      void setJavaEnvironment(JNIEnv *_environment);
+      void setJavaObject(jobject _javaObject);
+      void setJniApi(const ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> &_jniApi);
+
+    private:
+
+      JNIEnv *environment{};
+      jobject javaObject{};
+      ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> jniApi{};
+  };
+}
+
+#endif

+ 41 - 0
include/ls-std/core/jni/JniMethod.hpp

@@ -0,0 +1,41 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_METHOD_HPP
+#define LS_STD_JNI_METHOD_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniMethod
+  {
+    public:
+
+      explicit JniMethod(const ::std::string &_methodIdentifier, const ::std::string &_methodSignature);
+      ~JniMethod();
+
+      [[nodiscard]] jmethodID getMethodId();
+      [[nodiscard]] ::std::string getMethodIdentifier();
+      [[nodiscard]] ::std::string getMethodSignature();
+      void setMethodId(jmethodID _methodId);
+      void setMethodIdentifier(const ::std::string &_methodIdentifier);
+      void setMethodSignature(const ::std::string &_methodSignature);
+
+    private:
+
+      jmethodID methodId{};
+      ::std::string methodIdentifier{};
+      ::std::string methodSignature{};
+  };
+}
+
+#endif

+ 55 - 0
include/ls-std/core/jni/JniReturnValue.hpp

@@ -0,0 +1,55 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_RETURN_VALUE_HPP
+#define LS_STD_JNI_RETURN_VALUE_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniReturnValue
+  {
+    public:
+
+      JniReturnValue();
+      ~JniReturnValue();
+
+      [[nodiscard]] jboolean getBooleanValue() const;
+      [[nodiscard]] jbyte getByteValue() const;
+      [[nodiscard]] jchar getCharValue() const;
+      [[nodiscard]] jdouble getDoubleValue() const;
+      [[nodiscard]] jfloat getFloatValue() const;
+      [[nodiscard]] jint getIntegerValue() const;
+      [[nodiscard]] jlong getLongValue() const;
+      [[nodiscard]] jshort getShortValue() const;
+      void setBooleanValue(jboolean _booleanValue);
+      void setByteValue(jbyte _byteValue);
+      void setCharValue(jchar _charValue);
+      void setDoubleValue(jdouble _doubleValue);
+      void setFloatValue(jfloat _floatValue);
+      void setIntegerValue(jint _integerValue);
+      void setLongValue(jlong _longValue);
+      void setShortValue(jshort _shortValue);
+
+    private:
+
+      jboolean booleanValue{};
+      jbyte byteValue{};
+      jchar charValue{};
+      jdouble doubleValue{};
+      jfloat floatValue{};
+      jint integerValue{};
+      jlong longValue{};
+      jshort shortValue{};
+  };
+}
+
+#endif

+ 9 - 1
include/ls-std/io/logging/Logger.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-20
- * Changed:         2023-02-23
+ * Changed:         2023-04-12
  *
  * */
 
@@ -31,13 +31,19 @@ namespace ls::std::io
       void error(const ls::std::core::type::byte_type *_data);
       void fatal(const ls::std::core::type::byte_type *_data);
       [[nodiscard]] ls::std::io::LogLevel getLogLevel();
+      void hideLogLevel();
+      void hideTimestamp();
       void info(const ls::std::core::type::byte_type *_data);
       void setLogLevel(const ls::std::io::LogLevelValue &_logLevelValue);
+      void showLogLevel();
+      void showTimestamp();
       void trace(const ls::std::core::type::byte_type *_data);
       void warn(const ls::std::core::type::byte_type *_data);
 
     private:
 
+      bool displayLogLevel{};
+      bool displayTimestamp{};
       ls::std::io::LogLevel logLevel{};
       ::std::shared_ptr<ls::std::core::interface_type::IWriter> writer{};
 
@@ -45,6 +51,8 @@ namespace ls::std::io
       [[nodiscard]] static ::std::string _buildCharacterChain(size_t _amount);
       [[nodiscard]] static ::std::string _createFillContent(const ::std::string &_text);
       [[nodiscard]] static ::std::string _generateTimeString(tm *_localTime);
+      [[nodiscard]] ::std::string _getLogLevelString(const ls::std::io::LogLevel &_logLevel) const;
+      [[nodiscard]] ::std::string _getTimestampString() const;
       void _log(const ls::std::core::type::byte_type *_data, const ls::std::io::LogLevel &_logLevel);
       [[nodiscard]] static ::std::string _padRight(const ::std::string &_text);
   };

+ 19 - 0
include/ls-std/ls-std-core-jni.hpp

@@ -0,0 +1,19 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-08
+*
+* */
+
+#ifndef LS_STD_LS_STD_CORE_JNI_HPP
+#define LS_STD_LS_STD_CORE_JNI_HPP
+
+#include <ls-std/core/jni/JniApi.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/core/jni/JniClassParameter.hpp>
+#include <ls-std/core/jni/JniMethod.hpp>
+#include <ls-std/core/jni/JniReturnValue.hpp>
+
+#endif

+ 2 - 1
include/ls-std/ls-std-core.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-13
- * Changed:         2023-02-22
+ * Changed:         2023-03-27
  *
  * */
 
@@ -25,6 +25,7 @@
 #include <ls-std/core/exception/IllegalArithmeticOperationException.hpp>
 #include <ls-std/core/exception/IncompleteJsonException.hpp>
 #include <ls-std/core/exception/IndexOutOfBoundsException.hpp>
+#include <ls-std/core/exception/NotImplementedException.hpp>
 #include <ls-std/core/exception/NullPointerException.hpp>
 
 #include <ls-std/core/interface/IBoxing.hpp>

+ 15 - 0
include/ls-std/ls-std-time-jni.hpp

@@ -0,0 +1,15 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-08
+*
+* */
+
+#ifndef LS_STD_LS_STD_TIME_JNI_HPP
+#define LS_STD_LS_STD_TIME_JNI_HPP
+
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+
+#endif

+ 16 - 1
include/ls-std/ls-std-time.hpp

@@ -3,13 +3,28 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-16
- * Changed:         2023-02-03
+ * Changed:         2023-04-01
  *
  * */
 
 #ifndef LS_STD_LS_STD_TIME_HPP
 #define LS_STD_LS_STD_TIME_HPP
 
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/common/DateParameterMapper.hpp>
+
+#include <ls-std/time/system-time/IClock.hpp>
+#if defined(unix) || defined(__APPLE__)
+  #include <ls-std/time/system-time/PosixClock.hpp>
+#endif
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#ifdef _WIN32
+  #include <ls-std/time/system-time/WindowsClock.hpp>
+#endif
+
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
 #include <ls-std/time/Date.hpp>
 
 #endif

+ 53 - 0
include/ls-std/time/common/DateParameter.hpp

@@ -0,0 +1,53 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_HPP
+#define LS_STD_DATE_PARAMETER_HPP
+
+#include <cstdint>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL DateParameter
+  {
+    public:
+
+      DateParameter(ls::std::time::type::Year _year, ls::std::time::type::Month _month, ls::std::time::type::Day _day, ls::std::time::type::Hour _hour, ls::std::time::type::Minute _minute, ls::std::time::type::Second _second);
+      DateParameter();
+      ~DateParameter();
+
+      bool operator==(const ls::std::time::DateParameter &_dateParameter) const;
+
+      [[nodiscard]] ls::std::time::type::Day getDay() const;
+      [[nodiscard]] ls::std::time::type::Hour getHour() const;
+      [[nodiscard]] ls::std::time::type::Minute getMinute() const;
+      [[nodiscard]] ls::std::time::type::Month getMonth() const;
+      [[nodiscard]] ls::std::time::type::Second getSecond() const;
+      [[nodiscard]] ls::std::time::type::Year getYear() const;
+      void setDay(ls::std::time::type::Day _day);
+      void setHour(ls::std::time::type::Hour _hour);
+      void setMinute(ls::std::time::type::Minute _minute);
+      void setMonth(ls::std::time::type::Month _month);
+      void setSecond(ls::std::time::type::Second _second);
+      void setYear(ls::std::time::type::Year _year);
+
+    private:
+
+      ls::std::time::type::Day day{};
+      ls::std::time::type::Hour hour{};
+      ls::std::time::type::Minute minute{};
+      ls::std::time::type::Month month{};
+      ls::std::time::type::Second second{};
+      ls::std::time::type::Year year{};
+  };
+}
+
+#endif

+ 38 - 0
include/ls-std/time/common/DateParameterMapper.hpp

@@ -0,0 +1,38 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_MAPPER_HPP
+#define LS_STD_DATE_PARAMETER_MAPPER_HPP
+
+#include "DateParameter.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+#ifdef _WIN32
+  #include <windows.h>
+#endif
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL DateParameterMapper
+  {
+    public:
+
+      DateParameterMapper();
+      ~DateParameterMapper();
+
+#if defined(unix) || defined(__APPLE__)
+      [[nodiscard]] static ls::std::time::type::UnixTimestamp toUnixTimestamp(const ls::std::time::DateParameter &_dateParameter);
+#endif
+#ifdef _WIN32
+      [[nodiscard]] static SYSTEMTIME toWindowsSystemTime(const ls::std::time::DateParameter &_dateParameter);
+#endif
+  };
+}
+
+#endif

+ 30 - 0
include/ls-std/time/common/jni/JniDateParameterMapper.hpp

@@ -0,0 +1,30 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_DATE_PARAMETER_MAPPER_HPP
+#define LS_STD_JNI_DATE_PARAMETER_MAPPER_HPP
+
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+
+namespace ls::std::time::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniDateParameterMapper
+  {
+    public:
+
+      JniDateParameterMapper();
+      ~JniDateParameterMapper();
+
+      [[nodiscard]] static ls::std::time::DateParameter toDateParameter(const ls::std::core::experimental::JniClass &_javaClass);
+  };
+}
+
+#endif

+ 29 - 0
include/ls-std/time/system-time/IClock.hpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_I_CLOCK_HPP
+#define LS_STD_I_CLOCK_HPP
+
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL IClock
+  {
+    public:
+
+      IClock();
+      virtual ~IClock();
+
+      virtual bool setTime(const ls::std::time::DateParameter &_dateParameter) = 0;
+  };
+}
+
+#endif

+ 30 - 0
include/ls-std/time/system-time/PosixClock.hpp

@@ -0,0 +1,30 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_POSIX_CLOCK_HPP
+#define LS_STD_POSIX_CLOCK_HPP
+
+#include "IClock.hpp"
+#include <cstdint>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
+namespace ls::std::time
+{
+  class PosixClock : public ls::std::time::IClock
+  {
+    public:
+
+      PosixClock();
+      ~PosixClock() noexcept override;
+
+      [[nodiscard]] bool setTime(const ls::std::time::DateParameter &_dateParameter) override;
+  };
+}
+
+#endif

+ 41 - 0
include/ls-std/time/system-time/SystemTime.hpp

@@ -0,0 +1,41 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-07
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_SYSTEM_TIME_HPP
+#define LS_STD_SYSTEM_TIME_HPP
+
+#include "SystemTimeParameter.hpp"
+#include <cstdint>
+#include <ls-std/core/Class.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+#include <memory>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL SystemTime : public ls::std::core::Class
+  {
+    public:
+
+      explicit SystemTime(const ::std::shared_ptr<ls::std::time::SystemTimeParameter> &_parameter);
+      SystemTime();
+      ~SystemTime() noexcept override;
+
+      [[nodiscard]] bool set(const ls::std::time::DateParameter &_dateParameter);
+
+    private:
+
+      ::std::shared_ptr<ls::std::time::SystemTimeParameter> parameter{};
+
+      void _generateParameter();
+  };
+}
+
+#endif

+ 35 - 0
include/ls-std/time/system-time/SystemTimeParameter.hpp

@@ -0,0 +1,35 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_SYSTEM_TIME_PARAMETER_HPP
+#define LS_STD_SYSTEM_TIME_PARAMETER_HPP
+
+#include "IClock.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL SystemTimeParameter
+  {
+    public:
+
+      SystemTimeParameter();
+      ~SystemTimeParameter();
+
+      [[nodiscard]] ::std::shared_ptr<ls::std::time::IClock> getClock();
+      void setClock(const ::std::shared_ptr<ls::std::time::IClock> &_clock);
+
+    private:
+
+      ::std::shared_ptr<ls::std::time::IClock> clock{};
+  };
+}
+
+#endif

+ 29 - 0
include/ls-std/time/system-time/WindowsClock.hpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-01
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_WINDOW_CLOCK_HPP
+#define LS_STD_WINDOW_CLOCK_HPP
+
+#include "IClock.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL WindowsClock : public ls::std::time::IClock
+  {
+    public:
+
+      WindowsClock();
+      ~WindowsClock() noexcept override;
+
+      [[nodiscard]] bool setTime(const ls::std::time::DateParameter &_dateParameter) override;
+  };
+}
+
+#endif

+ 21 - 0
include/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h

@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_lynarstudios_ls_std_time_systemtime_SystemTimeJni */
+
+#ifndef _Included_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+#define _Included_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+ * Method:    set
+ * Signature: (Lcom/lynarstudios/ls/std/time/systemtime/DateParameter;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni_set
+  (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 24 - 0
include/ls-std/time/type/DateParameterTypes.hpp

@@ -0,0 +1,24 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_TYPES_HPP
+#define LS_STD_DATE_PARAMETER_TYPES_HPP
+
+namespace ls::std::time::type
+{
+  using Day = uint8_t;
+  using Hour = uint8_t;
+  using Minute = uint8_t;
+  using Month = uint8_t;
+  using Second = uint8_t;
+  using UnixTimestamp = uint32_t;
+  using Year = int;
+}
+
+#endif

+ 2 - 2
source/ls-std/core/LibraryVersion.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-05
-* Changed:         2023-02-23
+* Changed:         2023-03-05
 *
 * */
 
@@ -18,5 +18,5 @@ LibraryVersion::~LibraryVersion() = default;
 
 string LibraryVersion::getVersion()
 {
-  return "2023.1.0";
+  return "2023.2.0";
 }

+ 23 - 3
source/ls-std/core/evaluator/NullPointerArgumentEvaluator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-23
+* Changed:         2023-04-07
 *
 * */
 
@@ -12,15 +12,35 @@
 
 using ls::std::core::IllegalArgumentException;
 using ls::std::core::NullPointerArgumentEvaluator;
+using std::make_shared;
 using std::move;
 using std::shared_ptr;
 using std::string;
 
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const void *_rawArgument)
+{
+  shared_ptr<void> value{};
+
+  if (_rawArgument != nullptr)
+  {
+    value = make_shared<int>();
+  }
+
+  this->argument = value;
+}
+
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const void *_rawArgument, string _message) : NullPointerArgumentEvaluator(_rawArgument)
+{
+  this->message = ::move(_message);
+}
+
 NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument) : argument(_argument)
 {}
 
-NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument, string _message) : argument(_argument), message(::move(_message))
-{}
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument, string _message) : NullPointerArgumentEvaluator(_argument)
+{
+  this->message = ::move(_message);
+}
 
 NullPointerArgumentEvaluator::~NullPointerArgumentEvaluator() noexcept = default;
 

+ 19 - 1
source/ls-std/core/evaluator/NullPointerEvaluator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-23
+* Changed:         2023-04-04
 *
 * */
 
@@ -12,10 +12,28 @@
 
 using ls::std::core::NullPointerEvaluator;
 using ls::std::core::NullPointerException;
+using std::make_shared;
 using std::move;
 using std::shared_ptr;
 using std::string;
 
+NullPointerEvaluator::NullPointerEvaluator(const void *_rawArgument)
+{
+  shared_ptr<void> value{};
+
+  if (_rawArgument != nullptr)
+  {
+    value = make_shared<int>();
+  }
+
+  this->argument = value;
+}
+
+NullPointerEvaluator::NullPointerEvaluator(const void *_rawArgument, string _message) : NullPointerEvaluator(_rawArgument)
+{
+  this->message = ::move(_message);
+}
+
 NullPointerEvaluator::NullPointerEvaluator(const shared_ptr<void> &_argument) : argument(_argument)
 {}
 

+ 2 - 13
source/ls-std/core/exception/EventNotHandledException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ EventNotHandledException::~EventNotHandledException() noexcept = default;
 
 const char *EventNotHandledException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "event was not handled - nothing happened!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("event was not handled - nothing happened!");
 }

+ 2 - 13
source/ls-std/core/exception/EventNotSubscribedException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ EventNotSubscribedException::~EventNotSubscribedException() noexcept = default;
 
 const char *EventNotSubscribedException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "event was not subscribed!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("event was not subscribed!");
 }

+ 15 - 3
source/ls-std/core/exception/Exception.cpp

@@ -3,11 +3,12 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-22
-* Changed:         2023-02-23
+* Changed:         2023-03-28
 *
 * */
 
 #include <ls-std/core/exception/Exception.hpp>
+#include <ls-std/core/exception/ExceptionMessage.hpp>
 
 using ls::std::core::Exception;
 using std::move;
@@ -23,7 +24,18 @@ string Exception::getName() const
   return this->name;
 }
 
-const char *Exception::what() const noexcept
+const char *Exception::_getIdentifiedMessage(const string &_defaultMessage) const
 {
-  return "base exception class in use - method not implemented!";
+  string concatenatedMessage = this->name + " thrown - ";
+
+  if (this->message.empty())
+  {
+    concatenatedMessage = concatenatedMessage + _defaultMessage;
+  }
+  else
+  {
+    concatenatedMessage = concatenatedMessage + this->message;
+  }
+
+  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
 }

+ 2 - 13
source/ls-std/core/exception/FileNotFoundException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ FileNotFoundException::~FileNotFoundException() noexcept = default;
 
 const char *FileNotFoundException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "file not found!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("file not found!");
 }

+ 2 - 13
source/ls-std/core/exception/FileOperationException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ FileOperationException::~FileOperationException() noexcept = default;
 
 const char *FileOperationException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "file operation failed!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("file operation failed!");
 }

+ 2 - 13
source/ls-std/core/exception/IllegalArgumentException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ IllegalArgumentException::~IllegalArgumentException() noexcept = default;
 
 const char *IllegalArgumentException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "passed argument is not valid!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("passed argument is not valid!");
 }

+ 2 - 13
source/ls-std/core/exception/IllegalArithmeticOperationException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ IllegalArithmeticOperationException::~IllegalArithmeticOperationException() noex
 
 const char *IllegalArithmeticOperationException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "arithmetic operation is not allowed!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("arithmetic operation is not allowed!");
 }

+ 2 - 13
source/ls-std/core/exception/IncompleteJsonException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ IncompleteJsonException::~IncompleteJsonException() noexcept = default;
 
 const char *IncompleteJsonException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "this JSON string is incomplete.";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("this JSON string is incomplete.");
 }

+ 2 - 13
source/ls-std/core/exception/IndexOutOfBoundsException.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-10
-* Changed:         2023-02-23
+* Changed:         2023-03-28
 *
 * */
 
@@ -27,16 +27,5 @@ IndexOutOfBoundsException::~IndexOutOfBoundsException() noexcept = default;
 
 const char *IndexOutOfBoundsException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "provided index is out of bounds!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("provided index is out of bounds!");
 }

+ 33 - 0
source/ls-std/core/exception/NotImplementedException.cpp

@@ -0,0 +1,33 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-27
+* Changed:         2023-03-28
+*
+* */
+
+#include <ls-std/core/exception/ExceptionMessage.hpp>
+#include <ls-std/core/exception/NotImplementedException.hpp>
+#include <string>
+
+using ls::std::core::Exception;
+using ls::std::core::ExceptionMessage;
+using ls::std::core::NotImplementedException;
+using std::move;
+using std::string;
+
+NotImplementedException::NotImplementedException() : Exception("NotImplementedException")
+{}
+
+NotImplementedException::NotImplementedException(string _message) : NotImplementedException()
+{
+  this->message = ::move(_message);
+}
+
+NotImplementedException::~NotImplementedException() noexcept = default;
+
+const char *NotImplementedException::what() const noexcept
+{
+  return this->_getIdentifiedMessage("method is not implemented and should not be used!");
+}

+ 2 - 13
source/ls-std/core/exception/NullPointerException.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-04
- * Changed:         2023-02-23
+ * Changed:         2023-03-28
  *
  * */
 
@@ -27,16 +27,5 @@ NullPointerException::~NullPointerException() noexcept = default;
 
 const char *NullPointerException::what() const noexcept
 {
-  string concatenatedMessage = this->name + " thrown - ";
-
-  if (this->message.empty())
-  {
-    concatenatedMessage = concatenatedMessage + "reference is null!";
-  }
-  else
-  {
-    concatenatedMessage = concatenatedMessage + this->message;
-  }
-
-  return ExceptionMessage{concatenatedMessage}.toCharacterPointer();
+  return this->_getIdentifiedMessage("reference is null!");
 }

+ 16 - 0
source/ls-std/core/interface/IJniApi.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/interface/IJniApi.hpp>
+
+using ls::std::core::experimental::interface_type::IJniApi;
+
+IJniApi::IJniApi() = default;
+
+IJniApi::~IJniApi() = default;

+ 73 - 0
source/ls-std/core/jni/JniApi.cpp

@@ -0,0 +1,73 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/core/jni/JniApi.hpp>
+
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::core::experimental::JniApi;
+using std::string;
+
+JniApi::JniApi(JNIEnv *_environment)
+{
+  NullPointerArgumentEvaluator{_environment, "Java environment is not being provided!"}.evaluate();
+  this->environment = _environment;
+}
+
+JniApi::~JniApi() noexcept = default;
+
+jboolean JniApi::callBooleanMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallBooleanMethod(_javaObject, _methodId);
+}
+
+jbyte JniApi::callByteMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallByteMethod(_javaObject, _methodId);
+}
+
+jchar JniApi::callCharMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallCharMethod(_javaObject, _methodId);
+}
+
+jdouble JniApi::callDoubleMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallDoubleMethod(_javaObject, _methodId);
+}
+
+jfloat JniApi::callFloatMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallFloatMethod(_javaObject, _methodId);
+}
+
+jint JniApi::callIntMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallIntMethod(_javaObject, _methodId);
+}
+
+jlong JniApi::callLongMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallLongMethod(_javaObject, _methodId);
+}
+
+jshort JniApi::callShortMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallShortMethod(_javaObject, _methodId);
+}
+
+jclass JniApi::findClass(const string &_classPath)
+{
+  return this->environment->FindClass(_classPath.c_str());
+}
+
+jmethodID JniApi::getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature)
+{
+  return this->environment->GetMethodID(_javaClass, _methodIdentifier, _methodSignature);
+}

+ 203 - 0
source/ls-std/core/jni/JniClass.cpp

@@ -0,0 +1,203 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/ConditionalFunctionExecutor.hpp>
+#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/core/evaluator/NullPointerEvaluator.hpp>
+#include <ls-std/core/jni/JniApi.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <memory>
+
+using ls::std::core::ConditionalFunctionExecutor;
+using ls::std::core::EmptyStringArgumentEvaluator;
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::core::NullPointerEvaluator;
+using ls::std::core::experimental::JniApi;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::JniMethod;
+using ls::std::core::experimental::JniReturnValue;
+using std::make_pair;
+using std::make_shared;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+
+JniClass::JniClass(const shared_ptr<JniClassParameter> &_parameter, const string &_path)
+{
+  NullPointerArgumentEvaluator{_parameter, "no provided reference to JNI class parameter!"}.evaluate();
+  EmptyStringArgumentEvaluator{_path, "path to associated Java class is empty!"}.evaluate();
+  NullPointerArgumentEvaluator{_parameter->getJavaEnvironment(), "Java environment is not being provided!"}.evaluate();
+  this->parameter = _parameter;
+  this->path = _path;
+  ConditionalFunctionExecutor{_parameter->getJniApi() == nullptr}.execute([this]() { _createJniApi(); });
+}
+
+JniClass::~JniClass() = default;
+
+JniReturnValue JniClass::callMethod(const string &_methodIdentifier)
+{
+  JniReturnValue returnValue{};
+
+  if (this->_hasMethod(_methodIdentifier))
+  {
+    this->_callBooleanMethod(_methodIdentifier, returnValue);
+    this->_callByteMethod(_methodIdentifier, returnValue);
+    this->_callCharMethod(_methodIdentifier, returnValue);
+    this->_callDoubleMethod(_methodIdentifier, returnValue);
+    this->_callFloatMethod(_methodIdentifier, returnValue);
+    this->_callIntMethod(_methodIdentifier, returnValue);
+    this->_callLongMethod(_methodIdentifier, returnValue);
+    this->_callShortMethod(_methodIdentifier, returnValue);
+  }
+
+  return returnValue;
+}
+
+bool JniClass::hasMethod(const string &_methodIdentifier)
+{
+  return this->_hasMethod(_methodIdentifier);
+}
+
+bool JniClass::load()
+{
+  this->javaClass = this->parameter->getJniApi()->findClass(this->path);
+  return this->javaClass != nullptr;
+}
+
+bool JniClass::loadMethod(const string &_methodIdentifier, const string &_methodSignature)
+{
+  NullPointerEvaluator{this->javaClass, "no Java class reference available for loading class method!"}.evaluate();
+  jmethodID methodId = this->parameter->getJniApi()->getMethodId(this->javaClass, _methodIdentifier.c_str(), _methodSignature.c_str());
+  bool succeeded = methodId != nullptr && !this->_hasMethod(_methodIdentifier);
+
+  if (succeeded)
+  {
+    JniMethod method{_methodIdentifier, _methodSignature};
+    method.setMethodId(methodId);
+    succeeded = this->methods.insert(make_pair<string, JniMethod>(string{_methodIdentifier}, JniMethod{method})).second;
+  }
+
+  return succeeded;
+}
+
+void JniClass::_callBooleanMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")Z";
+  string methodSignature = method.getMethodSignature();
+  bool hasBooleanReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasBooleanReturnType)
+  {
+    _returnValue.setBooleanValue(this->parameter->getJniApi()->callBooleanMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callByteMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")B";
+  string methodSignature = method.getMethodSignature();
+  bool hasByteReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasByteReturnType)
+  {
+    _returnValue.setByteValue(this->parameter->getJniApi()->callByteMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callCharMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")C";
+  string methodSignature = method.getMethodSignature();
+  bool hasCharReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasCharReturnType)
+  {
+    _returnValue.setCharValue(this->parameter->getJniApi()->callCharMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callDoubleMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")D";
+  string methodSignature = method.getMethodSignature();
+  bool hasDoubleReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasDoubleReturnType)
+  {
+    _returnValue.setDoubleValue(this->parameter->getJniApi()->callDoubleMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callFloatMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")F";
+  string methodSignature = method.getMethodSignature();
+  bool hasFloatReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasFloatReturnType)
+  {
+    _returnValue.setFloatValue(this->parameter->getJniApi()->callFloatMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callIntMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")I";
+  string methodSignature = method.getMethodSignature();
+  bool hasIntegerReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasIntegerReturnType)
+  {
+    _returnValue.setIntegerValue(this->parameter->getJniApi()->callIntMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callLongMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")J";
+  string methodSignature = method.getMethodSignature();
+  bool hasLongReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasLongReturnType)
+  {
+    _returnValue.setLongValue(this->parameter->getJniApi()->callLongMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callShortMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")S";
+  string methodSignature = method.getMethodSignature();
+  bool hasShortReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasShortReturnType)
+  {
+    _returnValue.setShortValue(this->parameter->getJniApi()->callShortMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_createJniApi()
+{
+  this->parameter->setJniApi(make_shared<JniApi>(this->parameter->getJavaEnvironment()));
+}
+
+bool JniClass::_hasMethod(const string &_methodIdentifier)
+{
+  return this->methods.find(_methodIdentifier) != this->methods.end();
+}

+ 49 - 0
source/ls-std/core/jni/JniClassParameter.cpp

@@ -0,0 +1,49 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/jni/JniClassParameter.hpp>
+
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::interface_type::IJniApi;
+using std::shared_ptr;
+using std::string;
+
+JniClassParameter::JniClassParameter() = default;
+
+JniClassParameter::~JniClassParameter() = default;
+
+JNIEnv *JniClassParameter::getJavaEnvironment()
+{
+  return this->environment;
+}
+
+jobject JniClassParameter::getJavaObject()
+{
+  return this->javaObject;
+}
+
+shared_ptr<IJniApi> JniClassParameter::getJniApi()
+{
+  return this->jniApi;
+}
+
+void JniClassParameter::setJavaEnvironment(JNIEnv *_environment)
+{
+  this->environment = _environment;
+}
+
+void JniClassParameter::setJavaObject(jobject _javaObject)
+{
+  this->javaObject = _javaObject;
+}
+
+void JniClassParameter::setJniApi(const shared_ptr<IJniApi> &_jniApi)
+{
+  this->jniApi = _jniApi;
+}

+ 55 - 0
source/ls-std/core/jni/JniMethod.cpp

@@ -0,0 +1,55 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+#include <ls-std/core/jni/JniMethod.hpp>
+
+using ls::std::core::EmptyStringArgumentEvaluator;
+using ls::std::core::experimental::JniMethod;
+using std::string;
+
+JniMethod::JniMethod(const string &_methodIdentifier, const string &_methodSignature)
+{
+  EmptyStringArgumentEvaluator{_methodIdentifier, "no method identifier has been provided!"}.evaluate();
+  EmptyStringArgumentEvaluator{_methodSignature, "no method signature has been provided!"}.evaluate();
+  this->methodIdentifier = _methodIdentifier;
+  this->methodSignature = _methodSignature;
+}
+
+JniMethod::~JniMethod() = default;
+
+jmethodID JniMethod::getMethodId()
+{
+  return this->methodId;
+}
+
+string JniMethod::getMethodIdentifier()
+{
+  return this->methodIdentifier;
+}
+
+string JniMethod::getMethodSignature()
+{
+  return this->methodSignature;
+}
+
+void JniMethod::setMethodId(jmethodID _methodId)
+{
+  this->methodId = _methodId;
+}
+
+void JniMethod::setMethodIdentifier(const string &_methodIdentifier)
+{
+  this->methodIdentifier = _methodIdentifier;
+}
+
+void JniMethod::setMethodSignature(const string &_methodSignature)
+{
+  this->methodSignature = _methodSignature;
+}

+ 96 - 0
source/ls-std/core/jni/JniReturnValue.cpp

@@ -0,0 +1,96 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/jni/JniReturnValue.hpp>
+
+using ls::std::core::experimental::JniReturnValue;
+
+JniReturnValue::JniReturnValue() = default;
+
+JniReturnValue::~JniReturnValue() = default;
+
+jboolean JniReturnValue::getBooleanValue() const
+{
+  return this->booleanValue;
+}
+
+jbyte JniReturnValue::getByteValue() const
+{
+  return this->byteValue;
+}
+
+jchar JniReturnValue::getCharValue() const
+{
+  return this->charValue;
+}
+
+jdouble JniReturnValue::getDoubleValue() const
+{
+  return this->doubleValue;
+}
+
+jfloat JniReturnValue::getFloatValue() const
+{
+  return this->floatValue;
+}
+
+jint JniReturnValue::getIntegerValue() const
+{
+  return this->integerValue;
+}
+
+jlong JniReturnValue::getLongValue() const
+{
+  return this->longValue;
+}
+
+jshort JniReturnValue::getShortValue() const
+{
+  return this->shortValue;
+}
+
+void JniReturnValue::setBooleanValue(jboolean _booleanValue)
+{
+  this->booleanValue = _booleanValue;
+}
+
+void JniReturnValue::setByteValue(jbyte _byteValue)
+{
+  this->byteValue = _byteValue;
+}
+
+void JniReturnValue::setCharValue(jchar _charValue)
+{
+  this->charValue = _charValue;
+}
+
+void JniReturnValue::setDoubleValue(jdouble _doubleValue)
+{
+  this->doubleValue = _doubleValue;
+}
+
+void JniReturnValue::setFloatValue(jfloat _floatValue)
+{
+  this->floatValue = _floatValue;
+}
+
+void JniReturnValue::setIntegerValue(jint _integerValue)
+{
+  this->integerValue = _integerValue;
+}
+
+void JniReturnValue::setLongValue(jlong _longValue)
+{
+  this->longValue = _longValue;
+}
+
+void JniReturnValue::setShortValue(jshort _shortValue)
+{
+  this->shortValue = _shortValue;
+}

+ 3 - 3
source/ls-std/io/File.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-15
- * Changed:         2023-02-24
+ * Changed:         2023-04-13
  *
  * */
 
@@ -99,7 +99,7 @@ void File::createNewFile()
   }
   else
   {
-    throw FileOperationException{"operation: create new file"};
+    throw FileOperationException{R"lit(file ")lit" + this->absoluteFilePath + R"lit(" could not be created!)lit"};
   }
 }
 
@@ -208,7 +208,7 @@ void File::makeDirectory()
 {
   if (!File::_makeDirectory(this->absoluteFilePath))
   {
-    throw FileOperationException{"operation: create directory"};
+    throw FileOperationException{R"lit(directory ")lit" + this->absoluteFilePath + R"lit(" could not be created!)lit"};
   }
 }
 

+ 48 - 4
source/ls-std/io/logging/Logger.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-20
- * Changed:         2023-02-23
+ * Changed:         2023-04-12
  *
  * */
 
@@ -67,6 +67,16 @@ LogLevel Logger::getLogLevel()
   return this->logLevel;
 }
 
+void Logger::hideLogLevel()
+{
+  this->displayLogLevel = false;
+}
+
+void Logger::hideTimestamp()
+{
+  this->displayTimestamp = false;
+}
+
 void Logger::info(const byte_type *_data)
 {
   if (this->logLevel >= LogLevelValue::INFO)
@@ -80,6 +90,16 @@ void Logger::setLogLevel(const LogLevelValue &_logLevelValue)
   this->logLevel = _logLevelValue;
 }
 
+void Logger::showLogLevel()
+{
+  this->displayLogLevel = true;
+}
+
+void Logger::showTimestamp()
+{
+  this->displayTimestamp = true;
+}
+
 void Logger::trace(const byte_type *_data)
 {
   if (this->logLevel >= LogLevelValue::TRACE)
@@ -136,13 +156,37 @@ string Logger::_generateTimeString(tm *_localTime)
   return _stream.str();
 }
 
-void Logger::_log(const byte_type *_data, const LogLevel &_logLevel)
+string Logger::_getLogLevelString(const LogLevel &_logLevel) const
+{
+  string logLevelString{};
+
+  if (this->displayLogLevel)
+  {
+    logLevelString = Logger::_padRight(string{_logLevel.toString() + ":"});
+  }
+
+  return logLevelString;
+}
+
+string Logger::_getTimestampString() const
 {
   time_t timestamp = ::time(nullptr);
   tm *localTime = localtime(&timestamp);
+  string timestampString{};
 
-  string logLevelString = Logger::_padRight(string{_logLevel.toString() + ":"});
-  string message = "[" + Logger::_generateTimeString(localTime) + "] " + logLevelString + string(_data) + NewLine::getUnixNewLine();
+  if (this->displayTimestamp)
+  {
+    timestampString = "[" + Logger::_generateTimeString(localTime) + "] ";
+  }
+
+  return timestampString;
+}
+
+void Logger::_log(const byte_type *_data, const LogLevel &_logLevel)
+{
+  string logLevelString = this->_getLogLevelString(_logLevel);
+  string timestampString = this->_getTimestampString();
+  string message = timestampString + logLevelString + string(_data) + NewLine::getUnixNewLine();
   this->writer->write(message);
 }
 

+ 2 - 2
source/ls-std/io/section-pair/validator/SectionPairIdentifierValidator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-09
-* Changed:         2023-02-23
+* Changed:         2023-04-13
 *
 * */
 
@@ -36,5 +36,5 @@ bool SectionPairIdentifierValidator::isValid()
 
 string SectionPairIdentifierValidator::_getValidationRegex()
 {
-  return R"([a-z]([a-z0-9-]){1,31})";
+  return R"([a-z]([a-z0-9-]){1,63})";
 }

+ 2 - 2
source/ls-std/io/section-pair/validator/SectionPairValueValidator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-09
-* Changed:         2023-02-23
+* Changed:         2023-04-13
 *
 * */
 
@@ -40,6 +40,6 @@ bool SectionPairValueValidator::isValid()
 
 string SectionPairValueValidator::_getValidationRegex()
 {
-  string value = R"([a-zA-Z0-9\-_#!?\[\]\{\}\(\)\$ۤ<>+:;., \*\/"]{1,32})";
+  string value = R"([a-zA-Z0-9\-_#!?\[\]\{\}\(\)\$ۤ<>+:;., \*\/"]{1,512})";
   return value;
 }

+ 90 - 0
source/ls-std/time/common/DateParameter.cpp

@@ -0,0 +1,90 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/common/DateParameter.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::type::Day;
+using ls::std::time::type::Hour;
+using ls::std::time::type::Minute;
+using ls::std::time::type::Month;
+using ls::std::time::type::Second;
+using ls::std::time::type::Year;
+
+DateParameter::DateParameter(Year _year, Month _month, Day _day, Hour _hour, Minute _minute, Second _second) : year(_year), month(_month), day(_day), hour(_hour), minute(_minute), second(_second)
+{}
+
+DateParameter::DateParameter() = default;
+
+DateParameter::~DateParameter() = default;
+
+bool DateParameter::operator==(const DateParameter &_dateParameter) const
+{
+  return this->day == _dateParameter.getDay() && this->hour == _dateParameter.getHour() && this->minute == _dateParameter.getMinute() && this->month == _dateParameter.getMonth() && this->second == _dateParameter.getSecond() && this->year == _dateParameter.getYear();
+}
+
+Day DateParameter::getDay() const
+{
+  return this->day;
+}
+
+Hour DateParameter::getHour() const
+{
+  return this->hour;
+}
+
+Minute DateParameter::getMinute() const
+{
+  return this->minute;
+}
+
+Month DateParameter::getMonth() const
+{
+  return this->month;
+}
+
+Second DateParameter::getSecond() const
+{
+  return this->second;
+}
+
+Year DateParameter::getYear() const
+{
+  return this->year;
+}
+
+void DateParameter::setDay(Day _day)
+{
+  this->day = _day;
+}
+
+void DateParameter::setHour(Hour _hour)
+{
+  this->hour = _hour;
+}
+
+void DateParameter::setMinute(Minute _minute)
+{
+  this->minute = _minute;
+}
+
+void DateParameter::setMonth(Month _month)
+{
+  this->month = _month;
+}
+
+void DateParameter::setSecond(Second _second)
+{
+  this->second = _second;
+}
+
+void DateParameter::setYear(Year _year)
+{
+  this->year = _year;
+}

+ 56 - 0
source/ls-std/time/common/DateParameterMapper.cpp

@@ -0,0 +1,56 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-04-01
+*
+* */
+
+#if defined(unix) || defined(__APPLE__)
+  #include <ctime>
+#endif
+#include <ls-std/time/common/DateParameterMapper.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::type::UnixTimestamp;
+
+DateParameterMapper::DateParameterMapper() = default;
+
+DateParameterMapper::~DateParameterMapper() = default;
+
+#if defined(unix) || defined(__APPLE__)
+UnixTimestamp DateParameterMapper::toUnixTimestamp(const DateParameter &_dateParameter)
+{
+  time_t rawTime{};
+  ::time(&rawTime);
+  tm *timeInfo = localtime(&rawTime);
+  timeInfo->tm_year = _dateParameter.getYear() - 1900;
+  timeInfo->tm_mon = _dateParameter.getMonth() - 1;
+  timeInfo->tm_mday = _dateParameter.getDay();
+  timeInfo->tm_hour = _dateParameter.getHour();
+  timeInfo->tm_min = _dateParameter.getMinute();
+  timeInfo->tm_sec = _dateParameter.getSecond();
+  timeInfo->tm_isdst = -1;
+
+  return (UnixTimestamp) mktime(timeInfo);
+}
+#endif
+
+#ifdef _WIN32
+SYSTEMTIME DateParameterMapper::toWindowsSystemTime(const DateParameter &_dateParameter)
+{
+  SYSTEMTIME systemTime{};
+  systemTime.wYear = _dateParameter.getYear();
+  systemTime.wMonth = _dateParameter.getMonth();
+  systemTime.wDayOfWeek = 0;
+  systemTime.wDay = _dateParameter.getDay();
+  systemTime.wHour = _dateParameter.getHour();
+  systemTime.wMinute = _dateParameter.getMinute();
+  systemTime.wSecond = _dateParameter.getSecond();
+  systemTime.wMilliseconds = 0;
+
+  return systemTime;
+}
+#endif

+ 35 - 0
source/ls-std/time/common/jni/JniDateParameterMapper.cpp

@@ -0,0 +1,35 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+
+using ls::std::core::experimental::JniClass;
+using ls::std::time::DateParameter;
+using ls::std::time::experimental::JniDateParameterMapper;
+
+JniDateParameterMapper::JniDateParameterMapper() = default;
+
+JniDateParameterMapper::~JniDateParameterMapper() = default;
+
+DateParameter JniDateParameterMapper::toDateParameter(const JniClass &_javaClass)
+{
+  JniClass javaClass = _javaClass;
+  DateParameter dateParameter{};
+
+  dateParameter.setYear(javaClass.callMethod("getYear").getIntegerValue());
+  dateParameter.setMonth(javaClass.callMethod("getMonth").getByteValue());
+  dateParameter.setDay(javaClass.callMethod("getDay").getByteValue());
+  dateParameter.setHour(javaClass.callMethod("getHour").getByteValue());
+  dateParameter.setMinute(javaClass.callMethod("getMinute").getByteValue());
+  dateParameter.setSecond(javaClass.callMethod("getSecond").getByteValue());
+
+  return dateParameter;
+}

+ 16 - 0
source/ls-std/time/system-time/IClock.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/system-time/IClock.hpp>
+
+using ls::std::time::IClock;
+
+IClock::IClock() = default;
+
+IClock::~IClock() = default;

+ 28 - 0
source/ls-std/time/system-time/PosixClock.cpp

@@ -0,0 +1,28 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#include <ctime>
+#include <ls-std/time/common/DateParameterMapper.hpp>
+#include <ls-std/time/system-time/PosixClock.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::PosixClock;
+using ls::std::time::type::UnixTimestamp;
+
+PosixClock::PosixClock() = default;
+
+PosixClock::~PosixClock() noexcept = default;
+
+bool PosixClock::setTime(const DateParameter &_dateParameter)
+{
+  UnixTimestamp timestamp = DateParameterMapper::toUnixTimestamp(_dateParameter);
+  timespec timespec{timestamp, 0};
+  return clock_settime(CLOCK_REALTIME, &timespec) == 0;
+}

+ 65 - 0
source/ls-std/time/system-time/SystemTime.cpp

@@ -0,0 +1,65 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#include <ls-std/core/Class.hpp>
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#if defined(unix) || defined(__APPLE__)
+  #include <ls-std/time/system-time/PosixClock.hpp>
+#endif
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#ifdef _WIN32
+  #include <ls-std/time/system-time/WindowsClock.hpp>
+#endif
+#include <memory>
+
+using ls::std::core::Class;
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::time::DateParameter;
+#if defined(unix) || defined(__APPLE__)
+using ls::std::time::PosixClock;
+#endif
+using ls::std::time::SystemTime;
+using ls::std::time::SystemTimeParameter;
+#ifdef _WIN32
+using ls::std::time::WindowsClock;
+#endif
+using ls::std::time::type::UnixTimestamp;
+using std::make_shared;
+using std::shared_ptr;
+
+SystemTime::SystemTime(const shared_ptr<SystemTimeParameter> &_parameter) : SystemTime()
+{
+  NullPointerArgumentEvaluator{_parameter}.evaluate();
+  this->parameter = _parameter;
+}
+
+SystemTime::SystemTime() : Class("SystemTime")
+{
+  this->_generateParameter();
+}
+
+SystemTime::~SystemTime() noexcept = default;
+
+bool SystemTime::set(const DateParameter &_dateParameter)
+{
+  return this->parameter->getClock()->setTime(_dateParameter);
+}
+
+void SystemTime::_generateParameter()
+{
+  this->parameter = make_shared<SystemTimeParameter>();
+
+#if defined(unix) || defined(__APPLE__)
+  this->parameter->setClock(make_shared<PosixClock>());
+#endif
+#ifdef _WIN32
+  this->parameter->setClock(make_shared<WindowsClock>());
+#endif
+}

+ 29 - 0
source/ls-std/time/system-time/SystemTimeParameter.cpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#include <memory>
+
+using ls::std::time::IClock;
+using ls::std::time::SystemTimeParameter;
+using std::shared_ptr;
+
+SystemTimeParameter::SystemTimeParameter() = default;
+
+SystemTimeParameter::~SystemTimeParameter() = default;
+
+shared_ptr<IClock> SystemTimeParameter::getClock()
+{
+  return this->clock;
+}
+
+void SystemTimeParameter::setClock(const shared_ptr<IClock> &_clock)
+{
+  this->clock = _clock;
+}

+ 26 - 0
source/ls-std/time/system-time/WindowsClock.cpp

@@ -0,0 +1,26 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-01
+* Changed:         2023-04-01
+*
+* */
+
+#include <ls-std/time/common/DateParameterMapper.hpp>
+#include <ls-std/time/system-time/WindowsClock.hpp>
+#include <windows.h>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::WindowsClock;
+
+WindowsClock::WindowsClock() = default;
+
+WindowsClock::~WindowsClock() noexcept = default;
+
+bool WindowsClock::setTime(const DateParameter &_dateParameter)
+{
+  SYSTEMTIME systemTime = DateParameterMapper::toWindowsSystemTime(_dateParameter);
+  return SetLocalTime(&systemTime);
+}

+ 69 - 0
source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp

@@ -0,0 +1,69 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-16
+* Changed:         2023-04-10
+*
+* */
+
+#include <iostream>
+#include <ls-std/core/evaluator/NullPointerEvaluator.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/core/jni/JniClassParameter.hpp>
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h>
+#include <memory>
+
+using ls::std::core::NullPointerEvaluator;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::time::DateParameter;
+using ls::std::time::SystemTime;
+using ls::std::time::experimental::JniDateParameterMapper;
+using ls::std::time::type::Day;
+using ls::std::time::type::Hour;
+using ls::std::time::type::Minute;
+using ls::std::time::type::Month;
+using ls::std::time::type::Second;
+using ls::std::time::type::Year;
+using std::cout;
+using std::endl;
+using std::make_shared;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+
+JNIEXPORT jboolean JNICALL Java_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni_set(JNIEnv *_environment, jobject _object, jobject _dateParameter)
+{
+  shared_ptr<JniClassParameter> parameter = make_shared<JniClassParameter>();
+  parameter->setJavaEnvironment(_environment);
+  parameter->setJavaObject(_dateParameter);
+
+  JniClass javaClass{parameter, "com/lynarstudios/ls/std/time/systemtime/DateParameter"};
+  javaClass.load();
+
+  javaClass.loadMethod("getYear", "()I");
+  javaClass.loadMethod("getMonth", "()B");
+  javaClass.loadMethod("getDay", "()B");
+  javaClass.loadMethod("getHour", "()B");
+  javaClass.loadMethod("getMinute", "()B");
+  javaClass.loadMethod("getSecond", "()B");
+
+  // map
+
+  DateParameter dateParameter = JniDateParameterMapper::toDateParameter(javaClass);
+  bool success = SystemTime{}.set(dateParameter);
+
+  if (success)
+  {
+    cout << R"lit(system time successfully set to ")lit" << dateParameter.getYear() << "-" << (int) dateParameter.getMonth() << "-" << (int) dateParameter.getDay() << " " << (int) dateParameter.getHour() << ":" << (int) dateParameter.getMinute() << ":" << (int) dateParameter.getSecond() << R"lit(" ...)lit" << endl;
+  }
+  else
+  {
+    cout << "could not set system time ..." << endl;
+  }
+
+  return success;
+}

+ 2 - 8
test/cases/boxing/BooleanTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-09
- * Changed:         2023-02-24
+ * Changed:         2023-03-25
  *
  * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class BooleanTest : public Test
   {
-    protected:
+    public:
 
       BooleanTest() = default;
       ~BooleanTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/boxing/DoubleTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class DoubleTest : public Test
   {
-    protected:
+    public:
 
       DoubleTest() = default;
       ~DoubleTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/boxing/FloatTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class FloatTest : public Test
   {
-    protected:
+    public:
 
       FloatTest() = default;
       ~FloatTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/boxing/IntegerTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-09
- * Changed:         2023-02-24
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class IntegerTest : public Test
   {
-    protected:
+    public:
 
       IntegerTest() = default;
       ~IntegerTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/boxing/LongTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-17
- * Changed:         2023-02-24
+ * Changed:         2023-03-25
  *
  * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class LongTest : public Test
   {
-    protected:
+    public:
 
       LongTest() = default;
       ~LongTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/boxing/StringTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -18,16 +18,10 @@ namespace
 {
   class StringTest : public Test
   {
-    protected:
+    public:
 
       StringTest() = default;
       ~StringTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // assignment operators

+ 2 - 8
test/cases/core/ClassTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-16
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -22,16 +22,10 @@ namespace
 {
   class ClassTest : public Test
   {
-    protected:
+    public:
 
       ClassTest() = default;
       ~ClassTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(ClassTest, constructor_empty_parameter)

+ 2 - 8
test/cases/core/ConditionalFunctionExecutorTest.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-13
-* Changed:         2023-02-22
+* Changed:         2023-03-25
 *
 * */
 
@@ -21,16 +21,10 @@ namespace
 {
   class ConditionalFunctionExecutorTest : public Test
   {
-    protected:
+    public:
 
       ConditionalFunctionExecutorTest() = default;
       ~ConditionalFunctionExecutorTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(ConditionalFunctionExecutorTest, execute)

+ 3 - 9
test/cases/core/LibraryVersionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-02
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -17,20 +17,14 @@ namespace
 {
   class LibraryVersionTest : public Test
   {
-    protected:
+    public:
 
       LibraryVersionTest() = default;
       ~LibraryVersionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(LibraryVersionTest, getVersion)
   {
-    ASSERT_STREQ("2023.1.0", LibraryVersion::getVersion().c_str());
+    ASSERT_STREQ("2023.2.0", LibraryVersion::getVersion().c_str());
   }
 }

+ 2 - 8
test/cases/core/VersionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-09-28
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -17,16 +17,10 @@ namespace
 {
   class VersionTest : public Test
   {
-    protected:
+    public:
 
       VersionTest() = default;
       ~VersionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // implementation

+ 2 - 8
test/cases/core/evaluator/EmptyStringArgumentEvaluatorTest.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-03-25
 *
 * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class EmptyStringArgumentEvaluatorTest : public Test
   {
-    protected:
+    public:
 
       EmptyStringArgumentEvaluatorTest() = default;
       ~EmptyStringArgumentEvaluatorTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(EmptyStringArgumentEvaluatorTest, evaluate)

+ 2 - 8
test/cases/core/evaluator/IndexOutOfBoundsEvaluatorTest.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-10
-* Changed:         2023-02-22
+* Changed:         2023-03-25
 *
 * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class IndexOutOfBoundsEvaluatorTest : public Test
   {
-    protected:
+    public:
 
       IndexOutOfBoundsEvaluatorTest() = default;
       ~IndexOutOfBoundsEvaluatorTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(IndexOutOfBoundsEvaluatorTest, evaluate)

+ 49 - 9
test/cases/core/evaluator/NullPointerArgumentEvaluatorTest.cpp

@@ -3,16 +3,18 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-07
 *
 * */
 
 #include <gtest/gtest.h>
 #include <ls-std/ls-std-core.hpp>
+#include <memory>
 #include <string>
 
 using ls::std::core::IllegalArgumentException;
 using ls::std::core::NullPointerArgumentEvaluator;
+using std::shared_ptr;
 using std::string;
 using testing::Test;
 
@@ -20,25 +22,61 @@ namespace
 {
   class NullPointerArgumentEvaluatorTest : public Test
   {
-    protected:
+    public:
 
       NullPointerArgumentEvaluatorTest() = default;
       ~NullPointerArgumentEvaluatorTest() override = default;
+  };
 
-      void SetUp() override
-      {}
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_raw_pointer)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerArgumentEvaluator{nullptr}.evaluate();
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - passed argument is null!";
 
-      void TearDown() override
-      {}
-  };
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_raw_pointer_with_dedicated_message)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerArgumentEvaluator(nullptr, "this reference is null!").evaluate();
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - this reference is null!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
 
   TEST_F(NullPointerArgumentEvaluatorTest, evaluate)
   {
+    shared_ptr<void> value{};
+
     EXPECT_THROW(
         {
           try
           {
-            NullPointerArgumentEvaluator{nullptr}.evaluate();
+            NullPointerArgumentEvaluator{value}.evaluate();
           }
           catch (const IllegalArgumentException &_exception)
           {
@@ -54,11 +92,13 @@ namespace
 
   TEST_F(NullPointerArgumentEvaluatorTest, evaluate_dedicated_message)
   {
+    shared_ptr<void> value{};
+
     EXPECT_THROW(
         {
           try
           {
-            NullPointerArgumentEvaluator(nullptr, "this reference is null!").evaluate();
+            NullPointerArgumentEvaluator(value, "this reference is null!").evaluate();
           }
           catch (const IllegalArgumentException &_exception)
           {

+ 49 - 9
test/cases/core/evaluator/NullPointerEvaluatorTest.cpp

@@ -3,16 +3,18 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-04
 *
 * */
 
 #include <gtest/gtest.h>
 #include <ls-std/ls-std-core.hpp>
+#include <memory>
 #include <string>
 
 using ls::std::core::NullPointerEvaluator;
 using ls::std::core::NullPointerException;
+using std::shared_ptr;
 using std::string;
 using testing::Test;
 
@@ -20,25 +22,61 @@ namespace
 {
   class NullPointerArgumentTest : public Test
   {
-    protected:
+    public:
 
       NullPointerArgumentTest() = default;
       ~NullPointerArgumentTest() override = default;
+  };
 
-      void SetUp() override
-      {}
+  TEST_F(NullPointerArgumentTest, evaluate_raw_pointer)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerEvaluator{nullptr}.evaluate();
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - reference in use is null!";
 
-      void TearDown() override
-      {}
-  };
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+
+  TEST_F(NullPointerArgumentTest, evaluate_raw_pointer_dedicated_message)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerEvaluator(nullptr, "this reference is not set and causes this exception!").evaluate();
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - this reference is not set and causes this exception!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
 
   TEST_F(NullPointerArgumentTest, evaluate)
   {
+    shared_ptr<void> value{};
+
     EXPECT_THROW(
         {
           try
           {
-            NullPointerEvaluator{nullptr}.evaluate();
+            NullPointerEvaluator{value}.evaluate();
           }
           catch (const NullPointerException &_exception)
           {
@@ -54,11 +92,13 @@ namespace
 
   TEST_F(NullPointerArgumentTest, evaluate_dedicated_message)
   {
+    shared_ptr<void> value{};
+
     EXPECT_THROW(
         {
           try
           {
-            NullPointerEvaluator(nullptr, "this reference is not set and causes this exception!").evaluate();
+            NullPointerEvaluator(value, "this reference is not set and causes this exception!").evaluate();
           }
           catch (const NullPointerException &_exception)
           {

+ 2 - 8
test/cases/core/exception/EventNotHandledExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-27
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class EventNotHandledExceptionTest : public Test
   {
-    protected:
+    public:
 
       EventNotHandledExceptionTest() = default;
       ~EventNotHandledExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(EventNotHandledExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/EventNotSubscribedExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-27
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class EventNotSubscribedExceptionTest : public Test
   {
-    protected:
+    public:
 
       EventNotSubscribedExceptionTest() = default;
       ~EventNotSubscribedExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(EventNotSubscribedExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/ExceptionMessageTest.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-07
-* Changed:         2023-02-22
+* Changed:         2023-03-25
 *
 * */
 
@@ -18,16 +18,10 @@ namespace
 {
   class ExceptionMessageTest : public Test
   {
-    protected:
+    public:
 
       ExceptionMessageTest() = default;
       ~ExceptionMessageTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(ExceptionMessageTest, toCharacterPointer)

+ 2 - 8
test/cases/core/exception/FileNotFoundExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class FileNotFoundExceptionTest : public Test
   {
-    protected:
+    public:
 
       FileNotFoundExceptionTest() = default;
       ~FileNotFoundExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(FileNotFoundExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/FileOperationExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class FileOperationExceptionTest : public Test
   {
-    protected:
+    public:
 
       FileOperationExceptionTest() = default;
       ~FileOperationExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(FileOperationExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/IllegalArgumentExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class IllegalArgumentExceptionTest : public Test
   {
-    protected:
+    public:
 
       IllegalArgumentExceptionTest() = default;
       ~IllegalArgumentExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(IllegalArgumentExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/IllegalArithmeticOperationExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class IllegalArithmeticOperationExceptionTest : public Test
   {
-    protected:
+    public:
 
       IllegalArithmeticOperationExceptionTest() = default;
       ~IllegalArithmeticOperationExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(IllegalArithmeticOperationExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/IncompleteJsonExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class IncompleteJsonExceptionTest : public Test
   {
-    protected:
+    public:
 
       IncompleteJsonExceptionTest() = default;
       ~IncompleteJsonExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(IncompleteJsonExceptionTest, constructor)

+ 2 - 8
test/cases/core/exception/IndexOutOfBoundsExceptionTest.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-10
-* Changed:         2023-02-22
+* Changed:         2023-03-25
 *
 * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class IndexOutOfBoundsExceptionTest : public Test
   {
-    protected:
+    public:
 
       IndexOutOfBoundsExceptionTest() = default;
       ~IndexOutOfBoundsExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(IndexOutOfBoundsExceptionTest, constructor)

+ 72 - 0
test/cases/core/exception/NotImplementedExceptionTest.cpp

@@ -0,0 +1,72 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-27
+* Changed:         2023-03-27
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core.hpp>
+#include <string>
+
+using ls::std::core::NotImplementedException;
+using std::string;
+using testing::Test;
+
+namespace
+{
+  class NotImplementedExceptionTest : public Test
+  {
+    public:
+
+      NotImplementedExceptionTest() = default;
+      ~NotImplementedExceptionTest() override = default;
+  };
+
+  TEST_F(NotImplementedExceptionTest, constructor)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            throw NotImplementedException{};
+          }
+          catch (const NotImplementedException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - method is not implemented and should not be used!";
+
+            EXPECT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NotImplementedException);
+  }
+
+  TEST_F(NotImplementedExceptionTest, constructor_dedicated_message)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            throw NotImplementedException{R"lit(method "marshal" is not implemented!)lit"};
+          }
+          catch (const NotImplementedException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + R"lit( thrown - method "marshal" is not implemented!)lit";
+
+            EXPECT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NotImplementedException);
+  }
+
+  TEST_F(NotImplementedExceptionTest, getName)
+  {
+    ASSERT_STREQ("NotImplementedException", NotImplementedException{}.getName().c_str());
+  }
+}

+ 2 - 8
test/cases/core/exception/NullPointerExceptionTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2021-05-01
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class NullPointerExceptionTest : public Test
   {
-    protected:
+    public:
 
       NullPointerExceptionTest() = default;
       ~NullPointerExceptionTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(NullPointerExceptionTest, constructor)

+ 50 - 0
test/cases/core/jni/JniApiTest.cpp

@@ -0,0 +1,50 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <string>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::experimental::JniApi;
+using std::string;
+using testing::Test;
+
+namespace
+{
+  class JniApiTest : public Test
+  {
+    public:
+
+      JniApiTest() = default;
+      ~JniApiTest() override = default;
+  };
+
+  TEST_F(JniApiTest, constructor)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniApi jniApi{nullptr};
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+
+            string expected = _exception.getName() + " thrown - Java environment is not being provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+}

+ 77 - 0
test/cases/core/jni/JniClassParameterTest.cpp

@@ -0,0 +1,77 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std-core-jni-test.hpp>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <memory>
+
+using ls::std::core::experimental::JniApi;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::interface_type::IJniApi;
+using std::make_shared;
+using std::shared_ptr;
+using test::core::jni::MockJniApi;
+using testing::Test;
+
+namespace
+{
+  class JniClassParameterTest : public Test
+  {
+    public:
+
+      JniClassParameterTest() = default;
+      ~JniClassParameterTest() override = default;
+  };
+
+  TEST_F(JniClassParameterTest, getJavaEnvironment)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJavaEnvironment() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, getJavaObject)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJavaObject() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, getJniApi)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJniApi() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, setJavaEnvironment)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<JNIEnv> environment = make_shared<JNIEnv>();
+    parameter.setJavaEnvironment(environment.get());
+
+    ASSERT_TRUE(parameter.getJavaEnvironment() == environment.get());
+  }
+
+  TEST_F(JniClassParameterTest, setJavaObject)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<_jobject> javaObject = make_shared<_jobject>();
+    parameter.setJavaObject(javaObject.get());
+
+    ASSERT_TRUE(parameter.getJavaObject() == javaObject.get());
+  }
+
+  TEST_F(JniClassParameterTest, setJniApi)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<IJniApi> jniApi = make_shared<MockJniApi>();
+    parameter.setJniApi(jniApi);
+
+    ASSERT_TRUE(parameter.getJniApi() == jniApi);
+  }
+}

+ 369 - 0
test/cases/core/jni/JniClassTest.cpp

@@ -0,0 +1,369 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <ls-std-core-jni-test.hpp>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <memory>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::NullPointerException;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using std::make_shared;
+using std::shared_ptr;
+using std::string;
+using test::core::jni::MockJniApi;
+using testing::AtLeast;
+using testing::Return;
+using testing::Test;
+
+namespace
+{
+  class JniClassTest : public Test
+  {
+    public:
+
+      JniClassTest() = default;
+      ~JniClassTest() override = default;
+
+      JniClass createJniClass(const string &_classPath)
+      {
+        shared_ptr<JniClassParameter> parameter = make_shared<JniClassParameter>();
+        this->jniApi = make_shared<MockJniApi>();
+        parameter->setJniApi(this->jniApi);
+        shared_ptr<JNIEnv> environment = make_shared<JNIEnv>();
+        parameter->setJavaEnvironment(environment.get());
+
+        return JniClass{parameter, _classPath};
+      }
+
+      shared_ptr<MockJniApi> jniApi{};
+  };
+
+  TEST_F(JniClassTest, constructor_no_parameter_reference)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(nullptr, "java.utils.String");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no provided reference to JNI class parameter!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, constructor_empty_path)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(make_shared<JniClassParameter>(), "");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - path to associated Java class is empty!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, constructor_no_java_environment_reference)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(make_shared<JniClassParameter>(), "java.utils.String");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - Java environment is not being provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, callMethod_boolean_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "isBlue";
+    string methodSignature = "()Z";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callBooleanMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callBooleanMethod(testing::_, methodId)).WillByDefault(Return(true));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_TRUE(javaClass.callMethod(methodIdentifier).getBooleanValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_byte_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callByteMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callByteMethod(testing::_, methodId)).WillByDefault(Return(22));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(22, javaClass.callMethod(methodIdentifier).getByteValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_char_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getLetter";
+    string methodSignature = "()C";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callCharMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callCharMethod(testing::_, methodId)).WillByDefault(Return('P'));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ('P', javaClass.callMethod(methodIdentifier).getCharValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_double_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getPi";
+    string methodSignature = "()D";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).WillByDefault(Return(3.14159265l));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_DOUBLE_EQ(3.14159265l, javaClass.callMethod(methodIdentifier).getDoubleValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_float_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getPi";
+    string methodSignature = "()F";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callFloatMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callFloatMethod(testing::_, methodId)).WillByDefault(Return(3.14159f));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_FLOAT_EQ(3.14159f, javaClass.callMethod(methodIdentifier).getFloatValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_integer_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getYear";
+    string methodSignature = "()I";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callIntMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callIntMethod(testing::_, methodId)).WillByDefault(Return(1989));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(1989, javaClass.callMethod(methodIdentifier).getIntegerValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_long_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getAmountOfMoney";
+    string methodSignature = "()J";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callLongMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callLongMethod(testing::_, methodId)).WillByDefault(Return(18837828981));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(18837828981, javaClass.callMethod(methodIdentifier).getLongValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_short_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()S";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callShortMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callShortMethod(testing::_, methodId)).WillByDefault(Return(55));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(55, javaClass.callMethod(methodIdentifier).getShortValue());
+  }
+
+  TEST_F(JniClassTest, hasMethod)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    ASSERT_FALSE(javaClass.hasMethod("getDay"));
+  }
+
+  TEST_F(JniClassTest, load)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    ASSERT_TRUE(javaClass.load());
+  }
+
+  TEST_F(JniClassTest, loadMethod)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+  }
+
+  TEST_F(JniClassTest, loadMethod_repeat)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_FALSE(javaClass.loadMethod(methodIdentifier, methodSignature));
+  }
+
+  TEST_F(JniClassTest, loadMethod_without_previous_class_load)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            javaClass.loadMethod(methodIdentifier, methodSignature);
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no Java class reference available for loading class method!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+}

+ 114 - 0
test/cases/core/jni/JniMethodTest.cpp

@@ -0,0 +1,114 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <memory>
+#include <string>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::experimental::JniMethod;
+using std::make_shared;
+using std::string;
+using testing::Test;
+
+namespace
+{
+  class JniMethodTest : public Test
+  {
+    public:
+
+      JniMethodTest() = default;
+      ~JniMethodTest() override = default;
+  };
+
+  TEST_F(JniMethodTest, constructor_empty_method_identifier)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniMethod method("", "()B");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no method identifier has been provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniMethodTest, constructor_empty_method_signature)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniMethod method("getDay", "");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no method signature has been provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniMethodTest, getMethodId)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_TRUE(method.getMethodId() == nullptr);
+  }
+
+  TEST_F(JniMethodTest, getMethodIdentifier)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_STREQ("getDay", method.getMethodIdentifier().c_str());
+  }
+
+  TEST_F(JniMethodTest, getMethodSignature)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_STREQ("()B", method.getMethodSignature().c_str());
+  }
+
+  TEST_F(JniMethodTest, setMethodId)
+  {
+    JniMethod method{"getDay", "()B"};
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    method.setMethodId(methodId);
+
+    ASSERT_TRUE(method.getMethodId() == methodId);
+  }
+
+  TEST_F(JniMethodTest, setMethodIdentifier)
+  {
+    JniMethod method{"getDay", "()B"};
+    method.setMethodIdentifier("getHour");
+
+    ASSERT_STREQ("getHour", method.getMethodIdentifier().c_str());
+  }
+
+  TEST_F(JniMethodTest, setMethodSignature)
+  {
+    JniMethod method{"getDay", "()B"};
+    method.setMethodSignature("()I");
+
+    ASSERT_STREQ("()I", method.getMethodSignature().c_str());
+  }
+}

+ 137 - 0
test/cases/core/jni/JniReturnValueTest.cpp

@@ -0,0 +1,137 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+
+using ls::std::core::experimental::JniReturnValue;
+using testing::Test;
+
+namespace
+{
+  class JniReturnValueTest : public Test
+  {
+    public:
+
+      JniReturnValueTest() = default;
+      ~JniReturnValueTest() override = default;
+  };
+
+  TEST_F(JniReturnValueTest, getBooleanValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FALSE(returnValue.getBooleanValue());
+  }
+
+  TEST_F(JniReturnValueTest, getByteValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getByteValue());
+  }
+
+  TEST_F(JniReturnValueTest, getCharValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, (int) returnValue.getCharValue());
+  }
+
+  TEST_F(JniReturnValueTest, getDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FLOAT_EQ(0.0l, returnValue.getDoubleValue());
+  }
+
+  TEST_F(JniReturnValueTest, getFloatValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FLOAT_EQ(0.0f, returnValue.getFloatValue());
+  }
+
+  TEST_F(JniReturnValueTest, getIntegerValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getIntegerValue());
+  }
+
+  TEST_F(JniReturnValueTest, getLongValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getLongValue());
+  }
+
+  TEST_F(JniReturnValueTest, getShortValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getShortValue());
+  }
+
+  TEST_F(JniReturnValueTest, setBooleanValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setBooleanValue(true);
+
+    ASSERT_TRUE(returnValue.getBooleanValue());
+  }
+
+  TEST_F(JniReturnValueTest, setByteValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setByteValue(22);
+
+    ASSERT_EQ(22, returnValue.getByteValue());
+  }
+
+  TEST_F(JniReturnValueTest, setCharValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setCharValue('P');
+
+    ASSERT_EQ('P', returnValue.getCharValue());
+  }
+
+  TEST_F(JniReturnValueTest, setDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setDoubleValue(3.14159265l);
+
+    ASSERT_FLOAT_EQ(3.14159265l, returnValue.getDoubleValue());
+  }
+
+  TEST_F(JniReturnValueTest, setFloatValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setFloatValue(13.56f);
+
+    ASSERT_FLOAT_EQ(13.56f, returnValue.getFloatValue());
+  }
+
+  TEST_F(JniReturnValueTest, setIntegerValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setIntegerValue(1989);
+
+    ASSERT_EQ(1989, returnValue.getIntegerValue());
+  }
+
+  TEST_F(JniReturnValueTest, setLongValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setLongValue(16992831);
+
+    ASSERT_EQ(16992831, returnValue.getLongValue());
+  }
+
+  TEST_F(JniReturnValueTest, setShortValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setShortValue(13);
+
+    ASSERT_EQ(13, returnValue.getShortValue());
+  }
+}

+ 2 - 8
test/cases/encoding/Base64Test.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-01-08
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -17,16 +17,10 @@ namespace
 {
   class Base64Test : public Test
   {
-    protected:
+    public:
 
       Base64Test() = default;
       ~Base64Test() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(Base64Test, encode)

+ 2 - 8
test/cases/event/EventHandlerTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-27
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -19,16 +19,10 @@ namespace
 {
   class EventHandlerTest : public Test
   {
-    protected:
+    public:
 
       EventHandlerTest() = default;
       ~EventHandlerTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(EventHandlerTest, constructor_empty_parameter)

+ 2 - 8
test/cases/event/EventManagerTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-27
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -31,16 +31,10 @@ namespace
 {
   class EventManagerTest : public Test
   {
-    protected:
+    public:
 
       EventManagerTest() = default;
       ~EventManagerTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(EventManagerTest, getClassName)

+ 2 - 8
test/cases/event/EventTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-26
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -20,16 +20,10 @@ namespace
 {
   class EventTest : public Test
   {
-    protected:
+    public:
 
       EventTest() = default;
       ~EventTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   // additional functionality

+ 2 - 8
test/cases/event/NarratorTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-14
- * Changed:         2023-02-23
+ * Changed:         2023-03-25
  *
  * */
 
@@ -26,17 +26,11 @@ namespace
 {
   class NarratorTest : public Test
   {
-    protected:
+    public:
 
       NarratorTest() = default;
       ~NarratorTest() override = default;
 
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
-
       shared_ptr<TestDataMercedesCar> mercedes1{};
       shared_ptr<TestDataMercedesCar> mercedes2{};
       shared_ptr<TestDataMercedesCar> mercedes3{};

+ 2 - 8
test/cases/event/serialization/SerializableJsonEventTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-12-20
- * Changed:         2023-02-22
+ * Changed:         2023-03-25
  *
  * */
 
@@ -25,16 +25,10 @@ namespace
 {
   class SerializableJsonEventTest : public Test
   {
-    protected:
+    public:
 
       SerializableJsonEventTest() = default;
       ~SerializableJsonEventTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(SerializableJsonEventTest, constructor_parameter_not_set)

+ 2 - 8
test/cases/io/FileOutputStreamTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-20
- * Changed:         2023-02-23
+ * Changed:         2023-03-25
  *
  * */
 
@@ -25,16 +25,10 @@ namespace
 {
   class FileOutputStreamTest : public Test
   {
-    protected:
+    public:
 
       FileOutputStreamTest() = default;
       ~FileOutputStreamTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(FileOutputStreamTest, constructor_file_does_not_exist)

+ 2 - 8
test/cases/io/FileReaderTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-18
- * Changed:         2023-02-23
+ * Changed:         2023-03-25
  *
  * */
 
@@ -26,16 +26,10 @@ namespace
 {
   class FileReaderTest : public Test
   {
-    protected:
+    public:
 
       FileReaderTest() = default;
       ~FileReaderTest() override = default;
-
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
   };
 
   TEST_F(FileReaderTest, constructor_file_does_not_exist)

+ 10 - 8
test/cases/io/FileTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-15
- * Changed:         2023-02-23
+ * Changed:         2023-04-13
  *
  * */
 
@@ -24,19 +24,13 @@ namespace
 {
   class FileTest : public Test
   {
-    protected:
+    public:
 
       FileTest() = default;
       ~FileTest() override = default;
 
       string fileLocation = TestHelper::getResourcesFolderLocation() + "simple.txt";
 
-      void SetUp() override
-      {}
-
-      void TearDown() override
-      {}
-
       static bool hasFileInDirectory(const list<string> &_fileNamesInDirectory, const string &_fileName)
       {
         return find(_fileNamesInDirectory.begin(), _fileNamesInDirectory.end(), _fileName) != _fileNamesInDirectory.end();
@@ -153,6 +147,10 @@ namespace
           }
           catch (const FileOperationException &_exception)
           {
+            string expected = _exception.getName() + R"lit( thrown - file ")lit" + TestHelper::getResourcesFolderLocation() + R"lit(simple.txt" could not be created!)lit";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
             throw;
           }
         },
@@ -324,6 +322,10 @@ namespace
           }
           catch (const FileOperationException &_exception)
           {
+            string expected = _exception.getName() + R"lit( thrown - directory ")lit" + TestHelper::getResourcesFolderLocation() + R"lit(list-test" could not be created!)lit";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
             throw;
           }
         },

Някои файлове не бяха показани, защото твърде много файлове са промени