Browse Source

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

patrick-christopher.mattulat 3 năm trước cách đây
mục cha
commit
4904188daf
100 tập tin đã thay đổi với 2956 bổ sung và 476 xóa
  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;
           }
         },

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác