#include #include #include #include #include #include #include #include namespace smo { namespace comparator_lib { namespace { void registerExportedComparatorTypes( ComparatorApiManager::Resources& resources, const cologex::ComparatorLibDesc& libDesc) { for (const auto& exportedType : libDesc.exportedComparatorTypes) { const uint64_t packedTypeId = exportedType.typeId.pack(); if (resources.typeRegistry.contains(packedTypeId)) { throw std::runtime_error( std::string(__func__) + ": Duplicate comparator type registration for vendorId=0x" + std::to_string(exportedType.typeId.vendorId) + " typeId=0x" + std::to_string(exportedType.typeId.typeId)); } auto registeredType = std::make_shared( exportedType); resources.typeRegistry.emplace(packedTypeId, registeredType); } } void unregisterExportedComparatorTypes( ComparatorApiManager::Resources& resources, const cologex::ComparatorLibDesc& libDesc) { for (const auto& exportedType : libDesc.exportedComparatorTypes) { resources.typeRegistry.erase(exportedType.typeId.pack()); } } } // namespace ComparatorLib& ComparatorApiManager::loadComparatorLib( const std::string& libraryPath) { loadable_lib::LoadableLibraryManager& llm = loadable_lib::LoadableLibraryManager::getInstance(); if (getComparatorLib(libraryPath)) { throw std::runtime_error( std::string(__func__) + ": ComparatorLib already loaded: " + libraryPath); } std::shared_ptr loadedLibrary = llm.loadSharedLibrary(libraryPath); auto descFn = loadable_lib::LoadableLibraryManager::resolveSymbol< SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF *>( loadedLibrary->getDlopenHandle(), SMO_GET_COMPARATOR_LIB_DESC_FN_NAME_STR); const stim_buff::SmoCallbacks& callbacks = stim_buff::getSmoCallbacks(); const cologex::ComparatorLibDesc& libDesc = descFn(callbacks); auto lib = std::make_shared(loadedLibrary, descFn); lib->setComparatorLibDesc(libDesc); registerExportedComparatorTypes(s.rsrc, lib->comparatorLibDesc); s.rsrc.libs.push_back(lib); return *lib; } void ComparatorApiManager::unloadComparatorLib(const std::string& libraryPath) { auto& libs = s.rsrc.libs; auto it = std::find_if( libs.begin(), libs.end(), [&libraryPath](const std::shared_ptr& lib) { return lib->loadedSharedLibrary->libraryPath == libraryPath; }); if (it == libs.end()) { std::cerr << std::string(__func__) + ": Library not found: " << libraryPath << '\n'; return; } unregisterExportedComparatorTypes(s.rsrc, (*it)->comparatorLibDesc); std::shared_ptr loadedLibrary = (*it)->loadedSharedLibrary; libs.erase(it); loadable_lib::LoadableLibraryManager::getInstance() .unloadSharedLibrary(loadedLibrary); } void ComparatorApiManager::unloadAllComparatorLibs(void) { std::vector> loadedLibrariesTmp; loadedLibrariesTmp.reserve(s.rsrc.libs.size()); for (const auto& lib : s.rsrc.libs) { loadedLibrariesTmp.push_back(lib->loadedSharedLibrary); } s.rsrc.libs.clear(); s.rsrc.typeRegistry.clear(); loadable_lib::LoadableLibraryManager& llm = loadable_lib::LoadableLibraryManager::getInstance(); for (const auto& loadedLibrary : loadedLibrariesTmp) { llm.unloadSharedLibrary(loadedLibrary); } } void ComparatorApiManager::loadAllComparatorApiLibsFromOptions(void) { const auto& options = OptionParser::getOptions(); for (const auto& libPath : options.comparatorLibs) { loadComparatorLib(libPath); } } std::optional> ComparatorApiManager::getComparatorLib(const std::string& libraryPath) { auto& libs = s.rsrc.libs; auto it = std::find_if( libs.begin(), libs.end(), [&libraryPath](const std::shared_ptr& lib) { return lib->loadedSharedLibrary->libraryPath == libraryPath; }); if (it != libs.end()) { return *it; } return std::nullopt; } std::shared_ptr ComparatorApiManager::getComparatorType(cologex::ComparatorTypeId typeId) { const uint64_t packedTypeId = typeId.pack(); auto it = s.rsrc.typeRegistry.find(packedTypeId); if (it == s.rsrc.typeRegistry.end()) { return {}; } return it->second; } std::unique_ptr ComparatorApiManager::getNewComparatorInstance( cologex::ComparatorTypeId typeId) { return getNewComparatorInstance(getComparatorType(typeId)); } std::unique_ptr ComparatorApiManager::getNewComparatorInstance( const std::shared_ptr& comparatorType) { if (!comparatorType) { throw std::runtime_error( std::string(__func__) + ": comparatorType is null"); } if (!comparatorType->getNewInstance) { throw std::runtime_error( std::string(__func__) + ": getNewInstance is null"); } return comparatorType->getNewInstance(); } std::string ComparatorApiManager::stringifyLibs() const { std::string result; for (const auto& lib : s.rsrc.libs) { if (!result.empty()) { result += "\n"; } result += lib->stringify(); } return result; } } // namespace comparator_lib } // namespace smo