diff --git a/.gitignore b/.gitignore index cba86d0575..f607828408 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ *~ *.o *.so CMakeLists.txt.user* gh-pages -examples/makefile/main +core/examples/makefile/main diff --git a/.travis.yml b/.travis.yml index 0773e89567..528cc50dcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,58 @@ language: cpp compiler: - gcc - clang env: + global: + + # -- BEGIN Coverity Scan ENV + + # Pre-configuration steps that should not be analyzed + - COVERITY_SCAN_BUILD_COMMAND_PREPEND="cmake -DUS_BUILD_EXAMPLES:BOOL=ON -DUS_BUILD_TESTING:BOOL=ON -DUS_ENABLE_AUTOLOADING_SUPPORT:BOOL=ON -DUS_ENABLE_THREADING_SUPPORT:BOOL=ON ." + + # The build command with all of the arguments that you would apply to a manual `cov-build` + # Usually this is the same as STANDARD_BUILD_COMMAND, exluding the automated test arguments + - COVERITY_SCAN_BUILD_COMMAND="make -j4" + + - COVERITY_SCAN_PROJECT_NAME="saschazelzer/CppMicroServices" + + # Email address for notifications related to this build + - COVERITY_SCAN_NOTIFICATION_EMAIL="s.zelzer@dkfz-heidelberg.de" + + # Regular expression selects on which branches to run analysis + # Be aware of quotas. Do not run on every branch/commit + - COVERITY_SCAN_BRANCH_PATTERN="development" + + # COVERITY_SCAN_TOKEN via "travis encrypt" using the repo's public key + - secure: "byqeazsk6vCHFoWrZJvLFy/m1KI8sDIEhW7b1yvlGpcCrXQBoDk+dtr3kLCgiYl1+gC39av++0uOJnoM7xn/qiURW65CVDWxa9Giie079M63tqDRbOoeGezhBa8DEXJjhxZ77Iijt0tTOcp/VWg87uSiHSqI+B9HwrWDKwEtSzM=" + + - COVERITY_SCAN_BUILD_URL="https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" + + # -- END Coverity Scan ENV + + matrix: - BUILD_CONFIGURATION=0 - BUILD_CONFIGURATION=1 - BUILD_CONFIGURATION=2 - BUILD_CONFIGURATION=3 - BUILD_CONFIGURATION=4 - BUILD_CONFIGURATION=5 - BUILD_CONFIGURATION=6 - BUILD_CONFIGURATION=7 +matrix: + include: + - language: cpp + compiler: gcc + env: + script: curl -s $COVERITY_SCAN_BUILD_URL | bash + branches: only: - master - development - /^release-.*$/ -script: ctest -VV -S ./CMake/usCTestScript_travis.cmake +script: + - ctest -VV -S ./cmake/usCTestScript_travis.cmake + diff --git a/CMake/usPublicHeaderWrapper.h.in b/CMake/usPublicHeaderWrapper.h.in deleted file mode 100644 index 556302f562..0000000000 --- a/CMake/usPublicHeaderWrapper.h.in +++ /dev/null @@ -1 +0,0 @@ -#include "@_us_public_header@" diff --git a/CMakeLists.txt b/CMakeLists.txt index 2699f6a6a7..08d775bc32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,462 +1,430 @@ project(CppMicroServices) set(${PROJECT_NAME}_MAJOR_VERSION 2) -set(${PROJECT_NAME}_MINOR_VERSION 1) -set(${PROJECT_NAME}_PATCH_VERSION 1) +set(${PROJECT_NAME}_MINOR_VERSION 99) +set(${PROJECT_NAME}_PATCH_VERSION 0) set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION}) cmake_minimum_required(VERSION 2.8) cmake_policy(VERSION 2.8) cmake_policy(SET CMP0017 NEW) #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(CMAKE_MODULE_PATH - ${PROJECT_SOURCE_DIR}/CMake + ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(CMakeParseArguments) include(CMakePackageConfigHelpers) include(CheckCXXSourceCompiles) include(usFunctionCheckCompilerFlags) include(usFunctionEmbedResources) include(usFunctionGetGccVersion) include(usFunctionGenerateModuleInit) include(usFunctionGenerateExecutableInit) #----------------------------------------------------------------------------- # Init output directories #----------------------------------------------------------------------------- set(US_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(US_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(US_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") foreach(_type ARCHIVE LIBRARY RUNTIME) if(NOT CMAKE_${_type}_OUTPUT_DIRECTORY) set(CMAKE_${_type}_OUTPUT_DIRECTORY ${US_${_type}_OUTPUT_DIRECTORY}) endif() endforeach() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # CMake options #----------------------------------------------------------------------------- function(us_cache_var _var_name _var_default _var_type _var_help) set(_advanced 0) set(_force) foreach(_argn ${ARGN}) if(_argn STREQUAL ADVANCED) set(_advanced 1) elseif(_argn STREQUAL FORCE) set(_force FORCE) endif() endforeach() if(US_IS_EMBEDDED) if(NOT DEFINED ${_var_name} OR _force) set(${_var_name} ${_var_default} PARENT_SCOPE) endif() else() set(${_var_name} ${_var_default} CACHE ${_var_type} "${_var_help}" ${_force}) if(_advanced) mark_as_advanced(${_var_name}) endif() endif() endfunction() # Determine if we are being build inside a larger project if(NOT DEFINED US_IS_EMBEDDED) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(US_IS_EMBEDDED 0) else() set(US_IS_EMBEDDED 1) - set(CppMicroServices_EXPORTS 1) endif() endif() # Determine the name of the install component for "SDK" artifacts. # The default is "sdk" if(NOT DEFINED US_SDK_INSTALL_COMPONENT) set(US_SDK_INSTALL_COMPONENT COMPONENT sdk) elseif(US_SDK_INSTALL_COMPONENT) set(US_SDK_INSTALL_COMPONENT COMPONENT ${US_SDK_INSTALL_COMPONENT}) endif() us_cache_var(US_ENABLE_AUTOLOADING_SUPPORT OFF BOOL "Enable module auto-loading support") us_cache_var(US_ENABLE_THREADING_SUPPORT OFF BOOL "Enable threading support") us_cache_var(US_ENABLE_DEBUG_OUTPUT OFF BOOL "Enable debug messages" ADVANCED) us_cache_var(US_ENABLE_RESOURCE_COMPRESSION ON BOOL "Enable resource compression" ADVANCED) us_cache_var(US_BUILD_SHARED_LIBS ON BOOL "Build shared libraries") us_cache_var(US_BUILD_TESTING OFF BOOL "Build tests") +us_cache_var(US_BUILD_EXAMPLES OFF BOOL "Build example projects") + +if(US_BUILD_TESTING) + enable_testing() +endif() if(WIN32 AND NOT CYGWIN) set(default_runtime_install_dir bin/) set(default_library_install_dir bin/) set(default_archive_install_dir lib/) set(default_header_install_dir include/) set(default_auxiliary_install_dir share/) else() set(default_runtime_install_dir bin/) set(default_library_install_dir lib/${PROJECT_NAME}) set(default_archive_install_dir lib/${PROJECT_NAME}) set(default_header_install_dir include/${PROJECT_NAME}) set(default_auxiliary_install_dir share/${PROJECT_NAME}) endif() us_cache_var(RUNTIME_INSTALL_DIR ${default_runtime_install_dir} STRING "Relative install location for binaries" ADVANCED) us_cache_var(LIBRARY_INSTALL_DIR ${default_library_install_dir} STRING "Relative install location for libraries" ADVANCED) us_cache_var(ARCHIVE_INSTALL_DIR ${default_archive_install_dir} STRING "Relative install location for archives" ADVANCED) us_cache_var(HEADER_INSTALL_DIR ${default_header_install_dir} STRING "Relative install location for headers" ADVANCED) us_cache_var(AUXILIARY_INSTALL_DIR ${default_auxiliary_install_dir} STRING "Relative install location for auxiliary files" ADVANCED) +set(AUXILIARY_CMAKE_INSTALL_DIR ${AUXILIARY_INSTALL_DIR}/cmake) -us_cache_var(US_NAMESPACE "us" STRING "The namespace for the C++ micro services entities") -us_cache_var(US_HEADER_PREFIX "" STRING "The file name prefix for the public C++ micro services header files") +us_cache_var(US_NAMESPACE "us" STRING "The namespace for the C++ Micro Services symbols") set(BUILD_SHARED_LIBS ${US_BUILD_SHARED_LIBS}) -set(${PROJECT_NAME}_MODULE_INIT_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/CMake/usModuleInit.cpp" CACHE INTERNAL "The module initialization template code") -set(${PROJECT_NAME}_EXECUTABLE_INIT_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/CMake/usExecutableInit.cpp" CACHE INTERNAL "The executable initialization template code") +set(US_MODULE_INIT_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/usModuleInit.cpp" CACHE INTERNAL "The module initialization template code") +set(US_EXECUTABLE_INIT_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/usExecutableInit.cpp" CACHE INTERNAL "The executable initialization template code") #----------------------------------------------------------------------------- # US C/CXX Flags #----------------------------------------------------------------------------- -set(US_C_FLAGS) -set(US_C_FLAGS_RELEASE) -set(US_CXX_FLAGS) -set(US_CXX_FLAGS_RELEASE) +if(US_IS_EMBEDDED) + set(CMAKE_C_FLAGS) + set(CMAKE_C_FLAGS_RELEASE) + set(CMAKE_C_FLAGS_DEBUG) + set(CMAKE_CXX_FLAGS) + set(CMAKE_CXX_FLAGS_RELEASE) + set(CMAKE_CXX_FLAGS_DEBUG) + set(CMAKE_LINK_FLAGS) + set(CMAKE_LINK_FLAGS_RELEASE) + set(CMAKE_LINK_FLAGS_DEBUG) +endif() # Set C++ compiler flags if(NOT MSVC) foreach(_cxxflag -Werror -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast -Wstrict-null-sentinel -Wsign-promo -fdiagnostics-show-option) usFunctionCheckCompilerFlags(${_cxxflag} US_CXX_FLAGS) endforeach() endif() +set(US_HAVE_VISIBILITY_ATTRIBUTE 0) + if(CMAKE_COMPILER_IS_GNUCXX) usFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) if(${GCC_VERSION} VERSION_LESS "4.0.0") message(FATAL_ERROR "gcc version ${GCC_VERSION} not supported. Please use gcc >= 4.") endif() # With older versions of gcc the flag -fstack-protector-all requires an extra dependency to libssp.so. # If the gcc version is lower than 4.4.0 and the build type is Release let's not include the flag. if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0")) usFunctionCheckCompilerFlags("-fstack-protector-all" US_CXX_FLAGS) endif() if(MINGW) # suppress warnings about auto imported symbols set(US_CXX_FLAGS "-Wl,--enable-auto-import ${US_CXX_FLAGS}") # we need to define a Windows version set(US_CXX_FLAGS "-D_WIN32_WINNT=0x0500 ${US_CXX_FLAGS}") else() # Enable visibility support if(NOT ${GCC_VERSION} VERSION_LESS "4.5") - usFunctionCheckCompilerFlags("-fvisibility=hidden -fvisibility-inlines-hidden" US_CXX_FLAGS) + usFunctionCheckCompilerFlags("-fvisibility=hidden -fvisibility-inlines-hidden" _have_visibility) + if(_have_visibility) + set(US_CXX_FLAGS "${US_CXX_FLAGS} ${_have_visibility}") + set(US_HAVE_VISIBILITY_ATTRIBUTE 1) + endif() else() set(US_GCC_RTTI_WORKAROUND_NEEDED 1) endif() endif() usFunctionCheckCompilerFlags("-O1 -D_FORTIFY_SOURCE=2" _fortify_source_flag) if(_fortify_source_flag) set(US_CXX_FLAGS_RELEASE "${US_CXX_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2") endif() +else() + usFunctionCheckCompilerFlags("-fvisibility=hidden -fvisibility-inlines-hidden" _have_visibility) + if(_have_visibility) + set(US_CXX_FLAGS "${US_CXX_FLAGS} ${_have_visibility}") + set(US_HAVE_VISIBILITY_ATTRIBUTE 1) + endif() +endif() -elseif(MSVC) +if(MSVC) set(US_CXX_FLAGS "/MP /WX /wd4996 /wd4251 /wd4503 ${US_CXX_FLAGS}") endif() -if(NOT US_IS_EMBEDDED) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${US_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${US_CXX_FLAGS_RELEASE}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${US_C_FLAGS}") - set(CMAKE_C_FLAGS_REALEASE "${CMAKE_C_FLAGS_RELEASE} ${US_C_FLAGS_RELEASE}") -endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${US_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${US_CXX_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${US_C_FLAGS}") +set(CMAKE_C_FLAGS_REALEASE "${CMAKE_C_FLAGS_RELEASE} ${US_C_FLAGS_RELEASE}") #----------------------------------------------------------------------------- # US Link Flags #----------------------------------------------------------------------------- set(US_LINK_FLAGS ) if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) foreach(_linkflag -Wl,--no-undefined) set(_add_flag) usFunctionCheckCompilerFlags("${_linkflag}" _add_flag) if(_add_flag) set(US_LINK_FLAGS "${US_LINK_FLAGS} ${_linkflag}") endif() endforeach() endif() #----------------------------------------------------------------------------- # US Header Checks #----------------------------------------------------------------------------- include(CheckIncludeFileCXX) include(CheckCXXSourceCompiles) CHECK_INCLUDE_FILE_CXX(stdint.h US_HAVE_STDINT_H) CHECK_INCLUDE_FILE_CXX(tr1/unordered_map US_HAVE_TR1_UNORDERED_MAP_H) CHECK_INCLUDE_FILE_CXX(tr1/unordered_set US_HAVE_TR1_UNORDERED_SET_H) CHECK_INCLUDE_FILE_CXX(tr1/functional US_HAVE_TR1_FUNCTIONAL_H) CHECK_INCLUDE_FILE_CXX(unordered_map US_HAVE_UNORDERED_MAP_H) CHECK_INCLUDE_FILE_CXX(unordered_set US_HAVE_UNORDERED_SET_H) CHECK_INCLUDE_FILE_CXX(functional US_HAVE_FUNCTIONAL_H) if(US_HAVE_UNORDERED_MAP_H) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::unordered_map m; return 0; }" US_HAVE_TR1_UNORDERED_MAP) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::unordered_map m; return 0; }" US_HAVE_STD_UNORDERED_MAP) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::hash(); return 0; }" US_HAVE_TR1_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::hash(); return 0; }" US_HAVE_STD_HASH) if(US_HAVE_STD_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend struct std::hash; }; int main() { return 0; }" US_HAVE_STD_HASH_STRUCT) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend class std::hash; }; int main() { return 0; }" US_HAVE_STD_HASH_CLASS) elseif(US_HAVE_TR1_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend struct std::tr1::hash; }; int main() { return 0; }" US_HAVE_TR1_HASH_STRUCT) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend class std::tr1::hash; }; int main() { return 0; }" US_HAVE_TR1_HASH_CLASS) endif() elseif(US_HAVE_TR1_UNORDERED_MAP_H) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::unordered_map m; return 0; }" US_HAVE_TR1_UNORDERED_MAP) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::unordered_map m; return 0; }" US_HAVE_STD_UNORDERED_MAP) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::hash(); return 0; }" US_HAVE_TR1_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::hash(); return 0; }" US_HAVE_STD_HASH) if(US_HAVE_STD_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend struct std::hash; }; int main() { return 0; }" US_HAVE_STD_HASH_STRUCT) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend class std::hash; }; int main() { return 0; }" US_HAVE_STD_HASH_CLASS) elseif(US_HAVE_TR1_HASH) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend struct std::tr1::hash; }; int main() { return 0; }" US_HAVE_TR1_HASH_STRUCT) CHECK_CXX_SOURCE_COMPILES("#include \nstruct A { friend class std::tr1::hash; }; int main() { return 0; }" US_HAVE_TR1_HASH_CLASS) endif() else() message(SEND_ERROR "The header file \"unordered_map\" is not available.") endif() if(NOT (US_HAVE_TR1_UNORDERED_MAP OR US_HAVE_STD_UNORDERED_MAP)) message(SEND_ERROR "The \"unordered_map\" type is not available.") endif() if(US_HAVE_UNORDERED_SET_H) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::unordered_set s; return 0; }" US_HAVE_TR1_UNORDERED_SET) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::unordered_set s; return 0; }" US_HAVE_STD_UNORDERED_SET) elseif(US_HAVE_TR1_UNORDERED_SET_H) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::unordered_set s; return 0; }" US_HAVE_TR1_UNORDERED_SET) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::unordered_set s; return 0; }" US_HAVE_STD_UNORDERED_SET) else() message(SEND_ERROR "The header file \"unordered_set\" is not available.") endif() if(NOT (US_HAVE_TR1_UNORDERED_SET OR US_HAVE_STD_UNORDERED_SET)) message(SEND_ERROR "The \"unordered_set\" type is not available.") endif() if(NOT (US_HAVE_FUNCTIONAL_H OR US_HAVE_TR1_FUNCTIONAL_H)) message(SEND_ERROR "The header file \"functional\" is not available.") endif() if(US_HAVE_FUNCTIONAL_H) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::function f(main); return 0; }" US_HAVE_TR1_FUNCTION) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::function f(main); return 0; }" US_HAVE_STD_FUNCTION) endif() if((NOT (US_HAVE_STD_FUNCTION OR US_HAVE_TR1_FUNCTION)) AND US_HAVE_TR1_FUNCTIONAL_H) unset(US_HAVE_TR1_FUNCTION CACHE) unset(US_HAVE_STD_FUNCTION CACHE) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::tr1::function f(main); return 0; }" US_HAVE_TR1_FUNCTION) CHECK_CXX_SOURCE_COMPILES("#include \nint main() { std::function f(main); return 0; }" US_HAVE_STD_FUNCTION) endif() if(NOT (US_HAVE_STD_FUNCTION OR US_HAVE_TR1_FUNCTION)) message(SEND_ERROR "The \"function\" type is not available.") endif() #----------------------------------------------------------------------------- -# US include dirs and libraries +# Source directory #----------------------------------------------------------------------------- -set(US_INCLUDE_DIRS - ${PROJECT_BINARY_DIR}/include -) +set(US_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) -set(US_INTERNAL_INCLUDE_DIRS - ${PROJECT_BINARY_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/src/util - ${CMAKE_CURRENT_SOURCE_DIR}/src/service - ${CMAKE_CURRENT_SOURCE_DIR}/src/module -) +# Configure CppMicroServicesConfig.cmake for the build tree. +# The file is used in sub-directories. -# link library for third party libs -if(US_IS_EMBEDDED) - set(US_LIBRARY_TARGET ${US_EMBEDDING_LIBRARY}) -else() - set(US_LIBRARY_TARGET ${PROJECT_NAME}) -endif() - -# link libraries for the CppMicroServices lib -set(US_LINK_LIBRARIES ) -if(UNIX) - list(APPEND US_LINK_LIBRARIES dl) -endif() - -#----------------------------------------------------------------------------- -# Source directory -#----------------------------------------------------------------------------- - -set(us_config_h_file "${PROJECT_BINARY_DIR}/include/usConfig.h") -configure_file(usConfig.h.in ${us_config_h_file}) +set(PACKAGE_CONFIG_INCLUDE_DIR ${US_INCLUDE_DIRS}) +set(PACKAGE_CONFIG_RUNTIME_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +set(PACKAGE_CONFIG_CMAKE_DIR ${PROJECT_SOURCE_DIR}/cmake) set(US_RCC_EXECUTABLE_NAME usResourceCompiler) set(CppMicroServices_RCC_EXECUTABLE_NAME ${US_RCC_EXECUTABLE_NAME} CACHE INTERNAL "The target name of the usResourceCompiler executable.") -add_subdirectory(tools) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + @ONLY + ) -add_subdirectory(src) +set(us_global_config_h_file "${PROJECT_BINARY_DIR}/include/usGlobalConfig.h") +configure_file(${PROJECT_SOURCE_DIR}/cmake/usGlobalConfig.h.in ${us_global_config_h_file}) +include_directories(${US_INCLUDE_DIRS}) -#----------------------------------------------------------------------------- -# US testing -#----------------------------------------------------------------------------- +add_subdirectory(tools) -if(US_BUILD_TESTING) - enable_testing() - add_subdirectory(test) -endif() +add_subdirectory(core) #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- -add_subdirectory(documentation) +add_subdirectory(doc) #----------------------------------------------------------------------------- # Last configuration and install steps #----------------------------------------------------------------------------- -if(NOT US_IS_EMBEDDED) - export(TARGETS ${PROJECT_NAME} ${US_RCC_EXECUTABLE_NAME} - FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) - install(EXPORT ${PROJECT_NAME}Targets - FILE ${PROJECT_NAME}Targets.cmake - DESTINATION ${AUXILIARY_INSTALL_DIR}/CMake/) -endif() + +export(TARGETS ${US_RCC_EXECUTABLE_NAME} + FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) +install(EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR}) set(_install_cmake_scripts - ${${PROJECT_NAME}_MODULE_INIT_TEMPLATE} - ${${PROJECT_NAME}_EXECUTABLE_INIT_TEMPLATE} - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeParseArguments.cmake - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/usFunctionGenerateModuleInit.cmake - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/usFunctionGenerateExecutableInit.cmake - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/usFunctionEmbedResources.cmake + ${US_MODULE_INIT_TEMPLATE} + ${US_EXECUTABLE_INIT_TEMPLATE} + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeParseArguments.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindPackageHandleStandardArgs.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindPackageMessage.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/usFunctionGenerateModuleInit.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/usFunctionGenerateExecutableInit.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/usFunctionEmbedResources.cmake ) install(FILES ${_install_cmake_scripts} - DESTINATION ${AUXILIARY_INSTALL_DIR}/CMake/ - ) + DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR}) -# Configure CppMicroServicesConfig.cmake for the build tree - -set(PACKAGE_CONFIG_INCLUDE_DIR ${US_INCLUDE_DIRS}) -set(PACKAGE_CONFIG_RUNTIME_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -set(PACKAGE_CONFIG_CMAKE_DIR ${PROJECT_SOURCE_DIR}/CMake) -if(US_IS_EMBEDDED) - set(PACKAGE_EMBEDDED "if(@PROJECT_NAME@_IS_EMBEDDED) - set(@PROJECT_NAME@_INTERNAL_INCLUDE_DIRS @US_INTERNAL_INCLUDE_DIRS@) - set(@PROJECT_NAME@_SOURCES @US_SOURCES@) - set(@PROJECT_NAME@_PUBLIC_HEADERS @US_PUBLIC_HEADERS@) - set(@PROJECT_NAME@_PRIVATE_HEADERS @US_PRIVATE_HEADERS@) -endif()") -else() - set(PACKAGE_EMBEDDED ) -endif() - -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in - ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - @ONLY - ) +install(FILES ${us_global_config_h_file} + DESTINATION ${HEADER_INSTALL_DIR}) # Configure CppMicroServicesConfig.cmake for the install tree set(CONFIG_INCLUDE_DIR ${HEADER_INSTALL_DIR}) set(CONFIG_RUNTIME_DIR ${RUNTIME_INSTALL_DIR}) -set(CONFIG_CMAKE_DIR ${AUXILIARY_INSTALL_DIR}/CMake) +set(CONFIG_CMAKE_DIR ${AUXILIARY_CMAKE_INSTALL_DIR}) configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${AUXILIARY_INSTALL_DIR}/CMake/ + INSTALL_DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR} PATH_VARS CONFIG_INCLUDE_DIR CONFIG_RUNTIME_DIR CONFIG_CMAKE_DIR NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO ) # Version information configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake @ONLY ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - DESTINATION ${AUXILIARY_INSTALL_DIR}/CMake/ + DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT} ) - -#----------------------------------------------------------------------------- -# Build the examples -#----------------------------------------------------------------------------- - -option(US_BUILD_EXAMPLES "Build example projects" OFF) -if(US_BUILD_EXAMPLES) - if(NOT US_BUILD_SHARED_LIBS) - message(WARNING "Examples are not available if US_BUILD_SHARED_LIBS is OFF") - else() - set(CppMicroServices_DIR ${PROJECT_BINARY_DIR}) - add_subdirectory(examples) - endif() -endif() diff --git a/CppMicroServicesConfig.cmake.in b/CppMicroServicesConfig.cmake.in index 45c131937a..5220365511 100644 --- a/CppMicroServicesConfig.cmake.in +++ b/CppMicroServicesConfig.cmake.in @@ -1,34 +1,194 @@ -@PACKAGE_INIT@ +# A package config for @PROJECT_NAME@. +# This file loads component specific configuration files and +# sets the following variables which can be used in other +# CMake projects to build and link against @PROJECT_NAME@: +# +# US_INCLUDE_DIRS +# US_LIBRARIES +# US_RUNTIME_LIBRARY_DIRS +# +# The following variables are aliases for the ones above: +# +# CppMicroServices_INCLUDE_DIRS +# CppMicroServices_LIBRARIES +# CppMicroServices_RUNTIME_LIBRARY_DIRS +# +# To specify a compatible version for a specific component, +# set the following variable before calling find_package: +# +# US__FIND_VERSION +# +# After find_package returns successfully, the following additional +# variables will be set: +# +# US_FOUND +# CPPMICROSERVICES_FOUND +# +# US_RCC_EXECUTABLE +# +# US_CXX_FLAGS +# US_CXX_FLAGS_RELEASE +# US_CXX_FLAGS_DEBUG +# US_C_FLAGS +# US_C_FLAGS_RELEASE +# US_C_FLAGS_DEBUG +# US_LINK_FLAGS +# US_LINK_FLAGS_RELEASE +# US_LINK_FLAGS_DEBUG +# US_COMPILE_DEFINITIONS +# US_COMPILE_DEFINITIONS_RELEASE +# US_COMPILE_DEFINITIONS_DEBUG +# +# US_VERSION +# US_VERSION_MAJOR +# US_VERSION_MINOR +# US_VERSION_PATCH +# US_VERSION_TWEAK +# US_VERSION_COUNT +# +# Additional component specific variables: +# +# US__FOUND +# +# US__VERSION +# US__VERSION_MAJOR +# US__VERSION_MINOR +# US__VERSION_PATCH +# US__VERSION_TWEAK +# US__VERSION_COUNT +# +# US__CXX_FLAGS +# US__CXX_FLAGS_RELEASE +# US__CXX_FLAGS_DEBUG +# US__C_FLAGS +# US__C_FLAGS_RELEASE +# US__C_FLAGS_DEBUG +# US__LINK_FLAGS +# US__LINK_FLAGS_RELEASE +# US__LINK_FLAGS_DEBUG +# US__COMPILE_DEFINITIONS +# US__COMPILE_DEFINITIONS_RELEASE +# US__COMPILE_DEFINITIONS_DEBUG +# -set(@PROJECT_NAME@_CXX_FLAGS "@US_CXX_FLAGS@") -set(@PROJECT_NAME@_CXX_FLAGS_RELEASE "@US_CXX_FLAGS_RELEASE@") -set(@PROJECT_NAME@_CXX_FLAGS_DEBUG "@US_CXX_FLAGS_DEBUG@") -set(@PROJECT_NAME@_C_FLAGS "@US_C_FLAGS@") -set(@PROJECT_NAME@_C_FLAGS_RELEASE "@US_C_FLAGS_RELEASE@") -set(@PROJECT_NAME@_C_FLAGS_DEBUG "@US_C_FLAGS_DEBUG@") +@PACKAGE_INIT@ -set(@PROJECT_NAME@_INCLUDE_DIR @PACKAGE_CONFIG_INCLUDE_DIR@) +list(APPEND CMAKE_MODULE_PATH "@PACKAGE_CONFIG_CMAKE_DIR@") -set(@PROJECT_NAME@_RCC_EXECUTABLE_NAME @CppMicroServices_RCC_EXECUTABLE_NAME@) -set(@PROJECT_NAME@_MODULE_INIT_TEMPLATE @PACKAGE_CONFIG_CMAKE_DIR@/usModuleInit.cpp) -set(@PROJECT_NAME@_EXECUTABLE_INIT_TEMPLATE @PACKAGE_CONFIG_CMAKE_DIR@/usExecutableInit.cpp) +set(US_RCC_EXECUTABLE_NAME @US_RCC_EXECUTABLE_NAME@) +set(US_MODULE_INIT_TEMPLATE "@PACKAGE_CONFIG_CMAKE_DIR@/usModuleInit.cpp") +set(US_EXECUTABLE_INIT_TEMPLATE "@PACKAGE_CONFIG_CMAKE_DIR@/usExecutableInit.cpp") -set(@PROJECT_NAME@_INCLUDE_DIRS ${@PROJECT_NAME@_INCLUDE_DIR}) -set(@PROJECT_NAME@_LIBRARIES @US_LIBRARY_TARGET@) +set(US_IS_EMBEDDED @US_IS_EMBEDDED@) -find_program(@PROJECT_NAME@_RCC_EXECUTABLE ${@PROJECT_NAME@_RCC_EXECUTABLE_NAME} +# The CppMicroServices resource compiler +find_program(US_RCC_EXECUTABLE ${US_RCC_EXECUTABLE_NAME} PATHS "@PACKAGE_CONFIG_RUNTIME_DIR@" PATH_SUFFIXES Release Debug RelWithDebInfo MinSizeRel) -mark_as_advanced(@PROJECT_NAME@_RCC_EXECUTABLE) - -set(@PROJECT_NAME@_IS_EMBEDDED @US_IS_EMBEDDED@) -@PACKAGE_EMBEDDED@ +mark_as_advanced(US_RCC_EXECUTABLE) -if(NOT TARGET @PROJECT_NAME@ AND NOT @PROJECT_NAME@_IS_EMBEDDED) - include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake) +# Include helper macros +include(CMakeParseArguments) +if(CMAKE_VERSION VERSION_LESS "2.8.8") + # We need the HANDLE_COMPONENTS argument + include(@PACKAGE_CONFIG_CMAKE_DIR@/FindPackageHandleStandardArgs.cmake) +elseif(NOT COMMAND find_package_handle_standard_args) + include(FindPackageHandleStandardArgs) endif() - -include(@PACKAGE_CONFIG_CMAKE_DIR@/CMakeParseArguments.cmake) include(@PACKAGE_CONFIG_CMAKE_DIR@/usFunctionGenerateModuleInit.cmake) include(@PACKAGE_CONFIG_CMAKE_DIR@/usFunctionGenerateExecutableInit.cmake) include(@PACKAGE_CONFIG_CMAKE_DIR@/usFunctionEmbedResources.cmake) + +# Global include directory +set(US_INCLUDE_DIRS "@PACKAGE_CONFIG_INCLUDE_DIR@") + +# Clear variables +set(US_LIBRARIES ) +set(US_RUNTIME_LIBRARY_DIRS ) +set(US_CXX_FLAGS ) +set(US_CXX_FLAGS_RELEASE ) +set(US_CXX_FLAGS_DEBUG ) +set(US_C_FLAGS ) +set(US_C_FLAGS_RELEASE ) +set(US_C_FLAGS_DEBUG ) +set(US_LINK_FLAGS ) +set(US_LINK_FLAGS_RELEASE ) +set(US_LINK_FLAGS_DEBUG ) +set(US_COMPILE_DEFINITIONS ) +set(US_COMPILE_DEFINITIONS_RELEASE ) +set(US_COMPILE_DEFINITIONS_DEBUG ) + +# Components support +set(US_MODULES Core) # ConfigAdmin EventAdmin ... + +if(NOT @PROJECT_NAME@_FIND_COMPONENTS) + set(@PROJECT_NAME@_FIND_COMPONENTS Core) +endif() + +set(@PROJECT_NAME@_FOUND TRUE) +foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS}) + if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/us${component}Config.cmake") + set(US_${component}_FOUND 0) + set(CppMicroServices_${component}_FOUND 0) + else() + find_package(us${component} ${US_${component}_FIND_VERSION} QUIET REQUIRED + HINTS ${CMAKE_CURRENT_LIST_DIR} + NO_DEFAULT_PATH + ) + mark_as_advanced(us${component}_DIR) + set(US_${component}_FOUND ${us${component}_FOUND}) + set(CppMicroServices_${component}_FOUND ${US_${component}_FOUND}) + endif() + + if(US_${component}_FOUND) + list(APPEND US_INCLUDE_DIRS ${US_${component}_INCLUDE_DIRS}) + list(APPEND US_LIBRARIES ${US_${component}_LIBRARIES}) + list(APPEND US_RUNTIME_LIBRARY_DIRS ${US_${component}_RUNTIME_LIBRARY_DIRS}) + set(US_CXX_FLAGS "${US_CXX_FLAGS} ${US_${component}_CXX_FLAGS}") + set(US_CXX_FLAGS_RELEASE "${US_CXX_FLAGS_RELEASE} ${US_${component}_CXX_FLAGS_RELEASE}") + set(US_CXX_FLAGS_DEBUG "${US_CXX_FLAGS_DEBUG} ${US_${component}_CXX_FLAGS_DEBUG}") + set(US_C_FLAGS "${US_C_FLAGS} ${US_${component}_C_FLAGS}") + set(US_C_FLAGS_RELEASE "${US_C_FLAGS_RELEASE} ${US_${component}_C_FLAGS_RELEASE}") + set(US_C_FLAGS_DEBUG "${US_C_FLAGS_DEBUG} ${US_${component}_C_FLAGS_DEBUG}") + set(US_LINK_FLAGS "${US_LINK_FLAGS} ${US_${component}_LINK_FLAGS}") + set(US_LINK_FLAGS_RELEASE "${US_LINK_FLAGS_RELEASE} ${US_${component}_LINK_FLAGS_RELEASE}") + set(US_LINK_FLAGS_DEBUG "${US_LINK_FLAGS_DEBUG} ${US_${component}_LINK_FLAGS_DEBUG}") + set(US_COMPILE_DEFINITIONS "${US_COMPILE_DEFINITIONS} ${US_${component}_COMPILE_DEFINITIONS}") + set(US_COMPILE_DEFINITIONS_RELEASE "${US_COMPILE_DEFINITIONS_RELEASE} ${US_${component}_COMPILE_DEFINITIONS_RELEASE}") + set(US_COMPILE_DEFINITIONS_DEBUG "${US_COMPILE_DEFINITIONS_DEBUG} ${US_${component}_COMPILE_DEFINITIONS_DEBUG}") + + set(US_${component}_VERSION ${${component}_VERSION}) + set(US_${component}_VERSION_MAJOR ${${component}_VERSION_MAJOR}) + set(US_${component}_VERSION_MINOR ${${component}_VERSION_MINOR}) + set(US_${component}_VERSION_PATCH ${${component}_VERSION_PATCH}) + set(US_${component}_VERSION_TWEAK ${${component}_VERSION_TWEAK}) + set(US_${component}_VERSION_COUNT ${${component}_VERSION_COUNT}) + else() + if(@PROJECT_NAME@_FIND_REQUIRED_${component}) + set(@PROJECT_NAME@_FOUND FALSE) + endif() + endif() +endforeach() + +if(US_INCLUDE_DIRS) + list(REMOVE_DUPLICATES US_INCLUDE_DIRS) +endif() +if(US_LIBRARIES) + list(REMOVE_DUPLICATES US_LIBRARIES) +endif() +if(US_RUNTIME_LIBRARY_DIRS) + list(REMOVE_DUPLICATES US_RUNTIME_LIBRARY_DIRS) +endif() + +set(CppMicroServices_INCLUDE_DIRS ${US_INCLUDE_DIRS}) +set(CppMicroServices_LIBRARIES ${US_LIBRARIES}) +set(CppMicroServices_RUNTIME_LIBRARY_DIRS ${US_RUNTIME_LIBRARY_DIRS}) + +set(@PROJECT_NAME@_CONFIG ${CMAKE_CURRENT_LIST_FILE}) +find_package_handle_standard_args(@PROJECT_NAME@ + HANDLE_COMPONENTS + CONFIG_MODE +) + +string(TOUPPER "@PROJECT_NAME@" @PROJECT_NAME@_UPPER) +set(US_FOUND ${${@PROJECT_NAME@_UPPER}_FOUND}) diff --git a/README.md b/README.md index 5524513091..05b4c242e4 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,100 @@ [![Build Status](https://secure.travis-ci.org/saschazelzer/CppMicroServices.png)](http://travis-ci.org/saschazelzer/CppMicroServices) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/1329/badge.svg)](https://scan.coverity.com/projects/1329) + C++ Micro Services ================== Introduction ------------ The C++ Micro Services library provides a dynamic service registry and module system, partially based the OSGi Core Release 5 specifications. It enables developers to create a service oriented and dynamic software stack. Proper usage of the C++ Micro Services library leads to - Re-use of software components - Loose coupling - Separation of concerns - Clean APIs based on service interfaces - Extensible systems and more. Requirements ------------ This is a pure C++ implementation of the OSGi service model and does not have any third-party library dependencies. Supported Platforms ------------------- The library should compile on many different platforms. Below is a list of tested compiler/OS combinations: - GCC 4.6 (Ubuntu 12.04) - GCC 4.8 (Ubuntu 13.10) - Clang 3.2 (Ubuntu 13.10) - Clang (MacOS X 10.8 and 10.9) - Visual Studio 2008 SP1, 2010, 2012, 2013 (Windows 7) Legal ----- Copyright (c) German Cancer Research Center. Licensed under the [Apache License v2.0][apache_license]. Quick Start ----------- Essentially, the C++ Micro Services library provides you with a powerful dynamic service registry. Each shared or static library has an associated `ModuleContext` object, through which the service registry is accessed. To query the registry for a service object implementing one or more specific interfaces, the code would look like this: ```cpp #include #include using namespace us; void UseService(ModuleContext* context) { ServiceReference serviceRef = context->GetServiceReference(); if (serviceRef) { SomeInterface* service = context->GetService(serviceRef); if (service) { /* do something */ } } } ``` Registering a service object against a certain interface looks like this: ```cpp #include #include using namespace us; void RegisterSomeService(ModuleContext* context, SomeInterface* service) { context->RegisterService(service); } ``` The OSGi service model additionally allows to annotate services with properties and using these properties during service look-ups. It also allows to track the life-cycle of service objects. Please see the [Documentation](http://cppmicroservices.org/doc_latest/index.html) for more examples and tutorials and the API reference. There is also a blog post about [OSGi Lite for C++](http://blog.cppmicroservices.org/2012/04/15/osgi-lite-for-c++). Build Instructions ------------------ Please visit the [Build Instructions][bi_master] page online. [bi_master]: http://cppmicroservices.org/doc_latest/BuildInstructions.html [apache_license]: http://www.apache.org/licenses/LICENSE-2.0 diff --git a/CMake/CMakePackageConfigHelpers.cmake b/cmake/CMakePackageConfigHelpers.cmake similarity index 100% rename from CMake/CMakePackageConfigHelpers.cmake rename to cmake/CMakePackageConfigHelpers.cmake diff --git a/CMake/CMakeParseArguments.cmake b/cmake/CMakeParseArguments.cmake similarity index 100% rename from CMake/CMakeParseArguments.cmake rename to cmake/CMakeParseArguments.cmake diff --git a/cmake/FindPackageHandleStandardArgs.cmake b/cmake/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000000..70423a7e43 --- /dev/null +++ b/cmake/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,323 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) +# +# This function is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED, QUIET and version-related arguments to find_package(). +# It also sets the _FOUND variable. +# The package is considered found if all variables ... listed contain +# valid results, e.g. valid filepaths. +# +# There are two modes of this function. The first argument in both modes is +# the name of the Find-module where it is called (in original casing). +# +# The first simple mode looks like this: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( (DEFAULT_MSG|"Custom failure message") ... ) +# If the variables to are all valid, then _FOUND +# will be set to TRUE. +# If DEFAULT_MSG is given as second argument, then the function will generate +# itself useful success and error messages. You can also supply a custom error message +# for the failure case. This is not recommended. +# +# The second mode is more powerful and also supports version checking: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [FOUND_VAR ] +# [REQUIRED_VARS ...] +# [VERSION_VAR ] +# [HANDLE_COMPONENTS] +# [CONFIG_MODE] +# [FAIL_MESSAGE "Custom failure message"] ) +# +# In this mode, the name of the result-variable can be set either to either +# _FOUND or _FOUND using the FOUND_VAR option. +# Other names for the result-variable are not allowed. +# So for a Find-module named FindFooBar.cmake, the two possible names are +# FooBar_FOUND and FOOBAR_FOUND. It is recommended to use the original case version. +# If the FOUND_VAR option is not used, the default is _FOUND. +# +# As in the simple mode, if through are all valid, +# _FOUND will be set to TRUE. +# After REQUIRED_VARS the variables which are required for this package are listed. +# Following VERSION_VAR the name of the variable can be specified which holds +# the version of the package which has been found. If this is done, this version +# will be checked against the (potentially) specified required version used +# in the find_package() call. The EXACT keyword is also handled. The default +# messages include information about the required version and the version +# which has been actually found, both if the version is ok or not. +# If the package supports components, use the HANDLE_COMPONENTS option to enable +# handling them. In this case, find_package_handle_standard_args() will report +# which components have been found and which are missing, and the _FOUND +# variable will be set to FALSE if any of the required components (i.e. not the +# ones listed after OPTIONAL_COMPONENTS) are missing. +# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for +# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set +# to _VERSION and the macro will automatically check whether the +# Config module was found. +# Via FAIL_MESSAGE a custom failure message can be specified, if this is not +# used, the default message will be displayed. +# +# Example for mode 1: +# +# find_package_handle_standard_args(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, success will be reported, including the content of . +# On repeated Cmake runs, the same message won't be printed again. +# +# Example for mode 2: +# +# find_package_handle_standard_args(LibXslt FOUND_VAR LibXslt_FOUND +# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS +# VERSION_VAR LibXslt_VERSION_STRING) +# In this case, LibXslt is considered to be found if the variable(s) listed +# after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and LibXslt_INCLUDE_DIRS +# in this case. The result will then be stored in LibXslt_FOUND . +# Also the version of LibXslt will be checked by using the version contained +# in LibXslt_VERSION_STRING. +# Since no FAIL_MESSAGE is given, the default messages will be printed. +# +# Another example for mode 2: +# +# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) +# find_package_handle_standard_args(Automoc4 CONFIG_MODE) +# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 NO_MODULE) +# and adds an additional search directory for automoc4. +# Here the result will be stored in AUTOMOC4_FOUND. +# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper +# success/error message. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) + +# internal helper macro +macro(_FPHSA_FAILURE_MESSAGE _msg) + if (${_NAME}_FIND_REQUIRED) + message(FATAL_ERROR "${_msg}") + else () + if (NOT ${_NAME}_FIND_QUIETLY) + message(STATUS "${_msg}") + endif () + endif () +endmacro() + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + if(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + else() + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + if(${_NAME}_CONSIDERED_CONFIGS) + set(configsText "") + list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + math(EXPR configsCount "${configsCount} - 1") + foreach(currentConfigIndex RANGE ${configsCount}) + list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + set(configsText "${configsText} ${filename} (version ${version})\n") + endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + else() + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + endif() + endif() +endmacro() + + +function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + set(options CONFIG_MODE HANDLE_COMPONENTS) + set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) + set(multiValueArgs REQUIRED_VARS) + set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + if(${INDEX} EQUAL -1) + set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + set(FPHSA_REQUIRED_VARS ${ARGN}) + set(FPHSA_VERSION_VAR) + else() + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + if(FPHSA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT FPHSA_FAIL_MESSAGE) + set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + endif() + endif() + +# now that we collected all arguments, process them + + if("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + endif() + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + if(FPHSA_CONFIG_MODE) + list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + set(FPHSA_VERSION_VAR ${_NAME}_VERSION) + endif() + + if(NOT FPHSA_REQUIRED_VARS) + message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + endif() + + list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + string(TOUPPER ${_NAME} _NAME_UPPER) + string(TOLOWER ${_NAME} _NAME_LOWER) + + if(FPHSA_FOUND_VAR) + if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") + set(_FOUND_VAR ${FPHSA_FOUND_VAR}) + else() + message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") + endif() + else() + set(_FOUND_VAR ${_NAME_UPPER}_FOUND) + endif() + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + set(MISSING_VARS "") + set(DETAILS "") + # check if all passed variables are valid + unset(${_FOUND_VAR}) + foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + if(NOT ${_CURRENT_VAR}) + set(${_FOUND_VAR} FALSE) + set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") + else() + set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") + endif() + endforeach() + if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE") + set(${_FOUND_VAR} TRUE) + endif() + + # component handling + unset(FOUND_COMPONENTS_MSG) + unset(MISSING_COMPONENTS_MSG) + + if(FPHSA_HANDLE_COMPONENTS) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(${_NAME}_${comp}_FOUND) + + if(NOT DEFINED FOUND_COMPONENTS_MSG) + set(FOUND_COMPONENTS_MSG "found components: ") + endif() + set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}") + + else() + + if(NOT DEFINED MISSING_COMPONENTS_MSG) + set(MISSING_COMPONENTS_MSG "missing components: ") + endif() + set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}") + + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_FOUND_VAR} FALSE) + set(MISSING_VARS "${MISSING_VARS} ${comp}") + endif() + + endif() + endforeach() + set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") + set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]") + endif() + + # version handling: + set(VERSION_MSG "") + set(VERSION_OK TRUE) + set(VERSION ${${FPHSA_VERSION_VAR}} ) + if (${_NAME}_FIND_VERSION) + + if(VERSION) + + if(${_NAME}_FIND_VERSION_EXACT) # exact version required + if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + + else() # minimum version specified: + if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") + endif () + endif() + + else() + + # if the package was not found, but a version was given, add that to the output: + if(${_NAME}_FIND_VERSION_EXACT) + set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + else() + set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + endif() + + endif() + else () + if(VERSION) + set(VERSION_MSG "(found version \"${VERSION}\")") + endif() + endif () + + if(VERSION_OK) + set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") + else() + set(${_FOUND_VAR} FALSE) + endif() + + + # print the result: + if (${_FOUND_VAR}) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") + else () + + if(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + else() + if(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + else() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") + endif() + endif() + + endif () + + set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE) + +endfunction() diff --git a/cmake/FindPackageMessage.cmake b/cmake/FindPackageMessage.cmake new file mode 100644 index 0000000000..5cea43e352 --- /dev/null +++ b/cmake/FindPackageMessage.cmake @@ -0,0 +1,49 @@ +# FIND_PACKAGE_MESSAGE( "message for user" "find result details") +# +# This macro is intended to be used in FindXXX.cmake modules files. +# It will print a message once for each unique find result. +# This is useful for telling the user where a package was found. +# The first argument specifies the name (XXX) of the package. +# The second argument specifies the message to display. +# The third argument lists details about the find result so that +# if they change the message will be displayed again. +# The macro also obeys the QUIET argument to the find_package command. +# +# Example: +# +# if(X11_FOUND) +# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" +# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") +# else() +# ... +# endif() + +#============================================================================= +# Copyright 2008-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +function(FIND_PACKAGE_MESSAGE pkg msg details) + # Avoid printing a message repeatedly for the same find result. + if(NOT ${pkg}_FIND_QUIETLY) + string(REGEX REPLACE "[\n]" "" details "${details}") + set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) + if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + # The message has not yet been printed. + message(STATUS "${msg}") + + # Save the find details in the cache to avoid printing the same + # message again. + set("${DETAILS_VAR}" "${details}" + CACHE INTERNAL "Details about finding ${pkg}") + endif() + endif() +endfunction() diff --git a/CMake/usCTestScript.cmake b/cmake/usCTestScript.cmake similarity index 100% rename from CMake/usCTestScript.cmake rename to cmake/usCTestScript.cmake diff --git a/CMake/usCTestScript_custom.cmake b/cmake/usCTestScript_custom.cmake similarity index 85% rename from CMake/usCTestScript_custom.cmake rename to cmake/usCTestScript_custom.cmake index c378062467..ee9908c8bd 100644 --- a/CMake/usCTestScript_custom.cmake +++ b/cmake/usCTestScript_custom.cmake @@ -1,24 +1,24 @@ find_program(CTEST_COVERAGE_COMMAND NAMES gcov) find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) find_program(CTEST_GIT_COMMAND NAMES git) set(CTEST_SITE "bigeye") -set(CTEST_DASHBOARD_ROOT "/tmp") +set(CTEST_DASHBOARD_ROOT "/tmp/us builds") #set(CTEST_COMPILER "gcc-4.5") set(CTEST_CMAKE_GENERATOR "Unix Makefiles") set(CTEST_BUILD_FLAGS "-j") set(CTEST_BUILD_CONFIGURATION Debug) set(CTEST_PARALLEL_LEVEL 4) set(US_TEST_SHARED 1) set(US_TEST_STATIC 1) set(US_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../") set(US_BUILD_CONFIGURATION ) foreach(i RANGE 7) list(APPEND US_BUILD_CONFIGURATION ${i}) endforeach() -include(${US_SOURCE_DIR}/CMake/usCTestScript.cmake) +include(${US_SOURCE_DIR}/cmake/usCTestScript.cmake) diff --git a/CMake/usCTestScript_travis.cmake b/cmake/usCTestScript_travis.cmake similarity index 81% rename from CMake/usCTestScript_travis.cmake rename to cmake/usCTestScript_travis.cmake index aea8b9e2ac..3e9f3d2b65 100644 --- a/CMake/usCTestScript_travis.cmake +++ b/cmake/usCTestScript_travis.cmake @@ -1,17 +1,17 @@ find_program(CTEST_COVERAGE_COMMAND NAMES gcov) find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) find_program(CTEST_GIT_COMMAND NAMES git) set(CTEST_SITE "travis-ci") -set(CTEST_DASHBOARD_ROOT "/tmp") +set(CTEST_DASHBOARD_ROOT "/tmp/us builds") #set(CTEST_COMPILER "gcc-4.5") set(CTEST_CMAKE_GENERATOR "Unix Makefiles") set(CTEST_BUILD_FLAGS "-j") set(CTEST_BUILD_CONFIGURATION Release) set(US_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../") set(US_BUILD_CONFIGURATION $ENV{BUILD_CONFIGURATION}) -include(${US_SOURCE_DIR}/CMake/usCTestScript.cmake) +include(${US_SOURCE_DIR}/cmake/usCTestScript.cmake) diff --git a/CMake/usExecutableInit.cpp b/cmake/usExecutableInit.cpp similarity index 100% rename from CMake/usExecutableInit.cpp rename to cmake/usExecutableInit.cpp diff --git a/cmake/usExport.h.in b/cmake/usExport.h.in new file mode 100644 index 0000000000..d5370dc3e6 --- /dev/null +++ b/cmake/usExport.h.in @@ -0,0 +1,24 @@ +///------------------------------------------------------------------- +// Macros for import/export declarations +//------------------------------------------------------------------- + +#ifndef us@PROJECT_NAME@Export_H_ +#define us@PROJECT_NAME@Export_H_ + +#include + +#ifdef US_BUILD_SHARED_LIBS + // We are building a shared lib + #ifdef @PROJECT_TARGET@_EXPORTS + #define US_@PROJECT_NAME@_EXPORT US_ABI_EXPORT + #else + #define US_@PROJECT_NAME@_EXPORT US_ABI_IMPORT + #endif +#else + // We are building a static lib + // Don't hide RTTI symbols of definitions in the C++ Micro Services + // headers that are included in DSOs with hidden visibility + #define US_@PROJECT_NAME@_EXPORT US_ABI_EXPORT +#endif + +#endif // us@PROJECT_NAME@Export_H_ diff --git a/CMake/usFunctionCheckCompilerFlags.cmake b/cmake/usFunctionCheckCompilerFlags.cmake similarity index 100% rename from CMake/usFunctionCheckCompilerFlags.cmake rename to cmake/usFunctionCheckCompilerFlags.cmake diff --git a/CMake/usFunctionCompileSnippets.cmake b/cmake/usFunctionCompileSnippets.cmake similarity index 94% rename from CMake/usFunctionCompileSnippets.cmake rename to cmake/usFunctionCompileSnippets.cmake index 47f67f503f..6a3dcb92fd 100644 --- a/CMake/usFunctionCompileSnippets.cmake +++ b/cmake/usFunctionCompileSnippets.cmake @@ -1,48 +1,48 @@ function(usFunctionCompileSnippets snippet_path) # get all files called "main.cpp" file(GLOB_RECURSE main_cpp_list "${snippet_path}/main.cpp") foreach(main_cpp_file ${main_cpp_list}) # get the directory containing the main.cpp file get_filename_component(main_cpp_dir "${main_cpp_file}" PATH) set(snippet_src_files ) # If there exists a "files.cmake" file in the snippet directory, # include it and assume it sets the variable "snippet_src_files" # to a list of source files for the snippet. if(EXISTS "${main_cpp_dir}/files.cmake") include("${main_cpp_dir}/files.cmake") set(_tmp_src_files ${snippet_src_files}) set(snippet_src_files ) foreach(_src_file ${_tmp_src_files}) if(IS_ABSOLUTE ${_src_file}) list(APPEND snippet_src_files ${_src_file}) else() list(APPEND snippet_src_files ${main_cpp_dir}/${_src_file}) endif() endforeach() else() # glob all files in the directory and add them to the snippet src list file(GLOB_RECURSE snippet_src_files "${main_cpp_dir}/*") endif() # Uset the top-level directory name as the executable name string(REPLACE "/" ";" main_cpp_dir_tokens "${main_cpp_dir}") list(GET main_cpp_dir_tokens -1 snippet_exec_name) set(snippet_target_name "Snippet-${snippet_exec_name}") add_executable(${snippet_target_name} ${snippet_src_files}) - target_link_libraries(${snippet_target_name} ${US_LIBRARY_TARGET} ${snippet_link_libraries}) + target_link_libraries(${snippet_target_name} ${PROJECT_TARGET} ${snippet_link_libraries}) set_target_properties(${snippet_target_name} PROPERTIES LABELS Documentation RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/snippets" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/snippets" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/snippets" OUTPUT_NAME ${snippet_exec_name} ) endforeach() endfunction() diff --git a/CMake/usFunctionCreateTestModule.cmake b/cmake/usFunctionCreateTestModule.cmake similarity index 94% rename from CMake/usFunctionCreateTestModule.cmake rename to cmake/usFunctionCreateTestModule.cmake index 2ff602e560..11f31dfbe0 100644 --- a/CMake/usFunctionCreateTestModule.cmake +++ b/cmake/usFunctionCreateTestModule.cmake @@ -1,42 +1,42 @@ macro(_us_create_test_module_helper) if(_res_files) usFunctionEmbedResources(_srcs LIBRARY_NAME ${name} ROOT_DIR ${_res_root} FILES ${_res_files}) endif() add_library(${name} ${_srcs}) if(NOT US_BUILD_SHARED_LIBS) set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS US_STATIC_MODULE) endif() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") get_property(_compile_flags TARGET ${name} PROPERTY COMPILE_FLAGS) set_property(TARGET ${name} PROPERTY COMPILE_FLAGS "${_compile_flags} -fPIC") endif() - target_link_libraries(${name} ${US_LIBRARY_TARGET} ${US_LINK_LIBRARIES}) + target_link_libraries(${name} ${${PROJECT_NAME}_TARGET} ${US_LINK_LIBRARIES}) set(_us_test_module_libs "${_us_test_module_libs};${name}" CACHE INTERNAL "" FORCE) endmacro() function(usFunctionCreateTestModule name) set(_srcs ${ARGN}) set(_res_files ) usFunctionGenerateModuleInit(_srcs NAME "${name} Module" LIBRARY_NAME ${name}) _us_create_test_module_helper() endfunction() function(usFunctionCreateTestModuleWithResources name) cmake_parse_arguments(US_TEST "" "RESOURCES_ROOT" "SOURCES;RESOURCES" "" ${ARGN}) set(_srcs ${US_TEST_SOURCES}) set(_res_files ${US_TEST_RESOURCES}) if(US_TEST_RESOURCES_ROOT) set(_res_root ${US_TEST_RESOURCES_ROOT}) else() set(_res_root resources) endif() usFunctionGenerateModuleInit(_srcs NAME "${name} Module" LIBRARY_NAME ${name}) _us_create_test_module_helper() endfunction() diff --git a/CMake/usFunctionEmbedResources.cmake b/cmake/usFunctionEmbedResources.cmake similarity index 95% rename from CMake/usFunctionEmbedResources.cmake rename to cmake/usFunctionEmbedResources.cmake index 7452c168d1..6e9dbe8ce4 100644 --- a/CMake/usFunctionEmbedResources.cmake +++ b/cmake/usFunctionEmbedResources.cmake @@ -1,148 +1,147 @@ #! \ingroup MicroServicesCMake #! \brief Embed resources into a shared library or executable. #! #! This CMake function uses an external command line program to generate a source #! file containing data from external resources such as text files or images. The path #! to the generated source file is appended to the \c src_var variable. #! #! Each module can call this function (at most once) to embed resources and make them #! available at runtime through the Module class. Resources can also be embedded into #! executables, using the EXECUTABLE_NAME argument instead of LIBRARY_NAME. #! #! Example usage: #! \code{.cmake} #! set(module_srcs ) #! usFunctionEmbedResources(module_srcs #! LIBRARY_NAME "mylib" #! ROOT_DIR resources #! FILES config.properties logo.png #! ) #! \endcode #! #! \param LIBRARY_NAME (required if EXECUTABLE_NAME is empty) The library name of the module #! which will include the generated source file, without extension. #! \param EXECUTABLE_NAME (required if LIBRARY_NAME is empty) The name of the executable #! which will include the generated source file. #! \param COMPRESSION_LEVEL (optional) The zip compression level. Defaults to the default zip #! level. Level 0 disables compression. #! \param COMPRESSION_THRESHOLD (optional) The compression threshold ranging from 0 to 100 for #! actually compressing the resource data. The default threshold is 30, meaning a size #! reduction of 30 percent or better results in the resource data being compressed. #! \param ROOT_DIR (optional) The root path for all resources listed after the FILES argument. #! If no or a relative path is given, it is considered relativ to the current CMake source directory. #! \param FILES (optional) A list of resources (paths to external files in the file system) relative #! to the ROOT_DIR argument or the current CMake source directory if ROOT_DIR is empty. #! #! The ROOT_DIR and FILES arguments may be repeated any number of times to merge files from #! different root directories into the embedded resource tree (hence the relative file paths #! after the FILES argument must be unique). #! function(usFunctionEmbedResources src_var) set(prefix US_RESOURCE) set(arg_names LIBRARY_NAME EXECUTABLE_NAME COMPRESSION_LEVEL COMPRESSION_THRESHOLD ROOT_DIR FILES) foreach(arg_name ${arg_names}) set(${prefix}_${arg_name}) endforeach(arg_name) set(cmd_line_args ) set(absolute_res_files ) set(current_arg_name DEFAULT_ARGS) set(current_arg_list) set(current_root_dir ${CMAKE_CURRENT_SOURCE_DIR}) foreach(arg ${ARGN}) list(FIND arg_names "${arg}" is_arg_name) if(is_arg_name GREATER -1) set(${prefix}_${current_arg_name} ${current_arg_list}) set(current_arg_name "${arg}") set(current_arg_list) else() set(current_arg_list ${current_arg_list} "${arg}") if(current_arg_name STREQUAL "ROOT_DIR") set(current_root_dir "${arg}") if(NOT IS_ABSOLUTE ${current_root_dir}) set(current_root_dir "${CMAKE_CURRENT_SOURCE_DIR}/${current_root_dir}") endif() if(NOT IS_DIRECTORY ${current_root_dir}) message(SEND_ERROR "The ROOT_DIR argument is not a directory: ${current_root_dir}") endif() get_filename_component(current_root_dir "${current_root_dir}" REALPATH) - file(TO_NATIVE_PATH "${current_root_dir}" current_root_dir_native) - list(APPEND cmd_line_args -d "${current_root_dir_native}") + list(APPEND cmd_line_args -d "${current_root_dir}") elseif(current_arg_name STREQUAL "FILES") set(res_file "${current_root_dir}/${arg}") file(TO_NATIVE_PATH "${res_file}" res_file_native) if(IS_DIRECTORY ${res_file}) message(SEND_ERROR "A resource cannot be a directory: ${res_file_native}") endif() if(NOT EXISTS ${res_file}) message(SEND_ERROR "Resource does not exists: ${res_file_native}") endif() list(APPEND absolute_res_files ${res_file}) - file(TO_NATIVE_PATH "${arg}" res_filename_native) - list(APPEND cmd_line_args "${res_filename_native}") + list(APPEND cmd_line_args "${arg}") endif() endif(is_arg_name GREATER -1) endforeach(arg ${ARGN}) set(${prefix}_${current_arg_name} ${current_arg_list}) if(NOT src_var) message(SEND_ERROR "Output variable name not specified.") endif() if(US_RESOURCE_EXECUTABLE_NAME AND US_RESOURCE_LIBRARY_NAME) message(SEND_ERROR "Only one of LIBRARY_NAME or EXECUTABLE_NAME can be specified.") endif() if(NOT US_RESOURCE_LIBRARY_NAME AND NOT US_RESOURCE_EXECUTABLE_NAME) message(SEND_ERROR "LIBRARY_NAME or EXECUTABLE_NAME argument not specified.") endif() if(NOT US_RESOURCE_FILES) message(WARNING "No FILES argument given. Skipping resource processing.") return() endif() list(GET cmd_line_args 0 first_arg) if(NOT first_arg STREQUAL "-d") set(cmd_line_args -d "${CMAKE_CURRENT_SOURCE_DIR}" ${cmd_line_args}) endif() if(US_RESOURCE_COMPRESSION_LEVEL) set(cmd_line_args -c ${US_RESOURCE_COMPRESSION_LEVEL} ${cmd_line_args}) endif() if(US_RESOURCE_COMPRESSION_THRESHOLD) set(cmd_line_args -t ${US_RESOURCE_COMPRESSION_THRESHOLD} ${cmd_line_args}) endif() if(US_RESOURCE_LIBRARY_NAME) set(us_cpp_resource_file "${CMAKE_CURRENT_BINARY_DIR}/${US_RESOURCE_LIBRARY_NAME}_resources.cpp") set(us_lib_name ${US_RESOURCE_LIBRARY_NAME}) else() set(us_cpp_resource_file "${CMAKE_CURRENT_BINARY_DIR}/${US_RESOURCE_EXECUTABLE_NAME}_resources.cpp") - set(us_lib_name "\"\"") + set(us_lib_name "") endif() set(resource_compiler ${CppMicroServices_RCC_EXECUTABLE}) if(TARGET ${CppMicroServices_RCC_EXECUTABLE_NAME}) set(resource_compiler ${CppMicroServices_RCC_EXECUTABLE_NAME}) elseif(NOT resource_compiler) message(FATAL_ERROR "The CppMicroServices resource compiler was not found. Check the CppMicroServices_RCC_EXECUTABLE CMake variable.") endif() add_custom_command( OUTPUT ${us_cpp_resource_file} COMMAND ${resource_compiler} "${us_lib_name}" ${us_cpp_resource_file} ${cmd_line_args} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${absolute_res_files} ${resource_compiler} COMMENT "Generating embedded resource file ${us_cpp_resource_name}" + VERBATIM ) set(${src_var} "${${src_var}};${us_cpp_resource_file}" PARENT_SCOPE) endfunction() diff --git a/CMake/usFunctionGenerateExecutableInit.cmake b/cmake/usFunctionGenerateExecutableInit.cmake similarity index 91% rename from CMake/usFunctionGenerateExecutableInit.cmake rename to cmake/usFunctionGenerateExecutableInit.cmake index fc4030cf80..6fb6ad80dc 100644 --- a/CMake/usFunctionGenerateExecutableInit.cmake +++ b/cmake/usFunctionGenerateExecutableInit.cmake @@ -1,43 +1,43 @@ #! \ingroup MicroServicesCMake #! \brief Generate a source file which handles proper initialization of an executable. #! #! This CMake function will store the path to a generated source file in the #! src_var variable, which should be compiled into an executable. Example usage: #! #! \code{.cmake} #! set(executable_srcs ) #! usFunctionGenerateExecutableInit(executable_srcs #! IDENTIFIER "MyExecutable" #! ) #! add_executable(MyExecutable ${executable_srcs}) #! \endcode #! #! \param src_var (required) The name of a list variable to which the path of the generated #! source file will be appended. #! \param IDENTIFIER (required) A valid C identifier for the executable. #! #! \see #usFunctionGenerateModuleInit #! \see \ref MicroServices_AutoLoading #! function(usFunctionGenerateExecutableInit src_var) cmake_parse_arguments(US_EXECUTABLE "" "IDENTIFIER" "" ${ARGN}) # sanity checks if(NOT US_EXECUTABLE_IDENTIFIER) message(SEND_ERROR "IDENTIFIER argument is mandatory") endif() set(_regex_validation "[a-zA-Z_-][a-zA-Z_0-9-]*") string(REGEX MATCH ${_regex_validation} _valid_chars ${US_EXECUTABLE_IDENTIFIER}) if(NOT _valid_chars STREQUAL US_EXECUTABLE_IDENTIFIER) message(FATAL_ERROR "IDENTIFIER contains illegal characters.") endif() set(exec_init_src_file "${CMAKE_CURRENT_BINARY_DIR}/${US_EXECUTABLE_IDENTIFIER}_init.cpp") - configure_file(${CppMicroServices_EXECUTABLE_INIT_TEMPLATE} ${exec_init_src_file} @ONLY) + configure_file(${US_EXECUTABLE_INIT_TEMPLATE} ${exec_init_src_file} @ONLY) - set(_src ${${src_var}} ${exec_init_src_file}) + set(_src ${exec_init_src_file} ${${src_var}}) set(${src_var} ${_src} PARENT_SCOPE) endfunction() diff --git a/CMake/usFunctionGenerateModuleInit.cmake b/cmake/usFunctionGenerateModuleInit.cmake similarity index 93% rename from CMake/usFunctionGenerateModuleInit.cmake rename to cmake/usFunctionGenerateModuleInit.cmake index e02cb839cb..6986d228b8 100644 --- a/CMake/usFunctionGenerateModuleInit.cmake +++ b/cmake/usFunctionGenerateModuleInit.cmake @@ -1,54 +1,54 @@ #! \ingroup MicroServicesCMake #! \brief Generate a source file which handles proper initialization of a module. #! #! This CMake function will store the path to a generated source file in the #! src_var variable, which should be compiled into a module. Example usage: #! #! \code{.cmake} #! set(module_srcs ) #! usFunctionGenerateModuleInit(module_srcs #! NAME "My Module" #! LIBRARY_NAME "mylib" #! ) #! add_library(mylib ${module_srcs}) #! \endcode #! #! \param src_var (required) The name of a list variable to which the path of the generated #! source file will be appended. #! \param NAME (required) A human-readable name for the module. #! \param LIBRARY_NAME (optional) The name of the module, without extension. If empty, the #! NAME argument will be used. #! #! \see #usFunctionGenerateExecutableInit #! \see \ref MicroServices_AutoLoading #! function(usFunctionGenerateModuleInit src_var) cmake_parse_arguments(US_MODULE "EXECUTABLE" "NAME;LIBRARY_NAME" "" ${ARGN}) if(US_MODULE_EXECUTABLE) message(SEND_ERROR "EXECUTABLE option no longer supported. Use usFunctionGenerateExecutableInit instead.") endif() # sanity checks if(NOT US_MODULE_NAME) message(SEND_ERROR "NAME argument is mandatory") endif() if(NOT US_MODULE_LIBRARY_NAME) set(US_MODULE_LIBRARY_NAME ${US_MODULE_NAME}) endif() set(_regex_validation "[a-zA-Z_-][a-zA-Z_0-9-]*") string(REGEX MATCH ${_regex_validation} _valid_chars ${US_MODULE_LIBRARY_NAME}) if(NOT _valid_chars STREQUAL US_MODULE_LIBRARY_NAME) message(FATAL_ERROR "[Module: ${US_MODULE_NAME}] LIBRARY_NAME \"${US_MODULE_LIBRARY_NAME}\" contains illegal characters.") endif() set(module_init_src_file "${CMAKE_CURRENT_BINARY_DIR}/${US_MODULE_LIBRARY_NAME}_init.cpp") - configure_file(${CppMicroServices_MODULE_INIT_TEMPLATE} ${module_init_src_file} @ONLY) + configure_file(${US_MODULE_INIT_TEMPLATE} ${module_init_src_file} @ONLY) - set(_src ${${src_var}} ${module_init_src_file}) + set(_src ${module_init_src_file} ${${src_var}}) set(${src_var} ${_src} PARENT_SCOPE) endfunction() diff --git a/CMake/usFunctionGetGccVersion.cmake b/cmake/usFunctionGetGccVersion.cmake similarity index 100% rename from CMake/usFunctionGetGccVersion.cmake rename to cmake/usFunctionGetGccVersion.cmake diff --git a/usConfig.h.in b/cmake/usGlobalConfig.h.in similarity index 83% rename from usConfig.h.in rename to cmake/usGlobalConfig.h.in index 1b951bbb18..1ee63faa75 100644 --- a/usConfig.h.in +++ b/cmake/usGlobalConfig.h.in @@ -1,228 +1,206 @@ /* USCONFIG.h this file is generated. Do not change! */ -#ifndef USCONFIG_H -#define USCONFIG_H +#ifndef USGLOBALCONFIG_H +#define USGLOBALCONFIG_H #cmakedefine US_BUILD_SHARED_LIBS -#cmakedefine CppMicroServices_EXPORTS -#cmakedefine US_ENABLE_AUTOLOADING_SUPPORT #cmakedefine US_ENABLE_THREADING_SUPPORT #cmakedefine US_ENABLE_RESOURCE_COMPRESSION #cmakedefine US_GCC_RTTI_WORKAROUND_NEEDED +#cmakedefine US_HAVE_VISIBILITY_ATTRIBUTE //------------------------------------------------------------------- // Header Availability //------------------------------------------------------------------- #cmakedefine US_HAVE_STDINT_H #cmakedefine US_HAVE_TR1_UNORDERED_MAP_H #cmakedefine US_HAVE_TR1_UNORDERED_SET_H #cmakedefine US_HAVE_TR1_FUNCTIONAL_H #cmakedefine US_HAVE_UNORDERED_MAP_H #cmakedefine US_HAVE_UNORDERED_SET_H #cmakedefine US_HAVE_FUNCTIONAL_H #cmakedefine US_HAVE_TR1_UNORDERED_MAP #cmakedefine US_HAVE_TR1_UNORDERED_SET #cmakedefine US_HAVE_TR1_FUNCTION #cmakedefine US_HAVE_STD_UNORDERED_MAP #cmakedefine US_HAVE_STD_UNORDERED_SET #cmakedefine US_HAVE_STD_FUNCTION #cmakedefine US_HAVE_TR1_HASH #cmakedefine US_HAVE_TR1_HASH_STRUCT #cmakedefine US_HAVE_TR1_HASH_CLASS #cmakedefine US_HAVE_STD_HASH #cmakedefine US_HAVE_STD_HASH_STRUCT #cmakedefine US_HAVE_STD_HASH_CLASS ///------------------------------------------------------------------- // Version information //------------------------------------------------------------------- #define CppMicroServices_MAJOR_VERSION @CppMicroServices_MAJOR_VERSION@ #define CppMicroServices_MINOR_VERSION @CppMicroServices_MINOR_VERSION@ #define CppMicroServices_PATCH_VERSION @CppMicroServices_PATCH_VERSION@ #define CppMicroServices_VERSION @CppMicroServices_VERSION@ #define CppMicroServices_VERSION_STR "@CppMicroServices_VERSION@" -///------------------------------------------------------------------- -// Macros used by the unit tests -//------------------------------------------------------------------- - -#define CppMicroServices_SOURCE_DIR "@CppMicroServices_SOURCE_DIR@" - -///------------------------------------------------------------------- -// Macros for import/export declarations -//------------------------------------------------------------------- - -#if defined(WIN32) - #define US_ABI_EXPORT __declspec(dllexport) - #define US_ABI_IMPORT __declspec(dllimport) - #define US_ABI_LOCAL -#else - #define US_ABI_EXPORT __attribute__ ((visibility ("default"))) - #define US_ABI_IMPORT __attribute__ ((visibility ("default"))) - #define US_ABI_LOCAL __attribute__ ((visibility ("hidden"))) -#endif - -#ifdef US_BUILD_SHARED_LIBS - // We are building a shared lib - #ifdef CppMicroServices_EXPORTS - #define US_EXPORT US_ABI_EXPORT - #else - #define US_EXPORT US_ABI_IMPORT - #endif -#else - // We are building a static lib - // Don't hide RTTI symbols of definitions in the C++ Micro Services - // headers that are included in DSOs with hidden visibility - #define US_EXPORT US_ABI_EXPORT -#endif +#define US_MAJOR_VERSION @CppMicroServices_MAJOR_VERSION@ +#define US_MINOR_VERSION @CppMicroServices_MINOR_VERSION@ +#define US_PATCH_VERSION @CppMicroServices_PATCH_VERSION@ +#define US_VERSION @CppMicroServices_VERSION@ +#define US_VERSION_STR "@CppMicroServices_VERSION@" //------------------------------------------------------------------- // Namespace customization //------------------------------------------------------------------- #define US_NAMESPACE @US_NAMESPACE@ #ifndef US_NAMESPACE /* user namespace */ # define US_PREPEND_NAMESPACE(name) ::name # define US_USE_NAMESPACE # define US_BEGIN_NAMESPACE # define US_END_NAMESPACE # define US_FORWARD_DECLARE_CLASS(name) class name; # define US_FORWARD_DECLARE_STRUCT(name) struct name; #else /* user namespace */ # define US_PREPEND_NAMESPACE(name) ::US_NAMESPACE::name # define US_USE_NAMESPACE using namespace ::US_NAMESPACE; # define US_BEGIN_NAMESPACE namespace US_NAMESPACE { # define US_END_NAMESPACE } # define US_FORWARD_DECLARE_CLASS(name) \ US_BEGIN_NAMESPACE class name; US_END_NAMESPACE # define US_FORWARD_DECLARE_STRUCT(name) \ US_BEGIN_NAMESPACE struct name; US_END_NAMESPACE namespace US_NAMESPACE {} #endif /* user namespace */ //------------------------------------------------------------------- // Platform defines //------------------------------------------------------------------- #if defined(__APPLE__) #define US_PLATFORM_APPLE #endif #if defined(__linux__) #define US_PLATFORM_LINUX #endif #if defined(_WIN32) || defined(_WIN64) #define US_PLATFORM_WINDOWS #else #define US_PLATFORM_POSIX #endif +///------------------------------------------------------------------- +// Macros for import/export declarations +//------------------------------------------------------------------- + +#if defined(US_PLATFORM_WINDOWS) + #define US_ABI_EXPORT __declspec(dllexport) + #define US_ABI_IMPORT __declspec(dllimport) + #define US_ABI_LOCAL +#elif defined(US_HAVE_VISIBILITY_ATTRIBUTE) + #define US_ABI_EXPORT __attribute__ ((visibility ("default"))) + #define US_ABI_IMPORT __attribute__ ((visibility ("default"))) + #define US_ABI_LOCAL __attribute__ ((visibility ("hidden"))) +#else + #define US_ABI_EXPORT + #define US_ABI_IMPORT + #define US_ABI_LOCAL +#endif + //------------------------------------------------------------------- // Macros for suppressing warnings //------------------------------------------------------------------- #ifdef _MSC_VER #define US_MSVC_PUSH_DISABLE_WARNING(wn) \ __pragma(warning(push)) \ __pragma(warning(disable:wn)) #define US_MSVC_POP_WARNING \ __pragma(warning(pop)) #define US_MSVC_DISABLE_WARNING(wn) \ __pragma(warning(disable:wn)) #else #define US_MSVC_PUSH_DISABLE_WARNING(wn) #define US_MSVC_POP_WARNING #define US_MSVC_DISABLE_WARNING(wn) #endif // Do not warn about the usage of deprecated unsafe functions US_MSVC_DISABLE_WARNING(4996) // Mark a variable or expression result as unused #define US_UNUSED(x) (void)(x) -//------------------------------------------------------------------- -// Debuging & Logging -//------------------------------------------------------------------- - -#cmakedefine US_ENABLE_DEBUG_OUTPUT - -US_BEGIN_NAMESPACE - enum MsgType { DebugMsg = 0, InfoMsg = 1, WarningMsg = 2, ErrorMsg = 3 }; - typedef void (*MsgHandler)(MsgType, const char *); - US_EXPORT MsgHandler installMsgHandler(MsgHandler); -US_END_NAMESPACE //------------------------------------------------------------------- // Hash Container //------------------------------------------------------------------- #ifdef US_HAVE_UNORDERED_MAP_H #include #elif defined(US_HAVE_TR1_UNORDERED_MAP_H) #include #endif #ifdef US_HAVE_UNORDERED_SET_H #include #elif defined(US_HAVE_TR1_UNORDERED_SET_H) #include #endif #ifdef US_HAVE_STD_UNORDERED_MAP #define US_UNORDERED_MAP_TYPE ::std::unordered_map #elif defined(US_HAVE_TR1_UNORDERED_MAP) #define US_UNORDERED_MAP_TYPE ::std::tr1::unordered_map #endif #ifdef US_HAVE_STD_UNORDERED_SET #define US_UNORDERED_SET_TYPE ::std::unordered_set #elif defined(US_HAVE_TR1_UNORDERED_SET) #define US_UNORDERED_SET_TYPE ::std::tr1::unordered_set #endif #ifdef US_HAVE_STD_HASH #define US_HASH_FUNCTION_NAMESPACE ::std #ifdef US_HAVE_STD_HASH_STRUCT #define US_HASH_FUNCTION_FRIEND(type) friend struct ::std::hash #elif defined(US_HAVE_STD_HASH_CLASS) #define US_HASH_FUNCTION_FRIEND(type) friend class ::std::hash #endif #define US_HASH_FUNCTION_NAMESPACE_BEGIN namespace std { #define US_HASH_FUNCTION_NAMESPACE_END } #elif defined(US_HAVE_TR1_HASH) #define US_HASH_FUNCTION_NAMESPACE ::std::tr1 #ifdef US_HAVE_TR1_HASH_STRUCT #define US_HASH_FUNCTION_FRIEND(type) friend struct ::std::tr1::hash #elif defined(US_HAVE_TR1_HASH_CLASS) #define US_HASH_FUNCTION_FRIEND(type) friend class ::std::tr1::hash #endif #define US_HASH_FUNCTION_NAMESPACE_BEGIN namespace std { namespace tr1 { #define US_HASH_FUNCTION_NAMESPACE_END }} #endif #define US_HASH_FUNCTION_BEGIN(type) \ template<> \ struct hash : std::unary_function { \ std::size_t operator()(const type& arg) const { #define US_HASH_FUNCTION_END } }; #define US_HASH_FUNCTION(type, arg) hash()(arg) -#endif // USCONFIG_H +#endif // USGLOBALCONFIG_H diff --git a/CMake/usModuleInit.cpp b/cmake/usModuleInit.cpp similarity index 100% rename from CMake/usModuleInit.cpp rename to cmake/usModuleInit.cpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt new file mode 100644 index 0000000000..466d699cfd --- /dev/null +++ b/core/CMakeLists.txt @@ -0,0 +1,202 @@ +project(Core) + +set(${PROJECT_NAME}_MAJOR_VERSION 2) +set(${PROJECT_NAME}_MINOR_VERSION 99) +set(${PROJECT_NAME}_PATCH_VERSION 0) +set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION}) + +set(${PROJECT_NAME}_TARGET CppMicroServices) +set(PROJECT_TARGET ${${PROJECT_NAME}_TARGET}) + +cmake_minimum_required(VERSION 2.8) +cmake_policy(VERSION 2.8) +cmake_policy(SET CMP0017 NEW) + +#----------------------------------------------------------------------------- +# US include dirs and libraries +#----------------------------------------------------------------------------- + +set(${PROJECT_NAME}_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include +) + +set(${PROJECT_NAME}_INTERNAL_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/src/util + ${CMAKE_CURRENT_SOURCE_DIR}/src/service + ${CMAKE_CURRENT_SOURCE_DIR}/src/module +) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/us${PROJECT_NAME}Config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/us${PROJECT_NAME}Config.h +) + +configure_file(${CppMicroServices_SOURCE_DIR}/cmake/usExport.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/us${PROJECT_NAME}Export.h +) + +include_directories( + ${${PROJECT_NAME}_INCLUDE_DIRS} + ${${PROJECT_NAME}_INTERNAL_INCLUDE_DIRS} +) + +# link libraries for the CppMicroServices lib +set(${PROJECT_NAME}_LINK_LIBRARIES ) +if(UNIX) + list(APPEND ${PROJECT_NAME}_LINK_LIBRARIES dl) +endif() + +#----------------------------------------------------------------------------- +# Create library +#----------------------------------------------------------------------------- + +include(${CMAKE_CURRENT_SOURCE_DIR}/src/CMakeLists.txt) +include(${CMAKE_CURRENT_SOURCE_DIR}/include/CMakeLists.txt) + +set(${PROJECT_NAME}_SOURCES ) +foreach(_src ${_srcs}) + list(APPEND ${PROJECT_NAME}_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${_src}) +endforeach() + +set(${PROJECT_NAME}_PRIVATE_HEADERS ) +foreach(_header ${_private_headers}) + list(APPEND ${PROJECT_NAME}_PRIVATE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/${_header}) +endforeach() + +set(${PROJECT_NAME}_PUBLIC_HEADERS ) +foreach(_header ${_public_headers}) + list(APPEND ${PROJECT_NAME}_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/${_header}) +endforeach() +list(APPEND ${PROJECT_NAME}_PUBLIC_HEADERS + ${CMAKE_CURRENT_BINARY_DIR}/include/us${PROJECT_NAME}Config.h + ${CMAKE_CURRENT_BINARY_DIR}/include/us${PROJECT_NAME}Export.h +) + +# Generate the module init file +usFunctionGenerateModuleInit(${PROJECT_NAME}_SOURCES NAME ${${PROJECT_NAME}_TARGET}) + +# Configure the modules manifest.json file +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/resources/manifest.json.in + ${CMAKE_CURRENT_BINARY_DIR}/resources/manifest.json) + +# Embed module resources +usFunctionEmbedResources(${PROJECT_NAME}_SOURCES LIBRARY_NAME ${${PROJECT_NAME}_TARGET} + ROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/resources + FILES manifest.json) + +# Create the module library +add_library(${${PROJECT_NAME}_TARGET} ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_PRIVATE_HEADERS} ${${PROJECT_NAME}_PUBLIC_HEADERS} ${us_config_h_file}) + +# Link flags +if(${PROJECT_NAME}_LINK_FLAGS OR US_LINK_FLAGS) + set_target_properties(${${PROJECT_NAME}_TARGET} PROPERTIES + LINK_FLAGS "${US_LINK_FLAGS} ${${PROJECT_NAME}_LINK_FLAGS}" + ) +endif() + +# Compile definitions +set_property(TARGET ${${PROJECT_NAME}_TARGET} + APPEND PROPERTY COMPILE_DEFINITIONS US_FORCE_MODULE_INIT +) + +set_target_properties(${${PROJECT_NAME}_TARGET} PROPERTIES + SOVERSION ${${PROJECT_NAME}_VERSION} + PUBLIC_HEADER "${${PROJECT_NAME}_PUBLIC_HEADERS}" + PRIVATE_HEADER "${${PROJECT_NAME}_PRIVATE_HEADERS}" +) + +# Link additional libraries +if(${PROJECT_NAME}_LINK_LIBRARIES) + target_link_libraries(${${PROJECT_NAME}_TARGET} ${${PROJECT_NAME}_LINK_LIBRARIES}) +endif() + + +#----------------------------------------------------------------------------- +# Install support +#----------------------------------------------------------------------------- + +install(TARGETS ${${PROJECT_NAME}_TARGET} + EXPORT us${PROJECT_NAME}Targets + RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT} + LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT} + ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT} + PUBLIC_HEADER DESTINATION ${HEADER_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT} + PRIVATE_HEADER DESTINATION ${HEADER_INSTALL_DIR} ${US_SDK_INSTALL_COMPONENT}) + +#----------------------------------------------------------------------------- +# US testing +#----------------------------------------------------------------------------- + +if(US_BUILD_TESTING) + add_subdirectory(test) +endif() + +#----------------------------------------------------------------------------- +# Documentation +#----------------------------------------------------------------------------- + +add_subdirectory(doc) + +#----------------------------------------------------------------------------- +# Last configuration and install steps +#----------------------------------------------------------------------------- + +export(TARGETS ${${PROJECT_NAME}_TARGET} + FILE ${CppMicroServices_BINARY_DIR}/us${PROJECT_NAME}Targets.cmake) +install(EXPORT us${PROJECT_NAME}Targets + FILE us${PROJECT_NAME}Targets.cmake + DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR}) + +# Configure CoreConfig.cmake for the build tree + +set(PACKAGE_CONFIG_INCLUDE_DIR + ${${PROJECT_NAME}_INCLUDE_DIRS} + ${${PROJECT_NAME}_INTERNAL_INCLUDE_DIRS}) +set(PACKAGE_CONFIG_RUNTIME_LIBRARY_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/us${PROJECT_NAME}Config.cmake.in + ${CppMicroServices_BINARY_DIR}/us${PROJECT_NAME}Config.cmake + @ONLY + ) + +# Configure CoreConfig.cmake for the install tree + +set(CONFIG_INCLUDE_DIR ${HEADER_INSTALL_DIR}) +set(CONFIG_RUNTIME_LIBRARY_DIR ${RUNTIME_INSTALL_DIR}) + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/us${PROJECT_NAME}Config.cmake.in + ${CppMicroServices_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/us${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR} + PATH_VARS CONFIG_INCLUDE_DIR CONFIG_RUNTIME_LIBRARY_DIR + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + +# Version information +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/us${PROJECT_NAME}ConfigVersion.cmake.in + ${CppMicroServices_BINARY_DIR}/us${PROJECT_NAME}ConfigVersion.cmake + @ONLY + ) + +install(FILES ${CppMicroServices_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/us${PROJECT_NAME}Config.cmake + ${CppMicroServices_BINARY_DIR}/us${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${AUXILIARY_CMAKE_INSTALL_DIR} + ${US_SDK_INSTALL_COMPONENT} + ) + +#----------------------------------------------------------------------------- +# Build the examples +#----------------------------------------------------------------------------- + +if(US_BUILD_EXAMPLES) + if(NOT US_BUILD_SHARED_LIBS) + message(WARNING "Core examples are not available if US_BUILD_SHARED_LIBS is OFF") + else() + set(CppMicroServices_DIR ${CppMicroServices_BINARY_DIR}) + add_subdirectory(examples) + endif() +endif() diff --git a/README.md b/core/README.md similarity index 95% copy from README.md copy to core/README.md index 5524513091..05b4c242e4 100644 --- a/README.md +++ b/core/README.md @@ -1,98 +1,100 @@ [![Build Status](https://secure.travis-ci.org/saschazelzer/CppMicroServices.png)](http://travis-ci.org/saschazelzer/CppMicroServices) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/1329/badge.svg)](https://scan.coverity.com/projects/1329) + C++ Micro Services ================== Introduction ------------ The C++ Micro Services library provides a dynamic service registry and module system, partially based the OSGi Core Release 5 specifications. It enables developers to create a service oriented and dynamic software stack. Proper usage of the C++ Micro Services library leads to - Re-use of software components - Loose coupling - Separation of concerns - Clean APIs based on service interfaces - Extensible systems and more. Requirements ------------ This is a pure C++ implementation of the OSGi service model and does not have any third-party library dependencies. Supported Platforms ------------------- The library should compile on many different platforms. Below is a list of tested compiler/OS combinations: - GCC 4.6 (Ubuntu 12.04) - GCC 4.8 (Ubuntu 13.10) - Clang 3.2 (Ubuntu 13.10) - Clang (MacOS X 10.8 and 10.9) - Visual Studio 2008 SP1, 2010, 2012, 2013 (Windows 7) Legal ----- Copyright (c) German Cancer Research Center. Licensed under the [Apache License v2.0][apache_license]. Quick Start ----------- Essentially, the C++ Micro Services library provides you with a powerful dynamic service registry. Each shared or static library has an associated `ModuleContext` object, through which the service registry is accessed. To query the registry for a service object implementing one or more specific interfaces, the code would look like this: ```cpp #include #include using namespace us; void UseService(ModuleContext* context) { ServiceReference serviceRef = context->GetServiceReference(); if (serviceRef) { SomeInterface* service = context->GetService(serviceRef); if (service) { /* do something */ } } } ``` Registering a service object against a certain interface looks like this: ```cpp #include #include using namespace us; void RegisterSomeService(ModuleContext* context, SomeInterface* service) { context->RegisterService(service); } ``` The OSGi service model additionally allows to annotate services with properties and using these properties during service look-ups. It also allows to track the life-cycle of service objects. Please see the [Documentation](http://cppmicroservices.org/doc_latest/index.html) for more examples and tutorials and the API reference. There is also a blog post about [OSGi Lite for C++](http://blog.cppmicroservices.org/2012/04/15/osgi-lite-for-c++). Build Instructions ------------------ Please visit the [Build Instructions][bi_master] page online. [bi_master]: http://cppmicroservices.org/doc_latest/BuildInstructions.html [apache_license]: http://www.apache.org/licenses/LICENSE-2.0 diff --git a/core/doc/CMakeLists.txt b/core/doc/CMakeLists.txt new file mode 100644 index 0000000000..f5c5327bd6 --- /dev/null +++ b/core/doc/CMakeLists.txt @@ -0,0 +1,6 @@ +if(US_BUILD_TESTING) + include(usFunctionCompileSnippets) + # Compile source code snippets + add_subdirectory(snippets) +endif() + diff --git a/documentation/doxygen/MicroServices.dox b/core/doc/doxygen/MicroServices.dox similarity index 100% rename from documentation/doxygen/MicroServices.dox rename to core/doc/doxygen/MicroServices.dox diff --git a/documentation/doxygen/MicroServices_AutoLoading.md b/core/doc/doxygen/MicroServices_AutoLoading.md similarity index 100% rename from documentation/doxygen/MicroServices_AutoLoading.md rename to core/doc/doxygen/MicroServices_AutoLoading.md diff --git a/documentation/doxygen/MicroServices_Debugging.dox b/core/doc/doxygen/MicroServices_Debugging.dox similarity index 100% rename from documentation/doxygen/MicroServices_Debugging.dox rename to core/doc/doxygen/MicroServices_Debugging.dox diff --git a/documentation/doxygen/MicroServices_EmulateSingleton.dox b/core/doc/doxygen/MicroServices_EmulateSingleton.dox similarity index 100% rename from documentation/doxygen/MicroServices_EmulateSingleton.dox rename to core/doc/doxygen/MicroServices_EmulateSingleton.dox diff --git a/documentation/doxygen/MicroServices_ModuleProperties.md b/core/doc/doxygen/MicroServices_ModuleProperties.md similarity index 100% rename from documentation/doxygen/MicroServices_ModuleProperties.md rename to core/doc/doxygen/MicroServices_ModuleProperties.md diff --git a/documentation/doxygen/MicroServices_Resources.md b/core/doc/doxygen/MicroServices_Resources.md similarity index 100% rename from documentation/doxygen/MicroServices_Resources.md rename to core/doc/doxygen/MicroServices_Resources.md diff --git a/documentation/doxygen/MicroServices_ServiceHooks.md b/core/doc/doxygen/MicroServices_ServiceHooks.md similarity index 100% rename from documentation/doxygen/MicroServices_ServiceHooks.md rename to core/doc/doxygen/MicroServices_ServiceHooks.md diff --git a/documentation/doxygen/MicroServices_StaticModules.md b/core/doc/doxygen/MicroServices_StaticModules.md similarity index 100% rename from documentation/doxygen/MicroServices_StaticModules.md rename to core/doc/doxygen/MicroServices_StaticModules.md diff --git a/documentation/doxygen/MicroServices_TheModuleContext.md b/core/doc/doxygen/MicroServices_TheModuleContext.md similarity index 100% rename from documentation/doxygen/MicroServices_TheModuleContext.md rename to core/doc/doxygen/MicroServices_TheModuleContext.md diff --git a/documentation/doxygen/doxygen_extra.css b/core/doc/doxygen/doxygen_extra.css similarity index 100% rename from documentation/doxygen/doxygen_extra.css rename to core/doc/doxygen/doxygen_extra.css diff --git a/documentation/doxygen/examples/MicroServices_Example1.md b/core/doc/doxygen/examples/MicroServices_Example1.md similarity index 95% rename from documentation/doxygen/examples/MicroServices_Example1.md rename to core/doc/doxygen/examples/MicroServices_Example1.md index e5c92e2981..6e1abbf0ff 100644 --- a/documentation/doxygen/examples/MicroServices_Example1.md +++ b/core/doc/doxygen/examples/MicroServices_Example1.md @@ -1,97 +1,97 @@ Example 1 - Service Event Listener {#MicroServices_Example1} ================================== This example creates a simple module that listens for service events. This example does not do much at first, because it only prints out the details of registering and unregistering services. In the next example we will create a module that implements a service, which will cause this module to actually do something. For now, we will just use this example to help us understand the basics of creating a module and its activator. A module gains access to the C++ Micro Services API using a unique instance of ModuleContext. This unique module context can be used during static initialization of the module or at any later point during the life-time of the module. To execute code during static initialization (and de-initialization) time, the module must provide an implementation of the ModuleActivator interface; this interface has two methods, Load() and Unload(), that both receive the module's context and are called when the module is loaded (statically initialized) and unloaded, respectively. \note You do not need to remember the ModuleContext instance within the ModuleActivator::Load() method and provide custom access methods for later retrieval. Use the GetModuleContext() function to easily retrieve the current module's context. In the following source code, our module implements the ModuleActivator interface and uses the context to add itself as a listener for service events (in the `eventlistener/Activator.cpp` file): \snippet eventlistener/Activator.cpp Activator After implementing the C++ source code for the module activator, we must *export* the activator such that the C++ Micro Services library can create an instance of it and call the `Load()` and `Unload()` methods: \dontinclude eventlistener/Activator.cpp \skipline US_EXPORT Now we need to compile the source code. This example uses CMake as the build system and the top-level CMakeLists.txt file could look like this: \dontinclude examples/CMakeLists.txt \skip project \until eventlistener and the CMakeLists.txt file in the eventlistener subdirectory is: \include eventlistener/CMakeLists.txt The call to `#usFunctionGenerateModuleInit` is necessary to integrate the shared library as a module within the C++ Micro Service library. If you are not using CMake, you have to place a macro call to `#US_INITIALIZE_MODULE` yourself into the module's source code, e.g. in `Activator.cpp`. Have a look at the \ref MicroServices_GettingStarted documentation for more details about using CMake or other build systems (e.g. Makefiles) when writing modules. To run the examples contained in the C++ Micro Services library, we use a small -driver program called `CppMicroServicesExampleDriver`: +driver program called `usCoreExamplesDriver`: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > h h This help text l Load the module with id or name u Unload the module with id s Print status information q Quit > \endverbatim Typing `s` at the command prompt lists the available, loaded, and unloaded modules. To load the eventlistener module, type `l eventlistener` at the command prompt: \verbatim > s Id | Name | Status ----------------------------------- - | dictionaryclient | - - | dictionaryclient2 | - - | dictionaryclient3 | - - | dictionaryservice | - - | eventlistener | - - | frenchdictionary | - - | spellcheckclient | - - | spellcheckservice | - 1 | CppMicroServices | LOADED > l eventlistener Starting to listen for service events. > \endverbatim The above command loaded the eventlistener module (by loading its shared library). Keep in mind, that this module will not do much at this point since it only listens for service events and we are not registering any services. In the next example we will register a service that will generate an event for this module to -receive. To exit the `CppMicroServicesExampleDriver`, use the `q` command. +receive. To exit the `usCoreExamplesDriver`, use the `q` command. Next: \ref MicroServices_Example2 diff --git a/documentation/doxygen/examples/MicroServices_Example2.md b/core/doc/doxygen/examples/MicroServices_Example2.md similarity index 93% rename from documentation/doxygen/examples/MicroServices_Example2.md rename to core/doc/doxygen/examples/MicroServices_Example2.md index b7fe0bbca3..82aa352c2a 100644 --- a/documentation/doxygen/examples/MicroServices_Example2.md +++ b/core/doc/doxygen/examples/MicroServices_Example2.md @@ -1,87 +1,87 @@ Example 2 - Dictionary Service Module {#MicroServices_Example2} ===================================== This example creates a module that implements a service. Implementing a service is a two-step process, first we must define the interface of the service and then we must define an implementation of the service interface. In this particular example, we will create a dictionary service that we can use to check if a word exists, which indicates if the word is spelled correctly or not. First, we will start by defining a simple dictionary service interface in a file called `dictionaryservice/IDictionaryService.h`: \snippet dictionaryservice/IDictionaryService.h service The service interface is quite simple, with only one method that needs to be implemented. Because we provide an empty out-of-line destructor (defined in the file `IDictionaryService.cpp`) we must export the service interface by using the module specific `DICTIONARYSERVICE_EXPORT` macro. In the following source code, the module uses its module context to register the dictionary service. We implement the dictionary service as an inner class of the module activator class, but we could have also put it in a separate file. The source code for our module is as follows in a file called `dictionaryservice/Activator.cpp`: \snippet dictionaryservice/Activator.cpp Activator Note that we do not need to unregister the service in the Unload() method, because the C++ Micro Services library will automatically do so for us. The dictionary service that we have implemented is very simple; its dictionary is a set of only five words, so this solution is not optimal and is only intended for educational purposes. \note In this example, the service interface and implementation are both contained in one module which exports the interface class. However, service implementations almost never need to be exported and in many use cases it is beneficial to provide the service interface and its implementation(s) in separate modules. In such a scenario, clients of a service will only have a link-time dependency on the shared library providing the service interface (because of the out-of-line destructor) but not on any modules containing service implementations. This often leads to modules which do not export any symbols at all and hence need to be loaded into the running process manually or by using the \ref MicroServices_AutoLoading "auto-loading mechanism". For an introduction how to compile our source code, see \ref MicroServices_Example1. -After running the `CppMicroServicesExampleDriver` program we should make sure that the +After running the `usCoreExamplesDriver` program we should make sure that the module from Example 1 is active. We can use the `s` shell command to get a list of all modules, their state, and their module identifier number. If the Example 1 module is not active, we should load the module using the load command and the module's identifier number or name that is displayed by the `s` command. Now we can load our dictionary service module by typing the `l dictionaryservice` command: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > s Id | Name | Status ----------------------------------- - | dictionaryservice | - - | eventlistener | - 1 | CppMicroServices | LOADED > l eventlistener Starting to listen for service events. > l dictionaryservice Ex1: Service of type IDictionaryService/1.0 registered. > s Id | Name | Status ----------------------------------- 1 | CppMicroServices | LOADED 2 | Event Listener | LOADED 3 | Dictionary Service | LOADED > \endverbatim To unload the module, use the `u ` command. If the module from \ref MicroServices_Example1 "Example 1" is still active, then we should see it print out the details of the service event it receives -when our new module registers its dictionary service. Using the `CppMicroServicesExampleDriver` +when our new module registers its dictionary service. Using the `usCoreExamplesDriver` commands `u` and `l` we can unload and load it at will, respectively. Each time we load and unload our dictionary service module, we should see the details of the associated service event printed from the module from Example 1. In \ref MicroServices_Example3 "Example 3", we will create a client for our -dictionary service. To exit `CppMicroServicesExampleDriver`, we use the `q` command. +dictionary service. To exit `usCoreExamplesDriver`, we use the `q` command. Next: \ref MicroServices_Example2b Previous: \ref MicroServices_Example1 diff --git a/documentation/doxygen/examples/MicroServices_Example2b.md b/core/doc/doxygen/examples/MicroServices_Example2b.md similarity index 92% rename from documentation/doxygen/examples/MicroServices_Example2b.md rename to core/doc/doxygen/examples/MicroServices_Example2b.md index 4045a8e483..0470a6ee5b 100644 --- a/documentation/doxygen/examples/MicroServices_Example2b.md +++ b/core/doc/doxygen/examples/MicroServices_Example2b.md @@ -1,76 +1,76 @@ Example 2b - Alternative Dictionary Service Module {#MicroServices_Example2b} ================================================== This example creates an alternative implementation of the dictionary service defined in \ref MicroServices_Example2 "Example 2". The source code for the module is identical except that instead of using English words, French words are used. The only other difference is that in this module we do not need to define the dictionary service interface again, since we can just link the definition from the module in Example 2. The main point of this example is to illustrate that multiple implementations of the same service may exist; this example will also be of use to us in \ref MicroServices_Example5 "Example 5". In the following source code, the module uses its module context to register the dictionary service. We implement the dictionary service as an inner class of the module activator class, but we could have also put it in a separate file. The source code for our module is as follows in a file called `dictionaryclient/Activator.cpp`: \snippet frenchdictionary/Activator.cpp Activator For an introduction how to compile our source code, see \ref MicroServices_Example1. Because we use the `IDictionaryService` definition from Example 2, we also need to make sure that the proper include paths and linker dependencies are set: \include frenchdictionary/CMakeLists.txt -After running the `CppMicroServicesExampleDriver` program we should make sure that the +After running the `usCoreExamplesDriver` program we should make sure that the module from Example 1 is active. We can use the `s` shell command to get a list of all modules, their state, and their module identifier number. If the Example 1 module is not active, we should load the module using the load command and the module's identifier number or name that is displayed by the `s` command. Now we can load our dictionary service module by typing the `l frenchdictionary` command: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > s Id | Name | Status ----------------------------------- - | dictionaryservice | - - | eventlistener | - - | frenchdictionary | - 1 | CppMicroServices | LOADED > l eventlistener Starting to listen for service events. > l frenchdictionary Ex1: Service of type IDictionaryService/1.0 registered. Ex1: Service of type IDictionaryService/1.0 registered. > s Id | Name | Status ----------------------------------- 1 | CppMicroServices | LOADED 2 | Event Listener | LOADED 3 | Dictionary Service | LOADED 4 | French Dictionary | LOADED > \endverbatim To unload the module, use the `u ` command. If the module from \ref MicroServices_Example1 "Example 1" is still active, then we should see it print out the details of the service event it receives -when our new module registers its dictionary service. Using the `CppMicroServicesExampleDriver` +when our new module registers its dictionary service. Using the `usCoreExamplesDriver` commands `u` and `l` we can unload and load it at will, respectively. Each time we load and unload our dictionary service module, we should see the details of the associated service event printed from the module from Example 1. In \ref MicroServices_Example3 "Example 3", we will create a client for our -dictionary service. To exit `CppMicroServicesExampleDriver`, we use the `q` command. +dictionary service. To exit `usCoreExamplesDriver`, we use the `q` command. \note Because our french dictionary module has a link dependency on the dictionary service module from Example 2, this module is automatically loaded by the operating system loader. Unloading it will only succeed if there are no other dependent modules like our french dictionary module currently loaded. Next: \ref MicroServices_Example3 Previous: \ref MicroServices_Example2 diff --git a/documentation/doxygen/examples/MicroServices_Example3.md b/core/doc/doxygen/examples/MicroServices_Example3.md similarity index 94% rename from documentation/doxygen/examples/MicroServices_Example3.md rename to core/doc/doxygen/examples/MicroServices_Example3.md index 2c225c7ecf..7c8c16ce32 100644 --- a/documentation/doxygen/examples/MicroServices_Example3.md +++ b/core/doc/doxygen/examples/MicroServices_Example3.md @@ -1,58 +1,58 @@ Example 3 - Dictionary Client Module {#MicroServices_Example3} ==================================== This example creates a module that is a client of the dictionary service implemented in \ref MicroServices_Example2 "Example 2". In the following source code, our module uses its module context to query for a dictionary service. Our client module uses the first dictionary service it finds and if none are found it simply prints a message saying so and stops. Using a service is the same as using any C++ class. The source code for our module is as follows in a file called `dictionaryclient2/Activator.cpp`: \snippet dictionaryclient/Activator.cpp Activator Note that we do not need to unget or release the service in the Unload() method, because the C++ Micro Services library will automatically do so for us. Since we are using the `IDictionaryService` interface defined in Example 1, we must link our module to the `dictionaryservice` module: \include dictionaryclient/CMakeLists.txt -After running the `CppMicroServicesExampleDriver` executable, and loading the event +After running the `usCoreExamplesDriver` executable, and loading the event listener module, we can use the `l dictionaryclient` command to load our dictionary client module: \verbatim -CppMicroServices-debug> bin/CppMicroServicesExampleDriver +CppMicroServices-debug> bin/usCoreExamplesDriver > l eventlistener Starting to listen for service events. > l dictionaryclient Ex1: Service of type IDictionaryService/1.0 registered. Enter a blank line to exit. Enter word: \endverbatim The above command loads the module and its dependencies (the `dictionaryservice` module) in a single step. When we load the module, it will use the main thread to prompt us for words. Enter one word at a time to check the words and enter a blank line to stop checking words. To reload the module, we must use the `s` command to get the module identifier number for the module and first use the `u ` command to unload the module, then the `l ` command to re-load it. To test the dictionary service, enter any of the words in the dictionary (e.g., "welcome", "to", "the", "micro", "services", "tutorial") or any word not in the dictionary. This example client is simple enough and, in fact, is too simple. What would happen if the dictionary service were to unregister suddenly? Our client would abort with a segmentation fault due to a null pointer access when trying to use the service object. This dynamic service availability issue is a central tenent of the service model. As a result, we must make our client more robust in dealing with such situations. In \ref MicroServices_Example4 "Example 4", we explore a slightly more complicated dictionary client that dynamically monitors service availability. Next: \ref MicroServices_Example4 Previous: \ref MicroServices_Example2 diff --git a/documentation/doxygen/examples/MicroServices_Example4.md b/core/doc/doxygen/examples/MicroServices_Example4.md similarity index 95% rename from documentation/doxygen/examples/MicroServices_Example4.md rename to core/doc/doxygen/examples/MicroServices_Example4.md index a43e7dc970..d0e2f80f9b 100644 --- a/documentation/doxygen/examples/MicroServices_Example4.md +++ b/core/doc/doxygen/examples/MicroServices_Example4.md @@ -1,66 +1,66 @@ Example 4 - Robust Dictionary Client Module {#MicroServices_Example4} =========================================== In \ref MicroServices_Example3 "Example 3", we create a simple client module for our dictionary service. The problem with that client was that it did not monitor the dynamic availability of the dictionary service, thus an error would occur if the dictionary service disappeared while the client was using it. In this example we create a client for the dictionary service that monitors the dynamic availability of the dictionary service. The result is a more robust client. The functionality of the new dictionary client is essentially the same as the old client, it reads words from standard input and checks for their existence in the dictionary service. Our module uses its module context to register itself as a service event listener; monitoring service events allows the module to monitor the dynamic availability of the dictionary service. Our client uses the first dictionary service it finds. The source code for our module is as follows in a file called `Activator.cpp`: \snippet dictionaryclient2/Activator.cpp Activator The client listens for service events indicating the arrival or departure of dictionary services. If a new dictionary service arrives, the module will start using that service if and only if it currently does not have a dictionary service. If an existing dictionary service disappears, the module will check to see if the disappearing service is the one it is using; if it is it stops using it and tries to query for another dictionary service, otherwise it ignores the event. As in Example 3, we must link our module to the `dictionaryservice` module: \include dictionaryclient2/CMakeLists.txt -After running the `CppMicroServicesExampleDriver` executable, and loading the event +After running the `usCoreExamplesDriver` executable, and loading the event listener module, we can use the `l dictionaryclient2` command to load our robust dictionary client module: \verbatim -CppMicroServices-debug> bin/CppMicroServicesExampleDriver +CppMicroServices-debug> bin/usCoreExamplesDriver > l eventlistener Starting to listen for service events. > l dictionaryclient2 Ex1: Service of type IDictionaryService/1.0 registered. Enter a blank line to exit. Enter word: \endverbatim The above command loads the module and its dependencies (the `dictionaryservice` module) in a single step. When we load the module, it will use the main thread to prompt us for words. Enter one word at a time to check the words and enter a blank line to stop checking words. To reload the module, we must use the `s` command to get the module identifier number for the module and first use the `u ` command to unload the module, then the `l ` command to re-load it. To test the dictionary service, enter any of the words in the dictionary (e.g., "welcome", "to", "the", "micro", "services", "tutorial") or any word not in the dictionary. Since this client monitors the dynamic availability of the dictionary service, it is robust in the face of sudden departures of the the dictionary service. Further, when a dictionary service arrives, it automatically gets the service if it needs it and continues to function. These capabilities are a little difficult to demonstrate since we are using a simple single-threaded approach, but in a multi-threaded or GUI-oriented application this robustness is very useful. Next: \ref MicroServices_Example5 Previous: \ref MicroServices_Example3 diff --git a/documentation/doxygen/examples/MicroServices_Example5.md b/core/doc/doxygen/examples/MicroServices_Example5.md similarity index 95% rename from documentation/doxygen/examples/MicroServices_Example5.md rename to core/doc/doxygen/examples/MicroServices_Example5.md index 419fbad5bb..e5116cb0f7 100644 --- a/documentation/doxygen/examples/MicroServices_Example5.md +++ b/core/doc/doxygen/examples/MicroServices_Example5.md @@ -1,61 +1,61 @@ Example 5 - Service Tracker Dictionary Client Module {#MicroServices_Example5} ==================================================== In \ref MicroServices_Example4 "Example 4", we created a more robust client bundle for our dictionary service. Due to the complexity of dealing with dynamic service availability, even that client may not sufficiently address all situations. To deal with this complexity the C++ Micro Services library provides the `ServiceTracker` utility class. In this example we create a client for the dictionary service that uses the `ServiceTracker` class to monitor the dynamic availability of the dictionary service, resulting in an even more robust client. The functionality of the new dictionary client is essentially the same as the one from Example 4. Our module uses its module context to create a `ServiceTracker` instance to track the dynamic availability of the dictionary service on our behalf. Our client uses the dictionary service returned by the `ServiceTracker`, which is selected based on a ranking algorithm defined by the C++ Micro Services library. The source code for our modules is as follows in a file called `dictionaryclient3/Activator.cpp`: \snippet dictionaryclient3/Activator.cpp Activator Since this client uses the `ServiceTracker` utility class, it will automatically monitor the dynamic availability of the dictionary service. Again, we must link our module to the `dictionaryservice` module: \include dictionaryclient3/CMakeLists.txt -After running the `CppMicroServicesExampleDriver` executable, and loading the event +After running the `usCoreExamplesDriver` executable, and loading the event listener module, we can use the `l dictionaryclient3` command to load our robust dictionary client module: \verbatim -CppMicroServices-debug> bin/CppMicroServicesExampleDriver +CppMicroServices-debug> bin/usCoreExamplesDriver > l eventlistener Starting to listen for service events. > l dictionaryclient3 Ex1: Service of type IDictionaryService/1.0 registered. Enter a blank line to exit. Enter word: \endverbatim The above command loads the module and its dependencies (the `dictionaryservice` module) in a single step. When we load the module, it will use the main thread to prompt us for words. Enter one word at a time to check the words and enter a blank line to stop checking words. To reload the module, we must use the `s` command to get the module identifier number for the module and first use the `u ` command to unload the module, then the `l ` command to re-load it. To test the dictionary service, enter any of the words in the dictionary (e.g., "welcome", "to", "the", "micro", "services", "tutorial") or any word not in the dictionary. Since this client monitors the dynamic availability of the dictionary service, it is robust in the face of sudden departures of the the dictionary service. Further, when a dictionary service arrives, it automatically gets the service if it needs it and continues to function. These capabilities are a little difficult to demonstrate since we are using a simple single-threaded approach, but in a multi-threaded or GUI-oriented application this robustness is very useful. Next: \ref MicroServices_Example6 Previous: \ref MicroServices_Example4 diff --git a/documentation/doxygen/examples/MicroServices_Example6.md b/core/doc/doxygen/examples/MicroServices_Example6.md similarity index 95% rename from documentation/doxygen/examples/MicroServices_Example6.md rename to core/doc/doxygen/examples/MicroServices_Example6.md index 66559e8931..c5150a55bc 100644 --- a/documentation/doxygen/examples/MicroServices_Example6.md +++ b/core/doc/doxygen/examples/MicroServices_Example6.md @@ -1,123 +1,123 @@ Example 6 - Spell Checker Service Module {#MicroServices_Example6} ======================================== In this example, we complicate things further by defining a new service that uses an arbitrary number of dictionary services to perform its function. More precisely, we define a spell checker service which will aggregate all dictionary services and provide another service that allows us to spell check passages using our underlying dictionary services to verify the spelling of words. Our module will only provide the spell checker service if there are at least two dictionary services available. First, we will start by defining the spell checker service interface in a file called `spellcheckservice/ISpellCheckService.h`: \snippet spellcheckservice/ISpellCheckService.h service The service interface is quite simple, with only one method that needs to be implemented. Because we provide an empty out-of-line destructor (defined in the file `ISpellCheckService.cpp`) we must export the service interface by using the module specific `SPELLCHECKSERVICE_EXPORT` macro. In the following source code, the module needs to create a complete list of all dictionary services; this is somewhat tricky and must be done carefully if done manually via service event listners. Our module makes use of the `ServiceTracker` and `ServiceTrackerCustomizer` classes to robustly react to service events related to dictionary services. The module activator of our module now additionally implements the `ServiceTrackerCustomizer` class to be automatically notified of arriving, departing, or modified dictionary services. In case of a newly added dictionary service, our `ServiceTrackerCustomizer::AddingService()` implementation checks if a spell checker service was already registered and if not registers a new `ISpellCheckService` instance if at lead two dictionary services are available. If the number of dictionary services drops below two, our `ServiceTrackerCustomizer` implementation un-registers the previously registered spell checker service instance. These actions must be performed in a synchronized manner to avoid interference from service events originating from different threads. The implementation of our module activator is done in a file called `spellcheckservice/Activator.cpp`: \snippet spellcheckservice/Activator.cpp Activator Note that we do not need to unregister the service in stop() method, because the C++ Micro Services library will automatically do so for us. The spell checker service that we have implemented is very simple; it simply parses a given passage into words and then loops through all available dictionary services for each word until it determines that the word is correct. Any incorrect words are added to an error list that will be returned to the caller. This solution is not optimal and is only intended for educational purposes. \note In this example, the service interface and implementation are both contained in one module which exports the interface class. However, service implementations almost never need to be exported and in many use cases it is beneficial to provide the service interface and its implementation(s) in separate modules. In such a scenario, clients of a service will only have a link-time dependency on the shared library providing the service interface (because of the out-of-line destructor) but not on any modules containing service implementations. This often leads to modules which do not export any symbols at all and hence need to be loaded into the running process manually or by using the \ref MicroServices_AutoLoading "auto-loading mechanism". \note Due to the link dependency of our module to the module containing the dictionary service interface as well as a default implementation for it, there might be at least one dictionary service registered when our module is loaded, depending on your linker settings (e.g. on Windows, the linker usually by default optimizes the link dependency away since our module does not actually use any symbols from the dictionaryservice module. On Linux however, the link dependency is kept by default.) To observe the dynamic registration and un-registration of our spell checker service, we require the availability of at least two dictionary services. For an introduction how to compile our source code, see \ref MicroServices_Example1. -After running the `CppMicroServicesExampleDriver` program we should make sure that the +After running the `usCoreExamplesDriver` program we should make sure that the module from Example 1 is active. We can use the `s` shell command to get a list of all modules, their state, and their module identifier number. If the Example 1 module is not active, we should load the module using the load command and the module's identifier number or name that is displayed by the `s` command. Now we can load the spell checker service module by entering the `l spellcheckservice` command which will also trigger the loading of the dictionaryservice module containing the english dictionary: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > l eventlistener Starting to listen for service events. > l spellcheckservice Ex1: Service of type IDictionaryService/1.0 registered. > s Id | Name | Status ----------------------------------- - | dictionaryclient | - - | dictionaryclient2 | - - | dictionaryclient3 | - - | frenchdictionary | - - | spellcheckclient | - 1 | CppMicroServices | LOADED 2 | Event Listener | LOADED 3 | Dictionary Service | LOADED 4 | Spell Check Service | LOADED > \endverbatim To trigger the registration of the spell checker service from our module, we load the frenchdictionary using the `l frenchdictionary` command. If the module from \ref MicroServices_Example1 "Example 1" is still active, then we should see it print out the details of the service event it receives when our new module registers its spell checker service: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > l frenchdictionary Ex1: Service of type IDictionaryService/1.0 registered. Ex1: Service of type ISpellCheckService/1.0 registered. > \endverbatim We can experiment with our spell checker service's dynamic availability by stopping the french dictionary service; when the service is stopped, the eventlistener module will print that our module is no longer offering its spell checker service. Likewise, when the french dictionary service comes back, so will our spell checker service. We create a client for our spell checker service in -\ref MicroServices_Example7 "Example 7". To exit the `CppMicroServicesExampleDriver` program, we +\ref MicroServices_Example7 "Example 7". To exit the `usCoreExamplesDriver` program, we use the `q` command. Next: \ref MicroServices_Example7 Previous: \ref MicroServices_Example5 diff --git a/documentation/doxygen/examples/MicroServices_Example7.md b/core/doc/doxygen/examples/MicroServices_Example7.md similarity index 93% rename from documentation/doxygen/examples/MicroServices_Example7.md rename to core/doc/doxygen/examples/MicroServices_Example7.md index 8bcdc5e997..935d3dd3b0 100644 --- a/documentation/doxygen/examples/MicroServices_Example7.md +++ b/core/doc/doxygen/examples/MicroServices_Example7.md @@ -1,73 +1,73 @@ Example 7 - Spell Checker Client Module {#MicroServices_Example7} ======================================= In this example we create a client for the spell checker service we implemented in \ref MicroServices_Example6 "Example 6". This client monitors the dynamic availability of the spell checker service using the Service Tracker and is very similar in structure to the dictionary client we implemented in \ref MicroServices_Example5 "Example 5". The functionality of the spell checker client reads passages from standard input and spell checks them using the spell checker service. Our module uses its module context to create a `ServiceTracker` object to monitor spell checker services. The source code for our module is as follows in a file called `spellcheckclient/Activator.cpp`: \snippet spellcheckclient/Activator.cpp Activator -After running the `CppMicroServicesExampleDriver` program use the `s` command to make sure that +After running the `usCoreExamplesDriver` program use the `s` command to make sure that only the modules from Example 2, Example 2b, and Example 6 are loaded; use the load (`l`) and un-load (`u`) commands as appropriate to load and un-load the various tutorial modules, respectively. Now we can load our spell checker client module by entering `l spellcheckclient`: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > l Starting to listen for service events. > l spellcheckservice Ex1: Service of type IDictionaryService/1.0 registered. > s Id | Name | Status ----------------------------------- - | dictionaryclient | - - | dictionaryclient2 | - - | dictionaryclient3 | - - | frenchdictionary | - - | spellcheckclient | - 1 | CppMicroServices | LOADED 2 | Event Listener | LOADED 3 | Dictionary Service | LOADED 4 | Spell Check Service | LOADED > \endverbatim To trigger the registration of the spell checker service from our module, we load the frenchdictionary using the `l frenchdictionary` command. If the module from \ref MicroServices_Example1 "Example 1" is still active, then we should see it print out the details of the service event it receives when our new module registers its spell checker service: \verbatim -CppMicroServices-build> bin/CppMicroServicesExampleDriver +CppMicroServices-build> bin/usCoreExamplesDriver > l spellcheckservice > l frenchdictionary > l spellcheckclient Enter a blank line to exit. Enter passage: \endverbatim When we start the module, it will use the main thread to prompt us for passages; a passage is a collection or words separate by spaces, commas, periods, exclamation points, question marks, colons, or semi-colons. Enter a passage and press the enter key to spell check the passage or enter a blank line to stop spell checking passages. To restart the module, we must use the command `s` command to get the module identifier number for the module and first use the `u` command to un-load the module, then the `l` command to re-load it. Since this client uses the Service Tracker to monitor the dynamic availability of the spell checker service, it is robust in the scenario where the spell checker service suddenly departs. Further, when a spell checker service arrives, it automatically gets the service if it needs it and continues to function. These capabilities are a little difficult to demonstrate since we are using a simple single-threaded approach, but in a multi-threaded or GUI-oriented application this robustness is very useful. Previous: \ref MicroServices_Example6 diff --git a/documentation/doxygen/footer.html b/core/doc/doxygen/footer.html similarity index 100% rename from documentation/doxygen/footer.html rename to core/doc/doxygen/footer.html diff --git a/documentation/doxygen/header.html b/core/doc/doxygen/header.html similarity index 100% rename from documentation/doxygen/header.html rename to core/doc/doxygen/header.html diff --git a/documentation/doxygen/standalone/BuildInstructions.md b/core/doc/doxygen/standalone/BuildInstructions.md similarity index 100% rename from documentation/doxygen/standalone/BuildInstructions.md rename to core/doc/doxygen/standalone/BuildInstructions.md diff --git a/documentation/doxygen/standalone/MicroServices_GettingStarted.md b/core/doc/doxygen/standalone/MicroServices_GettingStarted.md similarity index 100% rename from documentation/doxygen/standalone/MicroServices_GettingStarted.md rename to core/doc/doxygen/standalone/MicroServices_GettingStarted.md diff --git a/documentation/snippets/CMakeLists.txt b/core/doc/snippets/CMakeLists.txt similarity index 100% rename from documentation/snippets/CMakeLists.txt rename to core/doc/snippets/CMakeLists.txt diff --git a/documentation/snippets/uServices-activator/main.cpp b/core/doc/snippets/uServices-activator/main.cpp similarity index 100% rename from documentation/snippets/uServices-activator/main.cpp rename to core/doc/snippets/uServices-activator/main.cpp diff --git a/documentation/snippets/uServices-modulecontext/main.cpp b/core/doc/snippets/uServices-modulecontext/main.cpp similarity index 100% rename from documentation/snippets/uServices-modulecontext/main.cpp rename to core/doc/snippets/uServices-modulecontext/main.cpp diff --git a/documentation/snippets/uServices-registration/main.cpp b/core/doc/snippets/uServices-registration/main.cpp similarity index 100% rename from documentation/snippets/uServices-registration/main.cpp rename to core/doc/snippets/uServices-registration/main.cpp diff --git a/documentation/snippets/uServices-resources/main.cpp b/core/doc/snippets/uServices-resources/main.cpp similarity index 100% rename from documentation/snippets/uServices-resources/main.cpp rename to core/doc/snippets/uServices-resources/main.cpp diff --git a/documentation/snippets/uServices-servicelistenerhook/main.cpp b/core/doc/snippets/uServices-servicelistenerhook/main.cpp similarity index 100% rename from documentation/snippets/uServices-servicelistenerhook/main.cpp rename to core/doc/snippets/uServices-servicelistenerhook/main.cpp diff --git a/documentation/snippets/uServices-servicetracker/main.cpp b/core/doc/snippets/uServices-servicetracker/main.cpp similarity index 100% rename from documentation/snippets/uServices-servicetracker/main.cpp rename to core/doc/snippets/uServices-servicetracker/main.cpp diff --git a/documentation/snippets/uServices-singleton/SingletonOne.cpp b/core/doc/snippets/uServices-singleton/SingletonOne.cpp similarity index 100% rename from documentation/snippets/uServices-singleton/SingletonOne.cpp rename to core/doc/snippets/uServices-singleton/SingletonOne.cpp diff --git a/documentation/snippets/uServices-singleton/SingletonOne.h b/core/doc/snippets/uServices-singleton/SingletonOne.h similarity index 98% rename from documentation/snippets/uServices-singleton/SingletonOne.h rename to core/doc/snippets/uServices-singleton/SingletonOne.h index 62dbf89270..8f993b075c 100644 --- a/documentation/snippets/uServices-singleton/SingletonOne.h +++ b/core/doc/snippets/uServices-singleton/SingletonOne.h @@ -1,64 +1,63 @@ #ifndef SINGLETONONE_H #define SINGLETONONE_H -#include #include #include #include //![s1] class SingletonOne { public: static SingletonOne& GetInstance(); // Just some member int a; private: SingletonOne(); ~SingletonOne(); // Disable copy constructor and assignment operator. SingletonOne(const SingletonOne&); SingletonOne& operator=(const SingletonOne&); }; //![s1] class SingletonTwoService; //![ss1] class SingletonOneService { public: // This will return a SingletonOneService instance with the // lowest service id at the time this method was called the first // time and returned a non-null value (which is usually the instance // which was registered first). A null-pointer is returned if no // instance was registered yet. static SingletonOneService* GetInstance(); int a; private: // Only our module activator class should be able to instantiate // a SingletonOneService object. friend class MyActivator; SingletonOneService(); ~SingletonOneService(); // Disable copy constructor and assignment operator. SingletonOneService(const SingletonOneService&); SingletonOneService& operator=(const SingletonOneService&); }; US_DECLARE_SERVICE_INTERFACE(SingletonOneService, "org.cppmicroservices.snippet.SingletonOneService") //![ss1] #endif // SINGLETONONE_H diff --git a/documentation/snippets/uServices-singleton/SingletonTwo.cpp b/core/doc/snippets/uServices-singleton/SingletonTwo.cpp similarity index 100% rename from documentation/snippets/uServices-singleton/SingletonTwo.cpp rename to core/doc/snippets/uServices-singleton/SingletonTwo.cpp diff --git a/documentation/snippets/uServices-singleton/SingletonTwo.h b/core/doc/snippets/uServices-singleton/SingletonTwo.h similarity index 96% rename from documentation/snippets/uServices-singleton/SingletonTwo.h rename to core/doc/snippets/uServices-singleton/SingletonTwo.h index 9eb8e2b36b..8185e509e0 100644 --- a/documentation/snippets/uServices-singleton/SingletonTwo.h +++ b/core/doc/snippets/uServices-singleton/SingletonTwo.h @@ -1,48 +1,48 @@ #ifndef SINGLETONTWO_H #define SINGLETONTWO_H -#include +#include #include class SingletonTwo { public: static SingletonTwo& GetInstance(); int b; private: SingletonTwo(); ~SingletonTwo(); // Disable copy constructor and assignment operator. SingletonTwo(const SingletonTwo&); SingletonTwo& operator=(const SingletonTwo&); }; class SingletonTwoService { public: static SingletonTwoService* GetInstance(); int b; private: friend class MyActivator; SingletonTwoService(); ~SingletonTwoService(); // Disable copy constructor and assignment operator. SingletonTwoService(const SingletonTwoService&); SingletonTwoService& operator=(const SingletonTwoService&); }; US_DECLARE_SERVICE_INTERFACE(SingletonTwoService, "org.cppmicroservices.snippet.SingletonTwoService") #endif // SINGLETONTWO_H diff --git a/documentation/snippets/uServices-singleton/files.cmake b/core/doc/snippets/uServices-singleton/files.cmake similarity index 100% rename from documentation/snippets/uServices-singleton/files.cmake rename to core/doc/snippets/uServices-singleton/files.cmake diff --git a/documentation/snippets/uServices-singleton/main.cpp b/core/doc/snippets/uServices-singleton/main.cpp similarity index 98% rename from documentation/snippets/uServices-singleton/main.cpp rename to core/doc/snippets/uServices-singleton/main.cpp index 9980ee1f53..76883c7e98 100644 --- a/documentation/snippets/uServices-singleton/main.cpp +++ b/core/doc/snippets/uServices-singleton/main.cpp @@ -1,69 +1,68 @@ -#include #include #include #include "SingletonOne.h" #include "SingletonTwo.h" US_USE_NAMESPACE class MyActivator : public ModuleActivator { public: //![0] void Load(ModuleContext* context) { // The Load() method of the module activator is called during static // initialization time of the shared library. // First create and register a SingletonTwoService instance. m_SingletonTwo = new SingletonTwoService; m_SingletonTwoReg = context->RegisterService(m_SingletonTwo); // Now the SingletonOneService constructor will get a valid // SingletonTwoService instance. m_SingletonOne = new SingletonOneService; m_SingletonOneReg = context->RegisterService(m_SingletonOne); } //![0] //![1] void Unload(ModuleContext* /*context*/) { // Services are automatically unregistered during unloading of // the shared library after the call to Unload(ModuleContext*) // has returned. // Since SingletonOneService needs a non-null SingletonTwoService // instance in its destructor, we explicitly unregister and delete the // SingletonOneService instance here. This way, the SingletonOneService // destructor will still get a valid SingletonTwoService instance. m_SingletonOneReg.Unregister(); delete m_SingletonOne; // For singletonTwoService, we could rely on the automatic unregistering // by the service registry and on automatic deletion if you used // smart pointer reference counting. You must not delete service instances // in this method without unregistering them first. m_SingletonTwoReg.Unregister(); delete m_SingletonTwo; } //![1] private: SingletonOneService* m_SingletonOne; SingletonTwoService* m_SingletonTwo; ServiceRegistration m_SingletonOneReg; ServiceRegistration m_SingletonTwoReg; }; US_EXPORT_MODULE_ACTIVATOR(uServices_singleton, MyActivator) int main() { } diff --git a/documentation/snippets/uServices-staticmodules/MyStaticModule.cpp b/core/doc/snippets/uServices-staticmodules/MyStaticModule.cpp similarity index 100% rename from documentation/snippets/uServices-staticmodules/MyStaticModule.cpp rename to core/doc/snippets/uServices-staticmodules/MyStaticModule.cpp diff --git a/documentation/snippets/uServices-staticmodules/files.cmake b/core/doc/snippets/uServices-staticmodules/files.cmake similarity index 100% rename from documentation/snippets/uServices-staticmodules/files.cmake rename to core/doc/snippets/uServices-staticmodules/files.cmake diff --git a/documentation/snippets/uServices-staticmodules/main.cpp b/core/doc/snippets/uServices-staticmodules/main.cpp similarity index 97% rename from documentation/snippets/uServices-staticmodules/main.cpp rename to core/doc/snippets/uServices-staticmodules/main.cpp index e78d3a64c4..404775b061 100644 --- a/documentation/snippets/uServices-staticmodules/main.cpp +++ b/core/doc/snippets/uServices-staticmodules/main.cpp @@ -1,34 +1,34 @@ -#include +#include US_USE_NAMESPACE //! [ImportStaticModuleIntoLib] #include US_IMPORT_MODULE(MyStaticModule) US_LOAD_IMPORTED_MODULES(HostingModule, MyStaticModule) //! [ImportStaticModuleIntoLib] // This is just for illustration purposes in code snippets extern "C" ModuleActivator* _us_module_activator_instance_MyStaticModule1() { return NULL; } extern "C" ModuleActivator* _us_module_activator_instance_MyStaticModule2() { return NULL; } extern "C" ModuleActivator* _us_init_resources_MyStaticModule2() { return NULL; } //! [ImportStaticModuleIntoMain] #include US_IMPORT_MODULE(MyStaticModule1) US_IMPORT_MODULE(MyStaticModule2) US_IMPORT_MODULE_RESOURCES(MyStaticModule2) US_LOAD_IMPORTED_MODULES_INTO_MAIN(MyStaticModule1 MyStaticModule2) //! [ImportStaticModuleIntoMain] int main(int /*argc*/, char* /*argv*/[]) { return 0; } //! [InitializeExecutable] #include US_INITIALIZE_EXECUTABLE("MyExecutable") //! [InitializeExecutable] diff --git a/examples/CMakeLists.txt b/core/examples/CMakeLists.txt similarity index 81% rename from examples/CMakeLists.txt rename to core/examples/CMakeLists.txt index f7ed1bdd07..cdeac59465 100644 --- a/examples/CMakeLists.txt +++ b/core/examples/CMakeLists.txt @@ -1,164 +1,169 @@ -project(CppMicroServicesExamples) +project(CoreExamples) cmake_minimum_required(VERSION 2.8) find_package(CppMicroServices NO_MODULE REQUIRED) include_directories(${CppMicroServices_INCLUDE_DIRS}) #----------------------------------------------------------------------------- # Set C/CXX flags #----------------------------------------------------------------------------- -if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CppMicroServices_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CppMicroServices_CXX_FLAGS_RELEASE}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CppMicroServices_CXX_FLAGS_DEBUG}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CppMicroServices_C_FLAGS}") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CppMicroServices_C_FLAGS_RELEASE}") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CppMicroServices_C_FLAGS_DEBUG}") -endif() +#if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CppMicroServices_CXX_FLAGS}") +# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CppMicroServices_CXX_FLAGS_RELEASE}") +# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CppMicroServices_CXX_FLAGS_DEBUG}") +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CppMicroServices_C_FLAGS}") +# set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CppMicroServices_C_FLAGS_RELEASE}") +# set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CppMicroServices_C_FLAGS_DEBUG}") +#endif() #----------------------------------------------------------------------------- # Init output directories #----------------------------------------------------------------------------- -set(CppMicroServicesExamples_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") -set(CppMicroServicesExamples_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") -set(CppMicroServicesExamples_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +set(CoreExamples_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") +set(CoreExamples_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") +set(CoreExamples_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") foreach(_type ARCHIVE LIBRARY RUNTIME) if(NOT CMAKE_${_type}_OUTPUT_DIRECTORY) - set(CMAKE_${_type}_OUTPUT_DIRECTORY ${CppMicroServicesExamples_${_type}_OUTPUT_DIRECTORY}) + set(CMAKE_${_type}_OUTPUT_DIRECTORY ${CoreExamples_${_type}_OUTPUT_DIRECTORY}) endif() endforeach() function(CreateExample _name) add_library(Example-${_name} SHARED ${ARGN}) if(${_name}_DEPENDS) foreach(_dep ${${_name}_DEPENDS}) - include_directories(${CppMicroServicesExamples_SOURCE_DIR}/${_dep}) + include_directories(${PROJECT_SOURCE_DIR}/${_dep}) target_link_libraries(Example-${_name} Example-${_dep}) endforeach() endif() target_link_libraries(Example-${_name} ${CppMicroServices_LIBRARIES}) set_target_properties(Example-${_name} PROPERTIES LABELS Examples OUTPUT_NAME ${_name} ) endfunction() add_subdirectory(eventlistener) add_subdirectory(dictionaryservice) add_subdirectory(frenchdictionary) add_subdirectory(dictionaryclient) add_subdirectory(dictionaryclient2) add_subdirectory(dictionaryclient3) add_subdirectory(spellcheckservice) add_subdirectory(spellcheckclient) add_subdirectory(driver) #----------------------------------------------------------------------------- # Test if examples compile against an install tree and if the # Makefile example compiles #----------------------------------------------------------------------------- if(US_BUILD_TESTING) enable_testing() set(_example_tests ) - set(_install_dir "${CppMicroServices_BINARY_DIR}/install_test/${CMAKE_INSTALL_PREFIX}") + if(WIN32) + string(REGEX REPLACE "^.:" "" _install_prefix ${CMAKE_INSTALL_PREFIX}) + else() + set(_install_prefix ${CMAKE_INSTALL_PREFIX}) + endif() + set(_install_dir "${CppMicroServices_BINARY_DIR}/install_test/${_install_prefix}") add_test(NAME usInstallCleanTest COMMAND ${CMAKE_COMMAND} -E remove_directory "${_install_dir}") add_test(NAME usInstallTest WORKING_DIRECTORY ${CppMicroServices_BINARY_DIR} COMMAND ${CMAKE_COMMAND} --build ${CppMicroServices_BINARY_DIR} --target install) set_tests_properties(usInstallTest PROPERTIES ENVIRONMENT "DESTDIR=${CppMicroServices_BINARY_DIR}/install_test" DEPENDS usInstallCleanTest) set(_examples_binary_dir "${CppMicroServices_BINARY_DIR}/examples_build") add_test(NAME usExamplesCleanTest COMMAND ${CMAKE_COMMAND} -E remove_directory "${_examples_binary_dir}") add_test(NAME usExamplesCreateDirTest COMMAND ${CMAKE_COMMAND} -E make_directory "${_examples_binary_dir}") set_tests_properties(usExamplesCreateDirTest PROPERTIES DEPENDS usExamplesCleanTest) list(APPEND _example_tests usInstallCleanTest usInstallTest usExamplesCleanTest usExamplesCreateDirTest) if(CMAKE_CONFIGURATION_TYPES) foreach(config ${CMAKE_CONFIGURATION_TYPES}) add_test(NAME usExamplesConfigureTest-${config} CONFIGURATIONS ${config} WORKING_DIRECTORY ${_examples_binary_dir} COMMAND ${CMAKE_COMMAND} -D CMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} -G ${CMAKE_GENERATOR} - "-DCppMicroServices_DIR:PATH=${_install_dir}/${CONFIG_CMAKE_DIR}" + "-DCppMicroServices_DIR:PATH=${_install_dir}/${AUXILIARY_CMAKE_INSTALL_DIR}" "${CMAKE_CURRENT_LIST_DIR}") set_tests_properties(usExamplesConfigureTest-${config} PROPERTIES DEPENDS "usInstallTest;usExamplesCreateDirTest") add_test(NAME usExamplesBuildTest-${config} CONFIGURATIONS ${config} WORKING_DIRECTORY ${_examples_binary_dir} COMMAND ${CMAKE_COMMAND} --build . --config ${config}) set_tests_properties(usExamplesBuildTest-${config} PROPERTIES DEPENDS usExamplesConfigureTest-${config}) list(APPEND _example_tests usExamplesConfigureTest-${config} usExamplesBuildTest-${config}) endforeach() else() add_test(NAME usExamplesConfigureTest-${CMAKE_BUILD_TYPE} WORKING_DIRECTORY ${_examples_binary_dir} COMMAND ${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -D CMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} -G ${CMAKE_GENERATOR} - "-DCppMicroServices_DIR:PATH=${_install_dir}/${CONFIG_CMAKE_DIR}" + "-DCppMicroServices_DIR:PATH=${_install_dir}/${AUXILIARY_CMAKE_INSTALL_DIR}" "${CMAKE_CURRENT_LIST_DIR}") set_tests_properties(usExamplesConfigureTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS "usInstallTest;usExamplesCreateDirTest") add_test(NAME usExamplesBuildTest-${CMAKE_BUILD_TYPE} WORKING_DIRECTORY ${_examples_binary_dir} COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE}) set_tests_properties(usExamplesBuildTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS usExamplesConfigureTest-${CMAKE_BUILD_TYPE}) list(APPEND _example_tests usExamplesConfigureTest-${CMAKE_BUILD_TYPE} usExamplesBuildTest-${CMAKE_BUILD_TYPE}) endif() # The makefile is Linux specific, so only try to build the Makefile example # if we are on a proper system if(UNIX AND NOT APPLE) find_program(MAKE_COMMAND NAMES make gmake) find_program(CXX_COMMAND NAMES g++) mark_as_advanced(MAKE_COMMAND CXX_COMMAND) if(MAKE_COMMAND AND CXX_COMMAND) add_test(NAME usMakefileExampleCleanTest - WORKING_DIRECTORY ${CppMicroServices_SOURCE_DIR}/examples/makefile + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/makefile COMMAND ${MAKE_COMMAND} clean) add_test(NAME usMakefileExampleTest - WORKING_DIRECTORY ${CppMicroServices_SOURCE_DIR}/examples/makefile + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/makefile COMMAND ${MAKE_COMMAND}) set_tests_properties(usMakefileExampleTest PROPERTIES DEPENDS "usMakefileExampleCleanTest;usInstallTest" - ENVIRONMENT "CppMicroServices_ROOT=${CppMicroServices_BINARY_DIR}/install_test${CMAKE_INSTALL_PREFIX};CppMicroServices_CXX_FLAGS=${CppMicroServices_CXX_FLAGS}") + ENVIRONMENT "CppMicroServices_ROOT=${CppMicroServices_BINARY_DIR}/install_test${CMAKE_INSTALL_PREFIX};CppMicroServices_CXX_FLAGS=${US_CXX_FLAGS}") list(APPEND _example_tests usMakefileExampleCleanTest usMakefileExampleTest) endif() endif() if(US_TEST_LABELS) set_tests_properties(${_example_tests} PROPERTIES LABELS "${US_TEST_LABELS}") endif() endif() diff --git a/examples/dictionaryclient/Activator.cpp b/core/examples/dictionaryclient/Activator.cpp similarity index 100% rename from examples/dictionaryclient/Activator.cpp rename to core/examples/dictionaryclient/Activator.cpp diff --git a/examples/dictionaryclient/CMakeLists.txt b/core/examples/dictionaryclient/CMakeLists.txt similarity index 100% rename from examples/dictionaryclient/CMakeLists.txt rename to core/examples/dictionaryclient/CMakeLists.txt diff --git a/examples/dictionaryclient2/Activator.cpp b/core/examples/dictionaryclient2/Activator.cpp similarity index 100% rename from examples/dictionaryclient2/Activator.cpp rename to core/examples/dictionaryclient2/Activator.cpp diff --git a/examples/dictionaryclient2/CMakeLists.txt b/core/examples/dictionaryclient2/CMakeLists.txt similarity index 100% rename from examples/dictionaryclient2/CMakeLists.txt rename to core/examples/dictionaryclient2/CMakeLists.txt diff --git a/examples/dictionaryclient3/Activator.cpp b/core/examples/dictionaryclient3/Activator.cpp similarity index 100% rename from examples/dictionaryclient3/Activator.cpp rename to core/examples/dictionaryclient3/Activator.cpp diff --git a/examples/dictionaryclient3/CMakeLists.txt b/core/examples/dictionaryclient3/CMakeLists.txt similarity index 100% rename from examples/dictionaryclient3/CMakeLists.txt rename to core/examples/dictionaryclient3/CMakeLists.txt diff --git a/examples/dictionaryservice/Activator.cpp b/core/examples/dictionaryservice/Activator.cpp similarity index 100% rename from examples/dictionaryservice/Activator.cpp rename to core/examples/dictionaryservice/Activator.cpp diff --git a/examples/dictionaryservice/CMakeLists.txt b/core/examples/dictionaryservice/CMakeLists.txt similarity index 100% rename from examples/dictionaryservice/CMakeLists.txt rename to core/examples/dictionaryservice/CMakeLists.txt diff --git a/examples/dictionaryservice/IDictionaryService.cpp b/core/examples/dictionaryservice/IDictionaryService.cpp similarity index 100% rename from examples/dictionaryservice/IDictionaryService.cpp rename to core/examples/dictionaryservice/IDictionaryService.cpp diff --git a/examples/dictionaryservice/IDictionaryService.h b/core/examples/dictionaryservice/IDictionaryService.h similarity index 100% rename from examples/dictionaryservice/IDictionaryService.h rename to core/examples/dictionaryservice/IDictionaryService.h diff --git a/examples/driver/CMakeLists.txt b/core/examples/driver/CMakeLists.txt similarity index 58% rename from examples/driver/CMakeLists.txt rename to core/examples/driver/CMakeLists.txt index f37d796a46..fe0c928f9a 100644 --- a/examples/driver/CMakeLists.txt +++ b/core/examples/driver/CMakeLists.txt @@ -1,16 +1,16 @@ if(WIN32) string(REPLACE "/" "\\\\" CMAKE_LIBRARY_OUTPUT_DIRECTORY_NATIVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) string(REPLACE "/" "\\\\" CMAKE_RUNTIME_OUTPUT_DIRECTORY_NATIVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) else() set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_NATIVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_NATIVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/usCppMicroServicesExampleDriverConfig.h.in - ${CMAKE_CURRENT_BINARY_DIR}/usCppMicroServicesExampleDriverConfig.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/us${PROJECT_NAME}DriverConfig.h.in + ${CMAKE_CURRENT_BINARY_DIR}/us${PROJECT_NAME}DriverConfig.h) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -add_executable(CppMicroServicesExampleDriver main.cpp) -target_link_libraries(CppMicroServicesExampleDriver ${CppMicroServices_LIBRARIES}) +add_executable(us${PROJECT_NAME}Driver main.cpp) +target_link_libraries(us${PROJECT_NAME}Driver ${CppMicroServices_LIBRARIES}) diff --git a/examples/driver/main.cpp b/core/examples/driver/main.cpp similarity index 99% rename from examples/driver/main.cpp rename to core/examples/driver/main.cpp index dc78d71414..89ee1c7ce9 100644 --- a/examples/driver/main.cpp +++ b/core/examples/driver/main.cpp @@ -1,298 +1,298 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include #include #include -#include "usCppMicroServicesExampleDriverConfig.h" +#include "usCoreExamplesDriverConfig.h" #if defined(US_PLATFORM_POSIX) #include #elif defined(US_PLATFORM_WINDOWS) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include #else #error Unsupported platform #endif #include #include #include #include #include #include #include US_USE_NAMESPACE #ifdef US_PLATFORM_WINDOWS static const std::string LIB_PATH = US_RUNTIME_OUTPUT_DIRECTORY; #else static const std::string LIB_PATH = US_LIBRARY_OUTPUT_DIRECTORY; #endif std::map GetExampleModules() { std::map names; names.insert(std::make_pair("Event Listener", "eventlistener")); names.insert(std::make_pair("Dictionary Service", "dictionaryservice")); names.insert(std::make_pair("French Dictionary", "frenchdictionary")); names.insert(std::make_pair("Dictionary Client", "dictionaryclient")); names.insert(std::make_pair("Dictionary Client 2", "dictionaryclient2")); names.insert(std::make_pair("Dictionary Client 3", "dictionaryclient3")); names.insert(std::make_pair("Spell Check Service", "spellcheckservice")); names.insert(std::make_pair("Spell Check Client", "spellcheckclient")); return names; } int main(int /*argc*/, char** /*argv*/) { char cmd[256]; std::map availableModules = GetExampleModules(); /* module path -> lib handle */ std::map libraryHandles; SharedLibrary sharedLib(LIB_PATH, ""); std::cout << "> "; while(std::cin.getline(cmd, sizeof(cmd))) { std::string strCmd(cmd); if (strCmd == "q") { break; } else if (strCmd == "h") { std::cout << std::left << std::setw(15) << "h" << " This help text\n" << std::setw(15) << "l " << " Load the module with id or name \n" << std::setw(15) << "u " << " Unload the module with id \n" << std::setw(15) << "s" << " Print status information\n" << std::setw(15) << "q" << " Quit\n" << std::flush; } else if (strCmd.find("l ") != std::string::npos) { std::string idOrName; idOrName.assign(strCmd.begin()+2, strCmd.end()); std::stringstream ss(idOrName); long int id = -1; ss >> id; if (id > 0) { Module* module = ModuleRegistry::GetModule(id); if (!module) { std::cout << "Error: unknown id" << std::endl; } else if (module->IsLoaded()) { std::cout << "Info: module already loaded" << std::endl; } else { try { std::map::iterator libIter = libraryHandles.find(module->GetLocation()); if (libIter != libraryHandles.end()) { libIter->second.Load(); } else { // The module has been loaded previously due to a // linker dependency SharedLibrary libHandle(module->GetLocation()); libHandle.Load(); libraryHandles.insert(std::make_pair(libHandle.GetFilePath(), libHandle)); } } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } } else { Module* module = ModuleRegistry::GetModule(idOrName); if (!module) { try { std::map::iterator libIter = libraryHandles.find(sharedLib.GetFilePath(idOrName)); if (libIter != libraryHandles.end()) { libIter->second.Load(); } else { bool libFound = false; for (std::map::const_iterator availableModuleIter = availableModules.begin(); availableModuleIter != availableModules.end(); ++availableModuleIter) { if (availableModuleIter->second == idOrName) { libFound = true; } } if (!libFound) { std::cout << "Error: unknown example module" << std::endl; } else { SharedLibrary libHandle(LIB_PATH, idOrName); libHandle.Load(); libraryHandles.insert(std::make_pair(libHandle.GetFilePath(), libHandle)); } } std::vector modules = ModuleRegistry::GetModules(); for (std::vector::const_iterator moduleIter = modules.begin(); moduleIter != modules.end(); ++moduleIter) { availableModules.erase((*moduleIter)->GetName()); } } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } else if (!module->IsLoaded()) { try { const std::string modulePath = module->GetLocation(); std::map::iterator libIter = libraryHandles.find(modulePath); if (libIter != libraryHandles.end()) { libIter->second.Load(); } else { SharedLibrary libHandle(LIB_PATH, idOrName); libHandle.Load(); libraryHandles.insert(std::make_pair(libHandle.GetFilePath(), libHandle)); } } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } else if (module) { std::cout << "Info: module already loaded" << std::endl; } } } else if (strCmd.find("u ") != std::string::npos) { std::stringstream ss(strCmd); ss.ignore(2); long int id = -1; ss >> id; if (id == 1) { std::cout << "Info: Unloading not possible" << std::endl; } else { Module* const module = ModuleRegistry::GetModule(id); if (module) { std::map::iterator libIter = libraryHandles.find(module->GetLocation()); if (libIter == libraryHandles.end()) { std::cout << "Info: Unloading not possible. The module was loaded by a dependent module." << std::endl; } else { try { libIter->second.Unload(); // Check if it has really been unloaded if (module->IsLoaded()) { std::cout << "Info: The module is still referenced by another loaded module. It will be unloaded when all dependent modules are unloaded." << std::endl; } } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } } else { std::cout << "Error: unknown id" << std::endl; } } } else if (strCmd == "s") { std::vector modules = ModuleRegistry::GetModules(); std::cout << std::left; std::cout << "Id | " << std::setw(20) << "Name" << " | " << std::setw(9) << "Status" << std::endl; std::cout << "-----------------------------------\n"; for (std::map::const_iterator nameIter = availableModules.begin(); nameIter != availableModules.end(); ++nameIter) { std::cout << " - | " << std::setw(20) << nameIter->second << " | " << std::setw(9) << "-" << std::endl; } for (std::vector::const_iterator moduleIter = modules.begin(); moduleIter != modules.end(); ++moduleIter) { std::cout << std::right << std::setw(2) << (*moduleIter)->GetModuleId() << std::left << " | "; std::cout << std::setw(20) << (*moduleIter)->GetName() << " | "; std::cout << std::setw(9) << ((*moduleIter)->IsLoaded() ? "LOADED" : "UNLOADED"); std::cout << std::endl; } } else { std::cout << "Unknown command: " << strCmd << " (type 'h' for help)" << std::endl; } std::cout << "> "; } return 0; } diff --git a/examples/driver/usCppMicroServicesExampleDriverConfig.h.in b/core/examples/driver/usCoreExamplesDriverConfig.h.in similarity index 98% rename from examples/driver/usCppMicroServicesExampleDriverConfig.h.in rename to core/examples/driver/usCoreExamplesDriverConfig.h.in index 880a0cfa25..144d1a6f08 100644 --- a/examples/driver/usCppMicroServicesExampleDriverConfig.h.in +++ b/core/examples/driver/usCoreExamplesDriverConfig.h.in @@ -1,41 +1,41 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USEXAMPLEDRIVERCONFIG_H #define USEXAMPLEDRIVERCONFIG_H -#include "usConfig.h" +#include "usGlobalConfig.h" #ifdef US_PLATFORM_POSIX #define PATH_SEPARATOR "/" #else #define PATH_SEPARATOR "\\" #endif #ifdef CMAKE_INTDIR #define US_LIBRARY_OUTPUT_DIRECTORY "@CMAKE_LIBRARY_OUTPUT_DIRECTORY_NATIVE@" PATH_SEPARATOR CMAKE_INTDIR #define US_RUNTIME_OUTPUT_DIRECTORY "@CMAKE_RUNTIME_OUTPUT_DIRECTORY_NATIVE@" PATH_SEPARATOR CMAKE_INTDIR #else #define US_LIBRARY_OUTPUT_DIRECTORY "@CMAKE_LIBRARY_OUTPUT_DIRECTORY_NATIVE@" #define US_RUNTIME_OUTPUT_DIRECTORY "@CMAKE_RUNTIME_OUTPUT_DIRECTORY_NATIVE@" #endif #endif // USEXAMPLEDRIVERCONFIG_H diff --git a/examples/eventlistener/Activator.cpp b/core/examples/eventlistener/Activator.cpp similarity index 100% rename from examples/eventlistener/Activator.cpp rename to core/examples/eventlistener/Activator.cpp diff --git a/examples/eventlistener/CMakeLists.txt b/core/examples/eventlistener/CMakeLists.txt similarity index 100% rename from examples/eventlistener/CMakeLists.txt rename to core/examples/eventlistener/CMakeLists.txt diff --git a/examples/frenchdictionary/Activator.cpp b/core/examples/frenchdictionary/Activator.cpp similarity index 100% rename from examples/frenchdictionary/Activator.cpp rename to core/examples/frenchdictionary/Activator.cpp diff --git a/examples/frenchdictionary/CMakeLists.txt b/core/examples/frenchdictionary/CMakeLists.txt similarity index 100% rename from examples/frenchdictionary/CMakeLists.txt rename to core/examples/frenchdictionary/CMakeLists.txt diff --git a/examples/makefile/IDictionaryService.cpp b/core/examples/makefile/IDictionaryService.cpp similarity index 100% rename from examples/makefile/IDictionaryService.cpp rename to core/examples/makefile/IDictionaryService.cpp diff --git a/examples/makefile/IDictionaryService.h b/core/examples/makefile/IDictionaryService.h similarity index 100% rename from examples/makefile/IDictionaryService.h rename to core/examples/makefile/IDictionaryService.h diff --git a/examples/makefile/Makefile b/core/examples/makefile/Makefile similarity index 64% rename from examples/makefile/Makefile rename to core/examples/makefile/Makefile index 0e4d21a6d2..860712a72a 100644 --- a/examples/makefile/Makefile +++ b/core/examples/makefile/Makefile @@ -1,26 +1,26 @@ CXX = g++ -CXXFLAGS = -g -Wall -Wno-unused -pedantic -fPIC $(CppMicroServices_CXX_FLAGS) -LDFLAGS = -Wl,-rpath=$(CppMicroServices_ROOT)/lib -Wl,-rpath=. +CXXFLAGS = -g -Wall -Wno-unused -pedantic -fPIC $(US_CXX_FLAGS) +LDFLAGS = -Wl,-rpath="$(CppMicroServices_ROOT)/lib" -Wl,-rpath=. LDLIBS = -lCppMicroServices -INCLUDEDIRS = -I$(CppMicroServices_ROOT)/include/CppMicroServices -LIBDIRS = -L$(CppMicroServices_ROOT)/lib/CppMicroServices -L. +INCLUDEDIRS = -I"$(CppMicroServices_ROOT)/include/CppMicroServices" +LIBDIRS = -L"$(CppMicroServices_ROOT)/lib/CppMicroServices" -L. all : main libmodule.so main: libmodule.so main.o $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(INCLUDEDIRS) $(LIBDIRS) $(LDLIBS) -lmodule libmodule.so: module.o IDictionaryService.o $(CXX) -shared -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(INCLUDEDIRS) $(LIBDIRS) $(LDLIBS) main.o: main.cpp $(CXX) $(CXXFLAGS) $(INCLUDEDIRS) -c $< -o $@ %.o: %.cpp $(CXX) $(CXXFLAGS) -DMODULE_EXPORTS $(INCLUDEDIRS) -c $< -o $@ .PHONY : clean clean: rm -f *.o diff --git a/examples/makefile/main.cpp b/core/examples/makefile/main.cpp similarity index 100% rename from examples/makefile/main.cpp rename to core/examples/makefile/main.cpp diff --git a/examples/makefile/module.cpp b/core/examples/makefile/module.cpp similarity index 100% rename from examples/makefile/module.cpp rename to core/examples/makefile/module.cpp diff --git a/examples/spellcheckclient/Activator.cpp b/core/examples/spellcheckclient/Activator.cpp similarity index 100% rename from examples/spellcheckclient/Activator.cpp rename to core/examples/spellcheckclient/Activator.cpp diff --git a/examples/spellcheckclient/CMakeLists.txt b/core/examples/spellcheckclient/CMakeLists.txt similarity index 100% rename from examples/spellcheckclient/CMakeLists.txt rename to core/examples/spellcheckclient/CMakeLists.txt diff --git a/examples/spellcheckservice/Activator.cpp b/core/examples/spellcheckservice/Activator.cpp similarity index 100% rename from examples/spellcheckservice/Activator.cpp rename to core/examples/spellcheckservice/Activator.cpp diff --git a/examples/spellcheckservice/CMakeLists.txt b/core/examples/spellcheckservice/CMakeLists.txt similarity index 100% rename from examples/spellcheckservice/CMakeLists.txt rename to core/examples/spellcheckservice/CMakeLists.txt diff --git a/examples/spellcheckservice/ISpellCheckService.cpp b/core/examples/spellcheckservice/ISpellCheckService.cpp similarity index 100% rename from examples/spellcheckservice/ISpellCheckService.cpp rename to core/examples/spellcheckservice/ISpellCheckService.cpp diff --git a/examples/spellcheckservice/ISpellCheckService.h b/core/examples/spellcheckservice/ISpellCheckService.h similarity index 100% rename from examples/spellcheckservice/ISpellCheckService.h rename to core/examples/spellcheckservice/ISpellCheckService.h diff --git a/core/include/CMakeLists.txt b/core/include/CMakeLists.txt new file mode 100644 index 0000000000..b06be463cd --- /dev/null +++ b/core/include/CMakeLists.txt @@ -0,0 +1,47 @@ +#----------------------------------------------------------------------------- +# Public header files +#----------------------------------------------------------------------------- + +set(_public_headers + usAny.h + usLDAPProp.h + usSharedData.h + usSharedLibrary.h + usShrinkableMap.h + usShrinkableVector.h + usUncompressResourceData.h + + usLDAPFilter.h + usPrototypeServiceFactory.h + usServiceEvent.h + usServiceEventListenerHook.h + usServiceException.h + usServiceFactory.h + usServiceFindHook.h + usServiceInterface.h + usServiceListenerHook.h + usServiceObjects.h + usServiceProperties.h + usServiceReference.h + usServiceReferenceBase.h + usServiceRegistration.h + usServiceRegistrationBase.h + usServiceTracker.h + usServiceTrackerCustomizer.h + + usGetModuleContext.h + usModule.h + usModuleActivator.h + usModuleContext.h + usModuleEvent.h + usModuleEventHook.h + usModuleFindHook.h + usModuleImport.h + usModuleInfo.h + usModuleInitialization.h + usModuleRegistry.h + usModuleResource.h + usModuleResourceStream.h + usModuleSettings.h + usModuleVersion.h +) diff --git a/src/util/usAny.h b/core/include/usAny.h similarity index 96% rename from src/util/usAny.h rename to core/include/usAny.h index 01b69af5d8..d59848c720 100644 --- a/src/util/usAny.h +++ b/core/include/usAny.h @@ -1,397 +1,397 @@ /*============================================================================= Library: CppMicroServices Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. Extracted from Boost 1.46.1 and adapted for CppMicroServices. Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =========================================================================*/ #ifndef US_ANY_H #define US_ANY_H #include #include #include #include #include #include -#include +#include US_BEGIN_NAMESPACE template std::string any_value_to_string(const T& val); -US_EXPORT std::string any_value_to_string(const std::vector& val); -US_EXPORT std::string any_value_to_string(const std::list& val); +US_Core_EXPORT std::string any_value_to_string(const std::vector& val); +US_Core_EXPORT std::string any_value_to_string(const std::list& val); /** * \ingroup MicroServicesUtils * * An Any class represents a general type and is capable of storing any type, supporting type-safe extraction * of the internally stored data. * * Code taken from the Boost 1.46.1 library. Original copyright by Kevlin Henney. Modified for CppMicroServices. */ class Any { public: /** * Creates an empty any type. */ Any(): _content(0) { } /** * Creates an Any which stores the init parameter inside. * * \param value The content of the Any * * Example: * \code * Any a(13); * Any a(string("12345")); * \endcode */ template Any(const ValueType& value) : _content(new Holder(value)) { } /** * Copy constructor, works with empty Anys and initialized Any values. * * \param other The Any to copy */ Any(const Any& other) : _content(other._content ? other._content->Clone() : 0) { } ~Any() { delete _content; } /** * Swaps the content of the two Anys. * * \param rhs The Any to swap this Any with. */ Any& Swap(Any& rhs) { std::swap(_content, rhs._content); return *this; } /** * Assignment operator for all types != Any. * * \param rhs The value which should be assigned to this Any. * * Example: * \code * Any a = 13; * Any a = string("12345"); * \endcode */ template Any& operator = (const ValueType& rhs) { Any(rhs).Swap(*this); return *this; } /** * Assignment operator for Any. * * \param rhs The Any which should be assigned to this Any. */ Any& operator = (const Any& rhs) { Any(rhs).Swap(*this); return *this; } /** * returns true if the Any is empty */ bool Empty() const { return !_content; } /** * Returns a string representation for the content. * * Custom types should either provide a std::ostream& operator<<(std::ostream& os, const CustomType& ct) * function or specialize the any_value_to_string template function for meaningful output. */ std::string ToString() const { return _content->ToString(); } /** * Returns the type information of the stored content. * If the Any is empty typeid(void) is returned. * It is suggested to always query an Any for its type info before trying to extract * data via an any_cast/ref_any_cast. */ const std::type_info& Type() const { return _content ? _content->Type() : typeid(void); } private: class Placeholder { public: virtual ~Placeholder() { } virtual std::string ToString() const = 0; virtual const std::type_info& Type() const = 0; virtual Placeholder* Clone() const = 0; }; template class Holder: public Placeholder { public: Holder(const ValueType& value) : _held(value) { } virtual std::string ToString() const { return any_value_to_string(_held); } virtual const std::type_info& Type() const { return typeid(ValueType); } virtual Placeholder* Clone() const { return new Holder(_held); } ValueType _held; private: // intentionally left unimplemented Holder& operator=(const Holder &); }; private: template friend ValueType* any_cast(Any*); template friend ValueType* unsafe_any_cast(Any*); Placeholder* _content; }; class BadAnyCastException : public std::bad_cast { public: BadAnyCastException(const std::string& msg = "") : std::bad_cast(), _msg(msg) {} ~BadAnyCastException() throw() {} virtual const char * what() const throw() { if (_msg.empty()) return "US_PREPEND_NAMESPACE(BadAnyCastException): " "failed conversion using US_PREPEND_NAMESPACE(any_cast)"; else return _msg.c_str(); } private: std::string _msg; }; /** * any_cast operator used to extract the ValueType from an Any*. Will return a pointer * to the stored value. * * Example Usage: * \code * MyType* pTmp = any_cast(pAny) * \endcode * Will return NULL if the cast fails, i.e. types don't match. */ template ValueType* any_cast(Any* operand) { return operand && operand->Type() == typeid(ValueType) ? &static_cast*>(operand->_content)->_held : 0; } /** * any_cast operator used to extract a const ValueType pointer from an const Any*. Will return a const pointer * to the stored value. * * Example Usage: * \code * const MyType* pTmp = any_cast(pAny) * \endcode * Will return NULL if the cast fails, i.e. types don't match. */ template const ValueType* any_cast(const Any* operand) { return any_cast(const_cast(operand)); } /** * any_cast operator used to extract a copy of the ValueType from an const Any&. * * Example Usage: * \code * MyType tmp = any_cast(anAny) * \endcode * Will throw a BadCastException if the cast fails. * Dont use an any_cast in combination with references, i.e. MyType& tmp = ... or const MyType& = ... * Some compilers will accept this code although a copy is returned. Use the ref_any_cast in * these cases. */ template ValueType any_cast(const Any& operand) { ValueType* result = any_cast(const_cast(&operand)); if (!result) throw BadAnyCastException("Failed to convert between const Any types"); return *result; } /** * any_cast operator used to extract a copy of the ValueType from an Any&. * * Example Usage: * \code * MyType tmp = any_cast(anAny) * \endcode * Will throw a BadCastException if the cast fails. * Dont use an any_cast in combination with references, i.e. MyType& tmp = ... or const MyType& tmp = ... * Some compilers will accept this code although a copy is returned. Use the ref_any_cast in * these cases. */ template ValueType any_cast(Any& operand) { ValueType* result = any_cast(&operand); if (!result) throw BadAnyCastException("Failed to convert between Any types"); return *result; } /** * ref_any_cast operator used to return a const reference to the internal data. * * Example Usage: * \code * const MyType& tmp = ref_any_cast(anAny); * \endcode */ template const ValueType& ref_any_cast(const Any & operand) { ValueType* result = any_cast(const_cast(&operand)); if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between const Any types"); return *result; } /** * ref_any_cast operator used to return a reference to the internal data. * * Example Usage: * \code * MyType& tmp = ref_any_cast(anAny); * \endcode */ template ValueType& ref_any_cast(Any& operand) { ValueType* result = any_cast(&operand); if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between Any types"); return *result; } /** * \internal * * The "unsafe" versions of any_cast are not part of the * public interface and may be removed at any time. They are * required where we know what type is stored in the any and can't * use typeid() comparison, e.g., when our types may travel across * different shared libraries. */ template ValueType* unsafe_any_cast(Any* operand) { return &static_cast*>(operand->_content)->_held; } /** * \internal * * The "unsafe" versions of any_cast are not part of the * public interface and may be removed at any time. They are * required where we know what type is stored in the any and can't * use typeid() comparison, e.g., when our types may travel across * different shared libraries. */ template const ValueType* unsafe_any_cast(const Any* operand) { return any_cast(const_cast(operand)); } -US_EXPORT std::string any_value_to_string(const std::vector& val); -US_EXPORT std::string any_value_to_string(const std::map& val); +US_Core_EXPORT std::string any_value_to_string(const std::vector& val); +US_Core_EXPORT std::string any_value_to_string(const std::map& val); template std::string any_value_to_string(const T& val) { std::stringstream ss; ss << val; return ss.str(); } US_END_NAMESPACE #endif // US_ANY_H diff --git a/core/include/usCoreConfig.h.in b/core/include/usCoreConfig.h.in new file mode 100644 index 0000000000..fab29d715c --- /dev/null +++ b/core/include/usCoreConfig.h.in @@ -0,0 +1,43 @@ +/* + usCoreConfig.h + This file is generated. Do not change! +*/ + +#ifndef USCORECONFIG_H +#define USCORECONFIG_H + +#include + +#cmakedefine US_ENABLE_AUTOLOADING_SUPPORT + +///------------------------------------------------------------------- +// Version information +//------------------------------------------------------------------- + +#define US_CORE_MAJOR_VERSION @Core_MAJOR_VERSION@ +#define US_CORE_MINOR_VERSION @Core_MINOR_VERSION@ +#define US_CORE_PATCH_VERSION @Core_PATCH_VERSION@ +#define US_CORE_VERSION @Core_VERSION@ +#define US_CORE_VERSION_STR "@Core_VERSION@" + + +//------------------------------------------------------------------- +// Debuging & Logging +//------------------------------------------------------------------- + +#cmakedefine US_ENABLE_DEBUG_OUTPUT + +US_BEGIN_NAMESPACE + enum MsgType { DebugMsg = 0, InfoMsg = 1, WarningMsg = 2, ErrorMsg = 3 }; + typedef void (*MsgHandler)(MsgType, const char *); + US_Core_EXPORT MsgHandler installMsgHandler(MsgHandler); +US_END_NAMESPACE + + +///------------------------------------------------------------------- +// Macros used by the unit tests +//------------------------------------------------------------------- + +#define US_CORE_SOURCE_DIR "@PROJECT_SOURCE_DIR@" + +#endif // USCORECONFIG_H diff --git a/src/module/usGetModuleContext.h b/core/include/usGetModuleContext.h similarity index 98% rename from src/module/usGetModuleContext.h rename to core/include/usGetModuleContext.h index b6b56971d6..394bd8b609 100644 --- a/src/module/usGetModuleContext.h +++ b/core/include/usGetModuleContext.h @@ -1,54 +1,54 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USGETMODULECONTEXT_H #define USGETMODULECONTEXT_H -#include +#include US_BEGIN_NAMESPACE class ModuleContext; /** * \ingroup MicroServices * * \brief Returns the module context of the calling module. * * This function allows easy access to the ModuleContext instance from * inside a C++ Micro Services module. * * \return The ModuleContext of the calling module. * * \internal * * Note that the corresponding function definition is provided for each * module by the usModuleInit.cpp file. This file is customized via CMake * configure_file(...) and automatically compiled into each module. * Consequently, the GetModuleContext function is not exported, since each * module gets its "own version". */ US_ABI_LOCAL ModuleContext* GetModuleContext(); US_END_NAMESPACE #endif // USGETMODULECONTEXT_H diff --git a/src/service/usLDAPFilter.h b/core/include/usLDAPFilter.h similarity index 97% rename from src/service/usLDAPFilter.h rename to core/include/usLDAPFilter.h index c90b051703..5512800e62 100644 --- a/src/service/usLDAPFilter.h +++ b/core/include/usLDAPFilter.h @@ -1,180 +1,180 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USLDAPFILTER_H #define USLDAPFILTER_H #include "usServiceProperties.h" #include "usSharedData.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4251) #endif US_BEGIN_NAMESPACE class LDAPFilterData; class ServiceReferenceBase; /** * \ingroup MicroServices * * An RFC 1960-based Filter. * *

* A LDAPFilter can be used numerous times to determine if the match * argument matches the filter string that was used to create the LDAPFilter. *

* Some examples of LDAP filters are: * * - "(cn=Babs Jensen)" * - "(!(cn=Tim Howes))" * - "(&(" + ServiceConstants::OBJECTCLASS() + "=Person)(|(sn=Jensen)(cn=Babs J*)))" * - "(o=univ*of*mich*)" * * \remarks This class is thread safe. * * \sa LDAPProp for a fluent API generating LDAP filter strings */ -class US_EXPORT LDAPFilter { +class US_Core_EXPORT LDAPFilter { private: typedef SharedDataPointer LDAPFilter::*bool_type; public: /** * Creates in invalid LDAPFilter object. * Test the validity by using the boolean conversion operator. * *

* Calling methods on an invalid LDAPFilter * will result in undefined behavior. */ LDAPFilter(); /** * Creates a LDAPFilter object. This LDAPFilter * object may be used to match a ServiceReference object or a * ServiceProperties object. * *

* If the filter cannot be parsed, an std::invalid_argument will be * thrown with a human readable message where the filter became unparsable. * * @param filter The filter string. * @return A LDAPFilter object encapsulating the filter string. * @throws std::invalid_argument If filter contains an invalid * filter string that cannot be parsed. * @see "Framework specification for a description of the filter string syntax." TODO! */ LDAPFilter(const std::string& filter); LDAPFilter(const LDAPFilter& other); ~LDAPFilter(); operator bool_type() const; /** * Filter using a service's properties. *

* This LDAPFilter is executed using the keys and values of the * referenced service's properties. The keys are looked up in a case * insensitive manner. * * @param reference The reference to the service whose properties are used * in the match. * @return true if the service's properties match this * LDAPFilter false otherwise. */ bool Match(const ServiceReferenceBase& reference) const; /** * Filter using a ServiceProperties object with case insensitive key lookup. This * LDAPFilter is executed using the specified ServiceProperties's keys * and values. The keys are looked up in a case insensitive manner. * * @param dictionary The ServiceProperties whose key/value pairs are used * in the match. * @return true if the ServiceProperties's values match this * filter; false otherwise. */ bool Match(const ServiceProperties& dictionary) const; /** * Filter using a ServiceProperties. This LDAPFilter is executed using * the specified ServiceProperties's keys and values. The keys are looked * up in a normal manner respecting case. * * @param dictionary The ServiceProperties whose key/value pairs are used * in the match. * @return true if the ServiceProperties's values match this * filter; false otherwise. */ bool MatchCase(const ServiceProperties& dictionary) const; /** * Returns this LDAPFilter's filter string. *

* The filter string is normalized by removing whitespace which does not * affect the meaning of the filter. * * @return This LDAPFilter's filter string. */ std::string ToString() const; /** * Compares this LDAPFilter to another LDAPFilter. * *

* This implementation returns the result of calling * this->ToString() == other.ToString(). * * @param other The object to compare against this LDAPFilter. * @return Returns the result of calling * this->ToString() == other.ToString(). */ bool operator==(const LDAPFilter& other) const; LDAPFilter& operator=(const LDAPFilter& filter); protected: SharedDataPointer d; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(LDAPFilter)& filter); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(LDAPFilter)& filter); #endif // USLDAPFILTER_H diff --git a/src/util/usLDAPProp.h b/core/include/usLDAPProp.h similarity index 94% rename from src/util/usLDAPProp.h rename to core/include/usLDAPProp.h index c7831b5cd1..ed8d8632c0 100644 --- a/src/util/usLDAPProp.h +++ b/core/include/usLDAPProp.h @@ -1,235 +1,235 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USLDAPPROP_H #define USLDAPPROP_H -#include +#include #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4251) #endif US_BEGIN_NAMESPACE /// \cond -class US_EXPORT LDAPPropExpr +class US_Core_EXPORT LDAPPropExpr { public: explicit LDAPPropExpr(const std::string& expr); LDAPPropExpr& operator!(); operator std::string() const; bool IsNull() const; private: LDAPPropExpr& operator=(const LDAPPropExpr&); std::string m_ldapExpr; }; /// \endcond /** * \ingroup MicroServicesUtils * * A fluent API for creating LDAP filter strings. * * Examples for creating LDAPFilter objects: * \code * // This creates the filter "(&(name=Ben)(!(count=1)))" * LDAPFilter filter(LDAPProp("name") == "Ben" && !(LDAPProp("count") == 1)); * * // This creates the filter "(|(presence=*)(!(absence=*)))" * LDAPFilter filter(LDAPProp("presence") || !LDAPProp("absence")); * * // This creates the filter "(&(ge>=-3)(approx~=hi))" * LDAPFilter filter(LDAPProp("ge") >= -3 && LDAPProp("approx").Approx("hi")); * \endcode * * \sa LDAPFilter */ -class US_EXPORT LDAPProp +class US_Core_EXPORT LDAPProp { public: /** * Create a LDAPProp instance for the named LDAP property. * * @param property The name of the LDAP property. */ LDAPProp(const std::string& property); /** * LDAP equality '=' * * @param s A type convertible to std::string. * @return A LDAP expression object. * * @{ */ LDAPPropExpr operator==(const std::string& s) const; LDAPPropExpr operator==(const us::Any& s) const; template LDAPPropExpr operator==(const T& s) const { std::stringstream ss; ss << s; return LDAPPropExpr("(" + m_property + "=" + ss.str() + ")"); } /// @} operator LDAPPropExpr () const; /** * States the absence of the LDAP property. * * @return A LDAP expression object. */ LDAPPropExpr operator!() const; /** * Convenience operator for LDAP inequality. * * Writing either * \code * LDAPProp("attr") != "val" * \endcode * or * \code * !(LDAPProp("attr") == "val") * \endcode * leads to the same string "(!(attr=val))". * * @param s A type convertible to std::string. * @return A LDAP expression object. * * @{ */ LDAPPropExpr operator!=(const std::string& s) const; LDAPPropExpr operator!=(const us::Any& s) const; template LDAPPropExpr operator!=(const T& s) const { std::stringstream ss; ss << s; return operator!=(ss.str()); } /// @} /** * LDAP greater or equal '>=' * * @param s A type convertible to std::string. * @return A LDAP expression object. * * @{ */ LDAPPropExpr operator>=(const std::string& s) const; LDAPPropExpr operator>=(const us::Any& s) const; template LDAPPropExpr operator>=(const T& s) const { std::stringstream ss; ss << s; return operator>=(ss.str()); } /// @} /** * LDAP less or equal '<=' * * @param s A type convertible to std::string. * @return A LDAP expression object. * * @{ */ LDAPPropExpr operator<=(const std::string& s) const; LDAPPropExpr operator<=(const us::Any& s) const; template LDAPPropExpr operator<=(const T& s) const { std::stringstream ss; ss << s; return operator<=(ss.str()); } /// @} /** * LDAP approximation '~=' * * @param s A type convertible to std::string. * @return A LDAP expression object. * * @{ */ LDAPPropExpr Approx(const std::string& s) const; LDAPPropExpr Approx(const us::Any& s) const; template LDAPPropExpr Approx(const T& s) const { std::stringstream ss; ss << s; return Approx(ss.str()); } /// @} private: LDAPProp& operator=(const LDAPProp&); std::string m_property; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif /** * \ingroup MicroServicesUtils * * LDAP logical and '&' * * @param left A LDAP expression. * @param right A LDAP expression. * @return A LDAP expression */ -US_EXPORT us::LDAPPropExpr operator&&(const us::LDAPPropExpr& left, const us::LDAPPropExpr& right); +US_Core_EXPORT us::LDAPPropExpr operator&&(const us::LDAPPropExpr& left, const us::LDAPPropExpr& right); /** * \ingroup MicroServicesUtils * * LDAP logical or '|' * * @param left A LDAP expression. * @param right A LDAP expression. * @return A LDAP expression */ -US_EXPORT us::LDAPPropExpr operator||(const us::LDAPPropExpr& left, const us::LDAPPropExpr& right); +US_Core_EXPORT us::LDAPPropExpr operator||(const us::LDAPPropExpr& left, const us::LDAPPropExpr& right); #endif // USLDAPPROP_H diff --git a/src/module/usModule.h b/core/include/usModule.h similarity index 98% rename from src/module/usModule.h rename to core/include/usModule.h index bc6e4b36db..6a873ff649 100644 --- a/src/module/usModule.h +++ b/core/include/usModule.h @@ -1,369 +1,369 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULE_H #define USMODULE_H #include "usModuleVersion.h" #include US_BEGIN_NAMESPACE class Any; class CoreModuleContext; struct ModuleInfo; class ModuleContext; class ModuleResource; class ModulePrivate; template class ServiceReference; typedef ServiceReference ServiceReferenceU; /** * \ingroup MicroServices * * Represents a CppMicroServices module. * *

* A %Module object is the access point to a CppMicroServices module. * Each CppMicroServices module has an associated %Module object. * *

* A module has unique identity, a long, chosen by the * framework. This identity does not change during the lifecycle of a module. * *

* A module can be in one of two states: *

    *
  • LOADED *
  • UNLOADED *
*

* You can determine the current state by using IsLoaded(). * *

* A module can only execute code when its state is LOADED. * An UNLOADED module is a * zombie and can only be reached because it was loaded before. However, * unloaded modules can be loaded again. * *

* The framework is the only entity that is allowed to create * %Module objects. * * @remarks This class is thread safe. */ -class US_EXPORT Module +class US_Core_EXPORT Module { public: /** * Returns the property key for looking up this module's id. * The property value is of type \c long. * * @return The id property key. */ static const std::string& PROP_ID(); /** * Returns the property key for looking up this module's name. * The property value is of type \c std::string. * * @return The name property key. */ static const std::string& PROP_NAME(); /** * Returns the property key for looking up this module's * location the file system. * The property value is of type \c std::string. * * @return The location property key. */ static const std::string& PROP_LOCATION(); /** * Returns the property key with a value of \c module.version for looking * up this module's version identifier. * The property value is of type \c std::string. * * @return The version property key. */ static const std::string& PROP_VERSION(); /** * Returns the property key with a value of \c module.vendor for looking * up this module's vendor information. * The property value is of type \c std::string. * * @return The version property key. */ static const std::string& PROP_VENDOR(); /** * Returns the property key with a value of \c module.description for looking * up this module's description. * The property value is of type \c std::string. * * @return The version property key. */ static const std::string& PROP_DESCRIPTION(); /** * Returns the property key with a value of \c module.autoload_dir for looking * up this module's auto-load directory. * The property value is of type \c std::string. * * @return The version property key. */ static const std::string& PROP_AUTOLOAD_DIR(); ~Module(); /** * Returns this module's current state. * *

* A module can be in only one state at any time. * * @return true if the module is LOADED * false if it is UNLOADED */ bool IsLoaded() const; /** * Returns this module's {@link ModuleContext}. The returned * ModuleContext can be used by the caller to act on behalf * of this module. * *

* If this module is not in the LOADED state, then this * module has no valid ModuleContext. This method will * return 0 if this module has no valid * ModuleContext. * * @return A ModuleContext for this module or * 0 if this module has no valid * ModuleContext. */ ModuleContext* GetModuleContext() const; /** * Returns this module's unique identifier. This module is assigned a unique * identifier by the framework when it was loaded. * *

* A module's unique identifier has the following attributes: *

    *
  • Is unique. *
  • Is a long. *
  • Its value is not reused for another module, even after a module is * unloaded. *
  • Does not change while a module remains loaded. *
  • Does not change when a module is reloaded. *
* *

* This method continues to return this module's unique identifier while * this module is in the UNLOADED state. * * @return The unique identifier of this module. */ long GetModuleId() const; /** * Returns this module's location. * *

* The location is the full path to the module's shared library. * This method continues to return this module's location * while this module is in the UNLOADED state. * * @return The string representation of this module's location. */ std::string GetLocation() const; /** * Returns the name of this module as specified by the * US_CREATE_MODULE CMake macro. The module * name together with a version must identify a unique module. * *

* This method continues to return this module's name while * this module is in the UNLOADED state. * * @return The name of this module. */ std::string GetName() const; /** * Returns the version of this module as specified by the * US_INITIALIZE_MODULE CMake macro. If this module does not have a * specified version then {@link ModuleVersion::EmptyVersion} is returned. * *

* This method continues to return this module's version while * this module is in the UNLOADED state. * * @return The version of this module. */ ModuleVersion GetVersion() const; /** * Returns the value of the specified property for this module. The * method returns an empty Any if the property is not found. * * @param key The name of the requested property. * @return The value of the requested property, or an empty string * if the property is undefined. * * @sa GetPropertyKeys() * @sa \ref MicroServices_ModuleProperties */ Any GetProperty(const std::string& key) const; /** * Returns a list of top-level property keys for this module. * * @return A list of available property keys. * * @sa \ref MicroServices_ModuleProperties */ std::vector GetPropertyKeys() const; /** * Returns this module's ServiceReference list for all services it * has registered or an empty list if this module has no registered * services. * * The list is valid at the time of the call to this method, however, * as the framework is a very dynamic environment, services can be * modified or unregistered at anytime. * * @return A list of ServiceReference objects for services this * module has registered. */ std::vector GetRegisteredServices() const; /** * Returns this module's ServiceReference list for all services it is * using or returns an empty list if this module is not using any * services. A module is considered to be using a service if its use * count for that service is greater than zero. * * The list is valid at the time of the call to this method, however, * as the framework is a very dynamic environment, services can be * modified or unregistered at anytime. * * @return A list of ServiceReference objects for all services this * module is using. */ std::vector GetServicesInUse() const; /** * Returns the resource at the specified \c path in this module. * The specified \c path is always relative to the root of this module and may * begin with '/'. A path value of "/" indicates the root of this module. * * \note In case of other modules being statically linked into this module, * the \c path can be ambiguous and returns the first resource matching the * provided \c path according to the order of the static module names in the * #US_LOAD_IMPORTED_MODULES macro. * * @param path The path name of the resource. * @return A ModuleResource object for the given \c path. If the \c path cannot * be found in this module or the module's state is \c UNLOADED, an invalid * ModuleResource object is returned. */ ModuleResource GetResource(const std::string& path) const; /** * Returns resources in this module and its statically linked modules. * * This method is intended to be used to obtain configuration, setup, localization * and other information from this module. * * This method can either return only resources in the specified \c path or recurse * into subdirectories returning resources in the directory tree beginning at the * specified path. * * Examples: * \snippet uServices-resources/main.cpp 0 * * \note In case of modules statically linked into this module, the returned * ModuleResource objects can represent the same resource path, coming from * different static modules. The order of the ModuleResource objects in the * returned container matches the order of the static module names in the * #US_LOAD_IMPORTED_MODULES macro. * * @param path The path name in which to look. The path is always relative to the root * of this module and may begin with '/'. A path value of "/" indicates the root of this module. * @param filePattern The resource name pattern for selecting entries in the specified path. * The pattern is only matched against the last element of the resource path. Substring * matching is supported using the wildcard charachter ('*'). If \c filePattern is empty, * this is equivalent to "*" and matches all resources. * @param recurse If \c true, recurse into subdirectories. Otherwise only return resources * from the specified path. * @return A vector of ModuleResource objects for each matching entry. The objects are sorted * such that resources from this module are returned first followed by the resources from * statically linked modules in the load order as specified in #US_LOAD_IMPORTED_MODULES. */ std::vector FindResources(const std::string& path, const std::string& filePattern, bool recurse) const; private: friend class CoreModuleActivator; friend class ModuleRegistry; friend class ServiceReferencePrivate; ModulePrivate* d; Module(); void Init(CoreModuleContext* coreCtx, ModuleInfo* info); void Uninit(); void Start(); void Stop(); // purposely not implemented Module(const Module &); Module& operator=(const Module&); }; US_END_NAMESPACE /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(Module)& module); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(Module)& module); /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, US_PREPEND_NAMESPACE(Module) const * module); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, US_PREPEND_NAMESPACE(Module) const * module); #endif // USMODULE_H diff --git a/src/module/usModuleActivator.h b/core/include/usModuleActivator.h similarity index 99% rename from src/module/usModuleActivator.h rename to core/include/usModuleActivator.h index c131c70ed5..903f68ad6c 100644 --- a/src/module/usModuleActivator.h +++ b/core/include/usModuleActivator.h @@ -1,137 +1,137 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEACTIVATOR_H_ #define USMODULEACTIVATOR_H_ -#include +#include US_BEGIN_NAMESPACE class ModuleContext; /** * \ingroup MicroServices * * Customizes the starting and stopping of a CppMicroServices module. *

* %ModuleActivator is an interface that can be implemented by * CppMicroServices modules. The CppMicroServices library can create instances of a * module's %ModuleActivator as required. If an instance's * ModuleActivator::Load method executes successfully, it is * guaranteed that the same instance's %ModuleActivator::Unload * method will be called when the module is to be unloaded. The CppMicroServices * library does not concurrently call a %ModuleActivator object. * *

* %ModuleActivator is an abstract class interface whose implementations * must be exported via a special macro. Implementations are usually declared * and defined directly in .cpp files. * *

* \snippet uServices-activator/main.cpp 0 * *

* The class implementing the %ModuleActivator interface must have a public * default constructor so that a %ModuleActivator * object can be created by the CppMicroServices library. * */ struct ModuleActivator { virtual ~ModuleActivator() {} /** * Called when this module is loaded. This method * can be used to register services or to allocate any resources that this * module may need globally (during the whole module lifetime). * *

* This method must complete and return to its caller in a timely manner. * * @param context The execution context of the module being loaded. * @throws std::exception If this method throws an exception, this * module is marked as stopped and the framework will remove this * module's listeners, unregister all services registered by this * module, and release all services used by this module. */ virtual void Load(ModuleContext* context) = 0; /** * Called when this module is unloaded. In general, this * method should undo the work that the ModuleActivator::Load * method started. There should be no active threads that were started by * this module when this method returns. * *

* This method must complete and return to its caller in a timely manner. * * @param context The execution context of the module being unloaded. * @throws std::exception If this method throws an exception, the * module is still marked as unloaded, and the framework will remove * the module's listeners, unregister all services registered by the * module, and release all services used by the module. */ virtual void Unload(ModuleContext* context) = 0; }; US_END_NAMESPACE #define US_MODULE_ACTIVATOR_INSTANCE_FUNCTION(type) \ struct ScopedPointer \ { \ ScopedPointer(US_PREPEND_NAMESPACE(ModuleActivator)* activator = 0) : m_Activator(activator) {} \ ~ScopedPointer() { delete m_Activator; } \ US_PREPEND_NAMESPACE(ModuleActivator)* m_Activator; \ }; \ \ static ScopedPointer activatorPtr; \ if (activatorPtr.m_Activator == 0) activatorPtr.m_Activator = new type; \ return activatorPtr.m_Activator; /** * \ingroup MicroServices * * \brief Export a module activator class. * * \param _module_libname The physical name of the module, without prefix or suffix. * \param _activator_type The fully-qualified type-name of the module activator class. * * Call this macro after the definition of your module activator to make it * accessible by the CppMicroServices library. * * Example: * \snippet uServices-activator/main.cpp 0 * * \note If you use this macro in a source file compiled into an executable, additional * requirements for the macro arguments apply: * - The \c _module_libname argument must match the value of \c _module_name used in the * \c #US_INITIALIZE_MODULE macro call. */ #define US_EXPORT_MODULE_ACTIVATOR(_module_libname, _activator_type) \ extern "C" US_ABI_EXPORT US_PREPEND_NAMESPACE(ModuleActivator)* _us_module_activator_instance_ ## _module_libname () \ { \ US_MODULE_ACTIVATOR_INSTANCE_FUNCTION(_activator_type) \ } #endif /* USMODULEACTIVATOR_H_ */ diff --git a/src/module/usModuleContext.h b/core/include/usModuleContext.h similarity index 99% rename from src/module/usModuleContext.h rename to core/include/usModuleContext.h index acf6025119..5abc94c1cb 100644 --- a/src/module/usModuleContext.h +++ b/core/include/usModuleContext.h @@ -1,851 +1,851 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULECONTEXT_H_ #define USMODULECONTEXT_H_ // TODO: Replace includes with forward directives! #include "usListenerFunctors_p.h" #include "usServiceInterface.h" #include "usServiceEvent.h" #include "usServiceRegistration.h" #include "usServiceException.h" #include "usModuleEvent.h" US_BEGIN_NAMESPACE typedef US_SERVICE_LISTENER_FUNCTOR ServiceListener; typedef US_MODULE_LISTENER_FUNCTOR ModuleListener; class ModuleContextPrivate; class ServiceFactory; template class ServiceObjects; /** * \ingroup MicroServices * * A module's execution context within the framework. The context is used to * grant access to other methods so that this module can interact with the * Micro Services Framework. * *

* ModuleContext methods allow a module to: *

    *
  • Subscribe to events published by the framework. *
  • Register service objects with the framework service registry. *
  • Retrieve ServiceReferences from the framework service * registry. *
  • Get and release service objects for a referenced service. *
  • Get the list of modules loaded in the framework. *
  • Get the {@link Module} object for a module. *
* *

* A ModuleContext object will be created and provided to the * module associated with this context when it is loaded using the * {@link ModuleActivator::Load} method. The same ModuleContext * object will be passed to the module associated with this context when it is * unloaded using the {@link ModuleActivator::Unload} method. A * ModuleContext object is generally for the private use of its * associated module and is not meant to be shared with other modules in the * module environment. * *

* The Module object associated with a ModuleContext * object is called the context module. * *

* The ModuleContext object is only valid during the execution of * its context module; that is, during the period when the context module * is loaded. If the ModuleContext * object is used subsequently, a std::logic_error is * thrown. The ModuleContext object is never reused after * its context module is unloaded. * *

* The framework is the only entity that can create ModuleContext * objects. * * @remarks This class is thread safe. */ -class US_EXPORT ModuleContext +class US_Core_EXPORT ModuleContext { public: ~ModuleContext(); /** * Returns the Module object associated with this * ModuleContext. This module is called the context module. * * @return The Module object associated with this * ModuleContext. * @throws std::logic_error If this ModuleContext is no * longer valid. */ Module* GetModule() const; /** * Returns the module with the specified identifier. * * @param id The identifier of the module to retrieve. * @return A Module object or 0 if the * identifier does not match any previously loaded module. */ Module* GetModule(long id) const; /** * Get the module that with the specified module name. * * @param name The name of the module to get. * @return The requested \c Module or \c NULL. */ Module* GetModule(const std::string& name); /** * Returns a list of all known modules. *

* This method returns a list of all modules loaded in the module * environment at the time of the call to this method. This list will * also contain modules which might already have been unloaded. * * @return A std::vector of Module objects which * will hold one object per known module. */ std::vector GetModules() const; /** * Registers the specified service object with the specified properties * under the specified class names into the framework. A * ServiceRegistration object is returned. The * ServiceRegistration object is for the private use of the * module registering the service and should not be shared with other * modules. The registering module is defined to be the context module. * Other modules can locate the service by using either the * {@link #GetServiceReferences} or {@link #GetServiceReference} method. * *

* A module can register a service object that implements the * ServiceFactory or PrototypeServiceFactory interface to have more * flexibility in providing service objects to other modules. * *

* The following steps are taken when registering a service: *

    *
  1. The framework adds the following service properties to the service * properties from the specified ServiceProperties (which may be * omitted):
    * A property named ServiceConstants#SERVICE_ID() identifying the * registration number of the service
    * A property named ServiceConstants#OBJECTCLASS() containing all the * specified classes.
    * A property named ServiceConstants#SERVICE_SCOPE() identifying the scope * of the service.
    * Properties with these names in the specified ServiceProperties will * be ignored. *
  2. The service is added to the framework service registry and may now be * used by other modules. *
  3. A service event of type ServiceEvent#REGISTERED is fired. *
  4. A ServiceRegistration object for this registration is * returned. *
* * @note This is a low-level method and should normally not be used directly. * Use one of the templated RegisterService methods instead. * * @param service The service object, which is a map of interface identifiers * to raw service pointers. * @param properties The properties for this service. The keys in the * properties object must all be std::string objects. See * {@link ServiceConstants} for a list of standard service property keys. * Changes should not be made to this object after calling this * method. To update the service's properties the * {@link ServiceRegistration::SetProperties} method must be called. * The set of properties may be omitted if the service has * no properties. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * * @throws std::invalid_argument If one of the following is true: *
    *
  • service is 0. *
  • properties contains case variants of the same key name. *
* @throws std::logic_error If this ModuleContext is no longer valid. * * @see ServiceRegistration * @see ServiceFactory * @see PrototypeServiceFactory */ ServiceRegistrationU RegisterService(const InterfaceMap& service, const ServiceProperties& properties = ServiceProperties()); /** * Registers the specified service object with the specified properties * using the specified template argument with the framework. * *

* This method is provided as a convenience when service will only be registered under * a single class name whose type is available to the caller. It is otherwise identical to * RegisterService(const InterfaceMap&, const ServiceProperties&) but should be preferred * since it avoids errors in the string literal identifying the class name or interface identifier. * * Example usage: * \snippet uServices-registration/main.cpp 1-1 * \snippet uServices-registration/main.cpp 1-2 * * @tparam S The type under which the service can be located. * @param service The service object or a ServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(S* service, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(service); return RegisterService(servicePointers, properties); } /** * Registers the specified service object with the specified properties * using the specified template argument with the framework. * *

* This method is provided as a convenience when registering a service under * two interface classes whose type is available to the caller. It is otherwise identical to * RegisterService(const InterfaceMap&, const ServiceProperties&) but should be preferred * since it avoids errors in the string literal identifying the class name or interface identifier. * * Example usage: * \snippet uServices-registration/main.cpp 2-1 * \snippet uServices-registration/main.cpp 2-2 * * @tparam I1 The first interface type under which the service can be located. * @tparam I2 The second interface type under which the service can be located. * @param impl The service object or a ServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(Impl* impl, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(impl); return RegisterService(servicePointers, properties); } /** * Registers the specified service object with the specified properties * using the specified template argument with the framework. * *

* This method is identical to the RegisterService(Impl*, const ServiceProperties&) * method except that it supports three service interface types. * * @tparam I1 The first interface type under which the service can be located. * @tparam I2 The second interface type under which the service can be located. * @tparam I3 The third interface type under which the service can be located. * @param impl The service object or a ServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(Impl* impl, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(impl); return RegisterService(servicePointers, properties); } /** * Registers the specified service factory as a service with the specified properties * using the specified template argument as service interface type with the framework. * *

* This method is provided as a convenience when factory will only be registered under * a single class name whose type is available to the caller. It is otherwise identical to * RegisterService(const InterfaceMap&, const ServiceProperties&) but should be preferred * since it avoids errors in the string literal identifying the class name or interface identifier. * * Example usage: * \snippet uServices-registration/main.cpp 1-1 * \snippet uServices-registration/main.cpp f1 * * @tparam S The type under which the service can be located. * @param factory The ServiceFactory or PrototypeServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service factory object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(ServiceFactory* factory, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(factory); return RegisterService(servicePointers, properties); } /** * Registers the specified service factory as a service with the specified properties * using the specified template argument as service interface type with the framework. * *

* This method is identical to the RegisterService(ServiceFactory*, const ServiceProperties&) * method except that it supports two service interface types. * * Example usage: * \snippet uServices-registration/main.cpp 2-1 * \snippet uServices-registration/main.cpp f2 * * @tparam I1 The first interface type under which the service can be located. * @tparam I2 The second interface type under which the service can be located. * @param factory The ServiceFactory or PrototypeServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service factory object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(ServiceFactory* factory, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(factory); return RegisterService(servicePointers, properties); } /** * Registers the specified service factory as a service with the specified properties * using the specified template argument as service interface type with the framework. * *

* This method is identical to the RegisterService(ServiceFactory*, const ServiceProperties&) * method except that it supports three service interface types. * * @tparam I1 The first interface type under which the service can be located. * @tparam I2 The second interface type under which the service can be located. * @tparam I3 The third interface type under which the service can be located. * @param factory The ServiceFactory or PrototypeServiceFactory object. * @param properties The properties for this service. * @return A ServiceRegistration object for use by the module * registering the service to update the service's properties or to * unregister the service. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid or the * \c service factory object is NULL. * * @see RegisterService(const InterfaceMap&, const ServiceProperties&) */ template ServiceRegistration RegisterService(ServiceFactory* factory, const ServiceProperties& properties = ServiceProperties()) { InterfaceMap servicePointers = MakeInterfaceMap(factory); return RegisterService(servicePointers, properties); } /** * Returns a list of ServiceReference objects. The returned * list contains services that * were registered under the specified class and match the specified filter * expression. * *

* The list is valid at the time of the call to this method. However since * the Micro Services framework is a very dynamic environment, services can be modified or * unregistered at any time. * *

* The specified filter expression is used to select the * registered services whose service properties contain keys and values * which satisfy the filter expression. See LDAPFilter for a description * of the filter syntax. If the specified filter is * empty, all registered services are considered to match the * filter. If the specified filter expression cannot be parsed, * an std::invalid_argument will be thrown with a human readable * message where the filter became unparsable. * *

* The result is a list of ServiceReference objects for all * services that meet all of the following conditions: *

    *
  • If the specified class name, clazz, is not * empty, the service must have been registered with the * specified class name. The complete list of class names with which a * service was registered is available from the service's * {@link ServiceConstants#OBJECTCLASS() objectClass} property. *
  • If the specified filter is not empty, the * filter expression must match the service. *
* * @param clazz The class name with which the service was registered or * an empty string for all services. * @param filter The filter expression or empty for all * services. * @return A list of ServiceReference objects or * an empty list if no services are registered which satisfy the * search. * @throws std::invalid_argument If the specified filter * contains an invalid filter expression that cannot be parsed. * @throws std::logic_error If this ModuleContext is no longer valid. */ std::vector GetServiceReferences(const std::string& clazz, const std::string& filter = std::string()); /** * Returns a list of ServiceReference objects. The returned * list contains services that * were registered under the interface id of the template argument S * and match the specified filter expression. * *

* This method is identical to GetServiceReferences(const std::string&, const std::string&) except that * the class name for the service object is automatically deduced from the template argument. * * @tparam S The type under which the requested service objects must have been registered. * @param filter The filter expression or empty for all * services. * @return A list of ServiceReference objects or * an empty list if no services are registered which satisfy the * search. * @throws std::invalid_argument If the specified filter * contains an invalid filter expression that cannot be parsed. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If the service type \c S is invalid. * * @see GetServiceReferences(const std::string&, const std::string&) */ template std::vector > GetServiceReferences(const std::string& filter = std::string()) { const char* clazz = us_service_interface_iid(); if (clazz == 0) throw ServiceException("The service interface class has no US_DECLARE_SERVICE_INTERFACE macro"); typedef std::vector BaseVectorT; BaseVectorT serviceRefs = GetServiceReferences(std::string(clazz), filter); std::vector > result; for(BaseVectorT::const_iterator i = serviceRefs.begin(); i != serviceRefs.end(); ++i) { result.push_back(ServiceReference(*i)); } return result; } /** * Returns a ServiceReference object for a service that * implements and was registered under the specified class. * *

* The returned ServiceReference object is valid at the time of * the call to this method. However as the Micro Services framework is a very dynamic * environment, services can be modified or unregistered at any time. * *

* This method is the same as calling * {@link ModuleContext::GetServiceReferences(const std::string&, const std::string&)} with an * empty filter expression. It is provided as a convenience for * when the caller is interested in any service that implements the * specified class. *

* If multiple such services exist, the service with the highest ranking (as * specified in its ServiceConstants::SERVICE_RANKING() property) is returned. *

* If there is a tie in ranking, the service with the lowest service ID (as * specified in its ServiceConstants::SERVICE_ID() property); that is, the * service that was registered first is returned. * * @param clazz The class name with which the service was registered. * @return A ServiceReference object, or an invalid ServiceReference if * no services are registered which implement the named class. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException If no service was registered under the given class name. * * @see #GetServiceReferences(const std::string&, const std::string&) */ ServiceReferenceU GetServiceReference(const std::string& clazz); /** * Returns a ServiceReference object for a service that * implements and was registered under the specified template class argument. * *

* This method is identical to GetServiceReference(const std::string&) except that * the class name for the service object is automatically deduced from the template argument. * * @tparam S The type under which the requested service must have been registered. * @return A ServiceReference object, or an invalid ServiceReference if * no services are registered which implement the type S. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws ServiceException It no service was registered under the given class name. * @see #GetServiceReference(const std::string&) * @see #GetServiceReferences(const std::string&) */ template ServiceReference GetServiceReference() { const char* clazz = us_service_interface_iid(); if (clazz == 0) throw ServiceException("The service interface class has no US_DECLARE_SERVICE_INTERFACE macro"); return ServiceReference(GetServiceReference(std::string(clazz))); } /** * Returns the service object referenced by the specified * ServiceReferenceBase object. *

* A module's use of a service is tracked by the module's use count of that * service. Each time a service's service object is returned by * {@link #GetService(const ServiceReference&)} the context module's use count for * that service is incremented by one. Each time the service is released by * {@link #UngetService(const ServiceReferenceBase&)} the context module's use count * for that service is decremented by one. *

* When a module's use count for a service drops to zero, the module should * no longer use that service. * *

* This method will always return 0 when the service * associated with this reference has been unregistered. * *

* The following steps are taken to get the service object: *

    *
  1. If the service has been unregistered, 0 is returned. *
  2. The context module's use count for this service is incremented by * one. *
  3. If the context module's use count for the service is currently one * and the service was registered with an object implementing the * ServiceFactory interface, the * {@link ServiceFactory::GetService} method is * called to create a service object for the context module. This service * object is cached by the framework. While the context module's use count * for the service is greater than zero, subsequent calls to get the * services's service object for the context module will return the cached * service object.
    * If the ServiceFactory object throws an * exception, 0 is returned and a warning is logged. *
  4. The service object for the service is returned. *
* * @param reference A reference to the service. * @return A service object for the service associated with * reference or 0 if the service is not * registered or the ServiceFactory threw * an exception. * @throws std::logic_error If this ModuleContext is no * longer valid. * @throws std::invalid_argument If the specified * ServiceReferenceBase is invalid (default constructed). * @see #UngetService(const ServiceReferenceBase&) * @see ServiceFactory */ void* GetService(const ServiceReferenceBase& reference); InterfaceMap GetService(const ServiceReferenceU& reference); /** * Returns the service object referenced by the specified * ServiceReference object. *

* This is a convenience method which is identical to void* GetService(const ServiceReferenceBase&) * except that it casts the service object to the supplied template argument type * * @tparam S The type the service object will be cast to. * @return A service object for the service associated with * reference or 0 if the service is not * registered, the ServiceFactory threw * an exception or the service could not be casted to the desired type. * @throws std::logic_error If this ModuleContext is no * longer valid. * @throws std::invalid_argument If the specified * ServiceReference is invalid (default constructed). * @see #GetService(const ServiceReferenceBase&) * @see #UngetService(const ServiceReferenceBase&) * @see ServiceFactory */ template S* GetService(const ServiceReference& reference) { const ServiceReferenceBase& baseRef = reference; return reinterpret_cast(GetService(baseRef)); } /** * Returns the ServiceObjects object for the service referenced by the specified * ServiceReference object. The ServiceObjects object can be used to obtain * multiple service objects for services with prototype scope. For services with * singleton or module scope, the ServiceObjects::GetService() method behaves * the same as the GetService(const ServiceReference&) method and the * ServiceObjects::UngetService(const ServiceReferenceBase&) method behaves the * same as the UngetService(const ServiceReferenceBase&) method. That is, only one, * use-counted service object is available from the ServiceObjects object. * * @tparam S Type of Service. * @param reference A reference to the service. * @return A ServiceObjects object for the service associated with the specified * reference or an invalid instance if the service is not registered. * @throws std::logic_error If this ModuleContext is no longer valid. * @throws std::invalid_argument If the specified ServiceReference is invalid * (default constructed or the service has been unregistered) * * @see PrototypeServiceFactory */ template ServiceObjects GetServiceObjects(const ServiceReference& reference) { return ServiceObjects(this, reference); } /** * Releases the service object referenced by the specified * ServiceReference object. If the context module's use count * for the service is zero, this method returns false. * Otherwise, the context modules's use count for the service is decremented * by one. * *

* The service's service object should no longer be used and all references * to it should be destroyed when a module's use count for the service drops * to zero. * *

* The following steps are taken to unget the service object: *

    *
  1. If the context module's use count for the service is zero or the * service has been unregistered, false is returned. *
  2. The context module's use count for this service is decremented by * one. *
  3. If the context module's use count for the service is currently zero * and the service was registered with a ServiceFactory object, * the ServiceFactory#UngetService * method is called to release the service object for the context module. *
  4. true is returned. *
* * @param reference A reference to the service to be released. * @return false if the context module's use count for the * service is zero or if the service has been unregistered; * true otherwise. * @throws std::logic_error If this ModuleContext is no * longer valid. * @see #GetService * @see ServiceFactory */ bool UngetService(const ServiceReferenceBase& reference); void AddServiceListener(const ServiceListener& delegate, const std::string& filter = std::string()); void RemoveServiceListener(const ServiceListener& delegate); void AddModuleListener(const ModuleListener& delegate); void RemoveModuleListener(const ModuleListener& delegate); /** * Adds the specified callback with the * specified filter to the context modules's list of listeners. * See LDAPFilter for a description of the filter syntax. Listeners * are notified when a service has a lifecycle state change. * *

* You must take care to remove registered listeners befor the receiver * object is destroyed. However, the Micro Services framework takes care * of removing all listeners registered by this context module's classes * after the module is unloaded. * *

* If the context module's list of listeners already contains a pair (r,c) * of receiver and callback such that * (r == receiver && c == callback), then this * method replaces that callback's filter (which may be empty) * with the specified one (which may be empty). * *

* The callback is called if the filter criteria is met. To filter based * upon the class of the service, the filter should reference the * ServiceConstants#OBJECTCLASS() property. If filter is * empty, all services are considered to match the filter. * *

* When using a filter, it is possible that the * ServiceEvents for the complete lifecycle of a service * will not be delivered to the callback. For example, if the * filter only matches when the property x has * the value 1, the callback will not be called if the * service is registered with the property x not set to the * value 1. Subsequently, when the service is modified * setting property x to the value 1, the * filter will match and the callback will be called with a * ServiceEvent of type MODIFIED. Thus, the * callback will not be called with a ServiceEvent of type * REGISTERED. * * @tparam R The type of the receiver (containing the member function to be called) * @param receiver The object to connect to. * @param callback The member function pointer to call. * @param filter The filter criteria. * @throws std::invalid_argument If filter contains an * invalid filter string that cannot be parsed. * @throws std::logic_error If this ModuleContext is no * longer valid. * @see ServiceEvent * @see RemoveServiceListener() */ template void AddServiceListener(R* receiver, void(R::*callback)(const ServiceEvent), const std::string& filter = std::string()) { AddServiceListener(ServiceListenerMemberFunctor(receiver, callback), static_cast(receiver), filter); } /** * Removes the specified callback from the context module's * list of listeners. * *

* If the (receiver,callback) pair is not contained in this * context module's list of listeners, this method does nothing. * * @tparam R The type of the receiver (containing the member function to be removed) * @param receiver The object from which to disconnect. * @param callback The member function pointer to remove. * @throws std::logic_error If this ModuleContext is no * longer valid. * @see AddServiceListener() */ template void RemoveServiceListener(R* receiver, void(R::*callback)(const ServiceEvent)) { RemoveServiceListener(ServiceListenerMemberFunctor(receiver, callback), static_cast(receiver)); } /** * Adds the specified callback to the context modules's list * of listeners. Listeners are notified when a module has a lifecycle * state change. * *

* If the context module's list of listeners already contains a pair (r,c) * of receiver and callback such that * (r == receiver && c == callback), then this method does nothing. * * @tparam R The type of the receiver (containing the member function to be called) * @param receiver The object to connect to. * @param callback The member function pointer to call. * @throws std::logic_error If this ModuleContext is no * longer valid. * @see ModuleEvent */ template void AddModuleListener(R* receiver, void(R::*callback)(const ModuleEvent)) { AddModuleListener(ModuleListenerMemberFunctor(receiver, callback), static_cast(receiver)); } /** * Removes the specified callback from the context module's * list of listeners. * *

* If the (receiver,callback) pair is not contained in this * context module's list of listeners, this method does nothing. * * @tparam R The type of the receiver (containing the member function to be removed) * @param receiver The object from which to disconnect. * @param callback The member function pointer to remove. * @throws std::logic_error If this ModuleContext is no * longer valid. * @see AddModuleListener() */ template void RemoveModuleListener(R* receiver, void(R::*callback)(const ModuleEvent)) { RemoveModuleListener(ModuleListenerMemberFunctor(receiver, callback), static_cast(receiver)); } /** * Get the absolute path for a file or directory in the persistent * storage area provided for the module. The returned path * might be empty if no storage path has been set previously. * If the path is non-empty, it is safe to assume that the path is writable. * * @see ModuleSettings::SetStoragePath(const std::string&) * * @param filename A relative name to the file or directory to be accessed. * @return The absolute path to the persistent storage area for the given file name. */ std::string GetDataFile(const std::string& filename) const; private: friend class Module; friend class ModulePrivate; ModuleContext(ModulePrivate* module); // purposely not implemented ModuleContext(const ModuleContext&); ModuleContext& operator=(const ModuleContext&); void AddServiceListener(const ServiceListener& delegate, void* data, const std::string& filter); void RemoveServiceListener(const ServiceListener& delegate, void* data); void AddModuleListener(const ModuleListener& delegate, void* data); void RemoveModuleListener(const ModuleListener& delegate, void* data); ModuleContextPrivate * const d; }; US_END_NAMESPACE #endif /* USMODULECONTEXT_H_ */ diff --git a/src/module/usModuleEvent.h b/core/include/usModuleEvent.h similarity index 93% rename from src/module/usModuleEvent.h rename to core/include/usModuleEvent.h index 0e1f076758..7394c5a4cb 100644 --- a/src/module/usModuleEvent.h +++ b/core/include/usModuleEvent.h @@ -1,162 +1,162 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEEVENT_H #define USMODULEEVENT_H #include #include "usSharedData.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4251) #endif US_BEGIN_NAMESPACE class Module; class ModuleEventData; /** * \ingroup MicroServices * * An event from the Micro Services framework describing a module lifecycle change. *

* ModuleEvent objects are delivered to listeners connected * via ModuleContext::AddModuleListener() when a change * occurs in a modules's lifecycle. A type code is used to identify * the event type for future extendability. * * @see ModuleContext#AddModuleListener */ -class US_EXPORT ModuleEvent +class US_Core_EXPORT ModuleEvent { SharedDataPointer d; public: enum Type { /** * The module has been loaded. *

* The module's * \link ModuleActivator::Load(ModuleContext*) ModuleActivator Load\endlink method * has been executed. */ LOADED, /** * The module has been unloaded. *

* The module's * \link ModuleActivator::Unload(ModuleContext*) ModuleActivator Unload\endlink method * has been executed. */ UNLOADED, /** * The module is about to be loaded. *

* The module's * \link ModuleActivator::Load(ModuleContext*) ModuleActivator Load\endlink method * is about to be called. */ LOADING, /** * The module is about to be unloaded. *

* The module's * \link ModuleActivator::Unload(ModuleContext*) ModuleActivator Unload\endlink method * is about to be called. */ UNLOADING }; /** * Creates an invalid instance. */ ModuleEvent(); ~ModuleEvent(); /** * Can be used to check if this ModuleEvent instance is valid, * or if it has been constructed using the default constructor. * * @return true if this event object is valid, * false otherwise. */ bool IsNull() const; /** * Creates a module event of the specified type. * * @param type The event type. * @param module The module which had a lifecycle change. */ ModuleEvent(Type type, Module* module); ModuleEvent(const ModuleEvent& other); ModuleEvent& operator=(const ModuleEvent& other); /** * Returns the module which had a lifecycle change. * * @return The module that had a change occur in its lifecycle. */ Module* GetModule() const; /** * Returns the type of lifecyle event. The type values are: *

    *
  • {@link #LOADING} *
  • {@link #LOADED} *
  • {@link #UNLOADING} *
  • {@link #UNLOADED} *
* * @return The type of lifecycle event. */ Type GetType() const; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif /** * \ingroup MicroServices * @{ */ -US_EXPORT std::ostream& operator<<(std::ostream& os, US_PREPEND_NAMESPACE(ModuleEvent::Type) eventType); -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleEvent)& event); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, US_PREPEND_NAMESPACE(ModuleEvent::Type) eventType); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleEvent)& event); /** @}*/ #endif // USMODULEEVENT_H diff --git a/src/module/usModuleEventHook.h b/core/include/usModuleEventHook.h similarity index 98% rename from src/module/usModuleEventHook.h rename to core/include/usModuleEventHook.h index 78d76ece37..b1b8898054 100644 --- a/src/module/usModuleEventHook.h +++ b/core/include/usModuleEventHook.h @@ -1,72 +1,72 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEEVENTHOOK_H #define USMODULEEVENTHOOK_H #include "usServiceInterface.h" #include "usShrinkableVector.h" US_BEGIN_NAMESPACE class ModuleContext; class ModuleEvent; /** * @ingroup MicroServices * * %Module Event Hook Service. * *

* Modules registering this service will be called during module lifecycle * (loading, loaded, unloading, and unloaded) operations. * * @remarks Implementations of this interface are required to be thread-safe. */ -struct US_EXPORT ModuleEventHook +struct US_Core_EXPORT ModuleEventHook { virtual ~ModuleEventHook(); /** * Module event hook method. This method is called prior to module event * delivery when a module is loading, loaded, unloading, or unloaded. * This method can filter the modules which receive the event. *

* This method is called one and only one time for * each module event generated, this includes module events which are * generated when there are no module listeners registered. * * @param event The module event to be delivered. * @param contexts A list of Module Contexts for modules which have * listeners to which the specified event will be delivered. The * implementation of this method may remove module contexts from the * list to prevent the event from being delivered to the * associated modules. */ virtual void Event(const ModuleEvent& event, ShrinkableVector& contexts) = 0; }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(us::ModuleEventHook, "org.cppmicroservices.ModuleEventHook/2.0.0") #endif // USMODULEEVENTHOOK_H diff --git a/src/module/usModuleFindHook.h b/core/include/usModuleFindHook.h similarity index 98% rename from src/module/usModuleFindHook.h rename to core/include/usModuleFindHook.h index f4eaf5a280..6d02b13a0f 100644 --- a/src/module/usModuleFindHook.h +++ b/core/include/usModuleFindHook.h @@ -1,73 +1,73 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEFINDHOOK_H #define USMODULEFINDHOOK_H #include "usServiceInterface.h" #include "usShrinkableVector.h" US_BEGIN_NAMESPACE class Module; class ModuleContext; /** * @ingroup MicroServices * * %Module Context Hook Service. * *

* Modules registering this service will be called during module find * (get modules) operations. * * @remarks Implementations of this interface are required to be thread-safe. */ -struct US_EXPORT ModuleFindHook +struct US_Core_EXPORT ModuleFindHook { virtual ~ModuleFindHook(); /** * Find hook method. This method is called for module find operations * using ModuleContext::GetBundle(long) * and ModuleContext::GetModules() methods. The find method can * filter the result of the find operation. * * \note A find operation using the ModuleContext::GetModule(const std::string&) * method does not cause the find method to be called, neither does any * call to the static methods of the ModuleRegistry class. * * @param context The module context of the module performing the find * operation. * @param modules A list of Modules to be returned as a result of the * find operation. The implementation of this method may remove * modules from the list to prevent the modules from being * returned to the module performing the find operation. */ virtual void Find(const ModuleContext* context, ShrinkableVector& modules) = 0; }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(us::ModuleFindHook, "org.cppmicroservices.ModuleFindHook/2.0.0") #endif // USMODULEFINDHOOK_H diff --git a/src/module/usModuleImport.h b/core/include/usModuleImport.h similarity index 99% rename from src/module/usModuleImport.h rename to core/include/usModuleImport.h index a5f7c99056..c10de0136a 100644 --- a/src/module/usModuleImport.h +++ b/core/include/usModuleImport.h @@ -1,158 +1,158 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEIMPORT_H #define USMODULEIMPORT_H -#include +#include #include US_BEGIN_NAMESPACE struct ModuleActivator; US_END_NAMESPACE /** * \ingroup MicroServices * * \brief Import a static module. * * \param _import_module_libname The physical name of the module to import, without prefix or suffix. * * This macro imports the static module named \c _import_module_libname. * * Inserting this macro into your application's source code will allow you to make use of * a static module. Do not forget to list the imported module when calling the macro * #US_LOAD_IMPORTED_MODULES and to actually link the static module to the importing * executable or shared library. * * Example: * \snippet uServices-staticmodules/main.cpp ImportStaticModuleIntoLib * * \sa US_LOAD_IMPORTED_MODULES * \sa \ref MicroServices_StaticModules */ #define US_IMPORT_MODULE(_import_module_libname) \ extern "C" US_PREPEND_NAMESPACE(ModuleActivator)* _us_module_activator_instance_ ## _import_module_libname (); \ void _dummy_reference_to_ ## _import_module_libname ## _activator() \ { \ _us_module_activator_instance_ ## _import_module_libname(); \ } /** * \ingroup MicroServices * * \brief Import a static module's resources. * * \param _import_module_libname The physical name of the module to import, without prefix or suffix. * * This macro imports the resources of the static module named \c _import_module_libname. * * Inserting this macro into your application's source code will allow you to make use of * the resources embedded in a static module. Do not forget to list the imported module when * calling the macro #US_LOAD_IMPORTED_MODULES and to actually link the static module to the * importing executable or shared library. * * \sa US_IMPORT_MODULE * \sa US_LOAD_IMPORTED_MODULES * \sa \ref MicroServices_StaticModules */ #define US_IMPORT_MODULE_RESOURCES(_import_module_libname) \ extern "C" US_PREPEND_NAMESPACE(ModuleActivator)* _us_init_resources_ ## _import_module_libname (); \ void _dummy_reference_to_ ## _import_module_libname ## _init_resources() \ { \ _us_init_resources_ ## _import_module_libname(); \ } /** * \ingroup MicroServices * \def US_LOAD_IMPORTED_MODULES_INTO_MAIN(_static_modules) * * \brief Import a list of static modules into an executable. * * \param _static_modules A space-deliminated list of physical module names, without prefix * or suffix. * * This macro ensures that the ModuleActivator::Load(ModuleContext*) function is called * for each imported static module when the importing executable is loaded (if the static * module provides an activator). If the static module provides embedded resources and * the US_IMPORT_MODULE_RESOURCES macro was called, the resources will be made available * through the importing module. * * There must be exactly one call of this macro in the executable which is * importing static modules. * * Example: * \snippet uServices-staticmodules/main.cpp ImportStaticModuleIntoMain * * \sa US_IMPORT_MODULE * \sa US_LOAD_IMPORTED_MODULES * \sa \ref MicroServices_StaticModules */ #ifdef US_BUILD_SHARED_LIBS #define US_LOAD_IMPORTED_MODULES_INTO_MAIN(_static_modules) \ extern "C" US_ABI_EXPORT const char* _us_get_imported_modules_for_() \ { \ return #_static_modules; \ } #else #define US_LOAD_IMPORTED_MODULES_INTO_MAIN(_static_modules) \ extern "C" US_ABI_EXPORT const char* _us_get_imported_modules_for_CppMicroServices() \ { \ return #_static_modules; \ } #endif /** * \ingroup MicroServices * * \brief Import a list of static modules into a shared library. * * \param _module_libname The physical name of the importing module, without prefix or suffix. * \param _static_modules A space-deliminated list of physical module names, without prefix * or suffix. * * This macro ensures that the ModuleActivator::Load(ModuleContext*) function is called * for each imported static module when the importing shared library is loaded (if the static * module provides an activator). If the static module provides embedded resources and * the US_IMPORT_MODULE_RESOURCES macro was called, the resources will be made available * through the importing module. * * There must be exactly one call of this macro in the shared library which is * importing static modules. * * Example: * \snippet uServices-staticmodules/main.cpp ImportStaticModuleIntoLib * * \sa US_IMPORT_MODULE * \sa US_LOAD_IMPORTED_MODULES_INTO_MAIN * \sa \ref MicroServices_StaticModules */ #define US_LOAD_IMPORTED_MODULES(_module_libname, _static_modules) \ extern "C" US_ABI_EXPORT const char* _us_get_imported_modules_for_ ## _module_libname () \ { \ return #_static_modules; \ } #endif // USMODULEREGISTRY_H diff --git a/src/module/usModuleInfo.h b/core/include/usModuleInfo.h similarity index 97% rename from src/module/usModuleInfo.h rename to core/include/usModuleInfo.h index 6d73321982..0ca559bb45 100644 --- a/src/module/usModuleInfo.h +++ b/core/include/usModuleInfo.h @@ -1,77 +1,77 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEINFO_H #define USMODULEINFO_H -#include +#include #include #include #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4251) #endif US_BEGIN_NAMESPACE struct ModuleActivator; /** * This class is not intended to be used directly. It is exported to support * the CppMicroServices module system. */ -struct US_EXPORT ModuleInfo +struct US_Core_EXPORT ModuleInfo { ModuleInfo(const std::string& name, const std::string& libName); typedef ModuleActivator*(*ModuleActivatorHook)(void); typedef int(*InitResourcesHook)(ModuleInfo*); typedef const unsigned char* ModuleResourceData; std::string name; std::string libName; std::string location; std::string autoLoadDir; long id; ModuleActivatorHook activatorHook; // In case of statically linked (imported) modules, there could // be more than one set of ModuleResourceData pointers. We aggregate // all pointers here. std::vector resourceData; std::vector resourceNames; std::vector resourceTree; }; US_END_NAMESPACE #ifdef _MSC_VER # pragma warning(pop) #endif #endif // USMODULEINFO_H diff --git a/src/module/usModuleInitialization.h b/core/include/usModuleInitialization.h similarity index 100% rename from src/module/usModuleInitialization.h rename to core/include/usModuleInitialization.h diff --git a/src/module/usModuleRegistry.h b/core/include/usModuleRegistry.h similarity index 97% rename from src/module/usModuleRegistry.h rename to core/include/usModuleRegistry.h index 3cf2337089..58a7e37a62 100644 --- a/src/module/usModuleRegistry.h +++ b/core/include/usModuleRegistry.h @@ -1,92 +1,92 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEREGISTRY_H #define USMODULEREGISTRY_H #include #include -#include +#include US_BEGIN_NAMESPACE class Module; struct ModuleInfo; struct ModuleActivator; /** * \ingroup MicroServices * * Here we handle all the modules that are loaded in the framework. */ -class US_EXPORT ModuleRegistry { +class US_Core_EXPORT ModuleRegistry { public: /** * Get the module that has the specified module identifier. * * @param id The identifier of the module to get. * @return Module or null * if the module was not found. */ static Module* GetModule(long id); /** * Get the module that has specified module name. * * @param name The name of the module to get. * @return Module or null. */ static Module* GetModule(const std::string& name); /** * Get all known modules. * * @return A list which is filled with all known modules. */ static std::vector GetModules(); /** * Get all modules currently in module state LOADED. * * @return A list which is filled with all modules in * state LOADED */ static std::vector GetLoadedModules(); private: friend class ModuleInitializer; // disabled ModuleRegistry(); static void Register(ModuleInfo* info); static void UnRegister(const ModuleInfo* info); }; US_END_NAMESPACE #endif // USMODULEREGISTRY_H diff --git a/src/module/usModuleResource.h b/core/include/usModuleResource.h similarity index 98% rename from src/module/usModuleResource.h rename to core/include/usModuleResource.h index e35cad739f..c56f8138d0 100644 --- a/src/module/usModuleResource.h +++ b/core/include/usModuleResource.h @@ -1,309 +1,309 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULERESOURCE_H #define USMODULERESOURCE_H -#include +#include #include #include US_MSVC_PUSH_DISABLE_WARNING(4396) US_BEGIN_NAMESPACE class ModuleResourcePrivate; class ModuleResourceTree; /** * \ingroup MicroServices * * Represents a resource (text file, image, etc.) embedded in a CppMicroServices module. * * A \c %ModuleResource object provides information about a resource (external file) which * was embedded into this module's shared library. \c %ModuleResource objects can be obtained * be calling Module#GetResource or Module#FindResources. * * Example code for retreiving a resource object and reading its contents: * \snippet uServices-resources/main.cpp 1 * * %ModuleResource objects have value semantics and copies are very inexpensive. * * \see ModuleResourceStream * \see \ref MicroServices_Resources */ -class US_EXPORT ModuleResource +class US_Core_EXPORT ModuleResource { private: typedef ModuleResourcePrivate* ModuleResource::*bool_type; public: /** * Creates in invalid %ModuleResource object. */ ModuleResource(); /** * Copy constructor. * @param resource The object to be copied. */ ModuleResource(const ModuleResource& resource); ~ModuleResource(); /** * Assignment operator. * * @param resource The %ModuleResource object which is assigned to this instance. * @return A reference to this %ModuleResource instance. */ ModuleResource& operator=(const ModuleResource& resource); /** * A less then operator using the full resource path as returned by * GetResourcePath() to define the ordering. * * @param resource The object to which this %ModuleResource object is compared to. * @return \c true if this %ModuleResource object is less then \c resource, * \c false otherwise. */ bool operator<(const ModuleResource& resource) const; /** * Equality operator for %ModuleResource objects. * * @param resource The object for testing equality. * @return \c true if this %ModuleResource object is equal to \c resource, i.e. * they are coming from the same module (shared or static) and have an equal * resource path, \c false otherwise. */ bool operator==(const ModuleResource& resource) const; /** * Inequality operator for %ModuleResource objects. * * @param resource The object for testing inequality. * @return The result of !(*this == resource). */ bool operator!=(const ModuleResource& resource) const; /** * Tests this %ModuleResource object for validity. * * Invalid %ModuleResource objects are created by the default constructor or * can be returned by the Module class if the resource path is not found. If a * module from which %ModuleResource objects have been obtained is un-loaded, * these objects become invalid. * * @return \c true if this %ModuleReource object is valid and can safely be used, * \c false otherwise. */ bool IsValid() const; /** * Returns \c true if the resource represents a file and the resource data * is in a compressed format, \c false otherwise. * * @return \c true if the resource data is compressed, \c false otherwise. */ bool IsCompressed() const; /** * Boolean conversion operator using IsValid(). */ operator bool_type() const; /** * Returns the name of the resource, excluding the path. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string name = resource.GetName(); // name = "archive.tar.gz" * \endcode * * @return The resource name. * @see GetPath(), GetResourcePath() */ std::string GetName() const; /** * Returns the resource's path, without the file name. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string path = resource.GetPath(); // path = "/data" * \endcode * * @return The resource path without the name. * @see GetResourcePath(), GetName() and IsDir() */ std::string GetPath() const; /** * Returns the resource path including the file name. * * @return The resource path including the file name. * @see GetPath(), GetName() and IsDir() */ std::string GetResourcePath() const; /** * Returns the base name of the resource without the path. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string base = resource.GetBaseName(); // base = "archive" * \endcode * * @return The resource base name. * @see GetName(), GetSuffix(), GetCompleteSuffix() and GetCompleteBaseName() */ std::string GetBaseName() const; /** * Returns the complete base name of the resource without the path. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string base = resource.GetCompleteBaseName(); // base = "archive.tar" * \endcode * * @return The resource's complete base name. * @see GetName(), GetSuffix(), GetCompleteSuffix(), and GetBaseName() */ std::string GetCompleteBaseName() const; /** * Returns the suffix of the resource. * * The suffix consists of all characters in the resource name after (but not * including) the last '.'. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string suffix = resource.GetSuffix(); // suffix = "gz" * \endcode * * @return The resource name suffix. * @see GetName(), GetCompleteSuffix(), GetBaseName() and GetCompleteBaseName() */ std::string GetSuffix() const; /** * Returns the complete suffix of the resource. * * The suffix consists of all characters in the resource name after (but not * including) the first '.'. * * Example: * \code * ModuleResource resource = module->GetResource("/data/archive.tar.gz"); * std::string suffix = resource.GetCompleteSuffix(); // suffix = "tar.gz" * \endcode * * @return The resource name suffix. * @see GetName(), GetSuffix(), GetBaseName(), and GetCompleteBaseName() */ std::string GetCompleteSuffix() const; /** * Returns \c true if this %ModuleResource object points to a directory and thus * may have child resources. * * @return \c true if this object points to a directory, \c false otherwise. */ bool IsDir() const; /** * Returns \c true if this %ModuleResource object points to a file resource. * * @return \c true if this object points to an embedded file, \c false otherwise. */ bool IsFile() const; /** * Returns a list of resource names which are children of this object. * * The returned names are relative to the path of this %ModuleResource object and * may contain duplicates in case of modules which are statically linked into the * module from which this object was retreived. * * @return A list of child resource names. */ std::vector GetChildren() const; /** * Returns the size of the raw embedded data for this %ModuleResource object. * * @return The resource data size. */ int GetSize() const; /** * Returns a data pointer pointing to the raw data of this %ModuleResource object. * If the resource is compressed the data returned is compressed and UncompressResourceData() * must be used to access the data. If the resource represents a directory \c 0 is returned. * * @return A raw pointer to the embedded data, or \c 0 if the resource is not a file resource. */ const unsigned char* GetData() const; private: ModuleResource(const std::string& file, ModuleResourceTree* resourceTree, const std::vector& resourceTrees); friend class Module; friend class ModulePrivate; US_HASH_FUNCTION_FRIEND(ModuleResource); std::size_t Hash() const; ModuleResourcePrivate* d; }; US_END_NAMESPACE US_MSVC_POP_WARNING /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleResource)& resource); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleResource)& resource); US_HASH_FUNCTION_NAMESPACE_BEGIN US_HASH_FUNCTION_BEGIN(US_PREPEND_NAMESPACE(ModuleResource)) return arg.Hash(); US_HASH_FUNCTION_END US_HASH_FUNCTION_NAMESPACE_END #endif // USMODULERESOURCE_H diff --git a/src/module/usModuleResourceStream.h b/core/include/usModuleResourceStream.h similarity index 94% rename from src/module/usModuleResourceStream.h rename to core/include/usModuleResourceStream.h index 7c4610e1dc..047439e606 100644 --- a/src/module/usModuleResourceStream.h +++ b/core/include/usModuleResourceStream.h @@ -1,65 +1,65 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef USMODULERESOURCESTREAM_H #define USMODULERESOURCESTREAM_H #include "usModuleResourceBuffer_p.h" #include US_BEGIN_NAMESPACE class ModuleResource; /** * \ingroup MicroServices * * An input stream class for ModuleResource objects. * * This class provides access to the resource data embedded in a module's * shared library via a STL input stream interface. * * \see ModuleResource for an example how to use this class. */ -class US_EXPORT ModuleResourceStream : private ModuleResourceBuffer, public std::istream +class US_Core_EXPORT ModuleResourceStream : private ModuleResourceBuffer, public std::istream { public: /** * Construct a %ModuleResourceStream object. * * @param resource The ModuleResource object for which an input stream * should be constructed. * @param mode The open mode of the stream. If \c std::ios_base::binary * is used, the resource data will be treated as binary data, otherwise * the data is interpreted as text data and the usual platform specific * end-of-line translations take place. */ ModuleResourceStream(const ModuleResource& resource, std::ios_base::openmode mode = std::ios_base::in); private: // purposely not implemented ModuleResourceStream(const ModuleResourceStream&); ModuleResourceStream& operator=(const ModuleResourceStream&); }; US_END_NAMESPACE #endif // USMODULERESOURCESTREAM_H diff --git a/src/module/usModuleSettings.h b/core/include/usModuleSettings.h similarity index 98% rename from src/module/usModuleSettings.h rename to core/include/usModuleSettings.h index 346eef3599..5593c723f6 100644 --- a/src/module/usModuleSettings.h +++ b/core/include/usModuleSettings.h @@ -1,153 +1,153 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULESETTINGS_H #define USMODULESETTINGS_H -#include "usConfig.h" +#include "usCoreConfig.h" #include #include US_BEGIN_NAMESPACE /** * \ingroup MicroServices * * Query and set certain properties of the CppMicroServices library. * * The following environment variables influence the runtime behavior * of the CppMicroServices library: * * - \e US_DISABLE_AUTOLOADING If set, auto-loading of modules is disabled. * - \e US_AUTOLOAD_PATHS A ':' (Unix) or ';' (Windows) separated list of paths * from which modules should be auto-loaded. * * \remarks This class is thread safe. */ -class US_EXPORT ModuleSettings +class US_Core_EXPORT ModuleSettings { public: typedef std::vector PathList; /** * Returns a special string which can be used as an argument for a * AddAutoLoadPath() call. * * When a module is loaded and this string has been added as a path * to the list of auto-load paths the CppMicroServices library will * auto-load all modules from the currently being loaded module's * auto-load directory. * * \return A string to be used in AddAutoLoadPath(). * * \remarks The returned string is contained in the default set of * auto-load paths, unless a new set of paths is given by a call to * SetAutoLoadPaths(). * * \sa MicroServices_AutoLoading * \sa US_INITIALIZE_MODULE */ static std::string CURRENT_MODULE_PATH(); /** * \return \c true if threading support has been configured into the * CppMicroServices library, \c false otherwise. */ static bool IsThreadingSupportEnabled(); /** * \return \c true if support for module auto-loading is enabled, * \c false otherwise. * * \remarks This method will always return \c false if support for auto-loading * has not been configured into the CppMicroServices library or if it has been * disabled by defining the US_DISABLE_AUTOLOADING environment variable. */ static bool IsAutoLoadingEnabled(); /** * Enable or disable auto-loading support. * * \param enable If \c true, enable auto-loading support, disable it otherwise. * * \remarks Calling this method will have no effect if support for * auto-loading has not been configured into the CppMicroServices library of it * it has been disabled by defining the US_DISABLE_AUTOLOADING envrionment variable. */ static void SetAutoLoadingEnabled(bool enable); /** * \return A list of paths in the file-system from which modules will be * auto-loaded. */ static PathList GetAutoLoadPaths(); /** * Set a list of paths in the file-system from which modules should be * auto-loaded. * @param paths A list of absolute file-system paths. */ static void SetAutoLoadPaths(const PathList& paths); /** * Add a path in the file-system to the list of paths from which modules * will be auto-loaded. * * @param path The additional absolute auto-load path in the file-system. */ static void AddAutoLoadPath(const std::string& path); /** * Set a local storage path for persistend module data. * * This path is used as a base directory for providing modules * with a storage path for writing persistent data. The callee * must ensure that the provided path exists and is writable. * * @see ModuleContext::GetDataFile(const std::string&) * * @param path An absolute path for writing persistent data. */ static void SetStoragePath(const std::string& path); /** * Get the absolute path for persistent data. The returned path * might be empty. If the path is non-empty, it is safe to assume * that the path exists and is writable. * * @return The absolute path to the persistent storage path. */ static std::string GetStoragePath(); private: // purposely not implemented ModuleSettings(); ModuleSettings(const ModuleSettings&); ModuleSettings& operator=(const ModuleSettings&); }; US_END_NAMESPACE #endif // USMODULESETTINGS_H diff --git a/src/module/usModuleVersion.h b/core/include/usModuleVersion.h similarity index 97% rename from src/module/usModuleVersion.h rename to core/include/usModuleVersion.h index 930dc724c1..fc5e9ef2aa 100644 --- a/src/module/usModuleVersion.h +++ b/core/include/usModuleVersion.h @@ -1,263 +1,263 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEVERSION_H #define USMODULEVERSION_H -#include +#include #include #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4251) #endif US_BEGIN_NAMESPACE /** * \ingroup MicroServices * * Version identifier for CppMicroServices modules. * *

* Version identifiers have four components. *

    *
  1. Major version. A non-negative integer.
  2. *
  3. Minor version. A non-negative integer.
  4. *
  5. Micro version. A non-negative integer.
  6. *
  7. Qualifier. A text string. See ModuleVersion(const std::string&) for the * format of the qualifier string.
  8. *
* *

* ModuleVersion objects are immutable. */ -class US_EXPORT ModuleVersion { +class US_Core_EXPORT ModuleVersion { private: friend class ModulePrivate; unsigned int majorVersion; unsigned int minorVersion; unsigned int microVersion; std::string qualifier; static const char SEPARATOR; // = "." bool undefined; /** * Called by the ModuleVersion constructors to validate the version components. * * @return true if the validation was successfull, false otherwise. */ void Validate(); ModuleVersion& operator=(const ModuleVersion& v); explicit ModuleVersion(bool undefined = false); public: /** * The empty version "0.0.0". */ static ModuleVersion EmptyVersion(); /** * Creates an undefined version identifier, representing either * infinity or minus infinity. */ static ModuleVersion UndefinedVersion(); /** * Creates a version identifier from the specified numerical components. * *

* The qualifier is set to the empty string. * * @param majorVersion Major component of the version identifier. * @param minorVersion Minor component of the version identifier. * @param microVersion Micro component of the version identifier. * */ ModuleVersion(unsigned int majorVersion, unsigned int minorVersion, unsigned int microVersion); /** * Creates a version identifier from the specified components. * * @param majorVersion Major component of the version identifier. * @param minorVersion Minor component of the version identifier. * @param microVersion Micro component of the version identifier. * @param qualifier Qualifier component of the version identifier. */ ModuleVersion(unsigned int majorVersion, unsigned int minorVersion, unsigned int microVersion, const std::string& qualifier); /** * Created a version identifier from the specified string. * *

* Here is the grammar for version strings. * *

    * version ::= majorVersion('.'minorVersion('.'microVersion('.'qualifier)?)?)?
    * majorVersion ::= digit+
    * minorVersion ::= digit+
    * microVersion ::= digit+
    * qualifier ::= (alpha|digit|'_'|'-')+
    * digit ::= [0..9]
    * alpha ::= [a..zA..Z]
    * 
* * There must be no whitespace in version. * * @param version string representation of the version identifier. */ ModuleVersion(const std::string& version); /** * Create a version identifier from another. * * @param version Another version identifier */ ModuleVersion(const ModuleVersion& version); /** * Parses a version identifier from the specified string. * *

* See ModuleVersion(const std::string&) for the format of the version string. * * @param version string representation of the version identifier. Leading * and trailing whitespace will be ignored. * @return A ModuleVersion object representing the version * identifier. If version is the empty string * then EmptyVersion will be * returned. */ static ModuleVersion ParseVersion(const std::string& version); /** * Returns the undefined state of this version identifier. * * @return true if this version identifier is undefined, * false otherwise. */ bool IsUndefined() const; /** * Returns the majorVersion component of this version identifier. * * @return The majorVersion component. */ unsigned int GetMajor() const; /** * Returns the minorVersion component of this version identifier. * * @return The minorVersion component. */ unsigned int GetMinor() const; /** * Returns the microVersion component of this version identifier. * * @return The microVersion component. */ unsigned int GetMicro() const; /** * Returns the qualifier component of this version identifier. * * @return The qualifier component. */ std::string GetQualifier() const; /** * Returns the string representation of this version identifier. * *

* The format of the version string will be majorVersion.minorVersion.microVersion * if qualifier is the empty string or * majorVersion.minorVersion.microVersion.qualifier otherwise. * * @return The string representation of this version identifier. */ std::string ToString() const; /** * Compares this ModuleVersion object to another object. * *

* A version is considered to be equal to another version if the * majorVersion, minorVersion and microVersion components are equal and the qualifier component * is equal. * * @param object The ModuleVersion object to be compared. * @return true if object is a * ModuleVersion and is equal to this object; * false otherwise. */ bool operator==(const ModuleVersion& object) const; /** * Compares this ModuleVersion object to another object. * *

* A version is considered to be less than another version if its * majorVersion component is less than the other version's majorVersion component, or the * majorVersion components are equal and its minorVersion component is less than the other * version's minorVersion component, or the majorVersion and minorVersion components are equal * and its microVersion component is less than the other version's microVersion component, * or the majorVersion, minorVersion and microVersion components are equal and it's qualifier * component is less than the other version's qualifier component (using * std::string::operator<()). * *

* A version is considered to be equal to another version if the * majorVersion, minorVersion and microVersion components are equal and the qualifier component * is equal. * * @param object The ModuleVersion object to be compared. * @return A negative integer, zero, or a positive integer if this object is * less than, equal to, or greater than the specified * ModuleVersion object. */ int Compare(const ModuleVersion& object) const; }; US_END_NAMESPACE #ifdef _MSC_VER # pragma warning(pop) #endif /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleVersion)& v); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ModuleVersion)& v); #endif // USMODULEVERSION_H diff --git a/src/service/usPrototypeServiceFactory.h b/core/include/usPrototypeServiceFactory.h similarity index 100% rename from src/service/usPrototypeServiceFactory.h rename to core/include/usPrototypeServiceFactory.h diff --git a/src/service/usServiceEvent.h b/core/include/usServiceEvent.h similarity index 95% rename from src/service/usServiceEvent.h rename to core/include/usServiceEvent.h index e1f5b91ae0..99e3aaec12 100644 --- a/src/service/usServiceEvent.h +++ b/core/include/usServiceEvent.h @@ -1,197 +1,197 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEEVENT_H #define USSERVICEEVENT_H #ifdef REGISTERED #ifdef _WIN32 #error The REGISTERED preprocessor define clashes with the ServiceEvent::REGISTERED\ enum type. Try to reorder your includes, compile with WIN32_LEAN_AND_MEAN, or undef\ the REGISTERED macro befor including this header. #else #error The REGISTERED preprocessor define clashes with the ServiceEvent::REGISTERED\ enum type. Try to reorder your includes or undef the REGISTERED macro befor including\ this header. #endif #endif #include "usSharedData.h" #include "usServiceReference.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4251) #endif US_BEGIN_NAMESPACE class ServiceEventData; /** * \ingroup MicroServices * * An event from the Micro Services framework describing a service lifecycle change. *

* ServiceEvent objects are delivered to * listeners connected via ModuleContext::AddServiceListener() when a * change occurs in this service's lifecycle. A type code is used to identify * the event type for future extendability. */ -class US_EXPORT ServiceEvent +class US_Core_EXPORT ServiceEvent { SharedDataPointer d; public: enum Type { /** * This service has been registered. *

* This event is delivered after the service * has been registered with the framework. * * @see ModuleContext#RegisterService() */ REGISTERED = 0x00000001, /** * The properties of a registered service have been modified. *

* This event is delivered after the service * properties have been modified. * * @see ServiceRegistration#SetProperties */ MODIFIED = 0x00000002, /** * This service is in the process of being unregistered. *

* This event is delivered before the service * has completed unregistering. * *

* If a module is using a service that is UNREGISTERING, the * module should release its use of the service when it receives this event. * If the module does not release its use of the service when it receives * this event, the framework will automatically release the module's use of * the service while completing the service unregistration operation. * * @see ServiceRegistration#Unregister * @see ModuleContext#UngetService */ UNREGISTERING = 0x00000004, /** * The properties of a registered service have been modified and the new * properties no longer match the listener's filter. *

* This event is delivered after the service * properties have been modified. This event is only delivered to listeners * which were added with a non-empty filter where the filter * matched the service properties prior to the modification but the filter * does not match the modified service properties. * * @see ServiceRegistration#SetProperties */ MODIFIED_ENDMATCH = 0x00000008 }; /** * Creates an invalid instance. */ ServiceEvent(); ~ServiceEvent(); /** * Can be used to check if this ServiceEvent instance is valid, * or if it has been constructed using the default constructor. * * @return true if this event object is valid, * false otherwise. */ bool IsNull() const; /** * Creates a new service event object. * * @param type The event type. * @param reference A ServiceReference object to the service * that had a lifecycle change. */ ServiceEvent(Type type, const ServiceReferenceBase& reference); ServiceEvent(const ServiceEvent& other); ServiceEvent& operator=(const ServiceEvent& other); /** * Returns a reference to the service that had a change occur in its * lifecycle. *

* This reference is the source of the event. * * @return Reference to the service that had a lifecycle change. */ ServiceReferenceU GetServiceReference() const; template ServiceReference GetServiceReference(InterfaceType) const { return GetServiceReference(); } /** * Returns the type of event. The event type values are: *

    *
  • {@link #REGISTERED}
  • *
  • {@link #MODIFIED}
  • *
  • {@link #MODIFIED_ENDMATCH}
  • *
  • {@link #UNREGISTERING}
  • *
* * @return Type of service lifecycle change. */ Type GetType() const; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif /** * \ingroup MicroServices * @{ */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceEvent::Type)& type); -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceEvent)& event); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceEvent::Type)& type); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceEvent)& event); /** @}*/ #endif // USSERVICEEVENT_H diff --git a/src/service/usServiceEventListenerHook.h b/core/include/usServiceEventListenerHook.h similarity index 98% rename from src/service/usServiceEventListenerHook.h rename to core/include/usServiceEventListenerHook.h index b69a63d69c..127a7aaf19 100644 --- a/src/service/usServiceEventListenerHook.h +++ b/core/include/usServiceEventListenerHook.h @@ -1,72 +1,72 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEEVENTLISTENERHOOK_H #define USSERVICEEVENTLISTENERHOOK_H #include "usServiceInterface.h" #include "usServiceListenerHook.h" #include "usShrinkableVector.h" #include "usShrinkableMap.h" US_BEGIN_NAMESPACE class ModuleContext; class ServiceEvent; /** * @ingroup MicroServices * * Service Event Listener Hook Service. * *

* Modules registering this service will be called during service * (register, modify, and unregister service) operations. * * @remarks Implementations of this interface are required to be thread-safe. */ -struct US_EXPORT ServiceEventListenerHook +struct US_Core_EXPORT ServiceEventListenerHook { typedef ShrinkableMap > ShrinkableMapType; virtual ~ServiceEventListenerHook(); /** * Event listener hook method. This method is called prior to service event * delivery when a publishing module registers, modifies or unregisters a * service. This method can filter the listeners which receive the event. * * @param event The service event to be delivered. * @param listeners A map of Module Contexts to a list of Listener * Infos for the module's listeners to which the specified event will * be delivered. The implementation of this method may remove module * contexts from the map and listener infos from the list * values to prevent the event from being delivered to the associated * listeners. */ virtual void Event(const ServiceEvent& event, ShrinkableMapType& listeners) = 0; }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(us::ServiceEventListenerHook, "org.cppmicroservices.ServiceEventListenerHook/2.0.0") #endif // USSERVICEEVENTLISTENERHOOK_H diff --git a/src/service/usServiceException.h b/core/include/usServiceException.h similarity index 93% rename from src/service/usServiceException.h rename to core/include/usServiceException.h index 210697801b..467b24327e 100644 --- a/src/service/usServiceException.h +++ b/core/include/usServiceException.h @@ -1,126 +1,126 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEEXCEPTION_H #define USSERVICEEXCEPTION_H #include -#include +#include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4275) #endif US_BEGIN_NAMESPACE /** * \ingroup MicroServices * * A service exception used to indicate that a service problem occurred. * *

* A ServiceException object is created by the framework or * to denote an exception condition in the service. An enum * type is used to identify the exception type for future extendability. * *

* This exception conforms to the general purpose exception chaining mechanism. */ -class US_EXPORT ServiceException : public std::runtime_error +class US_Core_EXPORT ServiceException : public std::runtime_error { public: enum Type { /** * No exception type is unspecified. */ UNSPECIFIED = 0, /** * The service has been unregistered. */ UNREGISTERED = 1, /** * The service factory produced an invalid service object. */ FACTORY_ERROR = 2, /** * The service factory threw an exception. */ FACTORY_EXCEPTION = 3, /** * An error occurred invoking a remote service. */ REMOTE = 5, /** * The service factory resulted in a recursive call to itself for the * requesting module. */ FACTORY_RECURSION = 6 }; /** * Creates a ServiceException with the specified message, * type and exception cause. * * @param msg The associated message. * @param type The type for this exception. */ ServiceException(const std::string& msg, const Type& type = UNSPECIFIED); ServiceException(const ServiceException& o); ServiceException& operator=(const ServiceException& o); ~ServiceException() throw() { } /** * Returns the type for this exception or UNSPECIFIED if the * type was unspecified or unknown. * * @return The type of this exception. */ Type GetType() const; private: /** * Type of service exception. */ Type type; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif /** * \ingroup MicroServices * @{ */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceException)& exc); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceException)& exc); /** @}*/ #endif // USSERVICEEXCEPTION_H diff --git a/src/service/usServiceFactory.h b/core/include/usServiceFactory.h similarity index 100% rename from src/service/usServiceFactory.h rename to core/include/usServiceFactory.h diff --git a/src/service/usServiceFindHook.h b/core/include/usServiceFindHook.h similarity index 98% rename from src/service/usServiceFindHook.h rename to core/include/usServiceFindHook.h index 8463263fa9..a3940887f3 100644 --- a/src/service/usServiceFindHook.h +++ b/core/include/usServiceFindHook.h @@ -1,76 +1,76 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEFINDHOOK_H #define USSERVICEFINDHOOK_H #include "usServiceInterface.h" #include "usShrinkableVector.h" #include US_BEGIN_NAMESPACE class Module; class ModuleContext; class ServiceReferenceBase; /** * @ingroup MicroServices * * Service Find Hook Service. * *

* Modules registering this service will be called during service find * (get service references) operations. * * @remarks Implementations of this interface are required to be thread-safe. */ -struct US_EXPORT ServiceFindHook +struct US_Core_EXPORT ServiceFindHook { virtual ~ServiceFindHook(); /** * Find hook method. This method is called during the service find operation * (for example, ModuleContext::GetServiceReferences()). This method can * filter the result of the find operation. * * @param context The module context of the module performing the find * operation. * @param name The class name of the services to find or an empty string to * find all services. * @param filter The filter criteria of the services to find or an empty string * for no filter criteria. * @param references A list of Service References to be returned as a result of the * find operation. The implementation of this method may remove * service references from the list to prevent the references from being * returned to the module performing the find operation. */ virtual void Find(const ModuleContext* context, const std::string& name, const std::string& filter, ShrinkableVector& references) = 0; }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(us::ServiceFindHook, "org.cppmicroservices.ServiceFindHook/2.0.0") #endif // USSERVICEFINDHOOK_H diff --git a/src/service/usServiceInterface.h b/core/include/usServiceInterface.h similarity index 99% rename from src/service/usServiceInterface.h rename to core/include/usServiceInterface.h index 5e1ab39e5d..b9638b9a28 100644 --- a/src/service/usServiceInterface.h +++ b/core/include/usServiceInterface.h @@ -1,342 +1,342 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEINTERFACE_H #define USSERVICEINTERFACE_H -#include +#include #include #include #include #include /** * \ingroup MicroServices * * Returns a unique id for a given type. * * This template method is specialized in the macro * #US_DECLARE_SERVICE_INTERFACE to return a unique id * for each service interface. * * @tparam T The service interface type. * @return A unique id for the service interface type T. */ template inline const char* us_service_interface_iid(); /// \cond template<> inline const char* us_service_interface_iid() { return ""; } /// \endcond #if defined(QT_DEBUG) || defined(QT_NO_DEBUG) #include #define US_DECLARE_SERVICE_INTERFACE(_service_interface_type, _service_interface_id) \ template<> inline const char* qobject_interface_iid<_service_interface_type*>() \ { return _service_interface_id; } \ template<> inline const char* us_service_interface_iid<_service_interface_type>() \ { return _service_interface_id; } \ template<> inline _service_interface_type* qobject_cast<_service_interface_type*>(QObject* object) \ { return reinterpret_cast<_service_interface_type*>(object ? object->qt_metacast(_service_interface_id) : 0); } \ template<> inline _service_interface_type* qobject_cast<_service_interface_type*>(const QObject* object) \ { return reinterpret_cast<_service_interface_type*>(object ? const_cast(object)->qt_metacast(_service_interface_id) : 0); } #else /** * \ingroup MicroServices * * \brief Declare a CppMicroServices service interface. * * This macro associates the given identifier \e _service_interface_id (a string literal) to the * interface class called _service_interface_type. The Identifier must be unique. For example: * * \code * #include * * struct ISomeInterace { ... }; * * US_DECLARE_SERVICE_INTERFACE(ISomeInterface, "com.mycompany.service.ISomeInterface/1.0") * \endcode * * This macro is normally used right after the class definition for _service_interface_type, in a header file. * * If you want to use #US_DECLARE_SERVICE_INTERFACE with interface classes declared in a * namespace then you have to make sure the #US_DECLARE_SERVICE_INTERFACE macro call is not * inside a namespace though. For example: * * \code * #include * * namespace Foo * { * struct ISomeInterface { ... }; * } * * US_DECLARE_SERVICE_INTERFACE(Foo::ISomeInterface, "com.mycompany.service.ISomeInterface/1.0") * \endcode * * @param _service_interface_type The service interface type. * @param _service_interface_id A string literal representing a globally unique identifier. */ #define US_DECLARE_SERVICE_INTERFACE(_service_interface_type, _service_interface_id) \ template<> inline const char* us_service_interface_iid<_service_interface_type>() \ { return _service_interface_id; } \ #endif US_BEGIN_NAMESPACE class ServiceFactory; /** * @ingroup MicroServices * * A helper type used in several methods to get proper * method overload resolutions. */ template struct InterfaceType {}; /** * @ingroup MicroServices * * A map containing interfaces ids and their corresponding service object * pointers. InterfaceMap instances represent a complete service object * which implementes one or more service interfaces. For each implemented * service interface, there is an entry in the map with the key being * the service interface id and the value a pointer to the service * interface implementation. * * To create InterfaceMap instances, use the MakeInterfaceMap helper class. * * @note This is a low-level type and should only rarely be used. * * @see MakeInterfaceMap */ typedef std::map InterfaceMap; template bool InsertInterfaceType(InterfaceMap& im, I* i) { if (us_service_interface_iid() == NULL) { throw ServiceException(std::string("The interface class ") + typeid(I).name() + " uses an invalid id in its US_DECLARE_SERVICE_INTERFACE macro call."); } im.insert(std::make_pair(std::string(us_service_interface_iid()), static_cast(static_cast(i)))); return true; } template<> inline bool InsertInterfaceType(InterfaceMap&, void*) { return false; } /** * @ingroup MicroServices * * Helper class for constructing InterfaceMap instances based * on service implementations or service factories. * * Example usage: * \code * MyService service; // implementes I1 and I2 * InterfaceMap im = MakeInterfaceMap(&service); * \endcode * * The MakeInterfaceMap supports service implementations with * up to three service interfaces. * * @see InterfaceMap */ template struct MakeInterfaceMap { ServiceFactory* m_factory; I1* m_interface1; I2* m_interface2; I3* m_interface3; /** * Constructor taking a service implementation pointer. * * @param impl A service implementation pointer, which must * be castable to a all specified service interfaces. */ template MakeInterfaceMap(Impl* impl) : m_factory(NULL) , m_interface1(static_cast(impl)) , m_interface2(static_cast(impl)) , m_interface3(static_cast(impl)) {} /** * Constructor taking a service factory. * * @param factory A service factory. */ MakeInterfaceMap(ServiceFactory* factory) : m_factory(factory) , m_interface1(NULL) , m_interface2(NULL) , m_interface3(NULL) { if (factory == NULL) { throw ServiceException("The service factory argument must not be NULL."); } } operator InterfaceMap () { InterfaceMap sim; InsertInterfaceType(sim, m_interface1); InsertInterfaceType(sim, m_interface2); InsertInterfaceType(sim, m_interface3); if (m_factory) { sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"), static_cast(m_factory))); } return sim; } }; /// \cond template struct MakeInterfaceMap { ServiceFactory* m_factory; I1* m_interface1; I2* m_interface2; template MakeInterfaceMap(Impl* impl) : m_factory(NULL) , m_interface1(static_cast(impl)) , m_interface2(static_cast(impl)) {} MakeInterfaceMap(ServiceFactory* factory) : m_factory(factory) , m_interface1(NULL) , m_interface2(NULL) { if (factory == NULL) { throw ServiceException("The service factory argument must not be NULL."); } } operator InterfaceMap () { InterfaceMap sim; InsertInterfaceType(sim, m_interface1); InsertInterfaceType(sim, m_interface2); if (m_factory) { sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"), static_cast(m_factory))); } return sim; } }; template struct MakeInterfaceMap { ServiceFactory* m_factory; I1* m_interface1; template MakeInterfaceMap(Impl* impl) : m_factory(NULL) , m_interface1(static_cast(impl)) {} MakeInterfaceMap(ServiceFactory* factory) : m_factory(factory) , m_interface1(NULL) { if (factory == NULL) { throw ServiceException("The service factory argument must not be NULL."); } } operator InterfaceMap () { InterfaceMap sim; InsertInterfaceType(sim, m_interface1); if (m_factory) { sim.insert(std::make_pair(std::string("org.cppmicroservices.factory"), static_cast(m_factory))); } return sim; } }; template<> struct MakeInterfaceMap; /// \endcond /** * @ingroup MicroServices * * Extract a service interface pointer from a given InterfaceMap instance. * * @param map a InterfaceMap instance. * @return The service interface pointer for the service interface id of the * \c I1 interface type or NULL if \c map does not contain an entry * for the given type. * * @see MakeInterfaceMap */ template I1* ExtractInterface(const InterfaceMap& map) { InterfaceMap::const_iterator iter = map.find(us_service_interface_iid()); if (iter != map.end()) { return reinterpret_cast(iter->second); } return NULL; } US_END_NAMESPACE #endif // USSERVICEINTERFACE_H diff --git a/src/service/usServiceListenerHook.h b/core/include/usServiceListenerHook.h similarity index 98% rename from src/service/usServiceListenerHook.h rename to core/include/usServiceListenerHook.h index 081253c192..6fd3598e12 100644 --- a/src/service/usServiceListenerHook.h +++ b/core/include/usServiceListenerHook.h @@ -1,176 +1,176 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICELISTENERHOOK_H #define USSERVICELISTENERHOOK_H #include "usServiceInterface.h" #include "usShrinkableVector.h" #include "usSharedData.h" #include US_BEGIN_NAMESPACE class ModuleContext; class ServiceListenerEntry; /** * @ingroup MicroServices * * Service Listener Hook Service. * *

* Modules registering this service will be called during service listener * addition and removal. * * @remarks Implementations of this interface are required to be thread-safe. */ -struct US_EXPORT ServiceListenerHook +struct US_Core_EXPORT ServiceListenerHook { class ListenerInfoData; /** * Information about a Service Listener. This class describes the module * which added the Service Listener and the filter with which it was added. * * @remark This class is not intended to be implemented by clients. */ - struct US_EXPORT ListenerInfo + struct US_Core_EXPORT ListenerInfo { ListenerInfo(); ListenerInfo(const ListenerInfo& other); ~ListenerInfo(); ListenerInfo& operator=(const ListenerInfo& other); /** * Can be used to check if this ListenerInfo instance is valid, * or if it has been constructed using the default constructor. * * @return true if this listener object is valid, * false otherwise. */ bool IsNull() const; /** * Return the context of the module which added the listener. * * @return The context of the module which added the listener. */ ModuleContext* GetModuleContext() const; /** * Return the filter string with which the listener was added. * * @return The filter string with which the listener was added. This may * be empty if the listener was added without a filter. */ std::string GetFilter() const; /** * Return the state of the listener for this addition and removal life * cycle. Initially this method will return \c false indicating the * listener has been added but has not been removed. After the listener * has been removed, this method must always returns \c true. * *

* There is an extremely rare case in which removed notification to * {@link ServiceListenerHook}s can be made before added notification if two * threads are racing to add and remove the same service listener. * Because {@link ServiceListenerHook}s are called synchronously during service * listener addition and removal, the CppMicroServices library cannot guarantee * in-order delivery of added and removed notification for a given * service listener. This method can be used to detect this rare * occurrence. * * @return \c false if the listener has not been been removed, * \c true otherwise. */ bool IsRemoved() const; /** * Compares this \c ListenerInfo to another \c ListenerInfo. * Two {@code ListenerInfo}s are equal if they refer to the same * listener for a given addition and removal life cycle. If the same * listener is added again, it will have a different * \c ListenerInfo which is not equal to this \c ListenerInfo. * * @param other The object to compare against this \c ListenerInfo. * @return \c true if the other object is a \c ListenerInfo * object and both objects refer to the same listener for a * given addition and removal life cycle. */ bool operator==(const ListenerInfo& other) const; private: friend class ServiceListenerEntry; US_HASH_FUNCTION_FRIEND(ServiceListenerHook::ListenerInfo); ListenerInfo(ListenerInfoData* data); ExplicitlySharedDataPointer d; }; virtual ~ServiceListenerHook(); /** * Added listeners hook method. This method is called to provide the hook * implementation with information on newly added service listeners. This * method will be called as service listeners are added while this hook is * registered. Also, immediately after registration of this hook, this * method will be called to provide the current collection of service * listeners which had been added prior to the hook being registered. * * @param listeners A collection of \c ListenerInfo objects for newly added * service listeners which are now listening to service events. */ virtual void Added(const std::vector& listeners) = 0; /** * Removed listeners hook method. This method is called to provide the hook * implementation with information on newly removed service listeners. This * method will be called as service listeners are removed while this hook is * registered. * * @param listeners A collection of \c ListenerInfo objects for newly removed * service listeners which are no longer listening to service events. */ virtual void Removed(const std::vector& listeners) = 0; }; US_END_NAMESPACE US_HASH_FUNCTION_NAMESPACE_BEGIN US_HASH_FUNCTION_BEGIN(US_PREPEND_NAMESPACE(ServiceListenerHook::ListenerInfo)) return US_HASH_FUNCTION(const US_PREPEND_NAMESPACE(ServiceListenerHook::ListenerInfoData)*, arg.d.Data()); US_HASH_FUNCTION_END US_HASH_FUNCTION_NAMESPACE_END US_DECLARE_SERVICE_INTERFACE(us::ServiceListenerHook, "org.cppmicroservices.ServiceListenerHook/2.0.0") #endif // USSERVICELISTENERHOOK_H diff --git a/src/service/usServiceObjects.h b/core/include/usServiceObjects.h similarity index 98% rename from src/service/usServiceObjects.h rename to core/include/usServiceObjects.h index f0db27accd..ae4fe9826f 100644 --- a/src/service/usServiceObjects.h +++ b/core/include/usServiceObjects.h @@ -1,259 +1,259 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEOBJECTS_H #define USSERVICEOBJECTS_H -#include +#include #include #include #include #include US_BEGIN_NAMESPACE class ServiceObjectsBasePrivate; -class US_EXPORT ServiceObjectsBase +class US_Core_EXPORT ServiceObjectsBase { private: ServiceObjectsBasePrivate* d; protected: ServiceObjectsBase(ModuleContext* context, const ServiceReferenceBase& reference); ServiceObjectsBase(const ServiceObjectsBase& other); ~ServiceObjectsBase(); ServiceObjectsBase& operator=(const ServiceObjectsBase& other); // Called by ServiceObjects with S != void void* GetService() const; // Called by the ServiceObjects specialization InterfaceMap GetServiceInterfaceMap() const; // Called by ServiceObjects with S != void void UngetService(void* service); // Called by the ServiceObjects specialization void UngetService(const InterfaceMap& interfaceMap); ServiceReferenceBase GetReference() const; }; /** * @ingroup MicroServices * * Allows multiple service objects for a service to be obtained. * * For services with \link ServiceConstants::SCOPE_PROTOTYPE prototype\endlink scope, * multiple service objects for the service can be obtained. For services with * \link ServiceConstants::SCOPE_SINGLETON singleton\endlink or * \link ServiceConstants::SCOPE_MODULE module \endlink scope, only one, use-counted * service object is available. Any unreleased service objects obtained from this * ServiceObjects object are automatically released by the framework when the modules * associated with the ModuleContext used to create this ServiceObjects object is * stopped. * * @tparam S Type of Service. */ template class ServiceObjects : private ServiceObjectsBase { public: /** * Returns a service object for the referenced service. * * This ServiceObjects object can be used to obtain multiple service objects for * the referenced service if the service has \link ServiceConstants::SCOPE_PROTOTYPE prototype\endlink * scope. If the referenced service has \link ServiceConstants::SCOPE_SINGLETON singleton\endlink * or \link ServiceConstants::SCOPE_MODULE module\endlink scope, this method * behaves the same as calling the ModuleContext::GetService(const ServiceReferenceBase&) * method for the referenced service. That is, only one, use-counted service object * is available from this ServiceObjects object. * * This method will always return \c NULL when the referenced service has been unregistered. * * For a prototype scope service, the following steps are taken to get the service object: * *

    *
  1. If the referenced service has been unregistered, \c NULL is returned.
  2. *
  3. The PrototypeServiceFactory::GetService(Module*, const ServiceRegistrationBase&) * method is called to create a service object for the caller.
  4. *
  5. If the service object (an instance of InterfaceMap) returned by the * PrototypeServiceFactory object is empty, does not contain all the interfaces * named when the service was registered or the PrototypeServiceFactory object * throws an exception, \c NULL is returned and a warning message is issued.
  6. *
  7. The service object is returned.
  8. *
* * @return A service object for the referenced service or \c NULL if the service is not * registered, the service object returned by a ServiceFactory does not contain * all the classes under which it was registered or the ServiceFactory threw an * exception. * * @throw std::logic_error If the ModuleContext used to create this ServiceObjects object * is no longer valid. * * @see UngetService() */ S* GetService() const { return reinterpret_cast(this->ServiceObjectsBase::GetService()); } /** * Releases a service object for the referenced service. * * This ServiceObjects object can be used to obtain multiple service objects for * the referenced service if the service has \link ServiceConstants::SCOPE_PROTOTYPE prototype\endlink * scope. If the referenced service has \link ServiceConstants::SCOPE_SINGLETON singleton\endlink * or \link ServiceConstants::SCOPE_MODULE module\endlink scope, this method * behaves the same as calling the ModuleContext::UngetService(const ServiceReferenceBase&) * method for the referenced service. That is, only one, use-counted service object * is available from this ServiceObjects object. * * For a prototype scope service, the following steps are take to release the service object: * *
    *
  1. If the referenced service has been unregistered, this method returns without * doing anything.
  2. *
  3. The PrototypeServiceFactory::UngetService(Module*, const ServiceRegistrationBase&, const InterfaceMap&) * method is called to release the specified service object.
  4. *
  5. The specified service object must no longer be used and all references to it * should be destroyed after calling this method.
  6. *
* * @param service A service object previously provided by this ServiceObjects object. * * @throw std::logic_error If the ModuleContext used to create this ServiceObjects * object is no longer valid. * @throw std::invalid_argument If the specified service was not provided by this * ServiceObjects object. * * @see GetService() */ void UngetService(S* service) { this->ServiceObjectsBase::UngetService(service); } /** * Returns the ServiceReference for this ServiceObjects object. * * @return The ServiceReference for this ServiceObjects object. */ ServiceReference GetServiceReference() const { return this->ServiceObjectsBase::GetReference(); } private: friend class ModuleContext; ServiceObjects(ModuleContext* context, const ServiceReference& reference) : ServiceObjectsBase(context, reference) {} }; /** * @ingroup MicroServices * * Allows multiple service objects for a service to be obtained. * * This is a specialization of the ServiceObjects class template for * "void", which maps to all service interface types. * * @see ServiceObjects */ template<> -class US_EXPORT ServiceObjects : private ServiceObjectsBase +class US_Core_EXPORT ServiceObjects : private ServiceObjectsBase { public: /** * Returns a service object as a InterfaceMap instance for the referenced service. * * This method is the same as ServiceObjects::GetService() except for the * return type. Further, this method will always return an empty InterfaeMap * object when the referenced service has been unregistered. * * @return A InterfaceMap object for the referenced service, which is empty if the * service is not registered, the InterfaceMap returned by a ServiceFactory * does not contain all the classes under which the service object was * registered or the ServiceFactory threw an exception. * * @throw std::logic_error If the ModuleContext used to create this ServiceObjects object * is no longer valid. * * @see ServiceObjects::GetService() * @see UngetService() */ InterfaceMap GetService() const; /** * Releases a service object for the referenced service. * * This method is the same as ServiceObjects::UngetService() except for the * parameter type. * * @param service An InterfaceMap object previously provided by this ServiceObjects object. * * @throw std::logic_error If the ModuleContext used to create this ServiceObjects * object is no longer valid. * @throw std::invalid_argument If the specified service was not provided by this * ServiceObjects object. * * @see ServiceObjects::UngetService() * @see GetService() */ void UngetService(const InterfaceMap& service); /** * Returns the ServiceReference for this ServiceObjects object. * * @return The ServiceReference for this ServiceObjects object. */ ServiceReferenceU GetServiceReference() const; private: friend class ModuleContext; ServiceObjects(ModuleContext* context, const ServiceReferenceU& reference); }; US_END_NAMESPACE #endif // USSERVICEOBJECTS_H diff --git a/src/service/usServiceProperties.h b/core/include/usServiceProperties.h similarity index 88% rename from src/service/usServiceProperties.h rename to core/include/usServiceProperties.h index 208d84ea77..9a443b2c17 100644 --- a/src/service/usServiceProperties.h +++ b/core/include/usServiceProperties.h @@ -1,138 +1,138 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef US_SERVICE_PROPERTIES_H #define US_SERVICE_PROPERTIES_H -#include +#include #include #include "usAny.h" US_BEGIN_NAMESPACE /** * \ingroup MicroServices * * A hash table with std::string as the key type and Any as the value * type. It is typically used for passing service properties to * ModuleContext::RegisterService. */ typedef US_UNORDERED_MAP_TYPE ServiceProperties; /** * \ingroup MicroServices */ namespace ServiceConstants { /** * Service property identifying all of the class names under which a service * was registered in the framework. The value of this property must be of * type std::vector<std::string>. * *

* This property is set by the framework when a service is registered. */ -US_EXPORT const std::string& OBJECTCLASS(); // = "objectclass" +US_Core_EXPORT const std::string& OBJECTCLASS(); // = "objectclass" /** * Service property identifying a service's registration number. The value * of this property must be of type long int. * *

* The value of this property is assigned by the framework when a service is * registered. The framework assigns a unique value that is larger than all * previously assigned values since the framework was started. These values * are NOT persistent across restarts of the framework. */ -US_EXPORT const std::string& SERVICE_ID(); // = "service.id" +US_Core_EXPORT const std::string& SERVICE_ID(); // = "service.id" /** * Service property identifying a service's ranking number. * *

* This property may be supplied in the * ServiceProperties object passed to the * ModuleContext::RegisterService method. The value of this * property must be of type int. * *

* The service ranking is used by the framework to determine the natural * order of services, see ServiceReference::operator<(const ServiceReference&), * and the default service to be returned from a call to the * {@link ModuleContext::GetServiceReference} method. * *

* The default ranking is zero (0). A service with a ranking of * std::numeric_limits::max() is very likely to be returned as the * default service, whereas a service with a ranking of * std::numeric_limits::min() is very unlikely to be returned. * *

* If the supplied property value is not of type int, it is * deemed to have a ranking value of zero. */ -US_EXPORT const std::string& SERVICE_RANKING(); // = "service.ranking" +US_Core_EXPORT const std::string& SERVICE_RANKING(); // = "service.ranking" /** * Service property identifying a service's scope. * This property is set by the framework when a service is registered. If the * registered object implements PrototypeServiceFactory, then the value of this * service property will be SCOPE_PROTOTYPE(). Otherwise, if the registered * object implements ServiceFactory, then the value of this service property will * be SCOPE_MODULE(). Otherwise, the value of this service property will be * SCOPE_SINGLETON(). */ -US_EXPORT const std::string& SERVICE_SCOPE(); // = "service.scope" +US_Core_EXPORT const std::string& SERVICE_SCOPE(); // = "service.scope" /** * Service scope is singleton. All modules using the service receive the same * service object. * * @see SERVICE_SCOPE() */ -US_EXPORT const std::string& SCOPE_SINGLETON(); // = "singleton" +US_Core_EXPORT const std::string& SCOPE_SINGLETON(); // = "singleton" /** * Service scope is module. Each module using the service receives a distinct * service object. * * @see SERVICE_SCOPE() */ -US_EXPORT const std::string& SCOPE_MODULE(); // = "module" +US_Core_EXPORT const std::string& SCOPE_MODULE(); // = "module" /** * Service scope is prototype. Each module using the service receives either * a distinct service object or can request multiple distinct service objects * via ServiceObjects. * * @see SERVICE_SCOPE() */ -US_EXPORT const std::string& SCOPE_PROTOTYPE(); // = "prototype" +US_Core_EXPORT const std::string& SCOPE_PROTOTYPE(); // = "prototype" } US_END_NAMESPACE #endif // US_SERVICE_PROPERTIES_H diff --git a/src/service/usServiceReference.h b/core/include/usServiceReference.h similarity index 100% rename from src/service/usServiceReference.h rename to core/include/usServiceReference.h diff --git a/src/service/usServiceReferenceBase.h b/core/include/usServiceReferenceBase.h similarity index 97% rename from src/service/usServiceReferenceBase.h rename to core/include/usServiceReferenceBase.h index 8949cec859..249d93f998 100644 --- a/src/service/usServiceReferenceBase.h +++ b/core/include/usServiceReferenceBase.h @@ -1,234 +1,234 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEREFERENCEBASE_H #define USSERVICEREFERENCEBASE_H #include US_MSVC_PUSH_DISABLE_WARNING(4396) US_BEGIN_NAMESPACE class Module; class ServiceRegistrationBasePrivate; class ServiceReferenceBasePrivate; /** * \ingroup MicroServices * * A reference to a service. * * \note This class is provided as public API for low-level service queries only. * In almost all cases you should use the template ServiceReference instead. */ -class US_EXPORT ServiceReferenceBase { +class US_Core_EXPORT ServiceReferenceBase { private: typedef ServiceReferenceBasePrivate* ServiceReferenceBase::*bool_type; public: ServiceReferenceBase(const ServiceReferenceBase& ref); /** * Converts this ServiceReferenceBase instance into a boolean * expression. If this instance was default constructed or * the service it references has been unregistered, the conversion * returns false, otherwise it returns true. */ operator bool_type() const; /** * Releases any resources held or locked by this * ServiceReferenceBase and renders it invalid. */ ServiceReferenceBase& operator=(int null); ~ServiceReferenceBase(); /** * Returns the property value to which the specified property key is mapped * in the properties ServiceProperties object of the service * referenced by this ServiceReferenceBase object. * *

* Property keys are case-insensitive. * *

* This method continues to return property values after the service has * been unregistered. This is so references to unregistered services can * still be interrogated. * * @param key The property key. * @return The property value to which the key is mapped; an invalid Any * if there is no property named after the key. */ Any GetProperty(const std::string& key) const; /** * Returns a list of the keys in the ServiceProperties * object of the service referenced by this ServiceReferenceBase * object. * *

* This method will continue to return the keys after the service has been * unregistered. This is so references to unregistered services can * still be interrogated. * * @param keys A vector being filled with the property keys. */ void GetPropertyKeys(std::vector& keys) const; /** * Returns the module that registered the service referenced by this * ServiceReferenceBase object. * *

* This method must return 0 when the service has been * unregistered. This can be used to determine if the service has been * unregistered. * * @return The module that registered the service referenced by this * ServiceReferenceBase object; 0 if that * service has already been unregistered. * @see ModuleContext::RegisterService(const InterfaceMap&, const ServiceProperties&) */ Module* GetModule() const; /** * Returns the modules that are using the service referenced by this * ServiceReferenceBase object. Specifically, this method returns * the modules whose usage count for that service is greater than zero. * * @param modules A list of modules whose usage count for the service referenced * by this ServiceReferenceBase object is greater than * zero. */ void GetUsingModules(std::vector& modules) const; /** * Returns the interface identifier this ServiceReferenceBase object * is bound to. * * A default constructed ServiceReferenceBase object is not bound to * any interface identifier and calling this method will return an * empty string. * * @return The interface identifier for this ServiceReferenceBase object. */ std::string GetInterfaceId() const; /** * Checks wether this ServiceReferenceBase object can be converted to * another ServiceReferenceBase object, which will be bound to the * given interface identifier. * * ServiceReferenceBase objects can be converted if the underlying service * implementation was registered under multiple service interfaces. * * @param interfaceid * @return \c true if this ServiceReferenceBase object can be converted, * \c false otherwise. */ bool IsConvertibleTo(const std::string& interfaceid) const; /** * Compares this ServiceReferenceBase with the specified * ServiceReferenceBase for order. * *

* If this ServiceReferenceBase and the specified * ServiceReferenceBase have the same \link ServiceConstants::SERVICE_ID() * service id\endlink they are equal. This ServiceReferenceBase is less * than the specified ServiceReferenceBase if it has a lower * {@link ServiceConstants::SERVICE_RANKING service ranking} and greater if it has a * higher service ranking. Otherwise, if this ServiceReferenceBase * and the specified ServiceReferenceBase have the same * {@link ServiceConstants::SERVICE_RANKING service ranking}, this * ServiceReferenceBase is less than the specified * ServiceReferenceBase if it has a higher * {@link ServiceConstants::SERVICE_ID service id} and greater if it has a lower * service id. * * @param reference The ServiceReferenceBase to be compared. * @return Returns a false or true if this * ServiceReferenceBase is less than or greater * than the specified ServiceReferenceBase. */ bool operator<(const ServiceReferenceBase& reference) const; bool operator==(const ServiceReferenceBase& reference) const; ServiceReferenceBase& operator=(const ServiceReferenceBase& reference); private: friend class ModulePrivate; friend class ModuleContext; friend class ModuleHooks; friend class ServiceHooks; friend class ServiceObjectsBase; friend class ServiceObjectsBasePrivate; friend class ServiceRegistrationBase; friend class ServiceRegistrationBasePrivate; friend class ServiceListeners; friend class ServiceRegistry; friend class LDAPFilter; template friend class ServiceReference; US_HASH_FUNCTION_FRIEND(ServiceReferenceBase); std::size_t Hash() const; /** * Creates an invalid ServiceReferenceBase object. You can use * this object in boolean expressions and it will evaluate to * false. */ ServiceReferenceBase(); ServiceReferenceBase(ServiceRegistrationBasePrivate* reg); void SetInterfaceId(const std::string& interfaceId); ServiceReferenceBasePrivate* d; }; US_END_NAMESPACE US_MSVC_POP_WARNING /** * \ingroup MicroServices */ -US_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceReferenceBase)& serviceRef); +US_Core_EXPORT std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceReferenceBase)& serviceRef); US_HASH_FUNCTION_NAMESPACE_BEGIN US_HASH_FUNCTION_BEGIN(US_PREPEND_NAMESPACE(ServiceReferenceBase)) return arg.Hash(); US_HASH_FUNCTION_END US_HASH_FUNCTION_NAMESPACE_END #endif // USSERVICEREFERENCEBASE_H diff --git a/src/service/usServiceRegistration.h b/core/include/usServiceRegistration.h similarity index 100% rename from src/service/usServiceRegistration.h rename to core/include/usServiceRegistration.h diff --git a/src/service/usServiceRegistrationBase.h b/core/include/usServiceRegistrationBase.h similarity index 99% rename from src/service/usServiceRegistrationBase.h rename to core/include/usServiceRegistrationBase.h index 5e02216946..7b08393548 100644 --- a/src/service/usServiceRegistrationBase.h +++ b/core/include/usServiceRegistrationBase.h @@ -1,223 +1,223 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICEREGISTRATIONBASE_H #define USSERVICEREGISTRATIONBASE_H #include "usServiceProperties.h" #include "usServiceReference.h" US_MSVC_PUSH_DISABLE_WARNING(4396) US_BEGIN_NAMESPACE class ModulePrivate; class ServiceRegistrationBasePrivate; class ServicePropertiesImpl; /** * \ingroup MicroServices * * A registered service. * *

* The framework returns a ServiceRegistrationBase object when a * ModuleContext#RegisterService() method invocation is successful. * The ServiceRegistrationBase object is for the private use of the * registering module and should not be shared with other modules. *

* The ServiceRegistrationBase object may be used to update the * properties of the service or to unregister the service. * * \note This class is provided as public API for low-level service management only. * In almost all cases you should use the template ServiceRegistration instead. * * @see ModuleContext#RegisterService() * @remarks This class is thread safe. */ -class US_EXPORT ServiceRegistrationBase +class US_Core_EXPORT ServiceRegistrationBase { private: typedef ServiceRegistrationBasePrivate* ServiceRegistrationBase::*bool_type; public: ServiceRegistrationBase(const ServiceRegistrationBase& reg); /** * A boolean conversion operator converting this ServiceRegistrationBase object * to \c true if it is valid and to \c false otherwise. A SeriveRegistration * object is invalid if it was default-constructed or was invalidated by * assigning 0 to it. * * \see operator=(int) * * \return \c true if this ServiceRegistrationBase object is valid, \c false * otherwise. */ operator bool_type() const; /** * Releases any resources held or locked by this * ServiceRegistrationBase and renders it invalid. * * \return This ServiceRegistrationBase object. */ ServiceRegistrationBase& operator=(int null); ~ServiceRegistrationBase(); /** * Returns a ServiceReference object for a service being * registered. *

* The ServiceReference object may be shared with other * modules. * * @throws std::logic_error If this * ServiceRegistrationBase object has already been * unregistered or if it is invalid. * @return ServiceReference object. */ ServiceReferenceBase GetReference(const std::string& interfaceId = std::string()) const; /** * Updates the properties associated with a service. * *

* The ServiceConstants#OBJECTCLASS and ServiceConstants#SERVICE_ID keys * cannot be modified by this method. These values are set by the framework * when the service is registered in the environment. * *

* The following steps are taken to modify service properties: *

    *
  1. The service's properties are replaced with the provided properties. *
  2. A service event of type ServiceEvent#MODIFIED is fired. *
* * @param properties The properties for this service. See {@link ServiceProperties} * for a list of standard service property keys. Changes should not * be made to this object after calling this method. To update the * service's properties this method should be called again. * * @throws std::logic_error If this ServiceRegistrationBase * object has already been unregistered or if it is invalid. * @throws std::invalid_argument If properties contains * case variants of the same key name. */ void SetProperties(const ServiceProperties& properties); /** * Unregisters a service. Remove a ServiceRegistrationBase object * from the framework service registry. All ServiceRegistrationBase * objects associated with this ServiceRegistrationBase object * can no longer be used to interact with the service once unregistration is * complete. * *

* The following steps are taken to unregister a service: *

    *
  1. The service is removed from the framework service registry so that * it can no longer be obtained. *
  2. A service event of type ServiceEvent#UNREGISTERING is fired * so that modules using this service can release their use of the service. * Once delivery of the service event is complete, the * ServiceRegistrationBase objects for the service may no longer be * used to get a service object for the service. *
  3. For each module whose use count for this service is greater than * zero:
    * The module's use count for this service is set to zero.
    * If the service was registered with a ServiceFactory object, the * ServiceFactory#UngetService method is called to release * the service object for the module. *
* * @throws std::logic_error If this * ServiceRegistrationBase object has already been * unregistered or if it is invalid. * @see ModuleContext#UngetService * @see ServiceFactory#UngetService */ void Unregister(); /** * Compare two ServiceRegistrationBase objects. * * If both ServiceRegistrationBase objects are valid, the comparison is done * using the underlying ServiceReference object. Otherwise, this ServiceRegistrationBase * object is less than the other object if and only if this object is invalid and * the other object is valid. * * @param o The ServiceRegistrationBase object to compare with. * @return \c true if this ServiceRegistrationBase object is less than the other object. */ bool operator<(const ServiceRegistrationBase& o) const; bool operator==(const ServiceRegistrationBase& registration) const; ServiceRegistrationBase& operator=(const ServiceRegistrationBase& registration); private: friend class ServiceRegistry; friend class ServiceReferenceBasePrivate; template friend class ServiceRegistration; US_HASH_FUNCTION_FRIEND(ServiceRegistrationBase); /** * Creates an invalid ServiceRegistrationBase object. You can use * this object in boolean expressions and it will evaluate to * false. */ ServiceRegistrationBase(); ServiceRegistrationBase(ServiceRegistrationBasePrivate* registrationPrivate); ServiceRegistrationBase(ModulePrivate* module, const InterfaceMap& service, const ServicePropertiesImpl& props); ServiceRegistrationBasePrivate* d; }; US_END_NAMESPACE US_MSVC_POP_WARNING US_HASH_FUNCTION_NAMESPACE_BEGIN US_HASH_FUNCTION_BEGIN(US_PREPEND_NAMESPACE(ServiceRegistrationBase)) return US_HASH_FUNCTION(US_PREPEND_NAMESPACE(ServiceRegistrationBasePrivate)*, arg.d); US_HASH_FUNCTION_END US_HASH_FUNCTION_NAMESPACE_END inline std::ostream& operator<<(std::ostream& os, const US_PREPEND_NAMESPACE(ServiceRegistrationBase)& /*reg*/) { return os << "US_PREPEND_NAMESPACE(ServiceRegistrationBase) object"; } #endif // USSERVICEREGISTRATIONBASE_H diff --git a/src/service/usServiceTracker.h b/core/include/usServiceTracker.h similarity index 100% rename from src/service/usServiceTracker.h rename to core/include/usServiceTracker.h diff --git a/src/service/usServiceTrackerCustomizer.h b/core/include/usServiceTrackerCustomizer.h similarity index 100% rename from src/service/usServiceTrackerCustomizer.h rename to core/include/usServiceTrackerCustomizer.h diff --git a/src/util/usSharedData.h b/core/include/usSharedData.h similarity index 100% rename from src/util/usSharedData.h rename to core/include/usSharedData.h diff --git a/src/util/usSharedLibrary.h b/core/include/usSharedLibrary.h similarity index 99% rename from src/util/usSharedLibrary.h rename to core/include/usSharedLibrary.h index 5bcd9308db..12d2af862c 100644 --- a/src/util/usSharedLibrary.h +++ b/core/include/usSharedLibrary.h @@ -1,223 +1,223 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSHAREDLIBRARY_H #define USSHAREDLIBRARY_H -#include "usConfig.h" +#include "usCoreConfig.h" #include "usSharedData.h" #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4251) #endif US_BEGIN_NAMESPACE class SharedLibraryPrivate; /** * \ingroup MicroServicesUtils * * The SharedLibrary class loads shared libraries at runtime. */ -class US_EXPORT SharedLibrary +class US_Core_EXPORT SharedLibrary { public: SharedLibrary(); SharedLibrary(const SharedLibrary& other); /** * Construct a SharedLibrary object using a library search path and * a library base name. * * @param libPath An absolute path containing the shared library * @param name The base name of the shared library, without prefix * and suffix. */ SharedLibrary(const std::string& libPath, const std::string& name); /** * Construct a SharedLibrary object using an absolute file path to * the shared library. Using this constructor effectively disables * all setters except SetFilePath(). * * @param absoluteFilePath The absolute path to the shared library. */ SharedLibrary(const std::string& absoluteFilePath); /** * Destroys this object but does not unload the shared library. */ ~SharedLibrary(); SharedLibrary& operator=(const SharedLibrary& other); /** * Loads the shared library pointed to by this SharedLibrary object. * On POSIX systems dlopen() is called with the RTLD_LAZY and * RTLD_LOCAL flags unless the compiler is gcc 4.4.x or older. Then * the RTLD_LAZY and RTLD_GLOBAL flags are used to load the shared library * to work around RTTI problems across shared library boundaries. * * @throws std::logic_error If the library is already loaded. * @throws std::runtime_error If loading the library failed. */ void Load(); /** * Loads the shared library pointed to by this SharedLibrary object, * using the specified flags on POSIX systems. * * @throws std::logic_error If the library is already loaded. * @throws std::runtime_error If loading the library failed. */ void Load(int flags); /** * Un-loads the shared library pointed to by this SharedLibrary object. * * @throws std::runtime_error If an error occurred while un-loading the * shared library. */ void Unload(); /** * Sets the base name of the shared library. Does nothing if the shared * library is already loaded or the SharedLibrary(const std::string&) * constructor was used. * * @param name The base name of the shared library, without prefix and * suffix. */ void SetName(const std::string& name); /** * Gets the base name of the shared library. * @return The shared libraries base name. */ std::string GetName() const; /** * Gets the absolute file path for the shared library with base name * \c name, using the search path returned by GetLibraryPath(). * * @param name The shared library base name. * @return The absolute file path of the shared library. */ std::string GetFilePath(const std::string& name) const; /** * Sets the absolute file path of this SharedLibrary object. * Using this methods with a non-empty \c absoluteFilePath argument * effectively disables all other setters. * * @param absoluteFilePath The new absolute file path of this SharedLibrary * object. */ void SetFilePath(const std::string& absoluteFilePath); /** * Gets the absolute file path of this SharedLibrary object. * * @return The absolute file path of the shared library. */ std::string GetFilePath() const; /** * Sets a new library search path. Does nothing if the shared * library is already loaded or the SharedLibrary(const std::string&) * constructor was used. * * @param path The new shared library search path. */ void SetLibraryPath(const std::string& path); /** * Gets the library search path of this SharedLibrary object. * * @return The library search path. */ std::string GetLibraryPath() const; /** * Sets the suffix for shared library names (e.g. lib). Does nothing if the shared * library is already loaded or the SharedLibrary(const std::string&) * constructor was used. * * @param suffix The shared library name suffix. */ void SetSuffix(const std::string& suffix); /** * Gets the file name suffix of this SharedLibrary object. * * @return The file name suffix of the shared library. */ std::string GetSuffix() const; /** * Sets the file name prefix for shared library names (e.g. .dll or .so). * Does nothing if the shared library is already loaded or the * SharedLibrary(const std::string&) constructor was used. * * @param prefix The shared library name prefix. */ void SetPrefix(const std::string& prefix); /** * Gets the file name prefix of this SharedLibrary object. * * @return The file name prefix of the shared library. */ std::string GetPrefix() const; /** * Gets the internal handle of this SharedLibrary object. * * @return \c NULL if the shared library is not loaded, the operating * system specific handle otherwise. */ void* GetHandle() const; /** * Gets the loaded/unloaded stated of this SharedLibrary object. * * @return \c true if the shared library is loaded, \c false otherwise. */ bool IsLoaded() const; private: ExplicitlySharedDataPointer d; }; US_END_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif #endif // USTESTUTILSHAREDLIBRARY_H diff --git a/src/util/usShrinkableMap.h b/core/include/usShrinkableMap.h similarity index 99% rename from src/util/usShrinkableMap.h rename to core/include/usShrinkableMap.h index 808b3ea343..d490f94189 100644 --- a/src/util/usShrinkableMap.h +++ b/core/include/usShrinkableMap.h @@ -1,181 +1,181 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSHRINKABLEMAP_H #define USSHRINKABLEMAP_H -#include "usConfig.h" +#include "usGlobalConfig.h" #include US_BEGIN_NAMESPACE /** * \ingroup MicroServicesUtils * * A std::map style associative container allowing query and removal * operations only. */ template class ShrinkableMap { private: static std::map emptyContainer; public: typedef std::map container_type; typedef typename container_type::iterator iterator; typedef typename container_type::const_iterator const_iterator; typedef typename container_type::size_type size_type; typedef typename container_type::key_type key_type; typedef typename container_type::mapped_type mapped_type; typedef typename container_type::value_type value_type; typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; ShrinkableMap() : container(emptyContainer) { } iterator begin() { return container.begin(); } const_iterator begin() const { return container.begin(); } iterator end() { return container.end(); } const_iterator end() const { return container.end(); } void erase(iterator pos) { return container.erase(pos); } void erase(iterator first, iterator last) { return container.erase(first, last); } size_type erase(const Key& key) { return container.erase(key); } bool empty() const { return container.empty(); } void clear() { container.clear(); } size_type size() const { return container.size(); } size_type max_size() const { return container.max_size(); } T& operator[](const Key& key) { return container[key]; } size_type count(const Key& key) const { return container.count(key); } iterator find(const Key& key) { return container.find(key); } const_iterator find(const Key& key) const { return container.find(key); } std::pair equal_range(const Key& key) { return container.equal_range(key); } std::pair equal_range(const Key& key) const { return container.equal_range(key); } iterator lower_bound(const Key& key) { return container.lower_bound(key); } const_iterator lower_bound(const Key& key) const { return container.lower_bound(key); } iterator upper_bound(const Key& key) { return container.upper_bound(key); } const_iterator upper_bound(const Key& key) const { return container.upper_bound(key); } private: friend class ServiceHooks; ShrinkableMap(container_type& container) : container(container) {} container_type& container; }; template std::map ShrinkableMap::emptyContainer; US_END_NAMESPACE #endif // USSHRINKABLEMAP_H diff --git a/src/util/usShrinkableVector.h b/core/include/usShrinkableVector.h similarity index 99% rename from src/util/usShrinkableVector.h rename to core/include/usShrinkableVector.h index 72c271d677..881da3358d 100644 --- a/src/util/usShrinkableVector.h +++ b/core/include/usShrinkableVector.h @@ -1,164 +1,164 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSHRINKABLEVECTOR_H #define USSHRINKABLEVECTOR_H -#include "usConfig.h" +#include "usGlobalConfig.h" #include US_BEGIN_NAMESPACE /** * \ingroup MicroServicesUtils * * A std::vector style container allowing query and removal * operations only. */ template class ShrinkableVector { private: static std::vector emptyVector; public: typedef std::vector container_type; typedef typename container_type::iterator iterator; typedef typename container_type::const_iterator const_iterator; typedef typename container_type::size_type size_type; typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; ShrinkableVector() : container(emptyVector) { } iterator begin() { return container.begin(); } const_iterator begin() const { return container.begin(); } iterator end() { return container.end(); } const_iterator end() const { return container.end(); } reference front() { return container.front(); } const_reference front() const { return container.front(); } reference back() { return container.back(); } const_reference back() const { return container.back(); } iterator erase(iterator pos) { return container.erase(pos); } iterator erase(iterator first, iterator last) { return container.erase(first, last); } void pop_back() { container.pop_back(); } bool empty() const { return container.empty(); } void clear() { container.clear(); } size_type size() const { return container.size(); } reference at(size_type pos) { return container.at(pos); } const_reference at(size_type pos) const { return container.at(pos); } const_reference operator[](size_type i) const { return container[i]; } reference operator[](size_type i) { return container[i]; } private: friend class ModuleHooks; friend class ServiceHooks; ShrinkableVector(container_type& container) : container(container) {} container_type& container; }; template std::vector ShrinkableVector::emptyVector; US_END_NAMESPACE #endif // USSHRINKABLEVECTOR_H diff --git a/src/util/usUncompressResourceData.h b/core/include/usUncompressResourceData.h similarity index 86% rename from src/util/usUncompressResourceData.h rename to core/include/usUncompressResourceData.h index a3e82f3679..131bf506a1 100644 --- a/src/util/usUncompressResourceData.h +++ b/core/include/usUncompressResourceData.h @@ -1,33 +1,33 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USUNCOMPRESSRESOURCEDATA_H #define USUNCOMPRESSRESOURCEDATA_H -#include "usConfig.h" +#include "usCoreConfig.h" US_BEGIN_NAMESPACE -US_EXPORT unsigned char* UncompressResourceData(const unsigned char* data, std::size_t size, std::size_t* uncompressedSize); +US_Core_EXPORT unsigned char* UncompressResourceData(const unsigned char* data, std::size_t size, std::size_t* uncompressedSize); US_END_NAMESPACE #endif // USUNCOMPRESSRESOURCEDATA_H diff --git a/src/resources/manifest.json.in b/core/resources/manifest.json.in similarity index 100% rename from src/resources/manifest.json.in rename to core/resources/manifest.json.in diff --git a/core/src/CMakeLists.txt b/core/src/CMakeLists.txt new file mode 100644 index 0000000000..b86061fd43 --- /dev/null +++ b/core/src/CMakeLists.txt @@ -0,0 +1,86 @@ +#----------------------------------------------------------------------------- +# Source files +#----------------------------------------------------------------------------- + +set(_srcs + util/usAny.cpp + util/jsoncpp.cpp + util/usLDAPProp.cpp + util/usSharedLibrary.cpp + util/usUncompressResourceData.c + util/usUncompressResourceData.cpp + util/usUtils.cpp + + service/usLDAPExpr.cpp + service/usLDAPFilter.cpp + service/usServiceException.cpp + service/usServiceEvent.cpp + service/usServiceEventListenerHook.cpp + service/usServiceFindHook.cpp + service/usServiceHooks.cpp + service/usServiceListenerEntry.cpp + service/usServiceListenerEntry_p.h + service/usServiceListenerHook.cpp + service/usServiceListeners.cpp + service/usServiceListeners_p.h + service/usServiceObjects.cpp + service/usServiceProperties.cpp + service/usServicePropertiesImpl.cpp + service/usServiceReferenceBase.cpp + service/usServiceReferenceBasePrivate.cpp + service/usServiceRegistrationBase.cpp + service/usServiceRegistrationBasePrivate.cpp + service/usServiceRegistry.cpp + service/usServiceRegistry_p.h + + module/usCoreModuleActivator.cpp + module/usCoreModuleContext_p.h + module/usCoreModuleContext.cpp + module/usModuleContext.cpp + module/usModule.cpp + module/usModuleEvent.cpp + module/usModuleEventHook.cpp + module/usModuleFindHook.cpp + module/usModuleHooks.cpp + module/usModuleInfo.cpp + module/usModuleManifest.cpp + module/usModulePrivate.cpp + module/usModuleRegistry.cpp + module/usModuleResource.cpp + module/usModuleResourceBuffer.cpp + module/usModuleResourceStream.cpp + module/usModuleResourceTree.cpp + module/usModuleSettings.cpp + module/usModuleUtils.cpp + module/usModuleVersion.cpp +) + +set(_private_headers + util/usAtomicInt_p.h + util/usListenerFunctors_p.h + util/usLog_p.h + util/usStaticInit_p.h + util/usThreads_p.h + util/usUtils_p.h + util/usWaitCondition_p.h + + util/dirent_win32_p.h + + service/usServiceHooks_p.h + service/usServiceListenerHook_p.h + service/usServicePropertiesImpl_p.h + service/usServiceTracker.tpp + service/usServiceTrackerPrivate.h + service/usServiceTrackerPrivate.tpp + service/usTrackedService_p.h + service/usTrackedServiceListener_p.h + service/usTrackedService.tpp + + module/usModuleAbstractTracked_p.h + module/usModuleAbstractTracked.tpp + module/usModuleHooks_p.h + module/usModuleResourceBuffer_p.h + module/usModuleResourceTree_p.h + module/usModuleUtils_p.h +) + diff --git a/src/module/usCoreModuleActivator.cpp b/core/src/module/usCoreModuleActivator.cpp similarity index 100% rename from src/module/usCoreModuleActivator.cpp rename to core/src/module/usCoreModuleActivator.cpp diff --git a/src/module/usCoreModuleContext.cpp b/core/src/module/usCoreModuleContext.cpp similarity index 97% rename from src/module/usCoreModuleContext.cpp rename to core/src/module/usCoreModuleContext.cpp index 75b6b514f5..9f19565031 100644 --- a/src/module/usCoreModuleContext.cpp +++ b/core/src/module/usCoreModuleContext.cpp @@ -1,53 +1,53 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include +#include US_MSVC_DISABLE_WARNING(4355) #include "usCoreModuleContext_p.h" US_BEGIN_NAMESPACE CoreModuleContext::CoreModuleContext() : listeners(this) , services(this) , serviceHooks(this) , moduleHooks(this) { } CoreModuleContext::~CoreModuleContext() { } void CoreModuleContext::Init() { serviceHooks.Open(); } void CoreModuleContext::Uninit() { serviceHooks.Close(); } US_END_NAMESPACE diff --git a/src/module/usCoreModuleContext_p.h b/core/src/module/usCoreModuleContext_p.h similarity index 100% rename from src/module/usCoreModuleContext_p.h rename to core/src/module/usCoreModuleContext_p.h diff --git a/src/module/usModule.cpp b/core/src/module/usModule.cpp similarity index 99% rename from src/module/usModule.cpp rename to core/src/module/usModule.cpp index 27eaf082cd..77497b296b 100644 --- a/src/module/usModule.cpp +++ b/core/src/module/usModule.cpp @@ -1,315 +1,316 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usModule.h" #include "usModuleContext.h" #include "usModuleActivator.h" #include "usModulePrivate.h" #include "usModuleResource.h" #include "usModuleSettings.h" #include "usCoreModuleContext_p.h" +#include "usCoreConfig.h" US_BEGIN_NAMESPACE const std::string& Module::PROP_ID() { static const std::string s("module.id"); return s; } const std::string& Module::PROP_NAME() { static const std::string s("module.name"); return s; } const std::string& Module::PROP_LOCATION() { static const std::string s("module.location"); return s; } const std::string& Module::PROP_VERSION() { static const std::string s("module.version"); return s; } const std::string&Module::PROP_VENDOR() { static const std::string s("module.vendor"); return s; } const std::string&Module::PROP_DESCRIPTION() { static const std::string s("module.description"); return s; } const std::string&Module::PROP_AUTOLOAD_DIR() { static const std::string s("module.autoload_dir"); return s; } Module::Module() : d(0) { } Module::~Module() { delete d; } void Module::Init(CoreModuleContext* coreCtx, ModuleInfo* info) { ModulePrivate* mp = new ModulePrivate(this, coreCtx, info); std::swap(mp, d); delete mp; } void Module::Uninit() { if (d->moduleContext != NULL) { //d->coreCtx->listeners.HooksModuleStopped(d->moduleContext); d->RemoveModuleResources(); delete d->moduleContext; d->moduleContext = 0; d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADED, this)); d->moduleActivator = 0; } } bool Module::IsLoaded() const { return d->moduleContext != 0; } void Module::Start() { if (d->moduleContext) { US_WARN << "Module " << d->info.name << " already started."; return; } d->moduleContext = new ModuleContext(this->d); // try // { d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::LOADING, this)); // try to get a ModuleActivator instance if (d->info.activatorHook) { try { d->moduleActivator = d->info.activatorHook(); } catch (...) { US_ERROR << "Creating the module activator of " << d->info.name << " failed"; throw; } d->moduleActivator->Load(d->moduleContext); } d->StartStaticModules(); #ifdef US_ENABLE_AUTOLOADING_SUPPORT if (ModuleSettings::IsAutoLoadingEnabled()) { AutoLoadModules(d->info); } #endif d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::LOADED, this)); // } // catch (...) // { // d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADING, this)); // d->RemoveModuleResources(); // delete d->moduleContext; // d->moduleContext = 0; // d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADED, this)); // US_ERROR << "Calling the module activator Load() method of " << d->info.name << " failed!"; // throw; // } } void Module::Stop() { if (d->moduleContext == 0) { US_WARN << "Module " << d->info.name << " already stopped."; return; } try { d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADING, this)); d->StopStaticModules(); if (d->moduleActivator) { d->moduleActivator->Unload(d->moduleContext); } } catch (...) { US_WARN << "Calling the module activator Unload() method of " << d->info.name << " failed!"; try { this->Uninit(); } catch (...) {} throw; } this->Uninit(); } ModuleContext* Module::GetModuleContext() const { return d->moduleContext; } long Module::GetModuleId() const { return d->info.id; } std::string Module::GetLocation() const { return d->info.location; } std::string Module::GetName() const { return d->info.name; } ModuleVersion Module::GetVersion() const { return d->version; } Any Module::GetProperty(const std::string& key) const { return d->moduleManifest.GetValue(key); } std::vector Module::GetPropertyKeys() const { return d->moduleManifest.GetKeys(); } std::vector Module::GetRegisteredServices() const { std::vector sr; std::vector res; d->coreCtx->services.GetRegisteredByModule(d, sr); for (std::vector::const_iterator i = sr.begin(); i != sr.end(); ++i) { res.push_back(i->GetReference()); } return res; } std::vector Module::GetServicesInUse() const { std::vector sr; std::vector res; d->coreCtx->services.GetUsedByModule(const_cast(this), sr); for (std::vector::const_iterator i = sr.begin(); i != sr.end(); ++i) { res.push_back(i->GetReference()); } return res; } ModuleResource Module::GetResource(const std::string& path) const { if (d->resourceTreePtrs.empty()) { return ModuleResource(); } for (std::size_t i = 0; i < d->resourceTreePtrs.size(); ++i) { if (!d->resourceTreePtrs[i]->IsValid()) continue; ModuleResource result(path, d->resourceTreePtrs[i], d->resourceTreePtrs); if (result) return result; } return ModuleResource(); } std::vector Module::FindResources(const std::string& path, const std::string& filePattern, bool recurse) const { std::vector result; if (d->resourceTreePtrs.empty()) return result; for (std::size_t i = 0; i < d->resourceTreePtrs.size(); ++i) { if (!d->resourceTreePtrs[i]->IsValid()) continue; std::vector nodes; d->resourceTreePtrs[i]->FindNodes(path, filePattern, recurse, nodes); for (std::vector::iterator nodeIter = nodes.begin(); nodeIter != nodes.end(); ++nodeIter) { result.push_back(ModuleResource(*nodeIter, d->resourceTreePtrs[i], d->resourceTreePtrs)); } } return result; } US_END_NAMESPACE US_USE_NAMESPACE std::ostream& operator<<(std::ostream& os, const Module& module) { os << "Module[" << "id=" << module.GetModuleId() << ", loc=" << module.GetLocation() << ", name=" << module.GetName() << "]"; return os; } std::ostream& operator<<(std::ostream& os, Module const * module) { return operator<<(os, *module); } diff --git a/src/module/usModuleAbstractTracked.tpp b/core/src/module/usModuleAbstractTracked.tpp similarity index 100% rename from src/module/usModuleAbstractTracked.tpp rename to core/src/module/usModuleAbstractTracked.tpp diff --git a/src/module/usModuleAbstractTracked_p.h b/core/src/module/usModuleAbstractTracked_p.h similarity index 100% rename from src/module/usModuleAbstractTracked_p.h rename to core/src/module/usModuleAbstractTracked_p.h diff --git a/src/module/usModuleContext.cpp b/core/src/module/usModuleContext.cpp similarity index 99% rename from src/module/usModuleContext.cpp rename to core/src/module/usModuleContext.cpp index e35e701dc0..3f20f7ed21 100644 --- a/src/module/usModuleContext.cpp +++ b/core/src/module/usModuleContext.cpp @@ -1,175 +1,173 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include "usModuleContext.h" #include "usModuleRegistry.h" #include "usModulePrivate.h" #include "usCoreModuleContext_p.h" #include "usServiceRegistry_p.h" #include "usServiceReferenceBasePrivate.h" US_BEGIN_NAMESPACE class ModuleContextPrivate { public: ModuleContextPrivate(ModulePrivate* module) : module(module) {} ModulePrivate* module; }; ModuleContext::ModuleContext(ModulePrivate* module) : d(new ModuleContextPrivate(module)) {} ModuleContext::~ModuleContext() { delete d; } Module* ModuleContext::GetModule() const { return d->module->q; } Module* ModuleContext::GetModule(long id) const { return d->module->coreCtx->moduleHooks.FilterModule(this, ModuleRegistry::GetModule(id)); } Module*ModuleContext::GetModule(const std::string& name) { return ModuleRegistry::GetModule(name); } std::vector ModuleContext::GetModules() const { std::vector modules = ModuleRegistry::GetModules(); d->module->coreCtx->moduleHooks.FilterModules(this, modules); return modules; } ServiceRegistrationU ModuleContext::RegisterService(const InterfaceMap& service, const ServiceProperties& properties) { return d->module->coreCtx->services.RegisterService(d->module, service, properties); } std::vector ModuleContext::GetServiceReferences(const std::string& clazz, const std::string& filter) { std::vector result; std::vector refs; d->module->coreCtx->services.Get(clazz, filter, d->module, refs); for (std::vector::const_iterator iter = refs.begin(); iter != refs.end(); ++iter) { result.push_back(ServiceReferenceU(*iter)); } return result; } ServiceReferenceU ModuleContext::GetServiceReference(const std::string& clazz) { return d->module->coreCtx->services.Get(d->module, clazz); } void* ModuleContext::GetService(const ServiceReferenceBase& reference) { if (!reference) { throw std::invalid_argument("Default constructed ServiceReference is not a valid input to GetService()"); } return reference.d->GetService(d->module->q); } InterfaceMap ModuleContext::GetService(const ServiceReferenceU& reference) { if (!reference) { throw std::invalid_argument("Default constructed ServiceReference is not a valid input to GetService()"); } return reference.d->GetServiceInterfaceMap(d->module->q); } bool ModuleContext::UngetService(const ServiceReferenceBase& reference) { ServiceReferenceBase ref = reference; return ref.d->UngetService(d->module->q, true); } void ModuleContext::AddServiceListener(const ServiceListener& delegate, const std::string& filter) { d->module->coreCtx->listeners.AddServiceListener(this, delegate, NULL, filter); } void ModuleContext::RemoveServiceListener(const ServiceListener& delegate) { d->module->coreCtx->listeners.RemoveServiceListener(this, delegate, NULL); } void ModuleContext::AddModuleListener(const ModuleListener& delegate) { d->module->coreCtx->listeners.AddModuleListener(this, delegate, NULL); } void ModuleContext::RemoveModuleListener(const ModuleListener& delegate) { d->module->coreCtx->listeners.RemoveModuleListener(this, delegate, NULL); } void ModuleContext::AddServiceListener(const ServiceListener& delegate, void* data, const std::string &filter) { d->module->coreCtx->listeners.AddServiceListener(this, delegate, data, filter); } void ModuleContext::RemoveServiceListener(const ServiceListener& delegate, void* data) { d->module->coreCtx->listeners.RemoveServiceListener(this, delegate, data); } void ModuleContext::AddModuleListener(const ModuleListener& delegate, void* data) { d->module->coreCtx->listeners.AddModuleListener(this, delegate, data); } void ModuleContext::RemoveModuleListener(const ModuleListener& delegate, void* data) { d->module->coreCtx->listeners.RemoveModuleListener(this, delegate, data); } std::string ModuleContext::GetDataFile(const std::string &filename) const { if (d->module->storagePath.empty()) return std::string(); return d->module->storagePath + filename; } US_END_NAMESPACE diff --git a/src/module/usModuleEvent.cpp b/core/src/module/usModuleEvent.cpp similarity index 100% rename from src/module/usModuleEvent.cpp rename to core/src/module/usModuleEvent.cpp diff --git a/src/module/usModuleEventHook.cpp b/core/src/module/usModuleEventHook.cpp similarity index 100% rename from src/module/usModuleEventHook.cpp rename to core/src/module/usModuleEventHook.cpp diff --git a/src/module/usModuleFindHook.cpp b/core/src/module/usModuleFindHook.cpp similarity index 100% rename from src/module/usModuleFindHook.cpp rename to core/src/module/usModuleFindHook.cpp diff --git a/src/module/usModuleHooks.cpp b/core/src/module/usModuleHooks.cpp similarity index 100% rename from src/module/usModuleHooks.cpp rename to core/src/module/usModuleHooks.cpp diff --git a/src/module/usModuleHooks_p.h b/core/src/module/usModuleHooks_p.h similarity index 98% rename from src/module/usModuleHooks_p.h rename to core/src/module/usModuleHooks_p.h index 5d7da7bb93..ec500a932b 100644 --- a/src/module/usModuleHooks_p.h +++ b/core/src/module/usModuleHooks_p.h @@ -1,59 +1,58 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEHOOKS_P_H #define USMODULEHOOKS_P_H -#include "usConfig.h" #include "usServiceListeners_p.h" #include US_BEGIN_NAMESPACE class CoreModuleContext; class Module; class ModuleContext; class ModuleEvent; class ModuleHooks { private: CoreModuleContext* const coreCtx; public: ModuleHooks(CoreModuleContext* ctx); Module* FilterModule(const ModuleContext* mc, Module* module) const; void FilterModules(const ModuleContext* mc, std::vector& modules) const; void FilterModuleEventReceivers(const ModuleEvent& evt, ServiceListeners::ModuleListenerMap& moduleListeners); }; US_END_NAMESPACE #endif // USMODULEHOOKS_P_H diff --git a/src/module/usModuleInfo.cpp b/core/src/module/usModuleInfo.cpp similarity index 100% rename from src/module/usModuleInfo.cpp rename to core/src/module/usModuleInfo.cpp diff --git a/src/module/usModuleManifest.cpp b/core/src/module/usModuleManifest.cpp similarity index 100% rename from src/module/usModuleManifest.cpp rename to core/src/module/usModuleManifest.cpp diff --git a/src/module/usModuleManifest_p.h b/core/src/module/usModuleManifest_p.h similarity index 100% rename from src/module/usModuleManifest_p.h rename to core/src/module/usModuleManifest_p.h diff --git a/src/module/usModulePrivate.cpp b/core/src/module/usModulePrivate.cpp similarity index 99% rename from src/module/usModulePrivate.cpp rename to core/src/module/usModulePrivate.cpp index b316bbe28a..5bd101e306 100644 --- a/src/module/usModulePrivate.cpp +++ b/core/src/module/usModulePrivate.cpp @@ -1,288 +1,286 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include "usModulePrivate.h" #include "usModule.h" #include "usModuleContext.h" #include "usModuleActivator.h" #include "usModuleUtils_p.h" #include "usModuleSettings.h" #include "usModuleResource.h" #include "usModuleResourceStream.h" #include "usCoreModuleContext_p.h" #include "usServiceRegistration.h" #include "usServiceReferenceBasePrivate.h" #include #include #include #include US_BEGIN_NAMESPACE AtomicInt ModulePrivate::idCounter; ModulePrivate::ModulePrivate(Module* qq, CoreModuleContext* coreCtx, ModuleInfo* info) : coreCtx(coreCtx) , info(*info) , moduleContext(0) , moduleActivator(0) , q(qq) { // Parse the statically imported module library names typedef const char*(*GetImportedModulesFunc)(void); std::string getImportedModulesSymbol("_us_get_imported_modules_for_"); getImportedModulesSymbol += this->info.libName; std::string location = this->info.location; if (this->info.libName.empty()) { /* make sure we retrieve symbols from the executable, if "libName" is empty */ location.clear(); } GetImportedModulesFunc getImportedModulesFunc = NULL; void* getImportedModulesSym = ModuleUtils::GetSymbol(location, getImportedModulesSymbol.c_str()); std::memcpy(&getImportedModulesFunc, &getImportedModulesSym, sizeof(void*)); if (getImportedModulesFunc != NULL) { std::string importedStaticModuleLibNames = getImportedModulesFunc(); std::istringstream iss(importedStaticModuleLibNames); std::copy(std::istream_iterator(iss), std::istream_iterator(), std::back_inserter >(this->staticModuleLibNames)); } InitializeResources(location); // Check if the module provides a manifest.json file and if yes, parse it. ModuleResource manifestRes; std::map::iterator resourceTreeIter = mapLibNameToResourceTrees.find(this->info.libName); if (resourceTreeIter != mapLibNameToResourceTrees.end() && resourceTreeIter->second->IsValid()) { manifestRes = ModuleResource("/manifest.json", resourceTreeIter->second, resourceTreePtrs); if (manifestRes) { ModuleResourceStream manifestStream(manifestRes); try { moduleManifest.Parse(manifestStream); } catch (const std::exception& e) { US_ERROR << "Parsing of manifest.json for module " << info->location << " failed: " << e.what(); } } } // Check if we got version information and validate the version identifier if (moduleManifest.Contains(Module::PROP_VERSION())) { Any versionAny = moduleManifest.GetValue(Module::PROP_VERSION()); std::string errMsg; if (versionAny.Type() != typeid(std::string)) { errMsg = std::string("The version identifier must be a string"); } try { version = ModuleVersion(versionAny.ToString()); } catch (const std::exception& e) { errMsg = std::string("The version identifier is invalid: ") + e.what(); } if (!errMsg.empty()) { throw std::invalid_argument(std::string("The Json value for ") + Module::PROP_VERSION() + " for module " + info->location + " is not valid: " + errMsg); } } std::stringstream propId; propId << this->info.id; moduleManifest.SetValue(Module::PROP_ID(), propId.str()); moduleManifest.SetValue(Module::PROP_LOCATION(), this->info.location); moduleManifest.SetValue(Module::PROP_NAME(), this->info.name); if (moduleManifest.Contains(Module::PROP_AUTOLOAD_DIR())) { this->info.autoLoadDir = moduleManifest.GetValue(Module::PROP_AUTOLOAD_DIR()).ToString(); } else { // default to the library name or a special name for executables if (!this->info.libName.empty()) { this->info.autoLoadDir = this->info.libName; moduleManifest.SetValue(Module::PROP_AUTOLOAD_DIR(), Any(this->info.autoLoadDir)); } else { this->info.autoLoadDir = "main"; moduleManifest.SetValue(Module::PROP_AUTOLOAD_DIR(), Any(this->info.autoLoadDir)); } } // comput the module storage path #ifdef US_PLATFORM_WINDOWS static const char separator = '\\'; #else static const char separator = '/'; #endif std::string baseStoragePath = ModuleSettings::GetStoragePath(); if (!baseStoragePath.empty()) { char buf[50]; sprintf(buf, "%ld", this->info.id); storagePath = baseStoragePath + separator + buf + "_" + this->info.libName + separator; } } ModulePrivate::~ModulePrivate() { delete moduleContext; for (std::size_t i = 0; i < this->resourceTreePtrs.size(); ++i) { delete resourceTreePtrs[i]; } } void ModulePrivate::RemoveModuleResources() { coreCtx->listeners.RemoveAllListeners(moduleContext); std::vector srs; coreCtx->services.GetRegisteredByModule(this, srs); for (std::vector::iterator i = srs.begin(); i != srs.end(); ++i) { try { i->Unregister(); } catch (const std::logic_error& /*ignore*/) { // Someone has unregistered the service after stop completed. // This should not occur, but we don't want get stuck in // an illegal state so we catch it. } } srs.clear(); coreCtx->services.GetUsedByModule(q, srs); for (std::vector::const_iterator i = srs.begin(); i != srs.end(); ++i) { i->GetReference(std::string()).d->UngetService(q, false); } for (std::size_t i = 0; i < resourceTreePtrs.size(); ++i) { resourceTreePtrs[i]->Invalidate(); } } void ModulePrivate::StartStaticModules() { std::string location = this->info.location; if (this->info.libName.empty()) { /* make sure we retrieve symbols from the executable, if "libName" is empty */ location.clear(); } for (std::vector::iterator i = staticModuleLibNames.begin(); i != staticModuleLibNames.end(); ++i) { std::string staticActivatorSymbol = "_us_module_activator_instance_"; staticActivatorSymbol += *i; ModuleInfo::ModuleActivatorHook staticActivator = NULL; void* staticActivatorSym = ModuleUtils::GetSymbol(location, staticActivatorSymbol.c_str()); std::memcpy(&staticActivator, &staticActivatorSym, sizeof(void*)); if (staticActivator) { US_DEBUG << "Loading static activator " << *i; staticActivators.push_back(staticActivator); staticActivator()->Load(moduleContext); } else { US_DEBUG << "Could not find an activator for the static module " << (*i) << ". It propably does not provide an activator on purpose.\n Or you either " "forgot a US_IMPORT_MODULE macro call in " << info.libName << " or to link " << (*i) << " to " << info.libName << "."; } } } void ModulePrivate::StopStaticModules() { for (std::list::iterator i = staticActivators.begin(); i != staticActivators.end(); ++i) { (*i)()->Unload(moduleContext); } } void ModulePrivate::InitializeResources(const std::string& location) { // Get the resource data from static modules and this module std::vector moduleLibNames; moduleLibNames.push_back(this->info.libName); moduleLibNames.insert(moduleLibNames.end(), this->staticModuleLibNames.begin(), this->staticModuleLibNames.end()); std::string initResourcesSymbolPrefix = "_us_init_resources_"; for (std::size_t i = 0; i < moduleLibNames.size(); ++i) { std::string initResourcesSymbol = initResourcesSymbolPrefix + moduleLibNames[i]; ModuleInfo::InitResourcesHook initResourcesFunc = NULL; void* initResourcesSym = ModuleUtils::GetSymbol(location, initResourcesSymbol.c_str()); std::memcpy(&initResourcesFunc, &initResourcesSym, sizeof(void*)); if (initResourcesFunc) { initResourcesFunc(&this->info); } } // Initialize this modules resource trees assert(this->info.resourceData.size() == this->info.resourceNames.size()); assert(this->info.resourceNames.size() == this->info.resourceTree.size()); for (std::size_t i = 0; i < this->info.resourceData.size(); ++i) { resourceTreePtrs.push_back(new ModuleResourceTree(this->info.resourceTree[i], this->info.resourceNames[i], this->info.resourceData[i])); mapLibNameToResourceTrees[moduleLibNames[i]] = resourceTreePtrs.back(); } } US_END_NAMESPACE diff --git a/src/module/usModulePrivate.h b/core/src/module/usModulePrivate.h similarity index 100% rename from src/module/usModulePrivate.h rename to core/src/module/usModulePrivate.h diff --git a/src/module/usModuleRegistry.cpp b/core/src/module/usModuleRegistry.cpp similarity index 99% rename from src/module/usModuleRegistry.cpp rename to core/src/module/usModuleRegistry.cpp index f1bdbfa865..f50d9fdac0 100644 --- a/src/module/usModuleRegistry.cpp +++ b/core/src/module/usModuleRegistry.cpp @@ -1,223 +1,221 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include "usModuleRegistry.h" #include "usModule.h" #include "usModuleInfo.h" #include "usModuleContext.h" #include "usModuleActivator.h" #include "usCoreModuleContext_p.h" #include "usGetModuleContext.h" #include "usStaticInit_p.h" #include #include US_BEGIN_NAMESPACE typedef US_UNORDERED_MAP_TYPE ModuleMap; US_GLOBAL_STATIC(CoreModuleContext, coreModuleContext) template struct ModuleDeleter { void operator()(GlobalStatic& globalStatic) const { ModuleMap* moduleMap = globalStatic.pointer; for (ModuleMap::const_iterator i = moduleMap->begin(); i != moduleMap->end(); ++i) { delete i->second; } DefaultGlobalStaticDeleter defaultDeleter; defaultDeleter(globalStatic); } }; /** * Table of all installed modules in this framework. * Key is the module id. */ US_GLOBAL_STATIC_WITH_DELETER(ModuleMap, modules, ModuleDeleter) /** * Lock for protecting the modules object */ US_GLOBAL_STATIC(Mutex, modulesLock) /** * Lock for protecting the register count */ US_GLOBAL_STATIC(Mutex, countLock) void ModuleRegistry::Register(ModuleInfo* info) { static long regCount = 0; if (info->id > 0) { // The module was already registered Module* module = 0; { MutexLock lock(*modulesLock()); module = modules()->operator[](info->id); assert(module != 0); } module->Start(); } else { Module* module = 0; // check if the module is reloaded { MutexLock lock(*modulesLock()); ModuleMap* map = modules(); for (ModuleMap::const_iterator i = map->begin(); i != map->end(); ++i) { if (i->second->GetLocation() == info->location) { module = i->second; info->id = module->GetModuleId(); } } } if (!module) { module = new Module(); countLock()->Lock(); info->id = ++regCount; countLock()->Unlock(); module->Init(coreModuleContext(), info); MutexLock lock(*modulesLock()); ModuleMap* map = modules(); map->insert(std::make_pair(info->id, module)); } else { module->Init(coreModuleContext(), info); } module->Start(); } } void ModuleRegistry::UnRegister(const ModuleInfo* info) { // If we are unregistering the core module, we just call // the module activators Unload() method (if there is a // module activator). Since we cannot be sure that the // ModuleContext for the core library is still valid, we // just pass a null-pointer. Using the module context during // static deinitalization time of the core library makes // no sense anyway. if (info->id == 1) { // Remove listeners from static modules if they have forgotten to do so coreModuleContext()->listeners.RemoveAllListeners(GetModuleContext()); if (info->activatorHook) { info->activatorHook()->Unload(0); } return; } Module* curr = 0; { MutexLock lock(*modulesLock()); curr = modules()->operator[](info->id); assert(curr != 0); } curr->Stop(); } Module* ModuleRegistry::GetModule(long id) { MutexLock lock(*modulesLock()); ModuleMap::const_iterator iter = modules()->find(id); if (iter != modules()->end()) { return iter->second; } return 0; } Module* ModuleRegistry::GetModule(const std::string& name) { MutexLock lock(*modulesLock()); ModuleMap::const_iterator iter = modules()->begin(); ModuleMap::const_iterator iterEnd = modules()->end(); for (; iter != iterEnd; ++iter) { if (iter->second->GetName() == name) { return iter->second; } } return 0; } std::vector ModuleRegistry::GetModules() { MutexLock lock(*modulesLock()); std::vector result; ModuleMap* map = modules(); ModuleMap::const_iterator iter = map->begin(); ModuleMap::const_iterator iterEnd = map->end(); for (; iter != iterEnd; ++iter) { result.push_back(iter->second); } return result; } std::vector ModuleRegistry::GetLoadedModules() { MutexLock lock(*modulesLock()); std::vector result; ModuleMap::const_iterator iter = modules()->begin(); ModuleMap::const_iterator iterEnd = modules()->end(); for (; iter != iterEnd; ++iter) { if (iter->second->IsLoaded()) { result.push_back(iter->second); } } return result; } US_END_NAMESPACE diff --git a/src/module/usModuleResource.cpp b/core/src/module/usModuleResource.cpp similarity index 100% rename from src/module/usModuleResource.cpp rename to core/src/module/usModuleResource.cpp diff --git a/src/module/usModuleResourceBuffer.cpp b/core/src/module/usModuleResourceBuffer.cpp similarity index 99% rename from src/module/usModuleResourceBuffer.cpp rename to core/src/module/usModuleResourceBuffer.cpp index bf60f5e908..1946ebbed4 100644 --- a/src/module/usModuleResourceBuffer.cpp +++ b/core/src/module/usModuleResourceBuffer.cpp @@ -1,303 +1,303 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "usModuleResourceBuffer_p.h" #include "usUncompressResourceData.h" -#include "stdint_p.h" +#include "us_stdint.h" #include #include #ifdef US_PLATFORM_WINDOWS #define DATA_NEEDS_NEWLINE_CONVERSION 1 #undef REMOVE_LAST_NEWLINE_IN_TEXT_MODE #else #undef DATA_NEEDS_NEWLINE_CONVERSION #define REMOVE_LAST_NEWLINE_IN_TEXT_MODE 1 #endif US_BEGIN_NAMESPACE class ModuleResourceBufferPrivate { public: ModuleResourceBufferPrivate(const char* begin, std::size_t size, std::ios_base::openmode mode) : begin(begin) , end(begin + size) , current(begin) , mode(mode) #ifdef US_ENABLE_RESOURCE_COMPRESSION , uncompressedData(NULL) #endif #ifdef DATA_NEEDS_NEWLINE_CONVERSION , pos(0) #endif { } ~ModuleResourceBufferPrivate() { #ifdef US_ENABLE_RESOURCE_COMPRESSION delete[] uncompressedData; #endif } const char* const begin; const char* const end; const char* current; const std::ios_base::openmode mode; #ifdef US_ENABLE_RESOURCE_COMPRESSION const unsigned char* uncompressedData; #endif #ifdef DATA_NEEDS_NEWLINE_CONVERSION // records the stream position ignoring CR characters std::streambuf::pos_type pos; #endif }; ModuleResourceBuffer::ModuleResourceBuffer(const unsigned char* data, std::size_t _size, std::ios_base::openmode mode, bool compressed) : d(NULL) { assert(_size < static_cast(std::numeric_limits::max())); // assert(data != NULL); if (compressed && _size) { #ifdef US_ENABLE_RESOURCE_COMPRESSION data = UncompressResourceData(data, _size, &_size); #else assert(!"CppMicroServices built without support for resource compression"); #endif } const char* begin = reinterpret_cast(data); std::size_t size = _size; #ifdef DATA_NEEDS_NEWLINE_CONVERSION if (data != NULL && !(mode & std::ios_base::binary) && begin[0] == '\r') { ++begin; --size; } #endif #ifdef REMOVE_LAST_NEWLINE_IN_TEXT_MODE if (data != NULL && !(mode & std::ios_base::binary) && begin[size-1] == '\n') { --size; } #endif d = new ModuleResourceBufferPrivate(begin, size, mode); #ifdef US_ENABLE_RESOURCE_COMPRESSION if (compressed) { d->uncompressedData = data; } #endif } ModuleResourceBuffer::~ModuleResourceBuffer() { delete d; } ModuleResourceBuffer::int_type ModuleResourceBuffer::underflow() { if (d->current == d->end) return traits_type::eof(); #ifdef DATA_NEEDS_NEWLINE_CONVERSION char c = *d->current; if (!(d->mode & std::ios_base::binary)) { if (c == '\r') { if (d->current + 1 == d->end) { return traits_type::eof(); } c = d->current[1]; } } return traits_type::to_int_type(c); #else return traits_type::to_int_type(*d->current); #endif } ModuleResourceBuffer::int_type ModuleResourceBuffer::uflow() { if (d->current == d->end) return traits_type::eof(); #ifdef DATA_NEEDS_NEWLINE_CONVERSION char c = *d->current++; if (!(d->mode & std::ios_base::binary)) { if (c == '\r') { if (d->current == d->end) { return traits_type::eof(); } c = *d->current++; } } return traits_type::to_int_type(c); #else return traits_type::to_int_type(*d->current++); #endif } ModuleResourceBuffer::int_type ModuleResourceBuffer::pbackfail(int_type ch) { int backOffset = -1; #ifdef DATA_NEEDS_NEWLINE_CONVERSION if (!(d->mode & std::ios_base::binary)) { while ((d->current - backOffset) >= d->begin && d->current[backOffset] == '\r') { --backOffset; } // d->begin always points to a character != '\r' } #endif if (d->current == d->begin || (ch != traits_type::eof() && ch != d->current[backOffset])) { return traits_type::eof(); } d->current += backOffset; return traits_type::to_int_type(*d->current); } std::streamsize ModuleResourceBuffer::showmanyc() { assert(d->current <= d->end); #ifdef DATA_NEEDS_NEWLINE_CONVERSION std::streamsize ssize = 0; std::size_t chunkSize = d->end - d->current; for (std::size_t i = 0; i < chunkSize; ++i) { if (d->current[i] != '\r') { ++ssize; } } return ssize; #else return d->end - d->current; #endif } std::streambuf::pos_type ModuleResourceBuffer::seekoff(std::streambuf::off_type off, std::ios_base::seekdir way, std::ios_base::openmode /*which*/) { #ifdef DATA_NEEDS_NEWLINE_CONVERSION std::streambuf::off_type step = 1; if (way == std::ios_base::beg) { d->current = d->begin; } else if (way == std::ios_base::end) { d->current = d->end; step = -1; } if (!(d->mode & std::ios_base::binary)) { if (way == std::ios_base::beg) { d->pos = 0; } else if (way == std::ios_base::end) { d->current -= 1; } std::streambuf::off_type i = 0; // scan through off amount of characters excluding '\r' while (i != off) { if (*d->current != '\r') { i += step; d->pos += step; } d->current += step; } // adjust the position in case of a "backwards" seek if (way == std::ios_base::end) { // fix pointer from previous while loop d->current += 1; d->pos = 0; i = 0; const std::streampos currInternalPos = d->current - d->begin; while (i != currInternalPos) { if (d->begin[i] != '\r') { d->pos += 1; } ++i; } } } else { d->current += off; d->pos = d->current - d->begin; } return d->pos; #else if (way == std::ios_base::beg) { d->current = d->begin + off; return off; } else if (way == std::ios_base::cur) { d->current += off; return d->current - d->begin; } else { d->current = d->end + off; return d->current - d->begin; } #endif } std::streambuf::pos_type ModuleResourceBuffer::seekpos(std::streambuf::pos_type sp, std::ios_base::openmode /*which*/) { return this->seekoff(sp, std::ios_base::beg); } US_END_NAMESPACE diff --git a/src/module/usModuleResourceBuffer_p.h b/core/src/module/usModuleResourceBuffer_p.h similarity index 94% rename from src/module/usModuleResourceBuffer_p.h rename to core/src/module/usModuleResourceBuffer_p.h index 95797022d4..0f09c86b33 100644 --- a/src/module/usModuleResourceBuffer_p.h +++ b/core/src/module/usModuleResourceBuffer_p.h @@ -1,63 +1,63 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef USMODULERESOURCEBUFFER_P_H #define USMODULERESOURCEBUFFER_P_H -#include +#include #include US_BEGIN_NAMESPACE class ModuleResourceBufferPrivate; -class US_EXPORT ModuleResourceBuffer: public std::streambuf +class US_Core_EXPORT ModuleResourceBuffer: public std::streambuf { public: explicit ModuleResourceBuffer(const unsigned char* data, std::size_t size, std::ios_base::openmode mode, bool compressed); ~ModuleResourceBuffer(); private: int_type underflow(); int_type uflow(); int_type pbackfail(int_type ch); std::streamsize showmanyc(); pos_type seekoff (off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); pos_type seekpos (pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); // purposely not implemented ModuleResourceBuffer(const ModuleResourceBuffer&); ModuleResourceBuffer& operator=(const ModuleResourceBuffer&); private: ModuleResourceBufferPrivate* d; }; US_END_NAMESPACE #endif // USMODULERESOURCEBUFFER_P_H diff --git a/src/module/usModuleResourceStream.cpp b/core/src/module/usModuleResourceStream.cpp similarity index 100% rename from src/module/usModuleResourceStream.cpp rename to core/src/module/usModuleResourceStream.cpp diff --git a/src/module/usModuleResourceTree.cpp b/core/src/module/usModuleResourceTree.cpp similarity index 99% rename from src/module/usModuleResourceTree.cpp rename to core/src/module/usModuleResourceTree.cpp index 3c760e91a8..6aa4351da5 100644 --- a/src/module/usModuleResourceTree.cpp +++ b/core/src/module/usModuleResourceTree.cpp @@ -1,345 +1,345 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usModuleResourceTree_p.h" #include "usUtils_p.h" -#include "stdint_p.h" +#include "us_stdint.h" #include #include //#define DEBUG_RESOURCE_MATCH US_BEGIN_NAMESPACE -US_EXPORT bool RegisterResourceData(int, ModuleInfo* moduleInfo, +US_Core_EXPORT bool RegisterResourceData(int, ModuleInfo* moduleInfo, ModuleInfo::ModuleResourceData resourceTree, ModuleInfo::ModuleResourceData resourceNames, ModuleInfo::ModuleResourceData resourceData) { moduleInfo->resourceTree.push_back(resourceTree); moduleInfo->resourceNames.push_back(resourceNames); moduleInfo->resourceData.push_back(resourceData); return true; } ModuleResourceTree::ModuleResourceTree(ModuleInfo::ModuleResourceData resourceTree, ModuleInfo::ModuleResourceData resourceNames, ModuleInfo::ModuleResourceData resourceData) : isValid(resourceTree && resourceNames && resourceData) , tree(resourceTree) , names(resourceNames) , payloads(resourceData) { } bool ModuleResourceTree::IsValid() const { return isValid; } void ModuleResourceTree::Invalidate() { isValid = false; } inline std::string ModuleResourceTree::GetName(int node) const { if(!node) // root return std::string(); const int offset = FindOffset(node); std::string ret; int nameOffset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); const int16_t nameLength = (names[nameOffset+0] << 8) + (names[nameOffset+1] << 0); nameOffset += 2; // jump past name length nameOffset += 4; // jump past hash ret.resize(nameLength); for(int i = 0; i < nameLength; ++i) { ret[i] = names[nameOffset+i]; } return ret; } int ModuleResourceTree::FindNode(const std::string& _path) const { std::string path = _path.empty() ? "/" : _path; #ifdef DEBUG_RESOURCE_MATCH US_DEBUG << "***" << " START " << path; #endif if(path == "/") return 0; // the root node is always first int childCount = (tree[6] << 24) + (tree[7] << 16) + (tree[8] << 8) + (tree[9] << 0); int child = (tree[10] << 24) + (tree[11] << 16) + (tree[12] << 8) + (tree[13] << 0); int node = -1; // split the full path into segments std::vector segments; { std::stringstream ss(path); std::string item; while(std::getline(ss, item, '/')) { if (item.empty()) continue; segments.push_back(item); } } //now iterate up the path hierarchy for (std::size_t i = 0; i < segments.size() && childCount; ++i) { const std::string& segment = segments[i]; #ifdef DEBUG_RESOURCE_MATCH US_DEBUG << " CHILDREN " << segment; for(int j = 0; j < childCount; ++j) { US_DEBUG << " " << child+j << " :: " << GetName(child+j); } #endif // get the hash value for the current segment const uint32_t currHash = static_cast(US_HASH_FUNCTION_NAMESPACE::US_HASH_FUNCTION(std::string,segment)); // do a binary search for the hash int l = 0; int r = childCount-1; int subNode = (l+r+1)/2; while(r != l) { const uint32_t subNodeHash = GetHash(child+subNode); if(currHash == subNodeHash) break; else if(currHash < subNodeHash) r = subNode - 1; else l = subNode; subNode = (l+r+1) / 2; } subNode += child; // now check fo collisions and do compare using equality bool found = false; if(GetHash(subNode) == currHash) { while(subNode > child && GetHash(subNode-1) == currHash) // walk up to include all collisions --subNode; for(; subNode < child+childCount && GetHash(subNode) == currHash; ++subNode) { // now test using name comparison if(GetName(subNode) == segment) { found = true; int offset = FindOffset(subNode); #ifdef DEBUG_RESOURCE_MATCH US_DEBUG << " TRY " << subNode << " " << GetName(subNode) << " " << offset; #endif offset += 4; // jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; if(i == segments.size()-1) { #ifdef DEBUG_RESOURCE_MATCH US_DEBUG << "!!!!" << " FINISHED " << subNode; #endif return subNode; } // if we are not at the end of the resource path and the current // segment is not a directory, return "not found" (this shouldn't happen). if(!(flags & Directory)) return -1; childCount = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); offset += 4; child = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); break; } } } if(!found) { break; } } #ifdef DEBUG_RESOURCE_MATCH US_DEBUG << "***" << " FINISHED " << node; #endif return node; } void ModuleResourceTree::FindNodes(const std::string& _path, const std::string& _filePattern, bool recurse, std::vector& result) { std::string path = _path.empty() ? std::string("/") : _path; if (path[path.size()-1] != '/') path.append("/"); std::string filePattern = _filePattern.empty() ? std::string("*") : _filePattern; int rootNode = FindNode(path); if (rootNode > -1) { this->FindNodes(result, path, rootNode, filePattern, recurse); } } short ModuleResourceTree::GetFlags(int node) const { if(node == -1) return 0; const int offset = FindOffset(node) + 4; //jump past name return (tree[offset+0] << 8) + (tree[offset+1] << 0); } void ModuleResourceTree::FindNodes(std::vector &result, const std::string& path, const int rootNode, const std::string &filePattern, bool recurse) { int offset = FindOffset(rootNode) + 6; // jump past name and type const int childCount = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); offset += 4; const int childNode = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); for(int i = childNode; i < childNode+childCount; ++i) { const int childOffset = FindOffset(i); const short childFlags = (tree[childOffset+4] << 8) + (tree[childOffset+5] << 0); if (!(childFlags & Directory)) { const std::string name = GetName(i); if (this->Matches(name, filePattern)) { result.push_back(path + name); } } else if (recurse) { this->FindNodes(result, path + GetName(i) + "/", i, filePattern, recurse); } } } uint32_t ModuleResourceTree::GetHash(int node) const { if(!node) // root node return 0; const int offset = FindOffset(node); int nameOffset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); nameOffset += 2; // jump past name length return (names[nameOffset+0] << 24) + (names[nameOffset+1] << 16) + (names[nameOffset+2] << 8) + (names[nameOffset+3] << 0); } bool ModuleResourceTree::Matches(const std::string &name, const std::string &filePattern) { // short-cut if (filePattern == "*") return true; std::stringstream ss(filePattern); std::string tok; std::size_t pos = 0; while(std::getline(ss, tok, '*')) { std::size_t index = name.find(tok, pos); if (index == std::string::npos) return false; pos = index + tok.size(); } return true; } const unsigned char* ModuleResourceTree::GetData(int node, int32_t* size) const { if(node == -1) { *size = 0; return 0; } int offset = FindOffset(node) + 4; // jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; offset += 4; // jump past the padding if(!(flags & Directory)) { const int dataOffset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); const int32_t dataLength = (payloads[dataOffset+0] << 24) + (payloads[dataOffset+1] << 16) + (payloads[dataOffset+2] << 8) + (payloads[dataOffset+3] << 0); const unsigned char* ret = payloads+dataOffset+4; *size = dataLength; return ret; } *size = 0; return 0; } void ModuleResourceTree::GetChildren(int node, std::vector& ret) const { if(node == -1) return; int offset = FindOffset(node) + 4; // jump past name const short flags = (tree[offset+0] << 8) + (tree[offset+1] << 0); offset += 2; if(flags & Directory) { const int childCount = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); offset += 4; const int childOffset = (tree[offset+0] << 24) + (tree[offset+1] << 16) + (tree[offset+2] << 8) + (tree[offset+3] << 0); for(int i = childOffset; i < childOffset+childCount; ++i) { ret.push_back(GetName(i)); } } } US_END_NAMESPACE diff --git a/src/module/usModuleResourceTree_p.h b/core/src/module/usModuleResourceTree_p.h similarity index 98% rename from src/module/usModuleResourceTree_p.h rename to core/src/module/usModuleResourceTree_p.h index 038e3434ed..6584ae4203 100644 --- a/src/module/usModuleResourceTree_p.h +++ b/core/src/module/usModuleResourceTree_p.h @@ -1,98 +1,96 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULERESOURCETREE_H #define USMODULERESOURCETREE_H -#include - #include "usModuleInfo.h" -#include "stdint_p.h" +#include "us_stdint.h" #include US_BEGIN_NAMESPACE struct ModuleInfo; /* * This class represents the triple of data pointers * (us_resource_data, us_resource_name, us_resource_tree) generate by * the resource compiler. * * Each module owns zero or one such triple but in case of a statically * linked (imported) module, the resource trees are "merged" together. */ class ModuleResourceTree { private: enum Flags { Directory = 0x01, Compressed = 0x02 }; bool isValid; const unsigned char *tree, *names, *payloads; // Returns the offset in the us_resource_tree array for a given node index inline int FindOffset(int node) const { return node * 14; } // sizeof each tree element std::string GetName(int node) const; short GetFlags(int node) const; void FindNodes(std::vector& result, const std::string& path, const int rootNode, const std::string& filePattern, bool recurse); uint32_t GetHash(int node) const; bool Matches(const std::string& name, const std::string& filePattern); public: ModuleResourceTree(ModuleInfo::ModuleResourceData resourceTree, ModuleInfo::ModuleResourceData resourceNames, ModuleInfo::ModuleResourceData resourceData); bool IsValid() const; void Invalidate(); // Returns an index enumerating the info entries in the us_resource_tree array for // the given resource path. int FindNode(const std::string& path) const; void FindNodes(const std::string& path, const std::string& filePattern, bool recurse, std::vector& result); inline bool IsCompressed(int node) const {return GetFlags(node) & Compressed ? true : false; } inline bool IsDir(int node) const { return GetFlags(node) & Directory ? true : false; } const unsigned char* GetData(int node, int32_t *size) const; void GetChildren(int node, std::vector& children) const; }; US_END_NAMESPACE #endif // USMODULERESOURCETREE_H diff --git a/src/module/usModuleSettings.cpp b/core/src/module/usModuleSettings.cpp similarity index 100% rename from src/module/usModuleSettings.cpp rename to core/src/module/usModuleSettings.cpp diff --git a/src/module/usModuleUtils.cpp b/core/src/module/usModuleUtils.cpp similarity index 100% rename from src/module/usModuleUtils.cpp rename to core/src/module/usModuleUtils.cpp diff --git a/src/module/usModuleUtils_p.h b/core/src/module/usModuleUtils_p.h similarity index 95% rename from src/module/usModuleUtils_p.h rename to core/src/module/usModuleUtils_p.h index 5ce9bd4abf..4a55394e42 100644 --- a/src/module/usModuleUtils_p.h +++ b/core/src/module/usModuleUtils_p.h @@ -1,45 +1,45 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEUTILS_H #define USMODULEUTILS_H -#include +#include #include US_BEGIN_NAMESPACE /** * This class is not intended to be used directly. It is exported to support * the CppMicroServices module system. */ -struct US_EXPORT ModuleUtils +struct US_Core_EXPORT ModuleUtils { static std::string GetLibraryPath(const std::string& libName, void* symbol); static void* GetSymbol(const std::string& libName, const char* symbol); }; US_END_NAMESPACE #endif // USMODULEUTILS_H diff --git a/src/module/usModuleVersion.cpp b/core/src/module/usModuleVersion.cpp similarity index 100% rename from src/module/usModuleVersion.cpp rename to core/src/module/usModuleVersion.cpp diff --git a/src/service/usLDAPExpr.cpp b/core/src/service/usLDAPExpr.cpp similarity index 100% rename from src/service/usLDAPExpr.cpp rename to core/src/service/usLDAPExpr.cpp diff --git a/src/service/usLDAPExpr_p.h b/core/src/service/usLDAPExpr_p.h similarity index 99% rename from src/service/usLDAPExpr_p.h rename to core/src/service/usLDAPExpr_p.h index 2791c08a2d..d1da7fac93 100644 --- a/src/service/usLDAPExpr_p.h +++ b/core/src/service/usLDAPExpr_p.h @@ -1,188 +1,188 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USLDAPEXPR_H #define USLDAPEXPR_H -#include +#include #include "usSharedData.h" #include #include US_BEGIN_NAMESPACE class Any; class LDAPExprData; class ServicePropertiesImpl; /** * This class is not part of the public API. */ class LDAPExpr { public: const static int AND; // = 0; const static int OR; // = 1; const static int NOT; // = 2; const static int EQ; // = 4; const static int LE; // = 8; const static int GE; // = 16; const static int APPROX; // = 32; const static int COMPLEX; // = AND | OR | NOT; const static int SIMPLE; // = EQ | LE | GE | APPROX; typedef char Byte; typedef std::vector StringList; typedef std::vector LocalCache; typedef US_UNORDERED_SET_TYPE ObjectClassSet; /** * Creates an invalid LDAPExpr object. Use with care. * * @see IsNull() */ LDAPExpr(); LDAPExpr(const std::string& filter); LDAPExpr(const LDAPExpr& other); LDAPExpr& operator=(const LDAPExpr& other); ~LDAPExpr(); /** * Get object class set matched by this LDAP expression. This will not work * with wildcards and NOT expressions. If a set can not be determined return false. * * \param objClasses The set of matched classes will be added to objClasses. * \return If the set cannot be determined, false is returned, true otherwise. */ bool GetMatchedObjectClasses(ObjectClassSet& objClasses) const; /** * Checks if this LDAP expression is "simple". The definition of * a simple filter is: *
    *
  • (name=value) is simple if * name is a member of the provided keywords, * and value does not contain a wildcard character;
  • *
  • (| EXPR+ ) is simple if all EXPR * expressions are simple;
  • *
  • No other expressions are simple.
  • *
* If the filter is found to be simple, the cache is * filled with mappings from the provided keywords to lists * of attribute values. The keyword-value-pairs are the ones that * satisfy this expression, for the given keywords. * * @param keywords The keywords to look for. * @param cache An array (indexed by the keyword indexes) of lists to * fill in with values saturating this expression. * @return true if this expression is simple, * false otherwise. */ bool IsSimple( const StringList& keywords, LocalCache& cache, bool matchCase) const; /** * Returns true if this instance is invalid, i.e. it was * constructed using LDAPExpr(). * * @return true if the expression is invalid, * false otherwise. */ bool IsNull() const; //! static bool Query(const std::string& filter, const ServicePropertiesImpl& pd); //! Evaluate this LDAP filter. bool Evaluate(const ServicePropertiesImpl& p, bool matchCase) const; //! const std::string ToString() const; private: class ParseState; //! LDAPExpr(int op, const std::vector& args); //! LDAPExpr(int op, const std::string& attrName, const std::string& attrValue); //! static LDAPExpr ParseExpr(ParseState& ps); //! static LDAPExpr ParseSimple(ParseState& ps); static std::string Trim(std::string str); static std::string ToLower(const std::string& str); //! bool Compare(const Any& obj, int op, const std::string& s) const; //! template bool CompareIntegralType(const Any& obj, const int op, const std::string& s) const; //! static bool CompareString(const std::string& s1, int op, const std::string& s2); //! static std::string FixupString(const std::string &s); //! static bool PatSubstr(const std::string& s, const std::string& pat); //! static bool PatSubstr(const std::string& s, int si, const std::string& pat, int pi); const static Byte WILDCARD; // = 65535; const static std::string WILDCARD_STRING;// = std::string( WILDCARD ); const static std::string NULLQ; // = "Null query"; const static std::string GARBAGE; // = "Trailing garbage"; const static std::string EOS; // = "Unexpected end of query"; const static std::string MALFORMED; // = "Malformed query"; const static std::string OPERATOR; // = "Undefined m_operator"; //! Shared pointer SharedDataPointer d; }; US_END_NAMESPACE #endif // USLDAPEXPR_H diff --git a/src/service/usLDAPFilter.cpp b/core/src/service/usLDAPFilter.cpp similarity index 100% rename from src/service/usLDAPFilter.cpp rename to core/src/service/usLDAPFilter.cpp diff --git a/src/service/usServiceEvent.cpp b/core/src/service/usServiceEvent.cpp similarity index 100% rename from src/service/usServiceEvent.cpp rename to core/src/service/usServiceEvent.cpp diff --git a/src/service/usServiceEventListenerHook.cpp b/core/src/service/usServiceEventListenerHook.cpp similarity index 100% rename from src/service/usServiceEventListenerHook.cpp rename to core/src/service/usServiceEventListenerHook.cpp diff --git a/src/service/usServiceException.cpp b/core/src/service/usServiceException.cpp similarity index 100% rename from src/service/usServiceException.cpp rename to core/src/service/usServiceException.cpp diff --git a/src/service/usServiceFindHook.cpp b/core/src/service/usServiceFindHook.cpp similarity index 100% rename from src/service/usServiceFindHook.cpp rename to core/src/service/usServiceFindHook.cpp diff --git a/src/service/usServiceHooks.cpp b/core/src/service/usServiceHooks.cpp similarity index 100% rename from src/service/usServiceHooks.cpp rename to core/src/service/usServiceHooks.cpp diff --git a/src/service/usServiceHooks_p.h b/core/src/service/usServiceHooks_p.h similarity index 100% rename from src/service/usServiceHooks_p.h rename to core/src/service/usServiceHooks_p.h diff --git a/src/service/usServiceListenerEntry.cpp b/core/src/service/usServiceListenerEntry.cpp similarity index 100% rename from src/service/usServiceListenerEntry.cpp rename to core/src/service/usServiceListenerEntry.cpp diff --git a/src/service/usServiceListenerEntry_p.h b/core/src/service/usServiceListenerEntry_p.h similarity index 100% rename from src/service/usServiceListenerEntry_p.h rename to core/src/service/usServiceListenerEntry_p.h diff --git a/src/service/usServiceListenerHook.cpp b/core/src/service/usServiceListenerHook.cpp similarity index 100% rename from src/service/usServiceListenerHook.cpp rename to core/src/service/usServiceListenerHook.cpp diff --git a/src/service/usServiceListenerHook_p.h b/core/src/service/usServiceListenerHook_p.h similarity index 97% rename from src/service/usServiceListenerHook_p.h rename to core/src/service/usServiceListenerHook_p.h index 322090519b..dfc84dc011 100644 --- a/src/service/usServiceListenerHook_p.h +++ b/core/src/service/usServiceListenerHook_p.h @@ -1,45 +1,43 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef USSERVICELISTENERHOOK_P_H #define USSERVICELISTENERHOOK_P_H -#include - #include "usServiceListenerHook.h" #include "usServiceListenerEntry_p.h" #include "usSharedData.h" US_BEGIN_NAMESPACE class ServiceListenerHook::ListenerInfoData : public SharedData { public: ListenerInfoData(ModuleContext* mc, const ServiceListenerEntry::ServiceListener& l, void* data, const std::string& filter); virtual ~ListenerInfoData(); ModuleContext* const mc; ServiceListenerEntry::ServiceListener listener; void* data; std::string filter; bool bRemoved; }; US_END_NAMESPACE #endif // USSERVICELISTENERHOOK_P_H diff --git a/src/service/usServiceListeners.cpp b/core/src/service/usServiceListeners.cpp similarity index 100% rename from src/service/usServiceListeners.cpp rename to core/src/service/usServiceListeners.cpp diff --git a/src/service/usServiceListeners_p.h b/core/src/service/usServiceListeners_p.h similarity index 99% rename from src/service/usServiceListeners_p.h rename to core/src/service/usServiceListeners_p.h index 51c2bf2ab3..1bd9c10703 100644 --- a/src/service/usServiceListeners_p.h +++ b/core/src/service/usServiceListeners_p.h @@ -1,181 +1,181 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICELISTENERS_H #define USSERVICELISTENERS_H #include #include #include -#include +#include #include "usServiceListenerEntry_p.h" US_BEGIN_NAMESPACE class CoreModuleContext; class ModuleContext; /** * Here we handle all listeners that modules have registered. * */ class ServiceListeners : private MultiThreaded<> { public: typedef US_MODULE_LISTENER_FUNCTOR ModuleListener; typedef US_UNORDERED_MAP_TYPE > > ModuleListenerMap; ModuleListenerMap moduleListenerMap; Mutex moduleListenerMapMutex; typedef US_UNORDERED_MAP_TYPE > CacheType; typedef US_UNORDERED_SET_TYPE ServiceListenerEntries; private: std::vector hashedServiceKeys; static const int OBJECTCLASS_IX; // = 0; static const int SERVICE_ID_IX; // = 1; /* Service listeners with complicated or empty filters */ std::list complicatedListeners; /* Service listeners with "simple" filters are cached. */ CacheType cache[2]; ServiceListenerEntries serviceSet; CoreModuleContext* coreCtx; public: ServiceListeners(CoreModuleContext* coreCtx); /** * Add a new service listener. If an old one exists, and it has the * same owning module, the old listener is removed first. * * @param mc The module context adding this listener. * @param listener The service listener to add. * @param data Additional data to distinguish ServiceListener objects. * @param filter An LDAP filter string to check when a service is modified. * @exception org.osgi.framework.InvalidSyntaxException * If the filter is not a correct LDAP expression. */ void AddServiceListener(ModuleContext* mc, const ServiceListenerEntry::ServiceListener& listener, void* data, const std::string& filter); /** * Remove service listener from current framework. Silently ignore * if listener doesn't exist. If listener is registered more than * once remove all instances. * * @param mc The module context who wants to remove listener. * @param listener Object to remove. * @param data Additional data to distinguish ServiceListener objects. */ void RemoveServiceListener(ModuleContext* mc, const ServiceListenerEntry::ServiceListener& listener, void* data); /** * Add a new module listener. * * @param mc The module context adding this listener. * @param listener The module listener to add. * @param data Additional data to distinguish ModuleListener objects. */ void AddModuleListener(ModuleContext* mc, const ModuleListener& listener, void* data); /** * Remove module listener from current framework. Silently ignore * if listener doesn't exist. * * @param mc The module context who wants to remove listener. * @param listener Object to remove. * @param data Additional data to distinguish ModuleListener objects. */ void RemoveModuleListener(ModuleContext* mc, const ModuleListener& listener, void* data); void ModuleChanged(const ModuleEvent& evt); /** * Remove all listener registered by a module in the current framework. * * @param mc Module context which listeners we want to remove. */ void RemoveAllListeners(ModuleContext* mc); /** * Notify hooks that a module is about to be stopped * * @param mc Module context which listeners are about to be removed. */ void HooksModuleStopped(ModuleContext* mc); /** * Receive notification that a service has had a change occur in its lifecycle. * * @see org.osgi.framework.ServiceListener#serviceChanged */ void ServiceChanged(ServiceListenerEntries& receivers, const ServiceEvent& evt, ServiceListenerEntries& matchBefore); void ServiceChanged(ServiceListenerEntries& receivers, const ServiceEvent& evt); /** * * */ void GetMatchingServiceListeners(const ServiceEvent& evt, ServiceListenerEntries& listeners, bool lockProps = true); std::vector GetListenerInfoCollection() const; private: void RemoveServiceListener_unlocked(const ServiceListenerEntry& entryToRemove); /** * Remove all references to a service listener from the service listener * cache. */ void RemoveFromCache(const ServiceListenerEntry& sle); /** * Checks if the specified service listener's filter is simple enough * to cache. */ void CheckSimple(const ServiceListenerEntry& sle); void AddToSet(ServiceListenerEntries& set, const ServiceListenerEntries& receivers, int cache_ix, const std::string& val); }; US_END_NAMESPACE #endif // USSERVICELISTENERS_H diff --git a/src/service/usServiceObjects.cpp b/core/src/service/usServiceObjects.cpp similarity index 100% rename from src/service/usServiceObjects.cpp rename to core/src/service/usServiceObjects.cpp diff --git a/src/service/usServiceProperties.cpp b/core/src/service/usServiceProperties.cpp similarity index 99% rename from src/service/usServiceProperties.cpp rename to core/src/service/usServiceProperties.cpp index d23acc7712..c7927fc7b8 100644 --- a/src/service/usServiceProperties.cpp +++ b/core/src/service/usServiceProperties.cpp @@ -1,83 +1,82 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usServiceProperties.h" -#include #include US_BEGIN_NAMESPACE const std::string& ServiceConstants::OBJECTCLASS() { static const std::string s("objectclass"); return s; } const std::string& ServiceConstants::SERVICE_ID() { static const std::string s("service.id"); return s; } const std::string& ServiceConstants::SERVICE_RANKING() { static const std::string s("service.ranking"); return s; } const std::string& ServiceConstants::SERVICE_SCOPE() { static const std::string s("service.scope"); return s; } const std::string& ServiceConstants::SCOPE_SINGLETON() { static const std::string s("singleton"); return s; } const std::string& ServiceConstants::SCOPE_MODULE() { static const std::string s("module"); return s; } const std::string& ServiceConstants::SCOPE_PROTOTYPE() { static const std::string s("prototype"); return s; } US_END_NAMESPACE US_USE_NAMESPACE // make sure all static locals get constructed, so that they // can be used in destructors of global statics. std::string tmp1 = ServiceConstants::OBJECTCLASS(); std::string tmp2 = ServiceConstants::SERVICE_ID(); std::string tmp3 = ServiceConstants::SERVICE_RANKING(); std::string tmp4 = ServiceConstants::SERVICE_SCOPE(); std::string tmp5 = ServiceConstants::SCOPE_SINGLETON(); std::string tmp6 = ServiceConstants::SCOPE_MODULE(); std::string tmp7 = ServiceConstants::SCOPE_PROTOTYPE(); diff --git a/src/service/usServicePropertiesImpl.cpp b/core/src/service/usServicePropertiesImpl.cpp similarity index 100% rename from src/service/usServicePropertiesImpl.cpp rename to core/src/service/usServicePropertiesImpl.cpp diff --git a/src/service/usServicePropertiesImpl_p.h b/core/src/service/usServicePropertiesImpl_p.h similarity index 100% rename from src/service/usServicePropertiesImpl_p.h rename to core/src/service/usServicePropertiesImpl_p.h diff --git a/src/service/usServiceReferenceBase.cpp b/core/src/service/usServiceReferenceBase.cpp similarity index 100% rename from src/service/usServiceReferenceBase.cpp rename to core/src/service/usServiceReferenceBase.cpp diff --git a/src/service/usServiceReferenceBasePrivate.cpp b/core/src/service/usServiceReferenceBasePrivate.cpp similarity index 99% rename from src/service/usServiceReferenceBasePrivate.cpp rename to core/src/service/usServiceReferenceBasePrivate.cpp index 913c78f6cb..d5424b6598 100644 --- a/src/service/usServiceReferenceBasePrivate.cpp +++ b/core/src/service/usServiceReferenceBasePrivate.cpp @@ -1,322 +1,320 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include "usServiceReferenceBasePrivate.h" #include "usServiceFactory.h" #include "usServiceException.h" #include "usServiceRegistry_p.h" #include "usServiceRegistrationBasePrivate.h" #include "usModule.h" #include "usModulePrivate.h" #include #include #ifdef _MSC_VER #pragma warning(disable:4503) // decorated name length exceeded, name was truncated #endif US_BEGIN_NAMESPACE ServiceReferenceBasePrivate::ServiceReferenceBasePrivate(ServiceRegistrationBasePrivate* reg) : ref(1), registration(reg) { if(registration) registration->ref.Ref(); } ServiceReferenceBasePrivate::~ServiceReferenceBasePrivate() { if (registration && !registration->ref.Deref()) delete registration; } InterfaceMap ServiceReferenceBasePrivate::GetServiceFromFactory(Module* module, ServiceFactory* factory, bool isModuleScope) { assert(factory && "Factory service pointer is NULL"); InterfaceMap s; try { InterfaceMap smap = factory->GetService(module, ServiceRegistrationBase(registration)); if (smap.empty()) { US_WARN << "ServiceFactory produced null"; return smap; } const std::vector& classes = ref_any_cast >(registration->properties.Value(ServiceConstants::OBJECTCLASS())); for (std::vector::const_iterator i = classes.begin(); i != classes.end(); ++i) { if (smap.find(*i) == smap.end() && *i != "org.cppmicroservices.factory") { US_WARN << "ServiceFactory produced an object " "that did not implement: " << (*i); smap.clear(); return smap; } } s = smap; if (isModuleScope) { registration->moduleServiceInstance.insert(std::make_pair(module, smap)); } else { registration->prototypeServiceInstances[module].push_back(smap); } } catch (...) { US_WARN << "ServiceFactory threw an exception"; s.clear(); } return s; } InterfaceMap ServiceReferenceBasePrivate::GetPrototypeService(Module* module) { InterfaceMap s; { MutexLock lock(registration->propsLock); if (registration->available) { ServiceFactory* factory = reinterpret_cast( registration->GetService("org.cppmicroservices.factory")); s = GetServiceFromFactory(module, factory, false); } } return s; } void* ServiceReferenceBasePrivate::GetService(Module* module) { void* s = NULL; { MutexLock lock(registration->propsLock); if (registration->available) { ServiceFactory* serviceFactory = reinterpret_cast( registration->GetService("org.cppmicroservices.factory")); const int count = registration->dependents[module]; if (count == 0) { if (serviceFactory) { const InterfaceMap im = GetServiceFromFactory(module, serviceFactory, true); s = im.find(interfaceId)->second; } else { s = registration->GetService(interfaceId); } } else { if (serviceFactory) { // return the already produced instance s = registration->moduleServiceInstance[module][interfaceId]; } else { s = registration->GetService(interfaceId); } } if (s) { registration->dependents[module] = count + 1; } } } return s; } InterfaceMap ServiceReferenceBasePrivate::GetServiceInterfaceMap(Module* module) { InterfaceMap s; { MutexLock lock(registration->propsLock); if (registration->available) { ServiceFactory* serviceFactory = reinterpret_cast( registration->GetService("org.cppmicroservices.factory")); const int count = registration->dependents[module]; if (count == 0) { if (serviceFactory) { s = GetServiceFromFactory(module, serviceFactory, true); } else { s = registration->service; } } else { if (serviceFactory) { // return the already produced instance s = registration->moduleServiceInstance[module]; } else { s = registration->service; } } if (!s.empty()) { registration->dependents[module] = count + 1; } } } return s; } bool ServiceReferenceBasePrivate::UngetPrototypeService(Module* module, const InterfaceMap& service) { MutexLock lock(registration->propsLock); ServiceRegistrationBasePrivate::ModuleToServicesMap::iterator iter = registration->prototypeServiceInstances.find(module); if (iter == registration->prototypeServiceInstances.end()) { return false; } std::list& prototypeServiceMaps = iter->second; for (std::list::iterator imIter = prototypeServiceMaps.begin(); imIter != prototypeServiceMaps.end(); ++imIter) { if (service == *imIter) { try { ServiceFactory* sf = reinterpret_cast( registration->GetService("org.cppmicroservices.factory")); sf->UngetService(module, ServiceRegistrationBase(registration), service); } catch (const std::exception& /*e*/) { US_WARN << "ServiceFactory threw an exception"; } prototypeServiceMaps.erase(imIter); if (prototypeServiceMaps.empty()) { registration->prototypeServiceInstances.erase(iter); } return true; } } return false; } bool ServiceReferenceBasePrivate::UngetService(Module* module, bool checkRefCounter) { MutexLock lock(registration->propsLock); bool hadReferences = false; bool removeService = false; int count= registration->dependents[module]; if (count > 0) { hadReferences = true; } if(checkRefCounter) { if (count > 1) { registration->dependents[module] = count - 1; } else if(count == 1) { removeService = true; } } else { removeService = true; } if (removeService) { InterfaceMap sfi = registration->moduleServiceInstance[module]; registration->moduleServiceInstance.erase(module); if (!sfi.empty()) { try { ServiceFactory* sf = reinterpret_cast( registration->GetService("org.cppmicroservices.factory")); sf->UngetService(module, ServiceRegistrationBase(registration), sfi); } catch (const std::exception& /*e*/) { US_WARN << "ServiceFactory threw an exception"; } } registration->dependents.erase(module); } return hadReferences && removeService; } const ServicePropertiesImpl& ServiceReferenceBasePrivate::GetProperties() const { return registration->properties; } Any ServiceReferenceBasePrivate::GetProperty(const std::string& key, bool lock) const { if (lock) { MutexLock lock(registration->propsLock); return registration->properties.Value(key); } else { return registration->properties.Value(key); } } bool ServiceReferenceBasePrivate::IsConvertibleTo(const std::string& interfaceId) const { return registration ? registration->service.find(interfaceId) != registration->service.end() : false; } US_END_NAMESPACE diff --git a/src/service/usServiceReferenceBasePrivate.h b/core/src/service/usServiceReferenceBasePrivate.h similarity index 100% rename from src/service/usServiceReferenceBasePrivate.h rename to core/src/service/usServiceReferenceBasePrivate.h diff --git a/src/service/usServiceRegistrationBase.cpp b/core/src/service/usServiceRegistrationBase.cpp similarity index 99% rename from src/service/usServiceRegistrationBase.cpp rename to core/src/service/usServiceRegistrationBase.cpp index bbab8bad4b..18e1fb40f5 100644 --- a/src/service/usServiceRegistrationBase.cpp +++ b/core/src/service/usServiceRegistrationBase.cpp @@ -1,273 +1,271 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include "usServiceRegistrationBase.h" #include "usServiceRegistrationBasePrivate.h" #include "usServiceListenerEntry_p.h" #include "usServiceRegistry_p.h" #include "usServiceFactory.h" #include "usModulePrivate.h" #include "usCoreModuleContext_p.h" #include US_BEGIN_NAMESPACE ServiceRegistrationBase::ServiceRegistrationBase() : d(0) { } ServiceRegistrationBase::ServiceRegistrationBase(const ServiceRegistrationBase& reg) : d(reg.d) { if (d) d->ref.Ref(); } ServiceRegistrationBase::ServiceRegistrationBase(ServiceRegistrationBasePrivate* registrationPrivate) : d(registrationPrivate) { if (d) d->ref.Ref(); } ServiceRegistrationBase::ServiceRegistrationBase(ModulePrivate* module, const InterfaceMap& service, const ServicePropertiesImpl& props) : d(new ServiceRegistrationBasePrivate(module, service, props)) { } ServiceRegistrationBase::operator bool_type() const { return d != NULL ? &ServiceRegistrationBase::d : NULL; } ServiceRegistrationBase& ServiceRegistrationBase::operator=(int null) { if (null == 0) { if (d && !d->ref.Deref()) { delete d; } d = 0; } return *this; } ServiceRegistrationBase::~ServiceRegistrationBase() { if (d && !d->ref.Deref()) delete d; } ServiceReferenceBase ServiceRegistrationBase::GetReference(const std::string& interfaceId) const { if (!d) throw std::logic_error("ServiceRegistrationBase object invalid"); if (!d->available) throw std::logic_error("Service is unregistered"); ServiceReferenceBase ref = d->reference; ref.SetInterfaceId(interfaceId); return ref; } void ServiceRegistrationBase::SetProperties(const ServiceProperties& props) { if (!d) throw std::logic_error("ServiceRegistrationBase object invalid"); MutexLock lock(d->eventLock); ServiceEvent modifiedEndMatchEvent(ServiceEvent::MODIFIED_ENDMATCH, d->reference); ServiceListeners::ServiceListenerEntries before; // TBD, optimize the locking of services { //MutexLock lock2(d->module->coreCtx->globalFwLock); if (d->available) { // NYI! Optimize the MODIFIED_ENDMATCH code int old_rank = 0; int new_rank = 0; std::vector classes; { MutexLock lock3(d->propsLock); { const Any& any = d->properties.Value(ServiceConstants::SERVICE_RANKING()); if (any.Type() == typeid(int)) old_rank = any_cast(any); } d->module->coreCtx->listeners.GetMatchingServiceListeners(modifiedEndMatchEvent, before, false); classes = ref_any_cast >(d->properties.Value(ServiceConstants::OBJECTCLASS())); long int sid = any_cast(d->properties.Value(ServiceConstants::SERVICE_ID())); d->properties = ServiceRegistry::CreateServiceProperties(props, classes, false, false, sid); { const Any& any = d->properties.Value(ServiceConstants::SERVICE_RANKING()); if (any.Type() == typeid(int)) new_rank = any_cast(any); } } if (old_rank != new_rank) { d->module->coreCtx->services.UpdateServiceRegistrationOrder(*this, classes); } } else { throw std::logic_error("Service is unregistered"); } } ServiceEvent modifiedEvent(ServiceEvent::MODIFIED, d->reference); ServiceListeners::ServiceListenerEntries matchingListeners; d->module->coreCtx->listeners.GetMatchingServiceListeners(modifiedEvent, matchingListeners); d->module->coreCtx->listeners.ServiceChanged(matchingListeners, modifiedEvent, before); d->module->coreCtx->listeners.ServiceChanged(before, modifiedEndMatchEvent); } void ServiceRegistrationBase::Unregister() { if (!d) throw std::logic_error("ServiceRegistrationBase object invalid"); if (d->unregistering) return; // Silently ignore redundant unregistration. { MutexLock lock(d->eventLock); if (d->unregistering) return; d->unregistering = true; if (d->available) { if (d->module) { d->module->coreCtx->services.RemoveServiceRegistration(*this); } } else { throw std::logic_error("Service is unregistered"); } } if (d->module) { ServiceListeners::ServiceListenerEntries listeners; ServiceEvent unregisteringEvent(ServiceEvent::UNREGISTERING, d->reference); d->module->coreCtx->listeners.GetMatchingServiceListeners(unregisteringEvent, listeners); d->module->coreCtx->listeners.ServiceChanged( listeners, unregisteringEvent); } { MutexLock lock(d->eventLock); { MutexLock lock2(d->propsLock); d->available = false; InterfaceMap::const_iterator factoryIter = d->service.find("org.cppmicroservices.factory"); if (d->module && factoryIter != d->service.end()) { ServiceFactory* serviceFactory = reinterpret_cast(factoryIter->second); ServiceRegistrationBasePrivate::ModuleToServicesMap::const_iterator end = d->prototypeServiceInstances.end(); // unget all prototype services for (ServiceRegistrationBasePrivate::ModuleToServicesMap::const_iterator i = d->prototypeServiceInstances.begin(); i != end; ++i) { for (std::list::const_iterator listIter = i->second.begin(); listIter != i->second.end(); ++listIter) { const InterfaceMap& service = *listIter; try { // NYI, don't call inside lock serviceFactory->UngetService(i->first, *this, service); } catch (const std::exception& /*ue*/) { US_WARN << "ServiceFactory UngetService implementation threw an exception"; } } } // unget module scope services ServiceRegistrationBasePrivate::ModuleToServiceMap::const_iterator moduleEnd = d->moduleServiceInstance.end(); for (ServiceRegistrationBasePrivate::ModuleToServiceMap::const_iterator i = d->moduleServiceInstance.begin(); i != moduleEnd; ++i) { try { // NYI, don't call inside lock serviceFactory->UngetService(i->first, *this, i->second); } catch (const std::exception& /*ue*/) { US_WARN << "ServiceFactory UngetService implementation threw an exception"; } } } d->module = 0; d->dependents.clear(); d->service.clear(); d->prototypeServiceInstances.clear(); d->moduleServiceInstance.clear(); // increment the reference count, since "d->reference" was used originally // to keep d alive. d->ref.Ref(); d->reference = 0; d->unregistering = false; } } } bool ServiceRegistrationBase::operator<(const ServiceRegistrationBase& o) const { if ((!d && !o.d) || !o.d) return false; if (!d) return true; return d->reference <(o.d->reference); } bool ServiceRegistrationBase::operator==(const ServiceRegistrationBase& registration) const { return d == registration.d; } ServiceRegistrationBase& ServiceRegistrationBase::operator=(const ServiceRegistrationBase& registration) { ServiceRegistrationBasePrivate* curr_d = d; d = registration.d; if (d) d->ref.Ref(); if (curr_d && !curr_d->ref.Deref()) delete curr_d; return *this; } US_END_NAMESPACE diff --git a/src/service/usServiceRegistrationBasePrivate.cpp b/core/src/service/usServiceRegistrationBasePrivate.cpp similarity index 100% rename from src/service/usServiceRegistrationBasePrivate.cpp rename to core/src/service/usServiceRegistrationBasePrivate.cpp diff --git a/src/service/usServiceRegistrationBasePrivate.h b/core/src/service/usServiceRegistrationBasePrivate.h similarity index 100% rename from src/service/usServiceRegistrationBasePrivate.h rename to core/src/service/usServiceRegistrationBasePrivate.h diff --git a/src/service/usServiceRegistry.cpp b/core/src/service/usServiceRegistry.cpp similarity index 99% rename from src/service/usServiceRegistry.cpp rename to core/src/service/usServiceRegistry.cpp index 5841b382d8..c6df274ef1 100644 --- a/src/service/usServiceRegistry.cpp +++ b/core/src/service/usServiceRegistry.cpp @@ -1,338 +1,336 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include #include #include "usServiceRegistry_p.h" #include "usServiceFactory.h" #include "usPrototypeServiceFactory.h" #include "usServiceRegistry_p.h" #include "usServiceRegistrationBasePrivate.h" #include "usModulePrivate.h" #include "usCoreModuleContext_p.h" US_BEGIN_NAMESPACE ServicePropertiesImpl ServiceRegistry::CreateServiceProperties(const ServiceProperties& in, const std::vector& classes, bool isFactory, bool isPrototypeFactory, long sid) { static long nextServiceID = 1; ServiceProperties props(in); if (!classes.empty()) { props.insert(std::make_pair(ServiceConstants::OBJECTCLASS(), classes)); } props.insert(std::make_pair(ServiceConstants::SERVICE_ID(), sid != -1 ? sid : nextServiceID++)); if (isPrototypeFactory) { props.insert(std::make_pair(ServiceConstants::SERVICE_SCOPE(), ServiceConstants::SCOPE_PROTOTYPE())); } else if (isFactory) { props.insert(std::make_pair(ServiceConstants::SERVICE_SCOPE(), ServiceConstants::SCOPE_MODULE())); } else { props.insert(std::make_pair(ServiceConstants::SERVICE_SCOPE(), ServiceConstants::SCOPE_SINGLETON())); } return ServicePropertiesImpl(props); } ServiceRegistry::ServiceRegistry(CoreModuleContext* coreCtx) : core(coreCtx) { } ServiceRegistry::~ServiceRegistry() { Clear(); } void ServiceRegistry::Clear() { services.clear(); serviceRegistrations.clear(); classServices.clear(); core = 0; } ServiceRegistrationBase ServiceRegistry::RegisterService(ModulePrivate* module, const InterfaceMap& service, const ServiceProperties& properties) { if (service.empty()) { throw std::invalid_argument("Can't register empty InterfaceMap as a service"); } // Check if we got a service factory bool isFactory = service.count("org.cppmicroservices.factory") > 0; bool isPrototypeFactory = (isFactory ? dynamic_cast(reinterpret_cast(service.find("org.cppmicroservices.factory")->second)) != NULL : false); std::vector classes; // Check if service implements claimed classes and that they exist. for (InterfaceMap::const_iterator i = service.begin(); i != service.end(); ++i) { if (i->first.empty() || (!isFactory && i->second == NULL)) { throw std::invalid_argument("Can't register as null class"); } classes.push_back(i->first); } ServiceRegistrationBase res(module, service, CreateServiceProperties(properties, classes, isFactory, isPrototypeFactory)); { MutexLock lock(mutex); services.insert(std::make_pair(res, classes)); serviceRegistrations.push_back(res); for (std::vector::const_iterator i = classes.begin(); i != classes.end(); ++i) { std::vector& s = classServices[*i]; std::vector::iterator ip = std::lower_bound(s.begin(), s.end(), res); s.insert(ip, res); } } ServiceReferenceBase r = res.GetReference(std::string()); ServiceListeners::ServiceListenerEntries listeners; ServiceEvent registeredEvent(ServiceEvent::REGISTERED, r); module->coreCtx->listeners.GetMatchingServiceListeners(registeredEvent, listeners); module->coreCtx->listeners.ServiceChanged(listeners, registeredEvent); return res; } void ServiceRegistry::UpdateServiceRegistrationOrder(const ServiceRegistrationBase& sr, const std::vector& classes) { MutexLock lock(mutex); for (std::vector::const_iterator i = classes.begin(); i != classes.end(); ++i) { std::vector& s = classServices[*i]; s.erase(std::remove(s.begin(), s.end(), sr), s.end()); s.insert(std::lower_bound(s.begin(), s.end(), sr), sr); } } void ServiceRegistry::Get(const std::string& clazz, std::vector& serviceRegs) const { MutexLock lock(mutex); Get_unlocked(clazz, serviceRegs); } void ServiceRegistry::Get_unlocked(const std::string& clazz, std::vector& serviceRegs) const { MapClassServices::const_iterator i = classServices.find(clazz); if (i != classServices.end()) { serviceRegs = i->second; } } ServiceReferenceBase ServiceRegistry::Get(ModulePrivate* module, const std::string& clazz) const { MutexLock lock(mutex); try { std::vector srs; Get_unlocked(clazz, "", module, srs); US_DEBUG << "get service ref " << clazz << " for module " << module->info.name << " = " << srs.size() << " refs"; if (!srs.empty()) { return srs.back(); } } catch (const std::invalid_argument& ) { } return ServiceReferenceBase(); } void ServiceRegistry::Get(const std::string& clazz, const std::string& filter, ModulePrivate* module, std::vector& res) const { MutexLock lock(mutex); Get_unlocked(clazz, filter, module, res); } void ServiceRegistry::Get_unlocked(const std::string& clazz, const std::string& filter, ModulePrivate* module, std::vector& res) const { std::vector::const_iterator s; std::vector::const_iterator send; std::vector v; LDAPExpr ldap; if (clazz.empty()) { if (!filter.empty()) { ldap = LDAPExpr(filter); LDAPExpr::ObjectClassSet matched; if (ldap.GetMatchedObjectClasses(matched)) { v.clear(); for(LDAPExpr::ObjectClassSet::const_iterator className = matched.begin(); className != matched.end(); ++className) { MapClassServices::const_iterator i = classServices.find(*className); if (i != classServices.end()) { std::copy(i->second.begin(), i->second.end(), std::back_inserter(v)); } } if (!v.empty()) { s = v.begin(); send = v.end(); } else { return; } } else { s = serviceRegistrations.begin(); send = serviceRegistrations.end(); } } else { s = serviceRegistrations.begin(); send = serviceRegistrations.end(); } } else { MapClassServices::const_iterator it = classServices.find(clazz); if (it != classServices.end()) { s = it->second.begin(); send = it->second.end(); } else { return; } if (!filter.empty()) { ldap = LDAPExpr(filter); } } for (; s != send; ++s) { ServiceReferenceBase sri = s->GetReference(clazz); if (filter.empty() || ldap.Evaluate(s->d->properties, false)) { res.push_back(sri); } } if (!res.empty()) { if (module != NULL) { core->serviceHooks.FilterServiceReferences(module->moduleContext, clazz, filter, res); } else { core->serviceHooks.FilterServiceReferences(NULL, clazz, filter, res); } } } void ServiceRegistry::RemoveServiceRegistration(const ServiceRegistrationBase& sr) { MutexLock lock(mutex); const std::vector& classes = ref_any_cast >( sr.d->properties.Value(ServiceConstants::OBJECTCLASS())); services.erase(sr); serviceRegistrations.erase(std::remove(serviceRegistrations.begin(), serviceRegistrations.end(), sr), serviceRegistrations.end()); for (std::vector::const_iterator i = classes.begin(); i != classes.end(); ++i) { std::vector& s = classServices[*i]; if (s.size() > 1) { s.erase(std::remove(s.begin(), s.end(), sr), s.end()); } else { classServices.erase(*i); } } } void ServiceRegistry::GetRegisteredByModule(ModulePrivate* p, std::vector& res) const { MutexLock lock(mutex); for (std::vector::const_iterator i = serviceRegistrations.begin(); i != serviceRegistrations.end(); ++i) { if (i->d->module == p) { res.push_back(*i); } } } void ServiceRegistry::GetUsedByModule(Module* p, std::vector& res) const { MutexLock lock(mutex); for (std::vector::const_iterator i = serviceRegistrations.begin(); i != serviceRegistrations.end(); ++i) { if (i->d->IsUsedByModule(p)) { res.push_back(*i); } } } US_END_NAMESPACE diff --git a/src/service/usServiceRegistry_p.h b/core/src/service/usServiceRegistry_p.h similarity index 100% rename from src/service/usServiceRegistry_p.h rename to core/src/service/usServiceRegistry_p.h diff --git a/src/service/usServiceTracker.tpp b/core/src/service/usServiceTracker.tpp similarity index 100% rename from src/service/usServiceTracker.tpp rename to core/src/service/usServiceTracker.tpp diff --git a/src/service/usServiceTrackerPrivate.h b/core/src/service/usServiceTrackerPrivate.h similarity index 100% rename from src/service/usServiceTrackerPrivate.h rename to core/src/service/usServiceTrackerPrivate.h diff --git a/src/service/usServiceTrackerPrivate.tpp b/core/src/service/usServiceTrackerPrivate.tpp similarity index 100% rename from src/service/usServiceTrackerPrivate.tpp rename to core/src/service/usServiceTrackerPrivate.tpp diff --git a/src/service/usTrackedService.tpp b/core/src/service/usTrackedService.tpp similarity index 100% rename from src/service/usTrackedService.tpp rename to core/src/service/usTrackedService.tpp diff --git a/src/service/usTrackedServiceListener_p.h b/core/src/service/usTrackedServiceListener_p.h similarity index 100% rename from src/service/usTrackedServiceListener_p.h rename to core/src/service/usTrackedServiceListener_p.h diff --git a/src/service/usTrackedService_p.h b/core/src/service/usTrackedService_p.h similarity index 100% rename from src/service/usTrackedService_p.h rename to core/src/service/usTrackedService_p.h diff --git a/src/util/dirent_win32_p.h b/core/src/util/dirent_win32_p.h similarity index 100% rename from src/util/dirent_win32_p.h rename to core/src/util/dirent_win32_p.h diff --git a/src/util/json_p.h b/core/src/util/json_p.h similarity index 100% rename from src/util/json_p.h rename to core/src/util/json_p.h diff --git a/src/util/jsoncpp.cpp b/core/src/util/jsoncpp.cpp similarity index 100% rename from src/util/jsoncpp.cpp rename to core/src/util/jsoncpp.cpp diff --git a/src/util/tinfl.c b/core/src/util/tinfl.c similarity index 100% rename from src/util/tinfl.c rename to core/src/util/tinfl.c diff --git a/src/util/usAny.cpp b/core/src/util/usAny.cpp similarity index 100% rename from src/util/usAny.cpp rename to core/src/util/usAny.cpp diff --git a/src/util/usAtomicInt_p.h b/core/src/util/usAtomicInt_p.h similarity index 98% rename from src/util/usAtomicInt_p.h rename to core/src/util/usAtomicInt_p.h index 99622bf0df..7f4cb098a8 100644 --- a/src/util/usAtomicInt_p.h +++ b/core/src/util/usAtomicInt_p.h @@ -1,79 +1,79 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USATOMICINT_H #define USATOMICINT_H -#include +#include #include "usThreads_p.h" US_BEGIN_NAMESPACE /** * This class acts as an atomic integer. * * The integer value represented by this class can be incremented * and decremented atomically. This is often useful in reference * counting scenarios to minimize locking overhead in multi-threaded * environments. */ class AtomicInt : private AtomicCounter { public: AtomicInt(int value = 0) : AtomicCounter(value) {} /** * Increase the reference count atomically by 1. * * \return true if the new value is unequal to zero, false * otherwise. */ inline bool Ref() const { return AtomicIncrement() != 0; } /** * Decrease the reference count atomically by 1. * * \return true if the new value is unequal to zero, false * otherwise. */ inline bool Deref() const { return AtomicDecrement() != 0; } /** * Returns the current value. * */ inline operator int() const { IntType curr(0); AtomicAssign(curr); return curr; } }; US_END_NAMESPACE #endif // USATOMICINT_H diff --git a/src/util/usLDAPProp.cpp b/core/src/util/usLDAPProp.cpp similarity index 100% rename from src/util/usLDAPProp.cpp rename to core/src/util/usLDAPProp.cpp diff --git a/src/util/usListenerFunctors_p.h b/core/src/util/usListenerFunctors_p.h similarity index 99% rename from src/util/usListenerFunctors_p.h rename to core/src/util/usListenerFunctors_p.h index 4f6037e317..4239fba1db 100644 --- a/src/util/usListenerFunctors_p.h +++ b/core/src/util/usListenerFunctors_p.h @@ -1,86 +1,85 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USLISTENERFUNCTORS_P_H #define USLISTENERFUNCTORS_P_H -#include #include #include #include #include #ifdef US_HAVE_TR1_FUNCTIONAL_H #include #elif defined(US_HAVE_FUNCTIONAL_H) #include #endif #ifdef US_HAVE_STD_FUNCTION #define US_FUNCTION_TYPE std::function #elif defined(US_HAVE_TR1_FUNCTION) #define US_FUNCTION_TYPE std::tr1::function #endif #define US_MODULE_LISTENER_FUNCTOR US_FUNCTION_TYPE #define US_SERVICE_LISTENER_FUNCTOR US_FUNCTION_TYPE US_BEGIN_NAMESPACE template US_MODULE_LISTENER_FUNCTOR ModuleListenerMemberFunctor(X* x, void (X::*memFn)(const US_PREPEND_NAMESPACE(ModuleEvent))) { return std::bind1st(std::mem_fun(memFn), x); } struct ModuleListenerCompare : std::binary_function, std::pair, bool> { bool operator()(const std::pair& p1, const std::pair& p2) const { return p1.second == p2.second && p1.first.target() == p2.first.target(); } }; template US_SERVICE_LISTENER_FUNCTOR ServiceListenerMemberFunctor(X* x, void (X::*memFn)(const US_PREPEND_NAMESPACE(ServiceEvent))) { return std::bind1st(std::mem_fun(memFn), x); } struct ServiceListenerCompare : std::binary_function { bool operator()(const US_SERVICE_LISTENER_FUNCTOR& f1, const US_SERVICE_LISTENER_FUNCTOR& f2) const { return f1.target() == f2.target(); } }; US_END_NAMESPACE US_HASH_FUNCTION_NAMESPACE_BEGIN US_HASH_FUNCTION_BEGIN(US_SERVICE_LISTENER_FUNCTOR) void(*targetFunc)(const US_PREPEND_NAMESPACE(ServiceEvent)&) = arg.target(); void* targetPtr = NULL; std::memcpy(&targetPtr, &targetFunc, sizeof(void*)); return US_HASH_FUNCTION(void*, targetPtr); US_HASH_FUNCTION_END US_HASH_FUNCTION_NAMESPACE_END #endif // USLISTENERFUNCTORS_P_H diff --git a/src/util/usLog_p.h b/core/src/util/usLog_p.h similarity index 96% rename from src/util/usLog_p.h rename to core/src/util/usLog_p.h index 33cc97be5f..bd65a8f9dd 100644 --- a/src/util/usLog_p.h +++ b/core/src/util/usLog_p.h @@ -1,99 +1,99 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USLOG_P_H #define USLOG_P_H -#include +#include #include #include US_BEGIN_NAMESPACE -US_EXPORT void message_output(MsgType, const char* buf); +US_Core_EXPORT void message_output(MsgType, const char* buf); struct LogMsg { LogMsg(int t, const char* file, int ln, const char* func) : type(static_cast(t)), enabled(true), buffer() { buffer << "In " << func << " at " << file << ":" << ln << " : "; } ~LogMsg() { if(enabled) message_output(type, buffer.str().c_str()); } template LogMsg& operator<<(T t) { if (enabled) buffer << t; return *this; } LogMsg& operator()(bool flag) { this->enabled = flag; return *this; } private: MsgType type; bool enabled; std::stringstream buffer; }; struct NoLogMsg { template NoLogMsg& operator<<(T) { return *this; } NoLogMsg& operator()(bool) { return *this; } }; US_END_NAMESPACE #if defined(US_ENABLE_DEBUG_OUTPUT) #define US_DEBUG US_PREPEND_NAMESPACE(LogMsg)(0, __FILE__, __LINE__, __FUNCTION__) #else #define US_DEBUG true ? US_PREPEND_NAMESPACE(NoLogMsg)() : US_PREPEND_NAMESPACE(NoLogMsg)() #endif #if !defined(US_NO_INFO_OUTPUT) #define US_INFO US_PREPEND_NAMESPACE(LogMsg)(1, __FILE__, __LINE__, __FUNCTION__) #else #define US_INFO true ? US_PREPEND_NAMESPACE(NoLogMsg)() : US_PREPEND_NAMESPACE(NoLogMsg)() #endif #if !defined(US_NO_WARNING_OUTPUT) #define US_WARN US_PREPEND_NAMESPACE(LogMsg)(2, __FILE__, __LINE__, __FUNCTION__) #else #define US_WARN true ? US_PREPEND_NAMESPACE(LogMsg)() : US_PREPEND_NAMESPACE(LogMsg)() #endif #define US_ERROR US_PREPEND_NAMESPACE(LogMsg)(3, __FILE__, __LINE__, __FUNCTION__) #endif // USLOG_P_H diff --git a/src/util/usSharedLibrary.cpp b/core/src/util/usSharedLibrary.cpp similarity index 100% rename from src/util/usSharedLibrary.cpp rename to core/src/util/usSharedLibrary.cpp diff --git a/src/util/usStaticInit_p.h b/core/src/util/usStaticInit_p.h similarity index 99% rename from src/util/usStaticInit_p.h rename to core/src/util/usStaticInit_p.h index abc5eee337..1614e1a499 100644 --- a/src/util/usStaticInit_p.h +++ b/core/src/util/usStaticInit_p.h @@ -1,169 +1,168 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Extracted from qglobal.h from Qt 4.7.3 and adapted for CppMicroServices. Original copyright (c) Nokia Corporation. Usage covered by the GNU Lesser General Public License version 2.1 (http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) and the Nokia Qt LGPL Exception version 1.1 (file LGPL_EXCEPTION.txt in Qt 4.7.3 package). =========================================================================*/ #ifndef US_STATIC_INIT_H #define US_STATIC_INIT_H -#include #include "usThreads_p.h" US_BEGIN_NAMESPACE // POD for US_GLOBAL_STATIC template class GlobalStatic : public MultiThreaded<> { public: GlobalStatic(T* p = 0, bool destroyed = false) : pointer(p), destroyed(destroyed) {} T* pointer; bool destroyed; private: // purposely not implemented GlobalStatic(const GlobalStatic&); GlobalStatic& operator=(const GlobalStatic&); }; template struct DefaultGlobalStaticDeleter { void operator()(GlobalStatic& globalStatic) const { delete globalStatic.pointer; globalStatic.pointer = 0; globalStatic.destroyed = true; } }; // Created as a function-local static to delete a GlobalStatic template class Deleter = DefaultGlobalStaticDeleter> class GlobalStaticDeleter { public: GlobalStatic &globalStatic; GlobalStaticDeleter(GlobalStatic &_globalStatic) : globalStatic(_globalStatic) { } inline ~GlobalStaticDeleter() { Deleter deleter; deleter(globalStatic); } }; US_END_NAMESPACE #define US_GLOBAL_STATIC_INIT(TYPE, NAME) \ static US_PREPEND_NAMESPACE(GlobalStatic)& this_##NAME() \ { \ static US_PREPEND_NAMESPACE(GlobalStatic) l; \ return l; \ } #define US_GLOBAL_STATIC(TYPE, NAME) \ US_GLOBAL_STATIC_INIT(TYPE, NAME) \ static TYPE *NAME() \ { \ if (!this_##NAME().pointer && !this_##NAME().destroyed) \ { \ TYPE *x = new TYPE; \ bool ok = false; \ { \ US_PREPEND_NAMESPACE(GlobalStatic)::Lock lock(this_##NAME()); \ US_UNUSED(lock); \ if (!this_##NAME().pointer) \ { \ this_##NAME().pointer = x; \ ok = true; \ } \ } \ if (!ok) \ delete x; \ else \ static US_PREPEND_NAMESPACE(GlobalStaticDeleter) cleanup(this_##NAME()); \ } \ return this_##NAME().pointer; \ } #define US_GLOBAL_STATIC_WITH_DELETER(TYPE, NAME, DELETER) \ US_GLOBAL_STATIC_INIT(TYPE, NAME) \ static TYPE *NAME() \ { \ if (!this_##NAME().pointer && !this_##NAME().destroyed) \ { \ TYPE *x = new TYPE; \ bool ok = false; \ { \ US_PREPEND_NAMESPACE(GlobalStatic)::Lock lock(this_##NAME()); \ US_UNUSED(lock); \ if (!this_##NAME().pointer) \ { \ this_##NAME().pointer = x; \ ok = true; \ } \ } \ if (!ok) \ delete x; \ else \ static US_PREPEND_NAMESPACE(GlobalStaticDeleter) cleanup(this_##NAME()); \ } \ return this_##NAME().pointer; \ } #define US_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ US_GLOBAL_STATIC_INIT(TYPE, NAME) \ static TYPE *NAME() \ { \ if (!this_##NAME().pointer && !this_##NAME().destroyed) \ { \ TYPE *x = new TYPE ARGS; \ bool ok = false; \ { \ US_PREPEND_NAMESPACE(GlobalStatic)::Lock lock(this_##NAME()); \ US_UNUSED(lock); \ if (!this_##NAME().pointer) \ { \ this_##NAME().pointer = x; \ ok = true; \ } \ } \ if (!ok) \ delete x; \ else \ static US_PREPEND_NAMESPACE(GlobalStaticDeleter) cleanup(this_##NAME()); \ } \ return this_##NAME().pointer; \ } #endif // US_STATIC_INIT_H diff --git a/src/util/usThreads_p.h b/core/src/util/usThreads_p.h similarity index 99% rename from src/util/usThreads_p.h rename to core/src/util/usThreads_p.h index ea7fc8aa67..b0318c8d4e 100644 --- a/src/util/usThreads_p.h +++ b/core/src/util/usThreads_p.h @@ -1,329 +1,329 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USTHREADINGMODEL_H #define USTHREADINGMODEL_H -#include +#include #ifdef US_ENABLE_THREADING_SUPPORT // Atomic compiler intrinsics #if defined(US_PLATFORM_APPLE) // OSAtomic.h optimizations only used in 10.5 and later #include #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 #include #define US_ATOMIC_OPTIMIZATION_APPLE #endif #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) # include #else # include #endif #define US_ATOMIC_OPTIMIZATION_GNUC #endif // Mutex support #ifdef US_PLATFORM_WINDOWS #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef NOMINMAX #define NOMINMAX #endif #include #define US_THREADS_MUTEX(x) HANDLE (x); #define US_THREADS_MUTEX_INIT(x) #define US_THREADS_MUTEX_CTOR(x) : x(::CreateMutex(NULL, FALSE, NULL)) #define US_THREADS_MUTEX_DELETE(x) ::CloseHandle (x) #define US_THREADS_MUTEX_LOCK(x) ::WaitForSingleObject (x, INFINITE) #define US_THREADS_MUTEX_UNLOCK(x) ::ReleaseMutex (x) #define US_THREADS_LONG LONG #define US_ATOMIC_OPTIMIZATION #define US_ATOMIC_INCREMENT(x) IntType n = InterlockedIncrement(x) #define US_ATOMIC_DECREMENT(x) IntType n = InterlockedDecrement(x) #define US_ATOMIC_ASSIGN(l, r) InterlockedExchange(l, r) #elif defined(US_PLATFORM_POSIX) #include #define US_THREADS_MUTEX(x) pthread_mutex_t (x); #define US_THREADS_MUTEX_INIT(x) ::pthread_mutex_init(&x, 0) #define US_THREADS_MUTEX_CTOR(x) : x() #define US_THREADS_MUTEX_DELETE(x) ::pthread_mutex_destroy (&x) #define US_THREADS_MUTEX_LOCK(x) ::pthread_mutex_lock (&x) #define US_THREADS_MUTEX_UNLOCK(x) ::pthread_mutex_unlock (&x) #define US_ATOMIC_OPTIMIZATION #if defined(US_ATOMIC_OPTIMIZATION_APPLE) #if defined (__LP64__) && __LP64__ #define US_THREADS_LONG volatile int64_t #define US_ATOMIC_INCREMENT(x) IntType n = OSAtomicIncrement64Barrier(x) #define US_ATOMIC_DECREMENT(x) IntType n = OSAtomicDecrement64Barrier(x) #define US_ATOMIC_ASSIGN(l, v) OSAtomicCompareAndSwap64Barrier(*l, v, l) #else #define US_THREADS_LONG volatile int32_t #define US_ATOMIC_INCREMENT(x) IntType n = OSAtomicIncrement32Barrier(x) #define US_ATOMIC_DECREMENT(x) IntType n = OSAtomicDecrement32Barrier(x) #define US_ATOMIC_ASSIGN(l, v) OSAtomicCompareAndSwap32Barrier(*l, v, l) #endif #elif defined(US_ATOMIC_OPTIMIZATION_GNUC) #define US_THREADS_LONG _Atomic_word #define US_ATOMIC_INCREMENT(x) IntType n = __sync_add_and_fetch(x, 1) #define US_ATOMIC_DECREMENT(x) IntType n = __sync_add_and_fetch(x, -1) #define US_ATOMIC_ASSIGN(l, v) __sync_val_compare_and_swap(l, *l, v) #else #define US_THREADS_LONG long #undef US_ATOMIC_OPTIMIZATION #define US_ATOMIC_INCREMENT(x) m_AtomicMtx.Lock(); \ IntType n = ++(*x); \ m_AtomicMtx.Unlock() #define US_ATOMIC_DECREMENT(x) m_AtomicMtx.Lock(); \ IntType n = --(*x); \ m_AtomicMtx.Unlock() #define US_ATOMIC_ASSIGN(l, v) m_AtomicMtx.Lock(); \ *l = v; \ m_AtomicMtx.Unlock() #endif #endif #else // single threaded #define US_THREADS_MUTEX(x) #define US_THREADS_MUTEX_INIT(x) #define US_THREADS_MUTEX_CTOR(x) #define US_THREADS_MUTEX_DELETE(x) #define US_THREADS_MUTEX_LOCK(x) #define US_THREADS_MUTEX_UNLOCK(x) #define US_THREADS_LONG int #define US_ATOMIC_INCREMENT(x) IntType n = ++(*x); #define US_ATOMIC_DECREMENT(x) IntType n = --(*x); #define US_ATOMIC_ASSIGN(l, r) *l = r; #endif US_BEGIN_NAMESPACE class Mutex { public: Mutex() US_THREADS_MUTEX_CTOR(m_Mtx) { US_THREADS_MUTEX_INIT(m_Mtx); } ~Mutex() { US_THREADS_MUTEX_DELETE(m_Mtx); } void Lock() { US_THREADS_MUTEX_LOCK(m_Mtx); } void Unlock() { US_THREADS_MUTEX_UNLOCK(m_Mtx); } private: template friend class WaitCondition; // Copy-constructor not implemented. Mutex(const Mutex &); // Copy-assignement operator not implemented. Mutex & operator = (const Mutex &); US_THREADS_MUTEX(m_Mtx) }; class MutexLock { public: typedef Mutex MutexType; MutexLock(MutexType& mtx) : m_Mtx(&mtx) { m_Mtx->Lock(); } ~MutexLock() { m_Mtx->Unlock(); } private: MutexType* m_Mtx; // purposely not implemented MutexLock(const MutexLock&); MutexLock& operator=(const MutexLock&); }; class AtomicCounter { public: typedef US_THREADS_LONG IntType; AtomicCounter(int value = 0) : m_Counter(value) {} IntType AtomicIncrement() const { US_ATOMIC_INCREMENT(&m_Counter); return n; } IntType AtomicIncrement(volatile IntType& lval) const { US_ATOMIC_INCREMENT(&lval); return n; } IntType AtomicDecrement() const { US_ATOMIC_DECREMENT(&m_Counter); return n; } IntType AtomicDecrement(volatile IntType& lval) const { US_ATOMIC_DECREMENT(&lval); return n; } void AtomicAssign(volatile IntType& lval) const { US_ATOMIC_ASSIGN(&lval, m_Counter); } void AtomicAssign(volatile IntType& lval, const IntType val) const { US_ATOMIC_ASSIGN(&lval, val); } mutable IntType m_Counter; private: #if !defined(US_ATOMIC_OPTIMIZATION) mutable Mutex m_AtomicMtx; #endif }; class MutexLockingStrategy { public: MutexLockingStrategy() #ifdef US_ENABLE_THREADING_SUPPORT : m_Mtx() #endif {} MutexLockingStrategy(const MutexLockingStrategy&) #ifdef US_ENABLE_THREADING_SUPPORT : m_Mtx() #endif {} class Lock; friend class Lock; class Lock { public: #ifdef US_ENABLE_THREADING_SUPPORT // Lock object explicit Lock(const MutexLockingStrategy& host) : m_Host(host) { m_Host.m_Mtx.Lock(); } // Lock object explicit Lock(const MutexLockingStrategy* host) : m_Host(*host) { m_Host.m_Mtx.Lock(); } // Unlock object ~Lock() { m_Host.m_Mtx.Unlock(); } #else explicit Lock(const MutexLockingStrategy&) {} explicit Lock(const MutexLockingStrategy*) {} #endif private: // private by design Lock(); Lock(const Lock&); Lock& operator=(const Lock&); #ifdef US_ENABLE_THREADING_SUPPORT const MutexLockingStrategy& m_Host; #endif }; protected: #ifdef US_ENABLE_THREADING_SUPPORT mutable Mutex m_Mtx; #endif }; class NoLockingStrategy { }; US_END_NAMESPACE #include US_BEGIN_NAMESPACE template class WaitConditionStrategy = NoWaitCondition > class MultiThreaded : public LockingStrategy, public WaitConditionStrategy > { friend class WaitConditionStrategy >; }; US_END_NAMESPACE #endif // USTHREADINGMODEL_H diff --git a/src/util/usUncompressResourceData.c b/core/src/util/usUncompressResourceData.c similarity index 100% rename from src/util/usUncompressResourceData.c rename to core/src/util/usUncompressResourceData.c diff --git a/src/util/usUncompressResourceData.cpp b/core/src/util/usUncompressResourceData.cpp similarity index 100% rename from src/util/usUncompressResourceData.cpp rename to core/src/util/usUncompressResourceData.cpp diff --git a/src/util/usUtils.cpp b/core/src/util/usUtils.cpp similarity index 100% rename from src/util/usUtils.cpp rename to core/src/util/usUtils.cpp diff --git a/src/util/usUtils_p.h b/core/src/util/usUtils_p.h similarity index 95% rename from src/util/usUtils_p.h rename to core/src/util/usUtils_p.h index 9ad7ba1542..b097924d4d 100644 --- a/src/util/usUtils_p.h +++ b/core/src/util/usUtils_p.h @@ -1,52 +1,52 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USUTILS_H #define USUTILS_H -#include +#include #include //------------------------------------------------------------------- // Module auto-loading //------------------------------------------------------------------- US_BEGIN_NAMESPACE struct ModuleInfo; void AutoLoadModules(const ModuleInfo& moduleInfo); US_END_NAMESPACE //------------------------------------------------------------------- // Error handling //------------------------------------------------------------------- US_BEGIN_NAMESPACE -US_EXPORT std::string GetLastErrorStr(); +US_Core_EXPORT std::string GetLastErrorStr(); US_END_NAMESPACE #endif // USUTILS_H diff --git a/src/util/usWaitCondition_p.h b/core/src/util/usWaitCondition_p.h similarity index 99% rename from src/util/usWaitCondition_p.h rename to core/src/util/usWaitCondition_p.h index 70e1107b65..8e5af89ebe 100644 --- a/src/util/usWaitCondition_p.h +++ b/core/src/util/usWaitCondition_p.h @@ -1,378 +1,378 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USWAITCONDITION_P_H #define USWAITCONDITION_P_H -#include "usConfig.h" +#include "usCoreConfig.h" #include "usLog_p.h" #include "usUtils_p.h" #include "usThreads_p.h" #ifdef US_PLATFORM_POSIX #include #include #endif US_BEGIN_NAMESPACE /** * \brief A thread synchronization object used to suspend execution until some * condition on shared data is met. * * A thread calls Wait() to suspend its execution until the condition is * met. Each call to Notify() from an executing thread will then cause a single * waiting thread to be released. A call to Notify() means, "signal * that the condition is true." NotifyAll() releases all threads waiting on * the condition variable. * * The WaitCondition implementation is consistent with the standard * definition and use of condition variables in pthreads and other common * thread libraries. * * IMPORTANT: A condition variable always requires an associated mutex * object. The mutex object is used to avoid a dangerous race condition when * Wait() and Notify() are called simultaneously from two different * threads. * * On systems using pthreads, this implementation abstracts the * standard calls to the pthread condition variable. On Win32 * systems, there is no system provided condition variable. This * class implements a condition variable using a critical section, a * semphore, an event and a number of counters. The implementation is * almost an extract translation of the implementation presented by * Douglas C Schmidt and Irfan Pyarali in "Strategies for Implementing * POSIX Condition Variables on Win32". This article can be found at * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html * */ template class WaitCondition { public: WaitCondition(); ~WaitCondition(); bool Wait(unsigned long time = 0); /** Notify that the condition is true and release one waiting thread */ void Notify(); /** Notify that the condition is true and release all waiting threads */ void NotifyAll(); private: // purposely not implemented WaitCondition(const WaitCondition& other); const WaitCondition& operator=(const WaitCondition&); #ifdef US_ENABLE_THREADING_SUPPORT /** Suspend execution of this thread until the condition is signaled. The * argument is a SimpleMutex object that must be locked prior to calling * this method. */ bool Wait(Mutex& mutex, unsigned long time = 0); bool Wait(Mutex* mutex, unsigned long time = 0); #ifdef US_PLATFORM_POSIX pthread_cond_t m_WaitCondition; #else int m_NumberOfWaiters; // number of waiting threads CRITICAL_SECTION m_NumberOfWaitersLock; // Serialize access to // m_NumberOfWaiters HANDLE m_Semaphore; // Semaphore to queue threads HANDLE m_WaitersAreDone; // Auto-reset event used by the // broadcast/signal thread to // wait for all the waiting // threads to wake up and // release the semaphore std::size_t m_WasNotifyAll; // Keeps track of whether we // were broadcasting or signaling #endif #endif // US_ENABLE_THREADING_SUPPORT }; template class NoWaitCondition { public: NoWaitCondition() {} private: // purposely not implemented NoWaitCondition(const NoWaitCondition& other); const NoWaitCondition& operator=(const NoWaitCondition&); }; // ------------------------------------------------------------------------ // WaitCondition implementation // ------------------------------------------------------------------------ #ifdef US_ENABLE_THREADING_SUPPORT template WaitCondition::WaitCondition() { #ifdef US_PLATFORM_POSIX pthread_cond_init(&m_WaitCondition, 0); #else m_NumberOfWaiters = 0; m_WasNotifyAll = 0; m_Semaphore = CreateSemaphore(0, // no security 0, // initial value 0x7fffffff, // max count 0); // unnamed InitializeCriticalSection(&m_NumberOfWaitersLock); m_WaitersAreDone = CreateEvent(0, // no security FALSE, // auto-reset FALSE, // non-signaled initially 0 ); // unnamed #endif } template WaitCondition::~WaitCondition() { #ifdef US_PLATFORM_POSIX pthread_cond_destroy(&m_WaitCondition); #else CloseHandle(m_Semaphore); CloseHandle(m_WaitersAreDone); DeleteCriticalSection(&m_NumberOfWaitersLock); #endif } template bool WaitCondition::Wait(unsigned long time) { return this->Wait(static_cast(this)->m_Mtx, time); } template void WaitCondition::Notify() { #ifdef US_PLATFORM_POSIX pthread_cond_signal(&m_WaitCondition); #else EnterCriticalSection(&m_NumberOfWaitersLock); int haveWaiters = m_NumberOfWaiters > 0; LeaveCriticalSection(&m_NumberOfWaitersLock); // if there were not any waiters, then this is a no-op if (haveWaiters) { ReleaseSemaphore(m_Semaphore, 1, 0); } #endif } template void WaitCondition::NotifyAll() { #ifdef US_PLATFORM_POSIX pthread_cond_broadcast(&m_WaitCondition); #else // This is needed to ensure that m_NumberOfWaiters and m_WasNotifyAll are // consistent EnterCriticalSection(&m_NumberOfWaitersLock); int haveWaiters = 0; if (m_NumberOfWaiters > 0) { // We are broadcasting, even if there is just one waiter... // Record that we are broadcasting, which helps optimize Notify() // for the non-broadcast case m_WasNotifyAll = 1; haveWaiters = 1; } if (haveWaiters) { // Wake up all waiters atomically ReleaseSemaphore(m_Semaphore, m_NumberOfWaiters, 0); LeaveCriticalSection(&m_NumberOfWaitersLock); // Wait for all the awakened threads to acquire the counting // semaphore WaitForSingleObject(m_WaitersAreDone, INFINITE); // This assignment is ok, even without the m_NumberOfWaitersLock held // because no other waiter threads can wake up to access it. m_WasNotifyAll = 0; } else { LeaveCriticalSection(&m_NumberOfWaitersLock); } #endif } template bool WaitCondition::Wait(Mutex* mutex, unsigned long timeoutMillis) { return Wait(*mutex, timeoutMillis); } template bool WaitCondition::Wait(Mutex& mutex, unsigned long timeoutMillis) { #ifdef US_PLATFORM_POSIX struct timespec ts, * pts = 0; if (timeoutMillis) { pts = &ts; struct timeval tv; int error = gettimeofday(&tv, NULL); if (error) { US_ERROR << "gettimeofday error: " << GetLastErrorStr(); return false; } ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; ts.tv_sec += timeoutMillis / 1000; ts.tv_nsec += (timeoutMillis % 1000) * 1000000; ts.tv_sec += ts.tv_nsec / 1000000000; ts.tv_nsec = ts.tv_nsec % 1000000000; } if (pts) { int error = pthread_cond_timedwait(&m_WaitCondition, &mutex.m_Mtx, pts); if (error == 0) { return true; } else { if (error != ETIMEDOUT) { US_ERROR << "pthread_cond_timedwait error: " << GetLastErrorStr(); } return false; } } else { int error = pthread_cond_wait(&m_WaitCondition, &mutex.m_Mtx); if (error) { US_ERROR << "pthread_cond_wait error: " << GetLastErrorStr(); return false; } return true; } #else // Avoid race conditions EnterCriticalSection(&m_NumberOfWaitersLock); m_NumberOfWaiters++; LeaveCriticalSection(&m_NumberOfWaitersLock); DWORD dw; bool result = true; // This call atomically releases the mutex and waits on the // semaphore until signaled dw = SignalObjectAndWait(mutex.m_Mtx, m_Semaphore, timeoutMillis ? timeoutMillis : INFINITE, FALSE); if (dw == WAIT_TIMEOUT) { result = false; } else if (dw == WAIT_FAILED) { result = false; US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr(); } // Reacquire lock to avoid race conditions EnterCriticalSection(&m_NumberOfWaitersLock); // We're no longer waiting.... m_NumberOfWaiters--; // Check to see if we're the last waiter after the broadcast int lastWaiter = m_WasNotifyAll && m_NumberOfWaiters == 0; LeaveCriticalSection(&m_NumberOfWaitersLock); // If we're the last waiter thread during this particular broadcast // then let the other threads proceed if (lastWaiter) { // This call atomically signals the m_WaitersAreDone event and waits // until it can acquire the external mutex. This is required to // ensure fairness dw = SignalObjectAndWait(m_WaitersAreDone, mutex.m_Mtx, INFINITE, FALSE); if (result && dw == WAIT_FAILED) { result = false; US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr(); } } else { // Always regain the external mutex since that's the guarentee we // give to our callers dw = WaitForSingleObject(mutex.m_Mtx, INFINITE); if (result && dw == WAIT_FAILED) { result = false; US_ERROR << "SignalObjectAndWait failed: " << GetLastErrorStr(); } } return result; #endif } #else template WaitCondition::WaitCondition() {} template WaitCondition::~WaitCondition() {} template bool WaitCondition::Wait(unsigned long) { return true; } template void WaitCondition::Notify() {} template void WaitCondition::NotifyAll() {} #endif US_END_NAMESPACE #endif // USWAITCONDITION_P_H diff --git a/test/CMakeLists.txt b/core/test/CMakeLists.txt similarity index 93% rename from test/CMakeLists.txt rename to core/test/CMakeLists.txt index a0e8c9d981..04a58b2da7 100644 --- a/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -1,93 +1,93 @@ #----------------------------------------------------------------------------- # Configure files, include dirs, etc. #----------------------------------------------------------------------------- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/usTestingConfig.h.in" "${PROJECT_BINARY_DIR}/include/usTestingConfig.h") -include_directories(${US_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) #----------------------------------------------------------------------------- # Create test modules #----------------------------------------------------------------------------- include(usFunctionCreateTestModule) set(_us_test_module_libs "" CACHE INTERNAL "" FORCE) add_subdirectory(modules) #----------------------------------------------------------------------------- # Add unit tests #----------------------------------------------------------------------------- set(_tests usDebugOutputTest usLDAPFilterTest usModuleTest usModuleResourceTest usServiceFactoryTest usServiceHooksTest usServiceRegistryPerformanceTest usServiceRegistryTest usServiceTemplateTest usServiceTrackerTest usStaticModuleResourceTest usStaticModuleTest ) if(US_BUILD_SHARED_LIBS) list(APPEND _tests usModuleHooksTest usModuleManifestTest usServiceListenerTest usSharedLibraryTest ) if(US_ENABLE_AUTOLOADING_SUPPORT) list(APPEND _tests usModuleAutoLoadTest) endif() endif() set(_additional_srcs usTestManager.cpp usTestUtilModuleListener.cpp ) -set(_test_driver ${PROJECT_NAME}TestDriver) +set(_test_driver us${PROJECT_NAME}TestDriver) set(_test_sourcelist_extra_args ) create_test_sourcelist(_srcs ${_test_driver}.cpp ${_tests} ${_test_sourcelist_extra_args}) usFunctionEmbedResources(_srcs EXECUTABLE_NAME ${_test_driver} FILES usTestResource.txt manifest.json) # Generate a custom "module init" file for the test driver executable if(US_BUILD_SHARED_LIBS) usFunctionGenerateExecutableInit(_srcs IDENTIFIER ${_test_driver}) endif() add_executable(${_test_driver} ${_srcs} ${_additional_srcs}) if(NOT US_BUILD_SHARED_LIBS) target_link_libraries(${_test_driver} ${_us_test_module_libs}) endif() -target_link_libraries(${_test_driver} ${US_LIBRARY_TARGET}) +target_link_libraries(${_test_driver} ${Core_TARGET}) if(UNIX AND NOT APPLE) target_link_libraries(${_test_driver} rt) endif() # Register tests foreach(_test ${_tests}) add_test(NAME ${_test} COMMAND ${_test_driver} ${_test}) endforeach() if(US_TEST_LABELS) set_tests_properties(${_tests} PROPERTIES LABELS "${US_TEST_LABELS}") endif() #----------------------------------------------------------------------------- # Add dependencies for shared libraries #----------------------------------------------------------------------------- if(US_BUILD_SHARED_LIBS) foreach(_test_module ${_us_test_module_libs}) add_dependencies(${_test_driver} ${_test_module}) endforeach() endif() diff --git a/test/manifest.json b/core/test/manifest.json similarity index 100% rename from test/manifest.json rename to core/test/manifest.json diff --git a/test/modules/CMakeLists.txt b/core/test/modules/CMakeLists.txt similarity index 100% rename from test/modules/CMakeLists.txt rename to core/test/modules/CMakeLists.txt diff --git a/test/modules/libA/CMakeLists.txt b/core/test/modules/libA/CMakeLists.txt similarity index 100% rename from test/modules/libA/CMakeLists.txt rename to core/test/modules/libA/CMakeLists.txt diff --git a/test/modules/libA/usTestModuleA.cpp b/core/test/modules/libA/usTestModuleA.cpp similarity index 98% rename from test/modules/libA/usTestModuleA.cpp rename to core/test/modules/libA/usTestModuleA.cpp index a654901ef2..11e145faec 100644 --- a/test/modules/libA/usTestModuleA.cpp +++ b/core/test/modules/libA/usTestModuleA.cpp @@ -1,77 +1,77 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usTestModuleAService.h" #include #include -#include +#include US_BEGIN_NAMESPACE struct TestModuleA : public TestModuleAService { TestModuleA(ModuleContext* mc) { US_INFO << "Registering TestModuleAService"; sr = mc->RegisterService(this); } void Unregister() { if (sr) { sr.Unregister(); sr = 0; } } private: ServiceRegistration sr; }; class TestModuleAActivator : public ModuleActivator { public: TestModuleAActivator() : s(0) {} ~TestModuleAActivator() { delete s; } void Load(ModuleContext* context) { s = new TestModuleA(context); } void Unload(ModuleContext*) { } private: TestModuleA* s; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleA, US_PREPEND_NAMESPACE(TestModuleAActivator)) diff --git a/test/modules/libA/usTestModuleAService.h b/core/test/modules/libA/usTestModuleAService.h similarity index 97% rename from test/modules/libA/usTestModuleAService.h rename to core/test/modules/libA/usTestModuleAService.h index 9ff99bb92e..3ae29ec0bf 100644 --- a/test/modules/libA/usTestModuleAService.h +++ b/core/test/modules/libA/usTestModuleAService.h @@ -1,40 +1,40 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USTESTMODULEASERVICE_H #define USTESTMODULEASERVICE_H -#include +#include #include US_BEGIN_NAMESPACE struct TestModuleAService { virtual ~TestModuleAService() {} }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(US_PREPEND_NAMESPACE(TestModuleAService), "org.cppmicroservices.TestModuleAService") #endif // USTESTMODULEASERVICE_H diff --git a/test/modules/libA2/CMakeLists.txt b/core/test/modules/libA2/CMakeLists.txt similarity index 100% rename from test/modules/libA2/CMakeLists.txt rename to core/test/modules/libA2/CMakeLists.txt diff --git a/test/modules/libA2/usTestModuleA2.cpp b/core/test/modules/libA2/usTestModuleA2.cpp similarity index 100% rename from test/modules/libA2/usTestModuleA2.cpp rename to core/test/modules/libA2/usTestModuleA2.cpp diff --git a/test/modules/libA2/usTestModuleA2Service.h b/core/test/modules/libA2/usTestModuleA2Service.h similarity index 97% rename from test/modules/libA2/usTestModuleA2Service.h rename to core/test/modules/libA2/usTestModuleA2Service.h index ce6c51a506..3160ed106b 100644 --- a/test/modules/libA2/usTestModuleA2Service.h +++ b/core/test/modules/libA2/usTestModuleA2Service.h @@ -1,40 +1,40 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USTESTMODULEA2SERVICE_H #define USTESTMODULEA2SERVICE_H -#include +#include #include US_BEGIN_NAMESPACE struct TestModuleA2Service { virtual ~TestModuleA2Service() {} }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(US_PREPEND_NAMESPACE(TestModuleA2Service), "org.us.TestModuleA2Service") #endif // USTESTMODULEA2SERVICE_H diff --git a/test/modules/libAL/CMakeLists.txt b/core/test/modules/libAL/CMakeLists.txt similarity index 100% rename from test/modules/libAL/CMakeLists.txt rename to core/test/modules/libAL/CMakeLists.txt diff --git a/test/modules/libAL/libAL_1/CMakeLists.txt b/core/test/modules/libAL/libAL_1/CMakeLists.txt similarity index 100% rename from test/modules/libAL/libAL_1/CMakeLists.txt rename to core/test/modules/libAL/libAL_1/CMakeLists.txt diff --git a/test/modules/libAL/libAL_1/usTestModuleAL_1.cpp b/core/test/modules/libAL/libAL_1/usTestModuleAL_1.cpp similarity index 97% rename from test/modules/libAL/libAL_1/usTestModuleAL_1.cpp rename to core/test/modules/libAL/libAL_1/usTestModuleAL_1.cpp index dd15f10b16..c9ece19da6 100644 --- a/test/modules/libAL/libAL_1/usTestModuleAL_1.cpp +++ b/core/test/modules/libAL/libAL_1/usTestModuleAL_1.cpp @@ -1,30 +1,30 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include +#include US_BEGIN_NAMESPACE struct US_ABI_EXPORT TestModuleAL_1_Dummy { }; US_END_NAMESPACE diff --git a/test/modules/libAL/usTestModuleAL.cpp b/core/test/modules/libAL/usTestModuleAL.cpp similarity index 96% rename from test/modules/libAL/usTestModuleAL.cpp rename to core/test/modules/libAL/usTestModuleAL.cpp index aaee431545..3104ca9f88 100644 --- a/test/modules/libAL/usTestModuleAL.cpp +++ b/core/test/modules/libAL/usTestModuleAL.cpp @@ -1,30 +1,30 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include +#include US_BEGIN_NAMESPACE struct TestModuleAL_Dummy { }; US_END_NAMESPACE diff --git a/test/modules/libAL2/CMakeLists.txt b/core/test/modules/libAL2/CMakeLists.txt similarity index 100% rename from test/modules/libAL2/CMakeLists.txt rename to core/test/modules/libAL2/CMakeLists.txt diff --git a/test/modules/libAL2/libAL2_1/CMakeLists.txt b/core/test/modules/libAL2/libAL2_1/CMakeLists.txt similarity index 100% rename from test/modules/libAL2/libAL2_1/CMakeLists.txt rename to core/test/modules/libAL2/libAL2_1/CMakeLists.txt diff --git a/test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp b/core/test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp similarity index 97% rename from test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp rename to core/test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp index b81eb15a35..ece8edfd67 100644 --- a/test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp +++ b/core/test/modules/libAL2/libAL2_1/usTestModuleAL2_1.cpp @@ -1,30 +1,30 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include +#include US_BEGIN_NAMESPACE struct US_ABI_EXPORT TestModuleAL2_1_Dummy { }; US_END_NAMESPACE diff --git a/test/modules/libAL2/resources/manifest.json b/core/test/modules/libAL2/resources/manifest.json similarity index 100% rename from test/modules/libAL2/resources/manifest.json rename to core/test/modules/libAL2/resources/manifest.json diff --git a/test/modules/libAL2/usTestModuleAL2.cpp b/core/test/modules/libAL2/usTestModuleAL2.cpp similarity index 96% rename from test/modules/libAL2/usTestModuleAL2.cpp rename to core/test/modules/libAL2/usTestModuleAL2.cpp index 0388565838..3ed5253115 100644 --- a/test/modules/libAL2/usTestModuleAL2.cpp +++ b/core/test/modules/libAL2/usTestModuleAL2.cpp @@ -1,30 +1,30 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include +#include US_BEGIN_NAMESPACE struct TestModuleAL2_Dummy { }; US_END_NAMESPACE diff --git a/test/modules/libBWithStatic/CMakeLists.txt b/core/test/modules/libBWithStatic/CMakeLists.txt similarity index 100% rename from test/modules/libBWithStatic/CMakeLists.txt rename to core/test/modules/libBWithStatic/CMakeLists.txt diff --git a/test/modules/libBWithStatic/resources/dynamic.txt b/core/test/modules/libBWithStatic/resources/dynamic.txt similarity index 100% rename from test/modules/libBWithStatic/resources/dynamic.txt rename to core/test/modules/libBWithStatic/resources/dynamic.txt diff --git a/test/modules/libBWithStatic/resources/res.txt b/core/test/modules/libBWithStatic/resources/res.txt similarity index 100% rename from test/modules/libBWithStatic/resources/res.txt rename to core/test/modules/libBWithStatic/resources/res.txt diff --git a/test/modules/libBWithStatic/resources_static/res.txt b/core/test/modules/libBWithStatic/resources_static/res.txt similarity index 100% rename from test/modules/libBWithStatic/resources_static/res.txt rename to core/test/modules/libBWithStatic/resources_static/res.txt diff --git a/test/modules/libBWithStatic/resources_static/static.txt b/core/test/modules/libBWithStatic/resources_static/static.txt similarity index 100% rename from test/modules/libBWithStatic/resources_static/static.txt rename to core/test/modules/libBWithStatic/resources_static/static.txt diff --git a/test/modules/libBWithStatic/usTestModuleB.cpp b/core/test/modules/libBWithStatic/usTestModuleB.cpp similarity index 98% rename from test/modules/libBWithStatic/usTestModuleB.cpp rename to core/test/modules/libBWithStatic/usTestModuleB.cpp index 7111c3164a..cfe626f7d8 100644 --- a/test/modules/libBWithStatic/usTestModuleB.cpp +++ b/core/test/modules/libBWithStatic/usTestModuleB.cpp @@ -1,71 +1,70 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usTestModuleBService.h" #include #include #include -#include US_BEGIN_NAMESPACE struct TestModuleB : public TestModuleBService { TestModuleB(ModuleContext* mc) { US_INFO << "Registering TestModuleBService"; mc->RegisterService(this); } }; class TestModuleBActivator : public ModuleActivator { public: TestModuleBActivator() : s(0) {} ~TestModuleBActivator() { delete s; } void Load(ModuleContext* context) { s = new TestModuleB(context); } void Unload(ModuleContext*) { } private: TestModuleB* s; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleB, US_PREPEND_NAMESPACE(TestModuleBActivator)) US_IMPORT_MODULE(TestModuleImportedByB) US_IMPORT_MODULE_RESOURCES(TestModuleImportedByB) US_LOAD_IMPORTED_MODULES(TestModuleB, TestModuleImportedByB) diff --git a/test/modules/libBWithStatic/usTestModuleBService.h b/core/test/modules/libBWithStatic/usTestModuleBService.h similarity index 97% rename from test/modules/libBWithStatic/usTestModuleBService.h rename to core/test/modules/libBWithStatic/usTestModuleBService.h index ababe97398..044d0853e8 100644 --- a/test/modules/libBWithStatic/usTestModuleBService.h +++ b/core/test/modules/libBWithStatic/usTestModuleBService.h @@ -1,40 +1,40 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USTESTMODULEBSERVICE_H #define USTESTMODULEBSERVICE_H -#include +#include #include US_BEGIN_NAMESPACE struct TestModuleBService { virtual ~TestModuleBService() {} }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(US_PREPEND_NAMESPACE(TestModuleBService), "org.cppmicroservices.TestModuleBService") #endif // USTESTMODULEASERVICE_H diff --git a/test/modules/libBWithStatic/usTestModuleImportedByB.cpp b/core/test/modules/libBWithStatic/usTestModuleImportedByB.cpp similarity index 98% rename from test/modules/libBWithStatic/usTestModuleImportedByB.cpp rename to core/test/modules/libBWithStatic/usTestModuleImportedByB.cpp index 8c6008e506..30b5d331cb 100644 --- a/test/modules/libBWithStatic/usTestModuleImportedByB.cpp +++ b/core/test/modules/libBWithStatic/usTestModuleImportedByB.cpp @@ -1,65 +1,64 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usTestModuleBService.h" #include #include -#include US_BEGIN_NAMESPACE struct TestModuleImportedByB : public TestModuleBService { TestModuleImportedByB(ModuleContext* mc) { US_INFO << "Registering TestModuleImportedByB"; mc->RegisterService(this); } }; class TestModuleImportedByBActivator : public ModuleActivator { public: TestModuleImportedByBActivator() : s(0) {} ~TestModuleImportedByBActivator() { delete s; } void Load(ModuleContext* context) { s = new TestModuleImportedByB(context); } void Unload(ModuleContext*) { } private: TestModuleImportedByB* s; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleImportedByB, US_PREPEND_NAMESPACE(TestModuleImportedByBActivator)) diff --git a/test/modules/libH/CMakeLists.txt b/core/test/modules/libH/CMakeLists.txt similarity index 100% rename from test/modules/libH/CMakeLists.txt rename to core/test/modules/libH/CMakeLists.txt diff --git a/test/modules/libH/usTestModuleH.cpp b/core/test/modules/libH/usTestModuleH.cpp similarity index 100% rename from test/modules/libH/usTestModuleH.cpp rename to core/test/modules/libH/usTestModuleH.cpp diff --git a/test/modules/libM/CMakeLists.txt b/core/test/modules/libM/CMakeLists.txt similarity index 100% rename from test/modules/libM/CMakeLists.txt rename to core/test/modules/libM/CMakeLists.txt diff --git a/test/modules/libM/resources/manifest.json b/core/test/modules/libM/resources/manifest.json similarity index 100% rename from test/modules/libM/resources/manifest.json rename to core/test/modules/libM/resources/manifest.json diff --git a/test/modules/libM/usTestModuleM.cpp b/core/test/modules/libM/usTestModuleM.cpp similarity index 100% rename from test/modules/libM/usTestModuleM.cpp rename to core/test/modules/libM/usTestModuleM.cpp diff --git a/test/modules/libRWithResources/CMakeLists.txt b/core/test/modules/libRWithResources/CMakeLists.txt similarity index 100% rename from test/modules/libRWithResources/CMakeLists.txt rename to core/test/modules/libRWithResources/CMakeLists.txt diff --git a/test/modules/libRWithResources/resources/foo.txt b/core/test/modules/libRWithResources/resources/foo.txt similarity index 100% rename from test/modules/libRWithResources/resources/foo.txt rename to core/test/modules/libRWithResources/resources/foo.txt diff --git a/test/modules/libRWithResources/resources/icons/compressable.bmp b/core/test/modules/libRWithResources/resources/icons/compressable.bmp similarity index 100% rename from test/modules/libRWithResources/resources/icons/compressable.bmp rename to core/test/modules/libRWithResources/resources/icons/compressable.bmp diff --git a/test/modules/libRWithResources/resources/icons/cppmicroservices.png b/core/test/modules/libRWithResources/resources/icons/cppmicroservices.png similarity index 100% rename from test/modules/libRWithResources/resources/icons/cppmicroservices.png rename to core/test/modules/libRWithResources/resources/icons/cppmicroservices.png diff --git a/test/modules/libRWithResources/resources/icons/readme.txt b/core/test/modules/libRWithResources/resources/icons/readme.txt similarity index 100% rename from test/modules/libRWithResources/resources/icons/readme.txt rename to core/test/modules/libRWithResources/resources/icons/readme.txt diff --git a/test/modules/libRWithResources/resources/special_chars.dummy.txt b/core/test/modules/libRWithResources/resources/special_chars.dummy.txt similarity index 100% rename from test/modules/libRWithResources/resources/special_chars.dummy.txt rename to core/test/modules/libRWithResources/resources/special_chars.dummy.txt diff --git a/test/modules/libRWithResources/resources/test.xml b/core/test/modules/libRWithResources/resources/test.xml similarity index 100% rename from test/modules/libRWithResources/resources/test.xml rename to core/test/modules/libRWithResources/resources/test.xml diff --git a/test/modules/libRWithResources/usTestModuleR.cpp b/core/test/modules/libRWithResources/usTestModuleR.cpp similarity index 100% rename from test/modules/libRWithResources/usTestModuleR.cpp rename to core/test/modules/libRWithResources/usTestModuleR.cpp diff --git a/test/modules/libS/CMakeLists.txt b/core/test/modules/libS/CMakeLists.txt similarity index 100% rename from test/modules/libS/CMakeLists.txt rename to core/test/modules/libS/CMakeLists.txt diff --git a/test/modules/libS/usTestModuleS.cpp b/core/test/modules/libS/usTestModuleS.cpp similarity index 99% rename from test/modules/libS/usTestModuleS.cpp rename to core/test/modules/libS/usTestModuleS.cpp index b25ead2668..8a4f7bc827 100644 --- a/test/modules/libS/usTestModuleS.cpp +++ b/core/test/modules/libS/usTestModuleS.cpp @@ -1,143 +1,142 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "../../usServiceControlInterface.h" #include "usTestModuleSService0.h" #include "usTestModuleSService1.h" #include "usTestModuleSService2.h" #include "usTestModuleSService3.h" #include #include #include -#include US_BEGIN_NAMESPACE class TestModuleS : public ServiceControlInterface, public TestModuleSService0, public TestModuleSService1, public TestModuleSService2, public TestModuleSService3 { public: TestModuleS(ModuleContext* mc) : mc(mc) { for(int i = 0; i <= 3; ++i) { servregs.push_back(ServiceRegistrationU()); } sreg = mc->RegisterService(this); sciReg = mc->RegisterService(this); } virtual const char* GetNameOfClass() const { return "TestModuleS"; } void ServiceControl(int offset, const std::string& operation, int ranking) { if (0 <= offset && offset <= 3) { if (operation == "register") { if (!servregs[offset]) { std::stringstream servicename; servicename << SERVICE << offset; InterfaceMap ifm; ifm.insert(std::make_pair(servicename.str(), static_cast(this))); ServiceProperties props; props.insert(std::make_pair(ServiceConstants::SERVICE_RANKING(), Any(ranking))); servregs[offset] = mc->RegisterService(ifm, props); } } if (operation == "unregister") { if (servregs[offset]) { ServiceRegistrationU sr1 = servregs[offset]; sr1.Unregister(); servregs[offset] = 0; } } } } void Unregister() { if (sreg) { sreg.Unregister(); } if (sciReg) { sciReg.Unregister(); } } private: static const std::string SERVICE; // = "org.cppmicroservices.TestModuleSService" ModuleContext* mc; std::vector servregs; ServiceRegistration sreg; ServiceRegistration sciReg; }; const std::string TestModuleS::SERVICE = "org.cppmicroservices.TestModuleSService"; class TestModuleSActivator : public ModuleActivator { public: TestModuleSActivator() : s(0) {} ~TestModuleSActivator() { delete s; } void Load(ModuleContext* context) { s = new TestModuleS(context); } void Unload(ModuleContext* /*context*/) { #ifndef US_BUILD_SHARED_LIBS s->Unregister(); #endif } private: TestModuleS* s; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleS, US_PREPEND_NAMESPACE(TestModuleSActivator)) diff --git a/test/modules/libS/usTestModuleSService0.h b/core/test/modules/libS/usTestModuleSService0.h similarity index 100% rename from test/modules/libS/usTestModuleSService0.h rename to core/test/modules/libS/usTestModuleSService0.h diff --git a/test/modules/libS/usTestModuleSService1.h b/core/test/modules/libS/usTestModuleSService1.h similarity index 100% rename from test/modules/libS/usTestModuleSService1.h rename to core/test/modules/libS/usTestModuleSService1.h diff --git a/test/modules/libS/usTestModuleSService2.h b/core/test/modules/libS/usTestModuleSService2.h similarity index 100% rename from test/modules/libS/usTestModuleSService2.h rename to core/test/modules/libS/usTestModuleSService2.h diff --git a/test/modules/libS/usTestModuleSService3.h b/core/test/modules/libS/usTestModuleSService3.h similarity index 100% rename from test/modules/libS/usTestModuleSService3.h rename to core/test/modules/libS/usTestModuleSService3.h diff --git a/test/modules/libSL1/CMakeLists.txt b/core/test/modules/libSL1/CMakeLists.txt similarity index 100% rename from test/modules/libSL1/CMakeLists.txt rename to core/test/modules/libSL1/CMakeLists.txt diff --git a/test/modules/libSL1/usActivatorSL1.cpp b/core/test/modules/libSL1/usActivatorSL1.cpp similarity index 100% rename from test/modules/libSL1/usActivatorSL1.cpp rename to core/test/modules/libSL1/usActivatorSL1.cpp diff --git a/test/modules/libSL1/usFooService.h b/core/test/modules/libSL1/usFooService.h similarity index 100% rename from test/modules/libSL1/usFooService.h rename to core/test/modules/libSL1/usFooService.h diff --git a/test/modules/libSL3/CMakeLists.txt b/core/test/modules/libSL3/CMakeLists.txt similarity index 100% rename from test/modules/libSL3/CMakeLists.txt rename to core/test/modules/libSL3/CMakeLists.txt diff --git a/test/modules/libSL3/usActivatorSL3.cpp b/core/test/modules/libSL3/usActivatorSL3.cpp similarity index 99% rename from test/modules/libSL3/usActivatorSL3.cpp rename to core/test/modules/libSL3/usActivatorSL3.cpp index ed636fc3da..beae9c9362 100644 --- a/test/modules/libSL3/usActivatorSL3.cpp +++ b/core/test/modules/libSL3/usActivatorSL3.cpp @@ -1,100 +1,99 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include #include #include #include #include -#include US_BEGIN_NAMESPACE class ActivatorSL3 : public ModuleActivator, public ModulePropsInterface, public ServiceTrackerCustomizer { public: ActivatorSL3() : tracker(0), context(0) {} ~ActivatorSL3() { delete tracker; } void Load(ModuleContext* context) { this->context = context; InterfaceMap im = MakeInterfaceMap(this); im.insert(std::make_pair(std::string("ActivatorSL3"), this)); sr = context->RegisterService(im); delete tracker; tracker = new FooTracker(context, this); tracker->Open(); } void Unload(ModuleContext* /*context*/) { tracker->Close(); } const ModulePropsInterface::Properties& GetProperties() const { return props; } FooService* AddingService(const ServiceReferenceType& reference) { props["serviceAdded"] = true; US_INFO << "SL3: Adding reference =" << reference; FooService* fooService = context->GetService(reference); fooService->foo(); return fooService; } void ModifiedService(const ServiceReferenceType& /*reference*/, FooService* /*service*/) { } void RemovedService(const ServiceReferenceType& reference, FooService* /*service*/) { props["serviceRemoved"] = true; US_INFO << "SL3: Removing reference =" << reference; } private: typedef ServiceTracker FooTracker; FooTracker* tracker; ModuleContext* context; ServiceRegistrationU sr; ModulePropsInterface::Properties props; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleSL3, US_PREPEND_NAMESPACE(ActivatorSL3)) diff --git a/test/modules/libSL4/CMakeLists.txt b/core/test/modules/libSL4/CMakeLists.txt similarity index 100% rename from test/modules/libSL4/CMakeLists.txt rename to core/test/modules/libSL4/CMakeLists.txt diff --git a/test/modules/libSL4/usActivatorSL4.cpp b/core/test/modules/libSL4/usActivatorSL4.cpp similarity index 98% rename from test/modules/libSL4/usActivatorSL4.cpp rename to core/test/modules/libSL4/usActivatorSL4.cpp index 4f0aebb814..cea41ce6fb 100644 --- a/test/modules/libSL4/usActivatorSL4.cpp +++ b/core/test/modules/libSL4/usActivatorSL4.cpp @@ -1,65 +1,64 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include #include #include -#include #include US_BEGIN_NAMESPACE class ActivatorSL4 : public ModuleActivator, public FooService { public: ~ActivatorSL4() { } void foo() { US_INFO << "TestModuleSL4: Doing foo"; } void Load(ModuleContext* context) { sr = context->RegisterService(this); US_INFO << "TestModuleSL4: Registered " << sr; } void Unload(ModuleContext* /*context*/) { } private: ServiceRegistration sr; }; US_END_NAMESPACE US_EXPORT_MODULE_ACTIVATOR(TestModuleSL4, US_PREPEND_NAMESPACE(ActivatorSL4)) diff --git a/test/usDebugOutputTest.cpp b/core/test/usDebugOutputTest.cpp similarity index 100% rename from test/usDebugOutputTest.cpp rename to core/test/usDebugOutputTest.cpp diff --git a/test/usLDAPFilterTest.cpp b/core/test/usLDAPFilterTest.cpp similarity index 100% rename from test/usLDAPFilterTest.cpp rename to core/test/usLDAPFilterTest.cpp diff --git a/test/usModuleAutoLoadTest.cpp b/core/test/usModuleAutoLoadTest.cpp similarity index 100% rename from test/usModuleAutoLoadTest.cpp rename to core/test/usModuleAutoLoadTest.cpp diff --git a/test/usModuleHooksTest.cpp b/core/test/usModuleHooksTest.cpp similarity index 100% rename from test/usModuleHooksTest.cpp rename to core/test/usModuleHooksTest.cpp diff --git a/test/usModuleManifestTest.cpp b/core/test/usModuleManifestTest.cpp similarity index 100% rename from test/usModuleManifestTest.cpp rename to core/test/usModuleManifestTest.cpp diff --git a/test/usModulePropsInterface.h b/core/test/usModulePropsInterface.h similarity index 100% rename from test/usModulePropsInterface.h rename to core/test/usModulePropsInterface.h diff --git a/test/usModuleResourceTest.cpp b/core/test/usModuleResourceTest.cpp similarity index 98% rename from test/usModuleResourceTest.cpp rename to core/test/usModuleResourceTest.cpp index ac4fc25cda..734cc0b7fb 100644 --- a/test/usModuleResourceTest.cpp +++ b/core/test/usModuleResourceTest.cpp @@ -1,542 +1,542 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include #include #include #include #include #include #include #include #include "usTestingMacros.h" #include #include US_USE_NAMESPACE namespace { void checkResourceInfo(const ModuleResource& res, const std::string& path, const std::string& baseName, const std::string& completeBaseName, const std::string& suffix, const std::string& completeSuffix, int size, bool children = false, bool compressed = false) { US_TEST_CONDITION_REQUIRED(res.IsValid(), "Valid resource") US_TEST_CONDITION(res.GetBaseName() == baseName, "GetBaseName()") US_TEST_CONDITION(res.GetChildren().empty() == !children, "No children") US_TEST_CONDITION(res.GetCompleteBaseName() == completeBaseName, "GetCompleteBaseName()") US_TEST_CONDITION(res.GetName() == completeBaseName + "." + suffix, "GetName()") US_TEST_CONDITION(res.GetResourcePath() == path + completeBaseName + "." + suffix, "GetResourcePath()") US_TEST_CONDITION(res.GetPath() == path, "GetPath()") US_TEST_CONDITION(res.GetSize() == size, "Data size") US_TEST_CONDITION(res.GetSuffix() == suffix, "Suffix") US_TEST_CONDITION(res.GetCompleteSuffix() == completeSuffix, "Complete suffix") US_TEST_CONDITION(res.IsCompressed() == compressed, "Compression flag") } void testTextResource(Module* module) { ModuleResource res = module->GetResource("foo.txt"); #ifdef US_PLATFORM_WINDOWS checkResourceInfo(res, "/", "foo", "foo", "txt", "txt", 16, false); const std::streampos ssize(13); const std::string fileData = "foo and\nbar\n\n"; #else checkResourceInfo(res, "/", "foo", "foo", "txt", "txt", 13, false); const std::streampos ssize(12); const std::string fileData = "foo and\nbar\n"; #endif ModuleResourceStream rs(res); rs.seekg(0, std::ios::end); US_TEST_CONDITION(rs.tellg() == ssize, "Stream content length"); rs.seekg(0, std::ios::beg); std::string content; content.reserve(res.GetSize()); char buffer[1024]; while (rs.read(buffer, sizeof(buffer))) { content.append(buffer, sizeof(buffer)); } content.append(buffer, static_cast(rs.gcount())); US_TEST_CONDITION(rs.eof(), "EOF check"); US_TEST_CONDITION(content == fileData, "Resource content"); rs.clear(); rs.seekg(0); US_TEST_CONDITION_REQUIRED(rs.tellg() == std::streampos(0), "Move to start") US_TEST_CONDITION_REQUIRED(rs.good(), "Start re-reading"); std::vector lines; std::string line; while (std::getline(rs, line)) { lines.push_back(line); } US_TEST_CONDITION_REQUIRED(lines.size() > 1, "Number of lines") US_TEST_CONDITION(lines[0] == "foo and", "Check first line") US_TEST_CONDITION(lines[1] == "bar", "Check second line") } void testTextResourceAsBinary(Module* module) { ModuleResource res = module->GetResource("foo.txt"); #ifdef US_PLATFORM_WINDOWS checkResourceInfo(res, "/", "foo", "foo", "txt", "txt", 16, false); const std::streampos ssize(16); const std::string fileData = "foo and\r\nbar\r\n\r\n"; #else checkResourceInfo(res, "/", "foo", "foo", "txt", "txt", 13, false); const std::streampos ssize(13); const std::string fileData = "foo and\nbar\n\n"; #endif ModuleResourceStream rs(res, std::ios_base::binary); rs.seekg(0, std::ios::end); US_TEST_CONDITION(rs.tellg() == ssize, "Stream content length"); rs.seekg(0, std::ios::beg); std::string content; content.reserve(res.GetSize()); char buffer[1024]; while (rs.read(buffer, sizeof(buffer))) { content.append(buffer, sizeof(buffer)); } content.append(buffer, static_cast(rs.gcount())); US_TEST_CONDITION(rs.eof(), "EOF check"); US_TEST_CONDITION(content == fileData, "Resource content"); } #ifdef US_BUILD_SHARED_LIBS void testInvalidResource(Module* module) { ModuleResource res = module->GetResource("invalid"); US_TEST_CONDITION_REQUIRED(res.IsValid() == false, "Check invalid resource") US_TEST_CONDITION(res.GetName().empty(), "Check empty name") US_TEST_CONDITION(res.GetPath().empty(), "Check empty path") US_TEST_CONDITION(res.GetResourcePath().empty(), "Check empty resource path") US_TEST_CONDITION(res.GetBaseName().empty(), "Check empty base name") US_TEST_CONDITION(res.GetCompleteBaseName().empty(), "Check empty complete base name") US_TEST_CONDITION(res.GetSuffix().empty(), "Check empty suffix") US_TEST_CONDITION(res.GetChildren().empty(), "Check empty children") US_TEST_CONDITION(res.GetSize() == 0, "Check zero size") US_TEST_CONDITION(res.GetData() == NULL, "Check NULL data") ModuleResourceStream rs(res); US_TEST_CONDITION(rs.good() == true, "Check invalid resource stream") rs.ignore(); US_TEST_CONDITION(rs.good() == false, "Check invalid resource stream") US_TEST_CONDITION(rs.eof() == true, "Check invalid resource stream") } #endif void testSpecialCharacters(Module* module) { ModuleResource res = module->GetResource("special_chars.dummy.txt"); #ifdef US_PLATFORM_WINDOWS checkResourceInfo(res, "/", "special_chars", "special_chars.dummy", "txt", "dummy.txt", 56, false); const std::streampos ssize(54); const std::string fileData = "German Füße (feet)\nFrench garçon de café (waiter)\n"; #else checkResourceInfo(res, "/", "special_chars", "special_chars.dummy", "txt", "dummy.txt", 54, false); const std::streampos ssize(53); const std::string fileData = "German Füße (feet)\nFrench garçon de café (waiter)"; #endif ModuleResourceStream rs(res); rs.seekg(0, std::ios_base::end); US_TEST_CONDITION(rs.tellg() == ssize, "Stream content length"); rs.seekg(0, std::ios_base::beg); std::string content; content.reserve(res.GetSize()); char buffer[1024]; while (rs.read(buffer, sizeof(buffer))) { content.append(buffer, sizeof(buffer)); } content.append(buffer, static_cast(rs.gcount())); US_TEST_CONDITION(rs.eof(), "EOF check"); US_TEST_CONDITION(content == fileData, "Resource content"); } void testBinaryResource(Module* module) { ModuleResource res = module->GetResource("/icons/cppmicroservices.png"); checkResourceInfo(res, "/icons/", "cppmicroservices", "cppmicroservices", "png", "png", 2424, false); ModuleResourceStream rs(res, std::ios_base::binary); rs.seekg(0, std::ios_base::end); std::streampos resLength = rs.tellg(); rs.seekg(0); - std::ifstream png(CppMicroServices_SOURCE_DIR "/test/modules/libRWithResources/resources/icons/cppmicroservices.png", + std::ifstream png(US_CORE_SOURCE_DIR "/test/modules/libRWithResources/resources/icons/cppmicroservices.png", std::ifstream::in | std::ifstream::binary); US_TEST_CONDITION_REQUIRED(png.is_open(), "Open reference file") png.seekg(0, std::ios_base::end); std::streampos pngLength = png.tellg(); png.seekg(0); US_TEST_CONDITION(res.GetSize() == resLength, "Check resource size") US_TEST_CONDITION_REQUIRED(resLength == pngLength, "Compare sizes") char c1 = 0; char c2 = 0; bool isEqual = true; int count = 0; while (png.get(c1) && rs.get(c2)) { ++count; if (c1 != c2) { isEqual = false; break; } } US_TEST_CONDITION_REQUIRED(count == pngLength, "Check if everything was read"); US_TEST_CONDITION_REQUIRED(isEqual, "Equal binary contents"); US_TEST_CONDITION(png.eof(), "EOF check"); } #ifdef US_ENABLE_RESOURCE_COMPRESSION void testCompressedResource(Module* module) { ModuleResource res = module->GetResource("/icons/compressable.bmp"); checkResourceInfo(res, "/icons/", "compressable", "compressable", "bmp", "bmp", 411, false, true); ModuleResourceStream rs(res, std::ios_base::binary); rs.seekg(0, std::ios_base::end); std::streampos resLength = rs.tellg(); rs.seekg(0); - std::ifstream bmp(CppMicroServices_SOURCE_DIR "/test/modules/libRWithResources/resources/icons/compressable.bmp", + std::ifstream bmp(US_CORE_SOURCE_DIR "/test/modules/libRWithResources/resources/icons/compressable.bmp", std::ifstream::in | std::ifstream::binary); US_TEST_CONDITION_REQUIRED(bmp.is_open(), "Open reference file") bmp.seekg(0, std::ios_base::end); std::streampos bmpLength = bmp.tellg(); bmp.seekg(0); US_TEST_CONDITION(300122 == resLength, "Check resource size") US_TEST_CONDITION_REQUIRED(resLength == bmpLength, "Compare sizes") char c1 = 0; char c2 = 0; bool isEqual = true; int count = 0; while (bmp.get(c1) && rs.get(c2)) { ++count; if (c1 != c2) { isEqual = false; break; } } US_TEST_CONDITION_REQUIRED(count == bmpLength, "Check if everything was read"); US_TEST_CONDITION_REQUIRED(isEqual, "Equal binary contents"); US_TEST_CONDITION(bmp.eof(), "EOF check"); } #endif struct ResourceComparator { bool operator()(const ModuleResource& mr1, const ModuleResource& mr2) const { return mr1 < mr2; } }; #ifdef US_BUILD_SHARED_LIBS void testResourceTree(Module* module) { ModuleResource res = module->GetResource(""); US_TEST_CONDITION(res.GetResourcePath() == "/", "Check root file path") US_TEST_CONDITION(res.IsDir() == true, "Check type") std::vector children = res.GetChildren(); std::sort(children.begin(), children.end()); US_TEST_CONDITION_REQUIRED(children.size() == 4, "Check child count") US_TEST_CONDITION(children[0] == "foo.txt", "Check child name") US_TEST_CONDITION(children[1] == "icons", "Check child name") US_TEST_CONDITION(children[2] == "special_chars.dummy.txt", "Check child name") US_TEST_CONDITION(children[3] == "test.xml", "Check child name") ModuleResource readme = module->GetResource("/icons/readme.txt"); US_TEST_CONDITION(readme.IsFile() && readme.GetChildren().empty(), "Check file resource") ModuleResource icons = module->GetResource("icons"); US_TEST_CONDITION(icons.IsDir() && !icons.IsFile() && !icons.GetChildren().empty(), "Check directory resource") children = icons.GetChildren(); US_TEST_CONDITION_REQUIRED(children.size() == 3, "Check icons child count") std::sort(children.begin(), children.end()); US_TEST_CONDITION(children[0] == "compressable.bmp", "Check child name") US_TEST_CONDITION(children[1] == "cppmicroservices.png", "Check child name") US_TEST_CONDITION(children[2] == "readme.txt", "Check child name") ResourceComparator resourceComparator; // find all .txt files std::vector nodes = module->FindResources("", "*.txt", false); std::sort(nodes.begin(), nodes.end(), resourceComparator); US_TEST_CONDITION_REQUIRED(nodes.size() == 2, "Found child count") US_TEST_CONDITION(nodes[0].GetResourcePath() == "/foo.txt", "Check child name") US_TEST_CONDITION(nodes[1].GetResourcePath() == "/special_chars.dummy.txt", "Check child name") nodes = module->FindResources("", "*.txt", true); std::sort(nodes.begin(), nodes.end(), resourceComparator); US_TEST_CONDITION_REQUIRED(nodes.size() == 3, "Found child count") US_TEST_CONDITION(nodes[0].GetResourcePath() == "/foo.txt", "Check child name") US_TEST_CONDITION(nodes[1].GetResourcePath() == "/icons/readme.txt", "Check child name") US_TEST_CONDITION(nodes[2].GetResourcePath() == "/special_chars.dummy.txt", "Check child name") // find all resources nodes = module->FindResources("", "", true); US_TEST_CONDITION(nodes.size() == 6, "Total resource number") nodes = module->FindResources("", "**", true); US_TEST_CONDITION(nodes.size() == 6, "Total resource number") // test pattern matching nodes.clear(); nodes = module->FindResources("/icons", "*micro*.png", false); US_TEST_CONDITION(nodes.size() == 1 && nodes[0].GetResourcePath() == "/icons/cppmicroservices.png", "Check file pattern matches") nodes.clear(); nodes = module->FindResources("", "*.txt", true); US_TEST_CONDITION(nodes.size() == 3, "Check recursive pattern matches") } #else void testResourceTree(Module* module) { ModuleResource res = module->GetResource(""); US_TEST_CONDITION(res.GetResourcePath() == "/", "Check root file path") US_TEST_CONDITION(res.IsDir() == true, "Check type") std::vector children = res.GetChildren(); std::sort(children.begin(), children.end()); US_TEST_CONDITION_REQUIRED(children.size() == 10, "Check child count") US_TEST_CONDITION(children[0] == "dynamic.txt", "Check dynamic.txt child name") US_TEST_CONDITION(children[1] == "foo.txt", "Check foo.txt child name") US_TEST_CONDITION(children[2] == "icons", "Check icons child name") US_TEST_CONDITION(children[3] == "manifest.json", "Check manifest.json child name") US_TEST_CONDITION(children[4] == "manifest.json", "Check manifest.json child name") US_TEST_CONDITION(children[5] == "res.txt", "Check res.txt child name") US_TEST_CONDITION(children[6] == "res.txt", "Check res.txt child name") US_TEST_CONDITION(children[7] == "special_chars.dummy.txt", "Check special_chars.dummy.txt child name") US_TEST_CONDITION(children[8] == "static.txt", "Check static.txt child name") US_TEST_CONDITION(children[9] == "test.xml", "Check test.xml child name") ModuleResource readme = module->GetResource("/icons/readme.txt"); US_TEST_CONDITION(readme.IsFile() && readme.GetChildren().empty(), "Check file resource") ModuleResource icons = module->GetResource("icons"); US_TEST_CONDITION(icons.IsDir() && !icons.IsFile() && !icons.GetChildren().empty(), "Check directory resource") children = icons.GetChildren(); US_TEST_CONDITION_REQUIRED(children.size() == 3, "Check icons child count") std::sort(children.begin(), children.end()); US_TEST_CONDITION(children[0] == "compressable.bmp", "Check child name") US_TEST_CONDITION(children[1] == "cppmicroservices.png", "Check child name") US_TEST_CONDITION(children[2] == "readme.txt", "Check child name") ResourceComparator resourceComparator; // find all .txt files std::vector nodes = module->FindResources("", "*.txt", false); std::sort(nodes.begin(), nodes.end(), resourceComparator); US_TEST_CONDITION_REQUIRED(nodes.size() == 6, "Found child count") US_TEST_CONDITION(nodes[0].GetResourcePath() == "/dynamic.txt", "Check dynamic.txt child name") US_TEST_CONDITION(nodes[1].GetResourcePath() == "/foo.txt", "Check child name") US_TEST_CONDITION(nodes[2].GetResourcePath() == "/res.txt", "Check res.txt child name") US_TEST_CONDITION(nodes[3].GetResourcePath() == "/res.txt", "Check res.txt child name") US_TEST_CONDITION(nodes[4].GetResourcePath() == "/special_chars.dummy.txt", "Check child name") US_TEST_CONDITION(nodes[5].GetResourcePath() == "/static.txt", "Check static.txt child name") nodes = module->FindResources("", "*.txt", true); std::sort(nodes.begin(), nodes.end(), resourceComparator); US_TEST_CONDITION_REQUIRED(nodes.size() == 7, "Found child count") US_TEST_CONDITION(nodes[0].GetResourcePath() == "/dynamic.txt", "Check dynamic.txt child name") US_TEST_CONDITION(nodes[1].GetResourcePath() == "/foo.txt", "Check child name") US_TEST_CONDITION(nodes[2].GetResourcePath() == "/icons/readme.txt", "Check child name") US_TEST_CONDITION(nodes[3].GetResourcePath() == "/res.txt", "Check res.txt child name") US_TEST_CONDITION(nodes[4].GetResourcePath() == "/res.txt", "Check res.txt child name") US_TEST_CONDITION(nodes[5].GetResourcePath() == "/special_chars.dummy.txt", "Check child name") US_TEST_CONDITION(nodes[6].GetResourcePath() == "/static.txt", "Check static.txt child name") // find all resources nodes = module->FindResources("", "", true); US_TEST_CONDITION(nodes.size() == 12, "Total resource number") nodes = module->FindResources("", "**", true); US_TEST_CONDITION(nodes.size() == 12, "Total resource number") // test pattern matching nodes.clear(); nodes = module->FindResources("/icons", "*micro*.png", false); US_TEST_CONDITION(nodes.size() == 1 && nodes[0].GetResourcePath() == "/icons/cppmicroservices.png", "Check file pattern matches") nodes.clear(); nodes = module->FindResources("", "*.txt", true); US_TEST_CONDITION(nodes.size() == 7, "Check recursive pattern matches") } #endif void testResourceOperators(Module* module) { ModuleResource invalid = module->GetResource("invalid"); ModuleResource foo = module->GetResource("foo.txt"); US_TEST_CONDITION_REQUIRED(foo.IsValid() && foo, "Check valid resource") ModuleResource foo2(foo); US_TEST_CONDITION(foo == foo, "Check equality operator") US_TEST_CONDITION(foo == foo2, "Check copy constructor and equality operator") US_TEST_CONDITION(foo != invalid, "Check inequality with invalid resource") ModuleResource xml = module->GetResource("/test.xml"); US_TEST_CONDITION_REQUIRED(xml.IsValid() && xml, "Check valid resource") US_TEST_CONDITION(foo != xml, "Check inequality") US_TEST_CONDITION(foo < xml, "Check operator<") // check operator< by using a set std::set resources; resources.insert(foo); resources.insert(foo); resources.insert(xml); US_TEST_CONDITION(resources.size() == 2, "Check operator< with set") // check hash function specialization US_UNORDERED_SET_TYPE resources2; resources2.insert(foo); resources2.insert(foo); resources2.insert(xml); US_TEST_CONDITION(resources2.size() == 2, "Check operator< with unordered set") // check operator<< std::ostringstream oss; oss << foo; US_TEST_CONDITION(oss.str() == foo.GetResourcePath(), "Check operator<<") } #ifdef US_BUILD_SHARED_LIBS void testResourceFromExecutable(Module* module) { ModuleResource resource = module->GetResource("usTestResource.txt"); US_TEST_CONDITION_REQUIRED(resource.IsValid(), "Check valid executable resource") std::string line; ModuleResourceStream rs(resource); std::getline(rs, line); US_TEST_CONDITION(line == "meant to be compiled into the test driver", "Check executable resource content") } #endif } // end unnamed namespace int usModuleResourceTest(int /*argc*/, char* /*argv*/[]) { US_TEST_BEGIN("ModuleResourceTest"); ModuleContext* mc = GetModuleContext(); assert(mc); #ifdef US_BUILD_SHARED_LIBS #ifdef US_PLATFORM_WINDOWS const std::string LIB_PATH = US_RUNTIME_OUTPUT_DIRECTORY; #else const std::string LIB_PATH = US_LIBRARY_OUTPUT_DIRECTORY; #endif SharedLibrary libR(LIB_PATH, "TestModuleR"); try { libR.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG(<< "Load module exception: " << e.what()) } Module* moduleR = ModuleRegistry::GetModule("TestModuleR Module"); US_TEST_CONDITION_REQUIRED(moduleR != NULL, "Test for existing module TestModuleR") US_TEST_CONDITION(moduleR->GetName() == "TestModuleR Module", "Test module name") testInvalidResource(moduleR); testResourceFromExecutable(mc->GetModule()); #else Module* moduleR = mc->GetModule(); US_TEST_CONDITION_REQUIRED(moduleR != NULL, "Test for existing module 0") US_TEST_CONDITION(moduleR->GetName() == "CppMicroServices", "Test module name") #endif testResourceTree(moduleR); testResourceOperators(moduleR); testTextResource(moduleR); testTextResourceAsBinary(moduleR); testSpecialCharacters(moduleR); testBinaryResource(moduleR); #ifdef US_ENABLE_RESOURCE_COMPRESSION testCompressedResource(moduleR); #endif #ifdef US_BUILD_SHARED_LIBS ModuleResource foo = moduleR->GetResource("foo.txt"); US_TEST_CONDITION(foo.IsValid() == true, "Valid resource") libR.Unload(); US_TEST_CONDITION(foo.IsValid() == false, "Invalidated resource") US_TEST_CONDITION(foo.GetData() == NULL, "NULL data") #endif US_TEST_END() } diff --git a/test/usModuleTest.cpp b/core/test/usModuleTest.cpp similarity index 99% rename from test/usModuleTest.cpp rename to core/test/usModuleTest.cpp index 98cbf2cf3f..db8f5fafc1 100644 --- a/test/usModuleTest.cpp +++ b/core/test/usModuleTest.cpp @@ -1,343 +1,343 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include #include #include #include #include #include #include #include #include #include "usTestUtilModuleListener.h" #include "usTestingMacros.h" #include "usTestingConfig.h" US_USE_NAMESPACE namespace { #ifdef US_PLATFORM_WINDOWS static const std::string LIB_PATH = US_RUNTIME_OUTPUT_DIRECTORY; static const char PATH_SEPARATOR = '\\'; #else static const std::string LIB_PATH = US_LIBRARY_OUTPUT_DIRECTORY; static const char PATH_SEPARATOR = '/'; #endif // Verify that the same member function pointers registered as listeners // with different receivers works. void frame02a() { ModuleContext* mc = GetModuleContext(); TestModuleListener listener1; TestModuleListener listener2; try { mc->RemoveModuleListener(&listener1, &TestModuleListener::ModuleChanged); mc->AddModuleListener(&listener1, &TestModuleListener::ModuleChanged); mc->RemoveModuleListener(&listener2, &TestModuleListener::ModuleChanged); mc->AddModuleListener(&listener2, &TestModuleListener::ModuleChanged); } catch (const std::logic_error& ise) { US_TEST_FAILED_MSG( << "module listener registration failed " << ise.what() << " : frameSL02a:FAIL" ); } SharedLibrary target(LIB_PATH, "TestModuleA"); #ifdef US_BUILD_SHARED_LIBS // Start the test target try { target.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG( << "Failed to load module, got exception: " << e.what() << " + in frameSL02a:FAIL" ); } Module* moduleA = ModuleRegistry::GetModule("TestModuleA Module"); US_TEST_CONDITION_REQUIRED(moduleA != 0, "Test for existing module TestModuleA") #endif std::vector pEvts; #ifdef US_BUILD_SHARED_LIBS pEvts.push_back(ModuleEvent(ModuleEvent::LOADING, moduleA)); pEvts.push_back(ModuleEvent(ModuleEvent::LOADED, moduleA)); #endif std::vector seEvts; US_TEST_CONDITION(listener1.CheckListenerEvents(pEvts, seEvts), "Check first module listener") US_TEST_CONDITION(listener2.CheckListenerEvents(pEvts, seEvts), "Check second module listener") mc->RemoveModuleListener(&listener1, &TestModuleListener::ModuleChanged); mc->RemoveModuleListener(&listener2, &TestModuleListener::ModuleChanged); target.Unload(); } // Verify information from the ModuleInfo struct void frame005a(ModuleContext* mc) { Module* m = mc->GetModule(); // check expected headers #ifdef US_BUILD_SHARED_LIBS - US_TEST_CONDITION("CppMicroServicesTestDriver" == m->GetName(), "Test module name") + US_TEST_CONDITION("usCoreTestDriver" == m->GetName(), "Test module name") US_TEST_CONDITION(ModuleVersion(0,1,0) == m->GetVersion(), "Test test driver module version") US_TEST_CONDITION(ModuleVersion(CppMicroServices_MAJOR_VERSION, CppMicroServices_MINOR_VERSION, CppMicroServices_PATCH_VERSION) == ModuleRegistry::GetModule(1)->GetVersion(), "Test CppMicroServices version") #else US_TEST_CONDITION("CppMicroServices" == m->GetName(), "Test module name") US_TEST_CONDITION(ModuleVersion(CppMicroServices_MAJOR_VERSION, CppMicroServices_MINOR_VERSION, CppMicroServices_PATCH_VERSION) == m->GetVersion(), "Test module version") #endif } // Get context id, location and status of the module void frame010a(ModuleContext* mc) { Module* m = mc->GetModule(); long int contextid = m->GetModuleId(); US_DEBUG << "CONTEXT ID:" << contextid; std::string location = m->GetLocation(); US_DEBUG << "LOCATION:" << location; US_TEST_CONDITION(!location.empty(), "Test for non-empty module location") US_TEST_CONDITION(m->IsLoaded(), "Test for loaded flag") US_TEST_CONDITION(ModuleSettings::GetStoragePath().empty(), "Test for empty base storage path") US_TEST_CONDITION(m->GetModuleContext()->GetDataFile("").empty(), "Test for empty data path") US_TEST_CONDITION(m->GetModuleContext()->GetDataFile("bla").empty(), "Test for empty data file path") } //---------------------------------------------------------------------------- //Test result of GetService(ServiceReference()). Should throw std::invalid_argument void frame018a(ModuleContext* mc) { try { mc->GetService(ServiceReferenceU()); US_DEBUG << "Got service object, expected std::invalid_argument exception"; US_TEST_FAILED_MSG(<< "Got service object, excpected std::invalid_argument exception") } catch (const std::invalid_argument& ) {} catch (...) { US_TEST_FAILED_MSG(<< "Got wrong exception, expected std::invalid_argument") } } // Load libA and check that it exists and that the service it registers exists, // also check that the expected events occur and that the storage paths are correct void frame020a(ModuleContext* mc, TestModuleListener& listener, #ifdef US_BUILD_SHARED_LIBS SharedLibrary& libA) { ModuleSettings::SetStoragePath(std::string("/tmp") + PATH_SEPARATOR); US_TEST_CONDITION(ModuleSettings::GetStoragePath() == "/tmp", "Test for valid base storage path") try { libA.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG(<< "Load module exception: " << e.what()) } Module* moduleA = ModuleRegistry::GetModule("TestModuleA Module"); US_TEST_CONDITION_REQUIRED(moduleA != 0, "Test for existing module TestModuleA") US_TEST_CONDITION(moduleA->GetName() == "TestModuleA Module", "Test module name") std::cout << moduleA->GetModuleContext()->GetDataFile(""); std::stringstream ss; ss << moduleA->GetModuleId(); const std::string baseStoragePath = std::string("/tmp") + PATH_SEPARATOR + ss.str() + "_TestModuleA" + PATH_SEPARATOR; US_TEST_CONDITION(moduleA->GetModuleContext()->GetDataFile("") == baseStoragePath, "Test for valid data path") US_TEST_CONDITION(moduleA->GetModuleContext()->GetDataFile("bla") == baseStoragePath + "bla", "Test for valid data file path") #else SharedLibrary& /*libA*/) { #endif // Check if libA registered the expected service try { ServiceReferenceU sr1 = mc->GetServiceReference("org.cppmicroservices.TestModuleAService"); InterfaceMap o1 = mc->GetService(sr1); US_TEST_CONDITION(!o1.empty(), "Test if service object found"); try { US_TEST_CONDITION(mc->UngetService(sr1), "Test if Service UnGet returns true"); } catch (const std::logic_error le) { US_TEST_FAILED_MSG(<< "UnGetService exception: " << le.what()) } // check the listeners for events std::vector pEvts; #ifdef US_BUILD_SHARED_LIBS pEvts.push_back(ModuleEvent(ModuleEvent::LOADING, moduleA)); pEvts.push_back(ModuleEvent(ModuleEvent::LOADED, moduleA)); #endif std::vector seEvts; #ifdef US_BUILD_SHARED_LIBS seEvts.push_back(ServiceEvent(ServiceEvent::REGISTERED, sr1)); #endif US_TEST_CONDITION(listener.CheckListenerEvents(pEvts, seEvts), "Test for unexpected events"); } catch (const ServiceException& /*se*/) { US_TEST_FAILED_MSG(<< "test module, expected service not found"); } #ifdef US_BUILD_SHARED_LIBS US_TEST_CONDITION(moduleA->IsLoaded() == true, "Test if loaded correctly"); #endif } // Unload libA and check for correct events void frame030b(ModuleContext* mc, TestModuleListener& listener, SharedLibrary& libA) { #ifdef US_BUILD_SHARED_LIBS Module* moduleA = ModuleRegistry::GetModule("TestModuleA Module"); US_TEST_CONDITION_REQUIRED(moduleA != 0, "Test for non-null module") #endif ServiceReferenceU sr1 = mc->GetServiceReference("org.cppmicroservices.TestModuleAService"); US_TEST_CONDITION(sr1, "Test for valid service reference") try { libA.Unload(); #ifdef US_BUILD_SHARED_LIBS US_TEST_CONDITION(moduleA->IsLoaded() == false, "Test for unloaded state") #endif } catch (const std::exception& e) { US_TEST_FAILED_MSG(<< "UnLoad module exception: " << e.what()) } std::vector pEvts; #ifdef US_BUILD_SHARED_LIBS pEvts.push_back(ModuleEvent(ModuleEvent::UNLOADING, moduleA)); pEvts.push_back(ModuleEvent(ModuleEvent::UNLOADED, moduleA)); #endif std::vector seEvts; #ifdef US_BUILD_SHARED_LIBS seEvts.push_back(ServiceEvent(ServiceEvent::UNREGISTERING, sr1)); #endif US_TEST_CONDITION(listener.CheckListenerEvents(pEvts, seEvts), "Test for unexpected events"); } struct LocalListener { void ServiceChanged(const ServiceEvent) {} }; // Add a service listener with a broken LDAP filter to Get an exception void frame045a(ModuleContext* mc) { LocalListener sListen1; std::string brokenFilter = "A broken LDAP filter"; try { mc->AddServiceListener(&sListen1, &LocalListener::ServiceChanged, brokenFilter); } catch (const std::invalid_argument& /*ia*/) { //assertEquals("InvalidSyntaxException.GetFilter should be same as input string", brokenFilter, ise.GetFilter()); } catch (...) { US_TEST_FAILED_MSG(<< "test module, wrong exception on broken LDAP filter:"); } } } // end unnamed namespace int usModuleTest(int /*argc*/, char* /*argv*/[]) { US_TEST_BEGIN("ModuleTest"); frame02a(); ModuleContext* mc = GetModuleContext(); TestModuleListener listener; try { mc->AddModuleListener(&listener, &TestModuleListener::ModuleChanged); } catch (const std::logic_error& ise) { US_TEST_OUTPUT( << "module listener registration failed " << ise.what() ); throw; } try { mc->AddServiceListener(&listener, &TestModuleListener::ServiceChanged); } catch (const std::logic_error& ise) { US_TEST_OUTPUT( << "service listener registration failed " << ise.what() ); throw; } frame005a(mc); frame010a(mc); frame018a(mc); SharedLibrary libA(LIB_PATH, "TestModuleA"); frame020a(mc, listener, libA); frame030b(mc, listener, libA); frame045a(mc); mc->RemoveModuleListener(&listener, &TestModuleListener::ModuleChanged); mc->RemoveServiceListener(&listener, &TestModuleListener::ServiceChanged); US_TEST_END() } diff --git a/test/usServiceControlInterface.h b/core/test/usServiceControlInterface.h similarity index 97% rename from test/usServiceControlInterface.h rename to core/test/usServiceControlInterface.h index 129832ff12..c6172a4778 100644 --- a/test/usServiceControlInterface.h +++ b/core/test/usServiceControlInterface.h @@ -1,45 +1,45 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICECONTROLINTERFACE_H #define USSERVICECONTROLINTERFACE_H -#include +#include #include #include US_BEGIN_NAMESPACE struct ServiceControlInterface { virtual ~ServiceControlInterface() {} virtual void ServiceControl(int service, const std::string& operation, int ranking) = 0; }; US_END_NAMESPACE US_DECLARE_SERVICE_INTERFACE(US_PREPEND_NAMESPACE(ServiceControlInterface), "org.us.testing.ServiceControlInterface") #endif // USSERVICECONTROLINTERFACE_H diff --git a/test/usServiceFactoryTest.cpp b/core/test/usServiceFactoryTest.cpp similarity index 100% rename from test/usServiceFactoryTest.cpp rename to core/test/usServiceFactoryTest.cpp diff --git a/test/usServiceHooksTest.cpp b/core/test/usServiceHooksTest.cpp similarity index 100% rename from test/usServiceHooksTest.cpp rename to core/test/usServiceHooksTest.cpp diff --git a/test/usServiceListenerTest.cpp b/core/test/usServiceListenerTest.cpp similarity index 99% rename from test/usServiceListenerTest.cpp rename to core/test/usServiceListenerTest.cpp index 42c6235d70..312d34b547 100644 --- a/test/usServiceListenerTest.cpp +++ b/core/test/usServiceListenerTest.cpp @@ -1,567 +1,565 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ -#include - #include #include #include #include #include #include #include US_USE_NAMESPACE #ifdef US_PLATFORM_WINDOWS static const std::string LIB_PATH = US_RUNTIME_OUTPUT_DIRECTORY; #else static const std::string LIB_PATH = US_LIBRARY_OUTPUT_DIRECTORY; #endif class TestServiceListener { private: friend bool runLoadUnloadTest(const std::string&, int cnt, SharedLibrary&, const std::vector&); const bool checkUsingModules; std::vector events; bool teststatus; ModuleContext* mc; public: TestServiceListener(ModuleContext* mc, bool checkUsingModules = true) : checkUsingModules(checkUsingModules), events(), teststatus(true), mc(mc) {} bool getTestStatus() const { return teststatus; } void clearEvents() { events.clear(); } bool checkEvents(const std::vector& eventTypes) { if (events.size() != eventTypes.size()) { dumpEvents(eventTypes); return false; } for (std::size_t i=0; i < eventTypes.size(); ++i) { if (eventTypes[i] != events[i].GetType()) { dumpEvents(eventTypes); return false; } } return true; } void serviceChanged(const ServiceEvent evt) { events.push_back(evt); US_TEST_OUTPUT( << "ServiceEvent: " << evt ); if (ServiceEvent::UNREGISTERING == evt.GetType()) { ServiceReferenceU sr = evt.GetServiceReference(); // Validate that no module is marked as using the service std::vector usingModules; sr.GetUsingModules(usingModules); if (checkUsingModules && !usingModules.empty()) { teststatus = false; printUsingModules(sr, "*** Using modules (unreg) should be empty but is: "); } // Check if the service can be fetched InterfaceMap service = mc->GetService(sr); sr.GetUsingModules(usingModules); // if (UNREGISTERSERVICE_VALID_DURING_UNREGISTERING) { // In this mode the service shall be obtainable during // unregistration. if (service.empty()) { teststatus = false; US_TEST_OUTPUT( << "*** Service should be available to ServiceListener " << "while handling unregistering event." ); } US_TEST_OUTPUT( << "Service (unreg): " << service.begin()->first << " -> " << service.begin()->second ); if (checkUsingModules && usingModules.size() != 1) { teststatus = false; printUsingModules(sr, "*** One using module expected " "(unreg, after getService), found: "); } else { printUsingModules(sr, "Using modules (unreg, after getService): "); } // } else { // // In this mode the service shall NOT be obtainable during // // unregistration. // if (null!=service) { // teststatus = false; // out.print("*** Service should not be available to ServiceListener " // +"while handling unregistering event."); // } // if (checkUsingBundles && null!=usingBundles) { // teststatus = false; // printUsingBundles(sr, // "*** Using bundles (unreg, after getService), " // +"should be null but is: "); // } else { // printUsingBundles(sr, // "Using bundles (unreg, after getService): null"); // } // } mc->UngetService(sr); // Check that the UNREGISTERING service can not be looked up // using the service registry. try { long sid = any_cast(sr.GetProperty(ServiceConstants::SERVICE_ID())); std::stringstream ss; ss << "(" << ServiceConstants::SERVICE_ID() << "=" << sid << ")"; std::vector srs = mc->GetServiceReferences("", ss.str()); if (srs.empty()) { US_TEST_OUTPUT( << "ServiceReference for UNREGISTERING service is not" " found in the service registry; ok." ); } else { teststatus = false; US_TEST_OUTPUT( << "*** ServiceReference for UNREGISTERING service," << sr << ", not found in the service registry; fail." ); US_TEST_OUTPUT( << "Found the following Service references:") ; for(std::vector::const_iterator sr = srs.begin(); sr != srs.end(); ++sr) { US_TEST_OUTPUT( << (*sr) ); } } } catch (const std::exception& e) { teststatus = false; US_TEST_OUTPUT( << "*** Unexpected excpetion when trying to lookup a" " service while it is in state UNREGISTERING: " << e.what() ); } } } void printUsingModules(const ServiceReferenceU& sr, const std::string& caption) { std::vector usingModules; sr.GetUsingModules(usingModules); US_TEST_OUTPUT( << (caption.empty() ? "Using modules: " : caption) ); for(std::vector::const_iterator module = usingModules.begin(); module != usingModules.end(); ++module) { US_TEST_OUTPUT( << " -" << (*module) ); } } // Print expected and actual service events. void dumpEvents(const std::vector& eventTypes) { std::size_t max = events.size() > eventTypes.size() ? events.size() : eventTypes.size(); US_TEST_OUTPUT( << "Expected event type -- Actual event" ); for (std::size_t i=0; i < max; ++i) { ServiceEvent evt = i < events.size() ? events[i] : ServiceEvent(); if (i < eventTypes.size()) { US_TEST_OUTPUT( << " " << eventTypes[i] << "--" << evt ); } else { US_TEST_OUTPUT( << " " << "- NONE - " << "--" << evt ); } } } }; // end of class ServiceListener bool runLoadUnloadTest(const std::string& name, int cnt, SharedLibrary& target, const std::vector& events) { bool teststatus = true; ModuleContext* mc = GetModuleContext(); for (int i = 0; i < cnt && teststatus; ++i) { TestServiceListener sListen(mc); try { mc->AddServiceListener(&sListen, &TestServiceListener::serviceChanged); //mc->AddServiceListener(MessageDelegate1(&sListen, &ServiceListener::serviceChanged)); } catch (const std::logic_error& ise) { teststatus = false; US_TEST_FAILED_MSG( << "service listener registration failed " << ise.what() << " :" << name << ":FAIL" ); } // Start the test target to get a service published. try { target.Load(); } catch (const std::exception& e) { teststatus = false; US_TEST_FAILED_MSG( << "Failed to load module, got exception: " << e.what() << " + in " << name << ":FAIL" ); } // Stop the test target to get a service unpublished. try { target.Unload(); } catch (const std::exception& e) { teststatus = false; US_TEST_FAILED_MSG( << "Failed to unload module, got exception: " << e.what() << " + in " << name << ":FAIL" ); } if (teststatus && !sListen.checkEvents(events)) { teststatus = false; US_TEST_FAILED_MSG( << "Service listener event notification error :" << name << ":FAIL" ); } try { mc->RemoveServiceListener(&sListen, &TestServiceListener::serviceChanged); teststatus &= sListen.teststatus; sListen.clearEvents(); } catch (const std::logic_error& ise) { teststatus = false; US_TEST_FAILED_MSG( << "service listener removal failed " << ise.what() << " :" << name << ":FAIL" ); } } return teststatus; } void frameSL02a() { ModuleContext* mc = GetModuleContext(); TestServiceListener listener1(mc); TestServiceListener listener2(mc); try { mc->RemoveServiceListener(&listener1, &TestServiceListener::serviceChanged); mc->AddServiceListener(&listener1, &TestServiceListener::serviceChanged); mc->RemoveServiceListener(&listener2, &TestServiceListener::serviceChanged); mc->AddServiceListener(&listener2, &TestServiceListener::serviceChanged); } catch (const std::logic_error& ise) { US_TEST_FAILED_MSG( << "service listener registration failed " << ise.what() << " : frameSL02a:FAIL" ); } SharedLibrary target(LIB_PATH, "TestModuleA"); // Start the test target to get a service published. try { target.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG( << "Failed to load module, got exception: " << e.what() << " + in frameSL02a:FAIL" ); } std::vector events; events.push_back(ServiceEvent::REGISTERED); US_TEST_CONDITION(listener1.checkEvents(events), "Check first service listener") US_TEST_CONDITION(listener2.checkEvents(events), "Check second service listener") mc->RemoveServiceListener(&listener1, &TestServiceListener::serviceChanged); mc->RemoveServiceListener(&listener2, &TestServiceListener::serviceChanged); target.Unload(); } void frameSL05a() { std::vector events; events.push_back(ServiceEvent::REGISTERED); events.push_back(ServiceEvent::UNREGISTERING); SharedLibrary libA(LIB_PATH, "TestModuleA"); bool testStatus = runLoadUnloadTest("FrameSL05a", 1, libA, events); US_TEST_CONDITION(testStatus, "FrameSL05a") } void frameSL10a() { std::vector events; events.push_back(ServiceEvent::REGISTERED); events.push_back(ServiceEvent::UNREGISTERING); SharedLibrary libA2(LIB_PATH, "TestModuleA2"); bool testStatus = runLoadUnloadTest("FrameSL10a", 1, libA2, events); US_TEST_CONDITION(testStatus, "FrameSL10a") } void frameSL25a() { ModuleContext* mc = GetModuleContext(); TestServiceListener sListen(mc, false); try { mc->AddServiceListener(&sListen, &TestServiceListener::serviceChanged); } catch (const std::logic_error& ise) { US_TEST_OUTPUT( << "service listener registration failed " << ise.what() ); throw; } SharedLibrary libSL1(LIB_PATH, "TestModuleSL1"); SharedLibrary libSL3(LIB_PATH, "TestModuleSL3"); SharedLibrary libSL4(LIB_PATH, "TestModuleSL4"); std::vector expectedServiceEventTypes; // Startup expectedServiceEventTypes.push_back(ServiceEvent::REGISTERED); // at start of libSL1 expectedServiceEventTypes.push_back(ServiceEvent::REGISTERED); // FooService at start of libSL4 expectedServiceEventTypes.push_back(ServiceEvent::REGISTERED); // at start of libSL3 // Stop libSL4 expectedServiceEventTypes.push_back(ServiceEvent::UNREGISTERING); // FooService at first stop of libSL4 #ifdef US_BUILD_SHARED_LIBS // Shutdown expectedServiceEventTypes.push_back(ServiceEvent::UNREGISTERING); // at stop of libSL1 expectedServiceEventTypes.push_back(ServiceEvent::UNREGISTERING); // at stop of libSL3 #endif // Start libModuleTestSL1 to ensure that the Service interface is available. try { US_TEST_OUTPUT( << "Starting libModuleTestSL1: " << libSL1.GetFilePath() ); libSL1.Load(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to load module, got exception: " << e.what() ); throw; } // Start libModuleTestSL4 that will require the serivce interface and publish // us::FooService try { US_TEST_OUTPUT( << "Starting libModuleTestSL4: " << libSL4.GetFilePath() ); libSL4.Load(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to load module, got exception: " << e.what() ); throw; } // Start libModuleTestSL3 that will require the serivce interface and get the service try { US_TEST_OUTPUT( << "Starting libModuleTestSL3: " << libSL3.GetFilePath() ); libSL3.Load(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to load module, got exception: " << e.what() ); throw; } // Check that libSL3 has been notified about the FooService. US_TEST_OUTPUT( << "Check that FooService is added to service tracker in libSL3" ); try { ServiceReferenceU libSL3SR = mc->GetServiceReference("ActivatorSL3"); InterfaceMap libSL3Activator = mc->GetService(libSL3SR); US_TEST_CONDITION_REQUIRED(!libSL3Activator.empty(), "ActivatorSL3 service != 0"); ServiceReference libSL3PropsI(libSL3SR); ModulePropsInterface* propsInterface = mc->GetService(libSL3PropsI); US_TEST_CONDITION_REQUIRED(propsInterface, "ModulePropsInterface != 0"); ModulePropsInterface::Properties::const_iterator i = propsInterface->GetProperties().find("serviceAdded"); US_TEST_CONDITION_REQUIRED(i != propsInterface->GetProperties().end(), "Property serviceAdded"); Any serviceAddedField3 = i->second; US_TEST_CONDITION_REQUIRED(!serviceAddedField3.Empty() && any_cast(serviceAddedField3), "libSL3 notified about presence of FooService"); mc->UngetService(libSL3SR); } catch (const ServiceException& se) { US_TEST_FAILED_MSG( << "Failed to get service reference:" << se ); } // Check that libSL1 has been notified about the FooService. US_TEST_OUTPUT( << "Check that FooService is added to service tracker in libSL1" ); try { ServiceReferenceU libSL1SR = mc->GetServiceReference("ActivatorSL1"); InterfaceMap libSL1Activator = mc->GetService(libSL1SR); US_TEST_CONDITION_REQUIRED(!libSL1Activator.empty(), "ActivatorSL1 service != 0"); ServiceReference libSL1PropsI(libSL1SR); ModulePropsInterface* propsInterface = mc->GetService(libSL1PropsI); US_TEST_CONDITION_REQUIRED(propsInterface, "Cast to ModulePropsInterface"); ModulePropsInterface::Properties::const_iterator i = propsInterface->GetProperties().find("serviceAdded"); US_TEST_CONDITION_REQUIRED(i != propsInterface->GetProperties().end(), "Property serviceAdded"); Any serviceAddedField1 = i->second; US_TEST_CONDITION_REQUIRED(!serviceAddedField1.Empty() && any_cast(serviceAddedField1), "libSL1 notified about presence of FooService"); mc->UngetService(libSL1SR); } catch (const ServiceException& se) { US_TEST_FAILED_MSG( << "Failed to get service reference:" << se ); } // Stop the service provider: libSL4 try { US_TEST_OUTPUT( << "Stop libSL4: " << libSL4.GetFilePath() ); libSL4.Unload(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to unload module, got exception:" << e.what() ); throw; } // Check that libSL3 has been notified about the removal of FooService. US_TEST_OUTPUT( << "Check that FooService is removed from service tracker in libSL3" ); try { ServiceReferenceU libSL3SR = mc->GetServiceReference("ActivatorSL3"); InterfaceMap libSL3Activator = mc->GetService(libSL3SR); US_TEST_CONDITION_REQUIRED(!libSL3Activator.empty(), "ActivatorSL3 service != 0"); ServiceReference libSL3PropsI(libSL3SR); ModulePropsInterface* propsInterface = mc->GetService(libSL3PropsI); US_TEST_CONDITION_REQUIRED(propsInterface, "Cast to ModulePropsInterface"); ModulePropsInterface::Properties::const_iterator i = propsInterface->GetProperties().find("serviceRemoved"); US_TEST_CONDITION_REQUIRED(i != propsInterface->GetProperties().end(), "Property serviceRemoved"); Any serviceRemovedField3 = i->second; US_TEST_CONDITION(!serviceRemovedField3.Empty() && any_cast(serviceRemovedField3), "libSL3 notified about removal of FooService"); mc->UngetService(libSL3SR); } catch (const ServiceException& se) { US_TEST_FAILED_MSG( << "Failed to get service reference:" << se ); } // Stop libSL1 try { US_TEST_OUTPUT( << "Stop libSL1:" << libSL1.GetFilePath() ); libSL1.Unload(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to unload module got exception" << e.what() ); throw; } // Stop pSL3 try { US_TEST_OUTPUT( << "Stop libSL3:" << libSL3.GetFilePath() ); libSL3.Unload(); } catch (const std::exception& e) { US_TEST_OUTPUT( << "Failed to unload module got exception" << e.what() ); throw; } // Check service events seen by this class US_TEST_OUTPUT( << "Checking ServiceEvents(ServiceListener):" ); if (!sListen.checkEvents(expectedServiceEventTypes)) { US_TEST_FAILED_MSG( << "Service listener event notification error" ); } US_TEST_CONDITION_REQUIRED(sListen.getTestStatus(), "Service listener checks"); try { mc->RemoveServiceListener(&sListen, &TestServiceListener::serviceChanged); sListen.clearEvents(); } catch (const std::logic_error& ise) { US_TEST_FAILED_MSG( << "service listener removal failed: " << ise.what() ); } } int usServiceListenerTest(int /*argc*/, char* /*argv*/[]) { US_TEST_BEGIN("ServiceListenerTest"); frameSL02a(); frameSL05a(); frameSL10a(); frameSL25a(); US_TEST_END() } diff --git a/test/usServiceRegistryPerformanceTest.cpp b/core/test/usServiceRegistryPerformanceTest.cpp similarity index 100% rename from test/usServiceRegistryPerformanceTest.cpp rename to core/test/usServiceRegistryPerformanceTest.cpp diff --git a/test/usServiceRegistryTest.cpp b/core/test/usServiceRegistryTest.cpp similarity index 100% rename from test/usServiceRegistryTest.cpp rename to core/test/usServiceRegistryTest.cpp diff --git a/test/usServiceTemplateTest.cpp b/core/test/usServiceTemplateTest.cpp similarity index 100% rename from test/usServiceTemplateTest.cpp rename to core/test/usServiceTemplateTest.cpp diff --git a/test/usServiceTrackerTest.cpp b/core/test/usServiceTrackerTest.cpp similarity index 99% rename from test/usServiceTrackerTest.cpp rename to core/test/usServiceTrackerTest.cpp index bcf834347d..7031e0da4d 100644 --- a/test/usServiceTrackerTest.cpp +++ b/core/test/usServiceTrackerTest.cpp @@ -1,283 +1,281 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include - #include #include #include #include #include #include #include #include #include "usServiceControlInterface.h" #include US_USE_NAMESPACE bool CheckConvertibility(const std::vector& refs, std::vector::const_iterator idBegin, std::vector::const_iterator idEnd) { std::vector ids; ids.assign(idBegin, idEnd); for (std::vector::const_iterator sri = refs.begin(); sri != refs.end(); ++sri) { for (std::vector::iterator idIter = ids.begin(); idIter != ids.end(); ++idIter) { if (sri->IsConvertibleTo(*idIter)) { ids.erase(idIter); break; } } } return ids.empty(); } struct MyInterfaceOne { virtual ~MyInterfaceOne() {} }; US_DECLARE_SERVICE_INTERFACE(MyInterfaceOne, "org.cppmicroservices.servicetrackertest.MyInterfaceOne") struct MyInterfaceTwo { virtual ~MyInterfaceTwo() {} }; US_DECLARE_SERVICE_INTERFACE(MyInterfaceTwo, "org.cppmicroservices.servicetrackertest.MyInterfaceTwo") class MyCustomizer : public us::ServiceTrackerCustomizer { public: MyCustomizer(us::ModuleContext* context) : m_context(context) {} virtual MyInterfaceOne* AddingService(const ServiceReferenceType& reference) { US_TEST_CONDITION_REQUIRED(reference, "AddingService() valid reference") return m_context->GetService(reference); } virtual void ModifiedService(const ServiceReferenceType& reference, MyInterfaceOne* service) { US_TEST_CONDITION(reference, "ModifiedService() valid reference") US_TEST_CONDITION(service, "ModifiedService() valid service") } virtual void RemovedService(const ServiceReferenceType& reference, MyInterfaceOne* service) { US_TEST_CONDITION(reference, "RemovedService() valid reference") US_TEST_CONDITION(service, "RemovedService() valid service") } private: us::ModuleContext* m_context; }; void TestFilterString() { us::ModuleContext* context = us::GetModuleContext(); MyCustomizer customizer(context); us::LDAPFilter filter("(" + us::ServiceConstants::SERVICE_ID() + ">=0)"); us::ServiceTracker tracker(context, filter, &customizer); tracker.Open(); struct MyServiceOne : public MyInterfaceOne {}; struct MyServiceTwo : public MyInterfaceTwo {}; MyServiceOne serviceOne; MyServiceTwo serviceTwo; context->RegisterService(&serviceOne); context->RegisterService(&serviceTwo); US_TEST_CONDITION(tracker.GetServiceReferences().size() == 1, "tracking count") } void TestServiceTracker() { #ifdef US_PLATFORM_WINDOWS const std::string LIB_PATH = US_RUNTIME_OUTPUT_DIRECTORY; #else const std::string LIB_PATH = US_LIBRARY_OUTPUT_DIRECTORY; #endif ModuleContext* mc = GetModuleContext(); SharedLibrary libS(LIB_PATH, "TestModuleS"); #ifdef US_BUILD_SHARED_LIBS // Start the test target to get a service published. try { libS.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG( << "Failed to load module, got exception: " << e.what() ); } #endif // 1. Create a ServiceTracker with ServiceTrackerCustomizer == null std::string s1("org.cppmicroservices.TestModuleSService"); ServiceReferenceU servref = mc->GetServiceReference(s1 + "0"); US_TEST_CONDITION_REQUIRED(servref != 0, "Test if registered service of id org.cppmicroservices.TestModuleSService0"); ServiceReference servCtrlRef = mc->GetServiceReference(); US_TEST_CONDITION_REQUIRED(servCtrlRef != 0, "Test if constrol service was registered"); ServiceControlInterface* serviceController = mc->GetService(servCtrlRef); US_TEST_CONDITION_REQUIRED(serviceController != 0, "Test valid service controller"); std::auto_ptr > st1(new ServiceTracker(mc, servref)); // 2. Check the size method with an unopened service tracker US_TEST_CONDITION_REQUIRED(st1->Size() == 0, "Test if size == 0"); // 3. Open the service tracker and see what it finds, // expect to find one instance of the implementation, // "org.cppmicroservices.TestModuleSService0" st1->Open(); std::vector sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 1, "Checking ServiceTracker size"); US_TEST_CONDITION_REQUIRED(s1 + "0" == sa2[0].GetInterfaceId(), "Checking service implementation name"); // 5. Close this service tracker st1->Close(); // 6. Check the size method, now when the servicetracker is closed US_TEST_CONDITION_REQUIRED(st1->Size() == 0, "Checking ServiceTracker size"); // 7. Check if we still track anything , we should get null sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.empty(), "Checking ServiceTracker size"); // 8. A new Servicetracker, this time with a filter for the object std::string fs = std::string("(") + ServiceConstants::OBJECTCLASS() + "=" + s1 + "*" + ")"; LDAPFilter f1(fs); st1.reset(new ServiceTracker(mc, f1)); // add a service serviceController->ServiceControl(1, "register", 7); // 9. Open the service tracker and see what it finds, // expect to find two instances of references to // "org.cppmicroservices.TestModuleSService*" // i.e. they refer to the same piece of code std::vector ids; ids.push_back((s1 + "0")); ids.push_back((s1 + "1")); ids.push_back((s1 + "2")); ids.push_back((s1 + "3")); st1->Open(); sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 2, "Checking service reference count"); US_TEST_CONDITION_REQUIRED(CheckConvertibility(sa2, ids.begin(), ids.begin()+2), "Check for expected interface id [0]"); US_TEST_CONDITION_REQUIRED(sa2[1].IsConvertibleTo(s1 + "1"), "Check for expected interface id [1]"); // 10. Get libTestModuleS to register one more service and see if it appears serviceController->ServiceControl(2, "register", 1); sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 3, "Checking service reference count"); US_TEST_CONDITION_REQUIRED(CheckConvertibility(sa2, ids.begin(), ids.begin()+3), "Check for expected interface id [2]"); // 11. Get libTestModuleS to register one more service and see if it appears serviceController->ServiceControl(3, "register", 2); sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 4, "Checking service reference count"); US_TEST_CONDITION_REQUIRED(CheckConvertibility(sa2, ids.begin(), ids.end()), "Check for expected interface id [3]"); // 12. Get libTestModuleS to unregister one service and see if it disappears serviceController->ServiceControl(3, "unregister", 0); sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 3, "Checking service reference count"); // 13. Get the highest ranking service reference, it should have ranking 7 ServiceReferenceU h1 = st1->GetServiceReference(); int rank = any_cast(h1.GetProperty(ServiceConstants::SERVICE_RANKING())); US_TEST_CONDITION_REQUIRED(rank == 7, "Check service rank"); // 14. Get the service of the highest ranked service reference InterfaceMap o1 = st1->GetService(h1); US_TEST_CONDITION_REQUIRED(!o1.empty(), "Check for non-null service"); // 14a Get the highest ranked service, directly this time InterfaceMap o3 = st1->GetService(); US_TEST_CONDITION_REQUIRED(!o3.empty(), "Check for non-null service"); US_TEST_CONDITION_REQUIRED(o1 == o3, "Check for equal service instances"); // 15. Now release the tracking of that service and then try to get it // from the servicetracker, which should yield a null object serviceController->ServiceControl(1, "unregister", 7); InterfaceMap o2 = st1->GetService(h1); US_TEST_CONDITION_REQUIRED(o2.empty(), "Checkt that service is null"); // 16. Get all service objects this tracker tracks, it should be 2 std::vector ts1 = st1->GetServices(); US_TEST_CONDITION_REQUIRED(ts1.size() == 2, "Check service count"); // 17. Test the remove method. // First register another service, then remove it being tracked serviceController->ServiceControl(1, "register", 7); h1 = st1->GetServiceReference(); std::vector sa3 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa3.size() == 3, "Check service reference count"); US_TEST_CONDITION_REQUIRED(CheckConvertibility(sa3, ids.begin(), ids.begin()+3), "Check for expected interface id [0]"); st1->Remove(h1); // remove tracking on one servref sa2 = st1->GetServiceReferences(); US_TEST_CONDITION_REQUIRED(sa2.size() == 2, "Check service reference count"); // 18. Test the addingService method,add a service reference // 19. Test the removedService method, remove a service reference // 20. Test the waitForService method InterfaceMap o9 = st1->WaitForService(50); US_TEST_CONDITION_REQUIRED(!o9.empty(), "Checking WaitForService method"); } int usServiceTrackerTest(int /*argc*/, char* /*argv*/[]) { US_TEST_BEGIN("ServiceTrackerTest") TestFilterString(); TestServiceTracker(); US_TEST_END() } diff --git a/test/usSharedLibraryTest.cpp b/core/test/usSharedLibraryTest.cpp similarity index 100% rename from test/usSharedLibraryTest.cpp rename to core/test/usSharedLibraryTest.cpp diff --git a/test/usStaticModuleResourceTest.cpp b/core/test/usStaticModuleResourceTest.cpp similarity index 100% rename from test/usStaticModuleResourceTest.cpp rename to core/test/usStaticModuleResourceTest.cpp diff --git a/test/usStaticModuleTest.cpp b/core/test/usStaticModuleTest.cpp similarity index 100% rename from test/usStaticModuleTest.cpp rename to core/test/usStaticModuleTest.cpp diff --git a/test/usTestManager.cpp b/core/test/usTestManager.cpp similarity index 100% rename from test/usTestManager.cpp rename to core/test/usTestManager.cpp diff --git a/test/usTestManager.h b/core/test/usTestManager.h similarity index 98% rename from test/usTestManager.h rename to core/test/usTestManager.h index 080198ef5b..75f5ccbcbc 100644 --- a/test/usTestManager.h +++ b/core/test/usTestManager.h @@ -1,57 +1,57 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef US_TESTMANAGER_H_INCLUDED #define US_TESTMANAGER_H_INCLUDED -#include +#include US_BEGIN_NAMESPACE class TestManager { public: TestManager() : m_FailedTests(0), m_PassedTests(0) {} virtual ~TestManager() {} static TestManager& GetInstance(); /** \brief Must be called at the beginning of a test run. */ void Initialize(); int NumberOfFailedTests(); int NumberOfPassedTests(); /** \brief Tell manager a subtest failed */ void TestFailed(); /** \brief Tell manager a subtest passed */ void TestPassed(); protected: int m_FailedTests; int m_PassedTests; }; US_END_NAMESPACE #endif // US_TESTMANAGER_H_INCLUDED diff --git a/test/usTestResource.txt b/core/test/usTestResource.txt similarity index 100% rename from test/usTestResource.txt rename to core/test/usTestResource.txt diff --git a/test/usTestUtilModuleListener.cpp b/core/test/usTestUtilModuleListener.cpp similarity index 100% rename from test/usTestUtilModuleListener.cpp rename to core/test/usTestUtilModuleListener.cpp diff --git a/test/usTestUtilModuleListener.h b/core/test/usTestUtilModuleListener.h similarity index 98% rename from test/usTestUtilModuleListener.h rename to core/test/usTestUtilModuleListener.h index 825d5a1d68..b8a75c8647 100644 --- a/test/usTestUtilModuleListener.h +++ b/core/test/usTestUtilModuleListener.h @@ -1,68 +1,66 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USTESTUTILMODULELISTENER_H #define USTESTUTILMODULELISTENER_H -#include "usConfig.h" - #include "usModuleEvent.h" #include "usServiceEvent.h" US_BEGIN_NAMESPACE class ModuleContext; class TestModuleListener { public: TestModuleListener(); void ModuleChanged(const ModuleEvent event); void ServiceChanged(const ServiceEvent event); ModuleEvent GetModuleEvent() const; ServiceEvent GetServiceEvent() const; bool CheckListenerEvents( bool pexp, ModuleEvent::Type ptype, bool sexp, ServiceEvent::Type stype, Module* moduleX, ServiceReferenceU* servX); bool CheckListenerEvents(const std::vector& pEvts); bool CheckListenerEvents(const std::vector& seEvts); bool CheckListenerEvents(const std::vector& pEvts, const std::vector& seEvts); private: std::vector serviceEvents; std::vector moduleEvents; }; US_END_NAMESPACE #endif // USTESTUTILMODULELISTENER_H diff --git a/test/usTestingConfig.h.in b/core/test/usTestingConfig.h.in similarity index 100% rename from test/usTestingConfig.h.in rename to core/test/usTestingConfig.h.in diff --git a/test/usTestingMacros.h b/core/test/usTestingMacros.h similarity index 100% rename from test/usTestingMacros.h rename to core/test/usTestingMacros.h diff --git a/core/usCoreConfig.cmake.in b/core/usCoreConfig.cmake.in new file mode 100644 index 0000000000..1f1e691f00 --- /dev/null +++ b/core/usCoreConfig.cmake.in @@ -0,0 +1,22 @@ +@PACKAGE_INIT@ + +set(US_@PROJECT_NAME@_CXX_FLAGS "") +set(US_@PROJECT_NAME@_CXX_FLAGS_RELEASE "") +set(US_@PROJECT_NAME@_CXX_FLAGS_DEBUG "") +set(US_@PROJECT_NAME@_C_FLAGS "") +set(US_@PROJECT_NAME@_C_FLAGS_RELEASE "") +set(US_@PROJECT_NAME@_C_FLAGS_DEBUG "") +set(US_@PROJECT_NAME@_LINK_FLAGS "") +set(US_@PROJECT_NAME@_LINK_FLAGS_RELEASE "") +set(US_@PROJECT_NAME@_LINK_FLAGS_DEBUG "") +set(US_@PROJECT_NAME@_COMPILE_DEFINITIONS "") +set(US_@PROJECT_NAME@_COMPILE_DEFINITIONS_RELEASE "") +set(US_@PROJECT_NAME@_COMPILE_DEFINITIONS_DEBUG "") + +set(US_@PROJECT_NAME@_INCLUDE_DIRS "@PACKAGE_CONFIG_INCLUDE_DIR@") +set(US_@PROJECT_NAME@_LIBRARIES @PROJECT_TARGET@) +set(US_@PROJECT_NAME@_RUNTIME_LIBRARY_DIRS "@PACKAGE_CONFIG_RUNTIME_LIBRARY_DIR@") + +if(NOT TARGET @PROJECT_TARGET@ AND NOT US_IS_EMBEDDED) + include(${CMAKE_CURRENT_LIST_DIR}/us@PROJECT_NAME@Targets.cmake) +endif() diff --git a/core/usCoreConfigVersion.cmake.in b/core/usCoreConfigVersion.cmake.in new file mode 100644 index 0000000000..85f5e62f36 --- /dev/null +++ b/core/usCoreConfigVersion.cmake.in @@ -0,0 +1,34 @@ +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version major number == requested version major number +# and the current version minor number >= requested version minor number + +set(PACKAGE_VERSION_MAJOR @Core_MAJOR_VERSION@) +set(PACKAGE_VERSION_MINOR @Core_MINOR_VERSION@) +set(PACKAGE_VERSION_PATCH @Core_PATCH_VERSION@) +set(PACKAGE_VERSION "@Core_VERSION@") + +if(PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) +else() + set(PACKAGE_VERSION_EXACT FALSE) + if(NOT PACKAGE_VERSION_MAJOR EQUAL PACKAGE_FIND_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_VERSION_MINOR LESS PACKAGE_FIND_VERSION_MINOR) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + endif() +endif() + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") + math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/documentation/CMakeDoxygenFilter.cpp b/doc/CMakeDoxygenFilter.cpp similarity index 100% rename from documentation/CMakeDoxygenFilter.cpp rename to doc/CMakeDoxygenFilter.cpp diff --git a/documentation/CMakeLists.txt b/doc/CMakeLists.txt similarity index 95% rename from documentation/CMakeLists.txt rename to doc/CMakeLists.txt index 7aec333a00..a12f7b2599 100644 --- a/documentation/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,84 +1,77 @@ - -if(US_BUILD_TESTING) - include(usFunctionCompileSnippets) - # Compile source code snippets - add_subdirectory(snippets) -endif() - if(NOT US_IS_EMBEDDED AND NOT US_NO_DOCUMENTATION) find_package(Doxygen) if(DOXYGEN_FOUND) option(US_DOCUMENTATION_FOR_WEBPAGE "Build Doxygen documentation for the webpage" OFF) set(US_DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Doxygen output directory") mark_as_advanced(US_DOCUMENTATION_FOR_WEBPAGE US_DOXYGEN_OUTPUT_DIR) set(US_HAVE_DOT "NO") if(DOXYGEN_DOT_EXECUTABLE) set(US_HAVE_DOT "YES") endif() if(NOT DEFINED US_DOXYGEN_DOT_NUM_THREADS) set(US_DOXYGEN_DOT_NUM_THREADS 4) endif() # We are in standalone mode, so we generate a "mainpage" set(US_DOXYGEN_MAIN_PAGE_CMD "\\mainpage") set(US_DOXYGEN_ENABLED_SECTIONS "us_standalone") if(US_DOCUMENTATION_FOR_WEBPAGE) configure_file(doxygen/header.html ${CMAKE_CURRENT_BINARY_DIR}/header.html COPY_ONLY) set(US_DOXYGEN_HEADER header.html) configure_file(doxygen/footer.html ${CMAKE_CURRENT_BINARY_DIR}/footer.html COPY_ONLY) set(US_DOXYGEN_FOOTER footer.html) configure_file(doxygen/doxygen_extra.css ${CMAKE_CURRENT_BINARY_DIR}/doxygen_extra.css COPY_ONLY) set(US_DOXYGEN_EXTRA_CSS doxygen_extra.css) set(US_DOXYGEN_OUTPUT_DIR ${PROJECT_SOURCE_DIR}/gh-pages) if(${PROJECT_NAME}_MINOR_VERSION EQUAL 99) set(US_DOXYGEN_HTML_OUTPUT "doc_latest") else() set(US_DOXYGEN_HTML_OUTPUT "doc_${${PROJECT_NAME}_MAJOR_VERSION}_${${PROJECT_NAME}_MINOR_VERSION}") endif() else() set(US_DOXYGEN_HEADER ) set(US_DOXYGEN_FOOTER ) set(US_DOXYGEN_CSS ) set(US_DOXYGEN_HTML_OUTPUT "html") endif() # Compile a command line tool which transforms comments in CMake scripts into # Doxygen parseable C code. set(CMakeDoxygenFilter_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CMakeDoxygenFilter${CMAKE_EXECUTABLE_SUFFIX}") try_compile(_result_var "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/CMakeDoxygenFilter.cpp" OUTPUT_VARIABLE _compile_output COPY_FILE ${CMakeDoxygenFilter_EXECUTABLE} ) if(NOT _result_var) message(FATAL_ERROR "error: Faild to compile ${CMAKE_CURRENT_SOURCE_DIR}/CMakeDoxygenFilter.cpp (result: ${result_var})\n${_compile_output}") endif() configure_file(doxygen.conf.in ${CMAKE_CURRENT_BINARY_DIR}/doxygen.conf) add_custom_target(doc ${DOXYGEN} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.conf WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${PROJECT_BINARY_DIR}\" --target doc)") install(DIRECTORY ${US_DOXYGEN_OUTPUT_DIR}/${US_DOXYGEN_HTML_OUTPUT} DESTINATION ${AUXILIARY_INSTALL_DIR}/doc/ COMPONENT doc) endif() endif() diff --git a/documentation/doxygen.conf.in b/doc/doxygen.conf.in similarity index 98% rename from documentation/doxygen.conf.in rename to doc/doxygen.conf.in index f637dbb6ec..5caf947d09 100644 --- a/documentation/doxygen.conf.in +++ b/doc/doxygen.conf.in @@ -1,2305 +1,2305 @@ # Doxyfile 1.8.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "C++ Micro Services" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = @CppMicroServices_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "A dynamic OSGi-like C++ service registry" # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = @US_DOXYGEN_OUTPUT_DIR@ +OUTPUT_DIRECTORY = "@US_DOXYGEN_OUTPUT_DIR@" # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- # Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, # Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a # new page for each member. If set to NO, the documentation of a member will be # part of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = "FIXME=\par Fix Me's:\n" \ "embmainpage{1}=@US_DOXYGEN_MAIN_PAGE_CMD@" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = YES # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the # todo list. This list is created by putting \todo commands in the # documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the # test list. This list is created by putting \test commands in the # documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = @US_DOXYGEN_ENABLED_SECTIONS@ # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 0 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES the list # will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = NO # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = @PROJECT_SOURCE_DIR@ \ - @PROJECT_SOURCE_DIR@/CMake/usFunctionEmbedResources.cmake \ - @PROJECT_SOURCE_DIR@/CMake/usFunctionGenerateModuleInit.cmake \ - @PROJECT_SOURCE_DIR@/CMake/usFunctionGenerateExecutableInit.cmake \ - @PROJECT_BINARY_DIR@/include/usConfig.h +INPUT = "@PROJECT_SOURCE_DIR@" \ + "@PROJECT_SOURCE_DIR@/cmake/usFunctionEmbedResources.cmake" \ + "@PROJECT_SOURCE_DIR@/cmake/usFunctionGenerateModuleInit.cmake" \ + "@PROJECT_SOURCE_DIR@/cmake/usFunctionGenerateExecutableInit.cmake" \ + "@PROJECT_BINARY_DIR@/include/usGlobalConfig.h" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = *.h \ *.dox \ *.md # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = @PROJECT_SOURCE_DIR@/README.md \ - @PROJECT_SOURCE_DIR@/documentation/snippets/ \ - @PROJECT_SOURCE_DIR@/examples/ \ - @PROJECT_SOURCE_DIR@/test/ \ - @PROJECT_SOURCE_DIR@/gh-pages/ \ - @PROJECT_SOURCE_DIR@/.git/ +EXCLUDE = "@PROJECT_SOURCE_DIR@/README.md" \ + "@PROJECT_SOURCE_DIR@/gh-pages/" \ + "@PROJECT_SOURCE_DIR@/.git/" # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = */.git/* \ +EXCLUDE_PATTERNS = */test/* \ + */snippets/* \ + */examples/* \ + */.git/* \ *_p.h \ *Private.* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = us \ US_NAMESPACE \ *Private* \ ModuleInfo \ ServiceObjectsBase* \ TrackedService* # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/documentation/snippets/ \ - @PROJECT_SOURCE_DIR@/examples/ +EXAMPLE_PATH = "@PROJECT_SOURCE_DIR@/core/doc/snippets/" \ + "@PROJECT_SOURCE_DIR@/core/examples/" # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = *.cmake=@CMakeDoxygenFilter_EXECUTABLE@ # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES, then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = @US_DOXYGEN_HTML_OUTPUT@ +HTML_OUTPUT = "@US_DOXYGEN_HTML_OUTPUT@" # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = @US_DOXYGEN_HEADER@ +HTML_HEADER = "@US_DOXYGEN_HEADER@" # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = @US_DOXYGEN_FOOTER@ +HTML_FOOTER = "@US_DOXYGEN_FOOTER@" # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = @US_DOXYGEN_EXTRA_CSS@ +HTML_EXTRA_STYLESHEET = "@US_DOXYGEN_EXTRA_CSS@" # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( # YES) or a normal table of contents ( NO) in the .chm file. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 300 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /