Forráskód Böngészése

LSSTD-1: Add RuntimeLibrary class

- add RuntimeLibrary class to represent runtime library containing symbols
- add test coverage for RuntimeLibrary
Patrick-Christopher Mattulat 1 éve
szülő
commit
e03fd424cc

+ 29 - 3
CMakeLists.txt

@@ -179,6 +179,7 @@ set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/io/StorableFile.cpp)
 
 set(SOURCE_FILES_OS
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/os/library/RuntimeLibrary.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/os/library/RuntimeLibraryLoader.cpp)
 
 set(SOURCE_FILES_TIME
@@ -258,7 +259,8 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/io/xml/XmlParserTestWrapper.cpp)
 
     set(TEST_FILES_OS
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/os/library/RuntimeLibraryLoaderTest.cpp)
+            #${CMAKE_CURRENT_SOURCE_DIR}/test/cases/os/library/RuntimeLibraryLoaderTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/os/library/RuntimeLibraryTest.cpp)
 
     set(TEST_FILES_SERIALIZATION
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/JsonTest.cpp)
@@ -603,7 +605,7 @@ endif ()
 # Linking (os)
 ##########################################################
 
-if (${LS_STD_BUILD_WITH_TESTS})
+if (${LS_STD_BUILD_WITH_TESTS} AND ${CMAKE_CXX_COMPILER_ID} STREQUAL GNU OR ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
     message("${MODULE_NAME_OS}: Linking libraries for test application...")
     target_link_libraries(${MODULE_NAME_OS}_test
             gtest
@@ -613,6 +615,15 @@ if (${LS_STD_BUILD_WITH_TESTS})
             "${MODULE_NAME_OS}")
 endif ()
 
+if (${LS_STD_BUILD_WITH_TESTS} AND ${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
+    message("${MODULE_NAME_OS}: Linking libraries for test application...")
+    target_link_libraries(${MODULE_NAME_OS}_test
+            gtest
+            gmock
+            gtest_main
+            "${MODULE_NAME_OS}")
+endif ()
+
 ##########################################################
 # Linking (time)
 ##########################################################
@@ -631,7 +642,7 @@ endif ()
 # Linking (all)
 ##########################################################
 
-if (${LS_STD_BUILD_WITH_TESTS})
+if (${LS_STD_BUILD_WITH_TESTS} AND ${CMAKE_CXX_COMPILER_ID} STREQUAL GNU OR ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
     message("${PROJECT_NAME}: Linking libraries for test application...")
     target_link_libraries(${PROJECT_NAME}_test
             gtest
@@ -646,3 +657,18 @@ if (${LS_STD_BUILD_WITH_TESTS})
             "${MODULE_NAME_OS}"
             "${MODULE_NAME_TIME}")
 endif ()
+
+if (${LS_STD_BUILD_WITH_TESTS} AND ${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
+    message("${PROJECT_NAME}: Linking libraries for test application...")
+    target_link_libraries(${PROJECT_NAME}_test
+            gtest
+            gmock
+            gtest_main
+            "${MODULE_NAME_CORE}"
+            "${MODULE_NAME_BOXING}"
+            "${MODULE_NAME_ENCODING}"
+            "${MODULE_NAME_EVENT}"
+            "${MODULE_NAME_IO}"
+            "${MODULE_NAME_OS}"
+            "${MODULE_NAME_TIME}")
+endif ()

+ 21 - 0
include/ls_std/core/types/RuntimeLibraryTypes.hpp

@@ -0,0 +1,21 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2022-10-27
+ * Changed:         2022-10-27
+ *
+ * */
+
+#ifndef LS_STD_RUNTIME_LIBRARY_TYPES_HPP
+#define LS_STD_RUNTIME_LIBRARY_TYPES_HPP
+
+#include <map>
+#include <string>
+
+namespace ls::std::core::type
+{
+  using runtime_library_entry = ::std::pair<::std::string, void*>;
+}
+
+#endif

+ 3 - 2
include/ls_std/ls_std_os.hpp

@@ -2,14 +2,15 @@
  * Author:          Patrick-Christopher Mattulat
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
- * Created:         2022-09-06
- * Changed:         2022-09-06
+ * Created:         2022-10-27
+ * Changed:         2022-10-27
  *
  * */
 
 #ifndef LS_STD_LS_STD_OS_HPP
 #define LS_STD_LS_STD_OS_HPP
 
+#include <ls_std/os/library/RuntimeLibrary.hpp>
 #include <ls_std/os/library/RuntimeLibraryLoader.hpp>
 #include <ls_std/os/library/RuntimeLibraryLoaderParameter.hpp>
 

+ 42 - 0
include/ls_std/os/library/RuntimeLibrary.hpp

@@ -0,0 +1,42 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2022-10-27
+ * Changed:         2022-10-27
+ *
+ * */
+
+#ifndef LS_STD_RUNTIME_LIBRARY_HPP
+#define LS_STD_RUNTIME_LIBRARY_HPP
+
+#include <string>
+#include <ls_std/os/library/goals/dynamic_goal.hpp>
+#include <ls_std/core/types/RuntimeLibraryTypes.hpp>
+#include <unordered_map>
+#include <windows.h>
+
+namespace ls::std::os
+{
+  class LS_STD_DYNAMIC_GOAL RuntimeLibrary
+  {
+    public:
+
+      RuntimeLibrary() = default;
+      ~RuntimeLibrary() = default;
+
+      bool addSymbol(const ls::std::core::type::runtime_library_entry& _entry);
+      void* getSymbol(const ::std::string& _symbolName);
+      bool hasSymbol(const ::std::string& _symbolName);
+
+    private:
+
+      ::std::unordered_map<::std::string, void*> symbols{};
+
+      [[nodiscard]] void* _getSymbol(const ::std::string& _symbolName);
+      [[nodiscard]] bool _hasSymbol(const ::std::string& _symbolName);
+      [[nodiscard]] bool _isValidEntry(const ls::std::core::type::runtime_library_entry& _entry);
+  };
+}
+
+#endif

+ 63 - 0
source/ls_std/os/library/RuntimeLibrary.cpp

@@ -0,0 +1,63 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2022-10-27
+ * Changed:         2022-10-27
+ *
+ * */
+
+#include <ls_std/os/library/RuntimeLibrary.hpp>
+#include <ls_std/core/exception/IllegalArgumentException.hpp>
+
+bool ls::std::os::RuntimeLibrary::addSymbol(const ls::std::core::type::runtime_library_entry& _entry)
+{
+  bool validEntry = this->_isValidEntry(_entry);
+  bool added{};
+
+  if (validEntry && !this->_hasSymbol(_entry.first))
+  {
+    added = this->symbols.emplace(_entry).second;
+  }
+  else
+  {
+    if (!validEntry)
+    {
+      throw ls::std::core::IllegalArgumentException{};
+    }
+  }
+
+  return added;
+}
+
+void *ls::std::os::RuntimeLibrary::getSymbol(const ::std::string &_symbolName)
+{
+  return this->_getSymbol(_symbolName);
+}
+
+bool ls::std::os::RuntimeLibrary::hasSymbol(const ::std::string &_symbolName)
+{
+  return this->_hasSymbol(_symbolName);
+}
+
+void *ls::std::os::RuntimeLibrary::_getSymbol(const ::std::string &_symbolName)
+{
+  void* symbol{};
+
+  if (this->_hasSymbol(_symbolName))
+  {
+    symbol = this->symbols.at(_symbolName);
+  }
+
+  return symbol;
+}
+
+bool ls::std::os::RuntimeLibrary::_hasSymbol(const ::std::string &_symbolName)
+{
+  return this->symbols.find(_symbolName) != this->symbols.end();
+}
+
+bool ls::std::os::RuntimeLibrary::_isValidEntry(const ls::std::core::type::runtime_library_entry &_entry)
+{
+  return !_entry.first.empty() && _entry.second != nullptr;
+}

+ 97 - 0
test/cases/os/library/RuntimeLibraryTest.cpp

@@ -0,0 +1,97 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2022-10-27
+ * Changed:         2022-10-27
+ *
+ * */
+
+#include <gtest/gtest.h>
+#include <ls_std/ls_std_os.hpp>
+#include <ls_std/ls_std_core.hpp>
+
+namespace
+{
+  class RuntimeLibraryTest : public ::testing::Test
+  {
+    protected:
+
+      RuntimeLibraryTest() = default;
+      ~RuntimeLibraryTest() override = default;
+
+      void SetUp() override
+      {}
+
+      void TearDown() override
+      {}
+  };
+
+  TEST_F(RuntimeLibraryTest, addSymbol)
+  {
+    ls::std::os::RuntimeLibrary runtimeLibrary{};
+    ls::std::core::type::runtime_library_entry entry = ::std::make_pair<::std::string, void *>("_func", (void *) ::std::make_shared<int>().get());
+
+    ASSERT_TRUE(runtimeLibrary.addSymbol(entry));
+  }
+
+  TEST_F(RuntimeLibraryTest, addSymbol_empty_key)
+  {
+    EXPECT_THROW({
+                   try
+                   {
+                     ls::std::os::RuntimeLibrary runtimeLibrary{};
+                     runtimeLibrary.addSymbol(::std::make_pair<::std::string, void *>("", (void *) ::std::make_shared<int>().get()));
+                   }
+                   catch (const ls::std::core::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls::std::core::IllegalArgumentException);
+  }
+
+  TEST_F(RuntimeLibraryTest, addSymbol_empty_reference)
+  {
+    EXPECT_THROW({
+                   try
+                   {
+                     ls::std::os::RuntimeLibrary runtimeLibrary{};
+                     runtimeLibrary.addSymbol(::std::make_pair<::std::string, void *>("_func", (void *) nullptr));
+                   }
+                   catch (const ls::std::core::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls::std::core::IllegalArgumentException);
+  }
+
+  TEST_F(RuntimeLibraryTest, getSymbol)
+  {
+    ls::std::os::RuntimeLibrary runtimeLibrary{};
+    ls::std::core::type::runtime_library_entry entry = ::std::make_pair<::std::string, void *>("_func", (void *) ::std::make_shared<int>().get());
+
+    ASSERT_TRUE(runtimeLibrary.addSymbol(entry));
+    ASSERT_TRUE(runtimeLibrary.getSymbol("_func") != nullptr);
+  }
+
+  TEST_F(RuntimeLibraryTest, getSymbol_not_available)
+  {
+    ls::std::os::RuntimeLibrary runtimeLibrary{};
+    ASSERT_TRUE(runtimeLibrary.getSymbol("_func") == nullptr);
+  }
+
+  TEST_F(RuntimeLibraryTest, hasSymbol)
+  {
+    ls::std::os::RuntimeLibrary runtimeLibrary{};
+    ls::std::core::type::runtime_library_entry entry = ::std::make_pair<::std::string, void *>("_func", (void *) ::std::make_shared<int>().get());
+
+    ASSERT_TRUE(runtimeLibrary.addSymbol(entry));
+    ASSERT_TRUE(runtimeLibrary.hasSymbol("_func"));
+  }
+
+  TEST_F(RuntimeLibraryTest, hasSymbol_not_available)
+  {
+    ls::std::os::RuntimeLibrary runtimeLibrary{};
+    ASSERT_FALSE(runtimeLibrary.hasSymbol("_func"));
+  }
+}