# HG changeset patch # User Sebastien Jodogne # Date 1787141493 -7200 # Node ID 4ba287b00973948a056088f0ef2610f87a133db3 # Parent bb9046c964831e7e06e0d3927caf55a54f4af8a3 cleaning source code: remove trailing spaces diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/AutoGeneratedCode.cmake --- a/OrthancFramework/Resources/CMake/AutoGeneratedCode.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/AutoGeneratedCode.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -76,5 +76,5 @@ list(APPEND AUTOGENERATED_SOURCES "${TARGET_BASE}.cpp" - ) + ) endmacro() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/BoostConfiguration.cmake --- a/OrthancFramework/Resources/CMake/BoostConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/BoostConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -54,14 +54,14 @@ else() set(tmp2 "missing") endif() - + message("Boost component ${item} - ${tmp2}") endforeach() - + message(FATAL_ERROR "Unable to locate Boost on this system") endif() - + # Patch by xnox to fix issue #166 (CMake find_boost version is now # broken with newer boost/cmake) # https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=166 @@ -70,8 +70,8 @@ else() set(BOOST144 104400) endif() - - + + # Boost releases 1.44 through 1.47 supply both V2 and V3 filesystem # http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/index.htm if (${Boost_VERSION} LESS ${BOOST144}) @@ -97,9 +97,9 @@ if (BOOST_STATIC AND NOT USE_LEGACY_BOOST) ## - ## Parameters for static compilation of Boost + ## Parameters for static compilation of Boost ## - + set(BOOST_NAME boost_1_89_0) set(BOOST_VERSION 1.89.0) set(BOOST_BCP_SUFFIX bcpdigest-1.12.11) @@ -137,7 +137,7 @@ ## ## Generic configuration of Boost - ## + ## if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-isystem ${BOOST_SOURCES_DIR}) @@ -162,9 +162,9 @@ add_definitions( # Static build of Boost (this was the only possibility in # Orthanc <= 1.7.1) - -DBOOST_ALL_NO_LIB - -DBOOST_ALL_NOLIB - -DBOOST_DATE_TIME_NO_LIB + -DBOOST_ALL_NO_LIB + -DBOOST_ALL_NOLIB + -DBOOST_DATE_TIME_NO_LIB -DBOOST_THREAD_BUILD_LIB -DBOOST_PROGRAM_OPTIONS_NO_LIB -DBOOST_REGEX_NO_LIB @@ -195,11 +195,11 @@ ) endif() - + ## ## Configuration of boost::thread ## - + if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR @@ -222,7 +222,7 @@ add_definitions(-DBOOST_HAS_SCHED_YIELD=1) endif() - # Fix for error: "boost_1_69_0/boost/chrono/detail/inlined/mac/thread_clock.hpp:54:28: + # Fix for error: "boost_1_69_0/boost/chrono/detail/inlined/mac/thread_clock.hpp:54:28: # error: use of undeclared identifier 'pthread_mach_thread_np'" # https://github.com/envoyproxy/envoy/pull/1785 if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") @@ -247,7 +247,7 @@ ## ## Configuration of boost::regex ## - + aux_source_directory(${BOOST_SOURCES_DIR}/libs/regex/src BOOST_REGEX_SOURCES) list(APPEND BOOST_SOURCES @@ -258,7 +258,7 @@ ## ## Configuration of boost::datetime ## - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp ) @@ -266,7 +266,7 @@ ## ## Configuration of boost::filesystem and boost::iostreams - ## + ## if (CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR @@ -309,11 +309,11 @@ list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/iostreams/src/file_descriptor.cpp ) - + ## ## Configuration of boost::locale - ## + ## if (NOT ENABLE_LOCALE) message("boost::locale is disabled") @@ -346,7 +346,7 @@ ${BOOST_SOURCES_DIR}/libs/locale/src/util/gregorian.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp - ) + ) if (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR CMAKE_SYSTEM_VERSION STREQUAL "LinuxStandardBase") @@ -354,7 +354,7 @@ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1 -DBOOST_LOCALE_NO_POSIX_BACKEND=1 ) - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/locale/src/std/codecvt.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/std/collate.cpp @@ -385,7 +385,7 @@ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1 -DBOOST_LOCALE_NO_STD_BACKEND=1 ) - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp @@ -444,7 +444,7 @@ endif() endif() - + ## ## Configuration of boost::program_options (new in Orthanc 1.13.0) ## diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/BoostConfigurationStatic-1.69.0.cmake --- a/OrthancFramework/Resources/CMake/BoostConfigurationStatic-1.69.0.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/BoostConfigurationStatic-1.69.0.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -22,9 +22,9 @@ if (BOOST_STATIC) ## - ## Parameters for static compilation of Boost + ## Parameters for static compilation of Boost ## - + set(BOOST_NAME boost_1_69_0) set(BOOST_VERSION 1.69.0) set(BOOST_BCP_SUFFIX bcpdigest-1.5.6) @@ -43,7 +43,7 @@ ## ## Patching boost - ## + ## if (FirstRun) execute_process( @@ -61,7 +61,7 @@ ## ## Generic configuration of Boost - ## + ## if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-isystem ${BOOST_SOURCES_DIR}) @@ -83,9 +83,9 @@ add_definitions( # Static build of Boost (this was the only possibility in # Orthanc <= 1.7.1) - -DBOOST_ALL_NO_LIB - -DBOOST_ALL_NOLIB - -DBOOST_DATE_TIME_NO_LIB + -DBOOST_ALL_NO_LIB + -DBOOST_ALL_NOLIB + -DBOOST_DATE_TIME_NO_LIB -DBOOST_THREAD_BUILD_LIB -DBOOST_PROGRAM_OPTIONS_NO_LIB -DBOOST_REGEX_NO_LIB @@ -114,11 +114,11 @@ ) endif() - + ## ## Configuration of boost::thread ## - + if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR @@ -141,7 +141,7 @@ add_definitions(-DBOOST_HAS_SCHED_YIELD=1) endif() - # Fix for error: "boost_1_69_0/boost/chrono/detail/inlined/mac/thread_clock.hpp:54:28: + # Fix for error: "boost_1_69_0/boost/chrono/detail/inlined/mac/thread_clock.hpp:54:28: # error: use of undeclared identifier 'pthread_mach_thread_np'" # https://github.com/envoyproxy/envoy/pull/1785 if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") @@ -166,7 +166,7 @@ ## ## Configuration of boost::regex ## - + aux_source_directory(${BOOST_SOURCES_DIR}/libs/regex/src BOOST_REGEX_SOURCES) list(APPEND BOOST_SOURCES @@ -177,7 +177,7 @@ ## ## Configuration of boost::datetime ## - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp ) @@ -185,7 +185,7 @@ ## ## Configuration of boost::filesystem and boost::iostreams - ## + ## if (CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR @@ -226,11 +226,11 @@ list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/iostreams/src/file_descriptor.cpp ) - + ## ## Configuration of boost::locale - ## + ## if (NOT ENABLE_LOCALE) message("boost::locale is disabled") @@ -261,7 +261,7 @@ ${BOOST_SOURCES_DIR}/libs/locale/src/util/gregorian.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp - ) + ) if (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR CMAKE_SYSTEM_VERSION STREQUAL "LinuxStandardBase") @@ -269,7 +269,7 @@ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1 -DBOOST_LOCALE_NO_POSIX_BACKEND=1 ) - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/locale/src/std/codecvt.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/std/collate.cpp @@ -300,7 +300,7 @@ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1 -DBOOST_LOCALE_NO_STD_BACKEND=1 ) - + list(APPEND BOOST_SOURCES ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp @@ -359,7 +359,7 @@ endif() endif() - + ## ## Configuration of boost::program_options (new in Orthanc 1.13.0) ## diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake --- a/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -33,7 +33,7 @@ ## $ rm -rf civetweb-1.16/src/third_party/ civetweb-1.16/test/ ## $ tar cvfz civetweb-1.16-fixed.tar.gz civetweb-1.16 ## - + set(CIVETWEB_SOURCES_DIR ${CMAKE_BINARY_DIR}/civetweb-1.16) set(CIVETWEB_URL "https://orthanc.uclouvain.be/downloads/third-party-downloads/civetweb-1.16-fixed.tar.gz") set(CIVETWEB_MD5 "038edf77ea37e47def9458e8903cd53d") @@ -70,7 +70,7 @@ # New in Orthanc 1.6.0: Enable support of compression in civetweb set(tmp "USE_ZLIB=1") - + if (ENABLE_SSL) add_definitions( -DNO_SSL_DL=1 @@ -98,7 +98,7 @@ ${CIVETWEB_SOURCES} PROPERTIES COMPILE_DEFINITIONS "${tmp}" ) - + source_group(ThirdParty\\Civetweb REGULAR_EXPRESSION ${CIVETWEB_SOURCES_DIR}/.*) add_definitions( diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/Compiler.cmake --- a/OrthancFramework/Resources/CMake/Compiler.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/Compiler.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ include(CheckLibraryExists) if ((CMAKE_CROSSCOMPILING AND NOT - "${CMAKE_SYSTEM_VERSION}" STREQUAL "CrossToolNg") OR + "${CMAKE_SYSTEM_VERSION}" STREQUAL "CrossToolNg") OR "${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") # Cross-compilation necessarily implies standalone and static build SET(STATIC_BUILD ON) @@ -70,7 +70,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long") # --std=c99 makes libcurl not to compile - # -pedantic gives a lot of warnings on OpenSSL + # -pedantic gives a lot of warnings on OpenSSL set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-variadic-macros") if (CMAKE_CROSSCOMPILING) @@ -85,12 +85,12 @@ foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG - CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL - CMAKE_CXX_FLAGS_MINSIZEREL - CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS_RELWITHDEBINFO) + CMAKE_C_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_RELWITHDEBINFO) string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") endforeach(flag_var) @@ -109,7 +109,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() - + add_definitions( -D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 @@ -188,7 +188,7 @@ # for LFS (Large File Support). # https://ohse.de/uwe/articles/lfs.html add_definitions( - -D_LARGEFILE64_SOURCE=1 + -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 ) endif() @@ -254,14 +254,14 @@ add_definitions( -D_XOPEN_SOURCE=1 ) - + # Linking with iconv breaks the Universal builds on modern compilers # link_libraries(iconv) elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten") message("Building using Emscripten (for WebAssembly or asm.js targets)") include(${CMAKE_CURRENT_LIST_DIR}/EmscriptenParameters.cmake) - + elseif (CMAKE_SYSTEM_NAME STREQUAL "Android") else() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -26,7 +26,7 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK) if (DCMTK_STATIC_VERSION STREQUAL "3.6.0") - include(${CMAKE_CURRENT_LIST_DIR}/DcmtkConfigurationStatic-3.6.0.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/DcmtkConfigurationStatic-3.6.0.cmake) elseif (DCMTK_STATIC_VERSION STREQUAL "3.6.2") include(${CMAKE_CURRENT_LIST_DIR}/DcmtkConfigurationStatic-3.6.2.cmake) elseif (DCMTK_STATIC_VERSION STREQUAL "3.6.4") @@ -55,14 +55,14 @@ AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmdata/libsrc DCMTK_SOURCES) AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/ofstd/libsrc DCMTK_SOURCES) - LIST(REMOVE_ITEM DCMTK_SOURCES + LIST(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/dcmdata/libsrc/mkdictbi.cc ${DCMTK_SOURCES_DIR}/dcmdata/libsrc/mkdeftag.cc ${DCMTK_SOURCES_DIR}/dcmdata/libsrc/dcdict_orthanc.cc ) if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/ofstd/libsrc/offilsys.cc ${DCMTK_SOURCES_DIR}/ofstd/libsrc/ofwhere.c # Needed since DCMTK 3.6.9 ) @@ -88,7 +88,7 @@ ${DCMTK_SOURCES_DIR}/dcmimgle/include ) endif() - + if (ENABLE_DCMTK_JPEG) AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc DCMTK_SOURCES) AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libijg8 DCMTK_SOURCES) @@ -100,7 +100,7 @@ ${DCMTK_SOURCES_DIR}/dcmjpeg/libijg12 ${DCMTK_SOURCES_DIR}/dcmjpeg/libijg16 ) - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc/ddpiimpl.cc # Solves linking problem in WebAssembly: "wasm-ld: error: @@ -111,7 +111,7 @@ ) if (NOT ENABLE_DCMTK_TRANSCODING) - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES # Disable support for encoding JPEG (modification in Orthanc 1.0.1) ${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc/djcodece.cc ${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc/djencsv1.cc @@ -134,12 +134,12 @@ ${DCMTK_SOURCES_DIR}/dcmjpls/include ${DCMTK_SOURCES_DIR}/dcmjpls/libcharls ) - list(APPEND DCMTK_SOURCES + list(APPEND DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc/djrplol.cc ) if (NOT ENABLE_DCMTK_TRANSCODING) - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/dcmjpls/libsrc/djcodece.cc # Disable support for encoding JPEG-LS (modification in Orthanc 1.0.1) @@ -176,8 +176,8 @@ add_definitions(-DWITH_OPENSSL=1) endif() - - + + # This fixes crashes related to the destruction of the DCMTK OFLogger # http://support.dcmtk.org/docs-snapshot/file_macros.html add_definitions( @@ -232,7 +232,7 @@ CHECK_LIBRARY_EXISTS(dcmdata "dcmDataDict" "" HAVE_DCMTK_LIB) if (NOT HAVE_DCMTK_LIB) message(FATAL_ERROR "Please install the libdcmtk package") - endif() + endif() find_path(DCMTK_INCLUDE_DIRS dcmtk/config/osconfig.h /usr/include @@ -265,17 +265,17 @@ endif() message("DCMTK configuration file: ${DCMTK_CONFIGURATION_FILE}") - + # Autodetection of the version of DCMTK file(STRINGS - "${DCMTK_CONFIGURATION_FILE}" + "${DCMTK_CONFIGURATION_FILE}" DCMTK_VERSION_NUMBER1 REGEX - ".*PACKAGE_VERSION .*") + ".*PACKAGE_VERSION .*") string(REGEX REPLACE ".*PACKAGE_VERSION.*\"([0-9]*)\\.([0-9]*)\\.([0-9]*)\"$" - "\\1\\2\\3" - DCMTK_VERSION_NUMBER + "\\1\\2\\3" + DCMTK_VERSION_NUMBER ${DCMTK_VERSION_NUMBER1}) set(DCMTK_USE_EMBEDDED_DICTIONARIES 0) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.0.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.0.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.0.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ else() message("Using the dictionary of private tags from DCMTK 3.6.0") endif() - + # Patches specific to DCMTK 3.6.0 message("Applying patch to solve vulnerability in DCMTK 3.6.0") execute_process( @@ -171,14 +171,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.2.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.2.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.2.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -184,14 +184,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.4.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.4.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.4.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -174,14 +174,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.5.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.5.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.5.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -174,14 +174,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.6.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.6.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.6.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -174,14 +174,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.7.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.7.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.7.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -76,11 +76,11 @@ WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE Failure ) - + if (Failure) message(FATAL_ERROR "Error while patching a file") - endif() - endif() + endif() + endif() configure_file( ${CMAKE_CURRENT_LIST_DIR}/../Patches/dcmtk-dcdict_orthanc.cc @@ -220,14 +220,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.8.cmake --- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.8.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.8.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -76,11 +76,11 @@ WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE Failure ) - + if (Failure) message(FATAL_ERROR "Error while patching a file") - endif() - endif() + endif() + endif() configure_file( ${CMAKE_CURRENT_LIST_DIR}/../Patches/dcmtk-dcdict_orthanc.cc @@ -233,14 +233,14 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc ) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - list(REMOVE_ITEM DCMTK_SOURCES + list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc ) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake --- a/OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -264,7 +264,7 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg") find_program(ORTHANC_FRAMEWORK_HG hg) - + if (${ORTHANC_FRAMEWORK_HG} MATCHES "ORTHANC_FRAMEWORK_HG-NOTFOUND") message(FATAL_ERROR "Please install Mercurial") endif() @@ -274,8 +274,8 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive" OR ORTHANC_FRAMEWORK_SOURCE STREQUAL "web") if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") - find_program(ORTHANC_FRAMEWORK_7ZIP 7z - PATHS + find_program(ORTHANC_FRAMEWORK_7ZIP 7z + PATHS "$ENV{ProgramFiles}/7-Zip" "$ENV{ProgramW6432}/7-Zip" ) @@ -303,7 +303,7 @@ ORTHANC_FRAMEWORK_ROOT STREQUAL "") message(FATAL_ERROR "The variable ORTHANC_FRAMEWORK_ROOT must provide the path to the sources of Orthanc") endif() - + if (NOT EXISTS ${ORTHANC_FRAMEWORK_ROOT}) message(FATAL_ERROR "Non-existing directory: ${ORTHANC_FRAMEWORK_ROOT}") endif() @@ -328,14 +328,14 @@ COMMAND ${ORTHANC_FRAMEWORK_HG} pull WORKING_DIRECTORY ${ORTHANC_ROOT} RESULT_VARIABLE Failure - ) + ) else() message("Forking the Orthanc source repository using Mercurial") execute_process( COMMAND ${ORTHANC_FRAMEWORK_HG} clone "https://orthanc.uclouvain.be/hg/orthanc/" WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE Failure - ) + ) endif() if (Failure OR NOT EXISTS ${ORTHANC_ROOT}) @@ -398,14 +398,14 @@ message("Downloading: ${ORTHANC_FRAMEWORK_URL}") file(DOWNLOAD - "${ORTHANC_FRAMEWORK_URL}" "${ORTHANC_FRAMEWORK_ARCHIVE}" + "${ORTHANC_FRAMEWORK_URL}" "${ORTHANC_FRAMEWORK_ARCHIVE}" SHOW_PROGRESS EXPECTED_MD5 "${ORTHANC_FRAMEWORK_MD5}" TIMEOUT 60 INACTIVITY_TIMEOUT 60 ) else() message("Using local copy of: ${ORTHANC_FRAMEWORK_URL}") - endif() + endif() endif() @@ -441,7 +441,7 @@ if (NOT ORTHANC_FRAMEWORK_ARCHIVE MATCHES ".tar.gz$") message(FATAL_ERROR "Archive should have the \".tar.gz\" extension: ${ORTHANC_FRAMEWORK_ARCHIVE}") endif() - + message("Uncompressing: ${ORTHANC_FRAMEWORK_ARCHIVE}") if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") @@ -454,7 +454,7 @@ RESULT_VARIABLE Failure OUTPUT_QUIET ) - + if (Failure) message(FATAL_ERROR "Error while running the uncompression tool") endif() @@ -476,7 +476,7 @@ RESULT_VARIABLE Failure ) endif() - + if (Failure) message(FATAL_ERROR "Error while running the uncompression tool") endif() @@ -542,10 +542,10 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++") endif() - + include(CheckIncludeFile) include(CheckIncludeFileCXX) - + if(CMAKE_VERSION VERSION_GREATER "3.11") find_package(Python REQUIRED COMPONENTS Interpreter) set(PYTHON_EXECUTABLE ${Python_EXECUTABLE}) @@ -553,7 +553,7 @@ include(FindPythonInterp) find_package(PythonInterp REQUIRED) endif() - + include(${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake) include(${CMAKE_CURRENT_LIST_DIR}/DownloadPackage.cmake) include(${CMAKE_CURRENT_LIST_DIR}/AutoGeneratedCode.cmake) @@ -614,19 +614,19 @@ if (${ORTHANC_FRAMEWORK_INCLUDE_DIR} STREQUAL "ORTHANC_FRAMEWORK_INCLUDE_DIR-NOTFOUND") message(FATAL_ERROR "Cannot locate the OrthancFramework.h header") endif() - + message("Orthanc framework include dir: ${ORTHANC_FRAMEWORK_INCLUDE_DIR}") include_directories(${ORTHANC_FRAMEWORK_INCLUDE_DIR}) if (ORTHANC_FRAMEWORK_USE_SHARED) set(CMAKE_REQUIRED_INCLUDES "${ORTHANC_FRAMEWORK_INCLUDE_DIR}") set(CMAKE_REQUIRED_LIBRARIES "${ORTHANC_FRAMEWORK_LIBRARIES}") - + check_cxx_symbol_exists("Orthanc::InitializeFramework" "OrthancFramework.h" HAVE_ORTHANC_FRAMEWORK) if (NOT HAVE_ORTHANC_FRAMEWORK) message(FATAL_ERROR "Cannot find the Orthanc framework") endif() - + unset(CMAKE_REQUIRED_INCLUDES) unset(CMAKE_REQUIRED_LIBRARIES) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/DownloadPackage.cmake --- a/OrthancFramework/Resources/CMake/DownloadPackage.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/DownloadPackage.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -59,8 +59,8 @@ ## if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") - find_program(ZIP_EXECUTABLE 7z - PATHS + find_program(ZIP_EXECUTABLE 7z + PATHS "$ENV{ProgramFiles}/7-Zip" "$ENV{ProgramW6432}/7-Zip" ) @@ -124,7 +124,7 @@ file(REMOVE ${TMP_PATH}) message(FATAL_ERROR "Cannot download file: ${Url}") endif() - + else() message("Using local copy of ${Url}") @@ -143,7 +143,7 @@ macro(DownloadPackage MD5 Url TargetDirectory) if (NOT IS_DIRECTORY "${TargetDirectory}") DownloadFile("${MD5}" "${Url}") - + GetUrlExtension(TMP_EXTENSION "${Url}") #message(${TMP_EXTENSION}) message("Uncompressing ${TMP_FILENAME}") @@ -152,7 +152,7 @@ # How to silently extract files using 7-zip # http://superuser.com/questions/331148/7zip-command-line-extract-silently-quietly - if (("${TMP_EXTENSION}" STREQUAL "gz") OR + if (("${TMP_EXTENSION}" STREQUAL "gz") OR ("${TMP_EXTENSION}" STREQUAL "tgz") OR ("${TMP_EXTENSION}" STREQUAL "xz")) execute_process( @@ -221,7 +221,7 @@ message(FATAL_ERROR "Unsupported package extension: ${TMP_EXTENSION}") endif() endif() - + if (Failure) message(FATAL_ERROR "Error while running the uncompression tool") endif() @@ -237,7 +237,7 @@ macro(DownloadCompressedFile MD5 Url TargetFile) if (NOT EXISTS "${TargetFile}") DownloadFile("${MD5}" "${Url}") - + GetUrlExtension(TMP_EXTENSION "${Url}") #message(${TMP_EXTENSION}) message("Uncompressing ${TMP_FILENAME}") @@ -275,7 +275,7 @@ message(FATAL_ERROR "Unsupported file extension: ${TMP_EXTENSION}") endif() endif() - + if (Failure) message(FATAL_ERROR "Error while running the uncompression tool") endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/EmbedResources.py --- a/OrthancFramework/Resources/CMake/EmbedResources.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/EmbedResources.py Wed Aug 19 14:11:33 2026 +0200 @@ -90,7 +90,7 @@ if resourceName in resources: raise Exception("Twice the same resource: " + resourceName) - + if os.path.isdir(pathName): # The resource is a directory: Recursively explore its files content = {} @@ -165,7 +165,7 @@ for ns in NAMESPACE.split('.'): header.write('namespace %s {\n' % ns) - + header.write(""" enum FileResourceId @@ -177,7 +177,7 @@ if resources[name]['Type'] == 'File': if isFirst: isFirst = False - else: + else: header.write(',\n') header.write(' %s' % name) @@ -193,7 +193,7 @@ if resources[name]['Type'] == 'Directory': if isFirst: isFirst = False - else: + else: header.write(',\n') header.write(' %s' % name) @@ -235,8 +235,8 @@ # http://stackoverflow.com/a/1035360 pos = 0 - buffer = [] # instead of appending a few bytes at a time to the cpp file, - # we first append each chunk to a list, join it and write it + buffer = [] # instead of appending a few bytes at a time to the cpp file, + # we first append each chunk to a list, join it and write it # to the file. We've measured that it was 2-3 times faster in python3. # Note that speed is important since if generation is too slow, # cmake might try to compile the EmbeddedResources.cpp file while it is diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/EmscriptenParameters.cmake --- a/OrthancFramework/Resources/CMake/EmscriptenParameters.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/EmscriptenParameters.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ if (EMSCRIPTEN_TARGET_MODE STREQUAL "wasm") # WebAssembly set(WASM_FLAGS "${WASM_FLAGS} -s WASM=1") - + elseif (EMSCRIPTEN_TARGET_MODE STREQUAL "asm.js") # asm.js targeting IE 11 set(WASM_FLAGS "-s WASM=0 -s ASM_JS=2 -s LEGACY_VM_SUPPORT=1") diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake --- a/OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -70,11 +70,11 @@ if (MSVC) # VS2012 does not support tuples correctly yet add_definitions(/D _VARIADIC_MAX=10) endif() - + if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") add_definitions(-DGTEST_HAS_CLONE=0) endif() - + source_group(ThirdParty\\GoogleTest REGULAR_EXPRESSION ${GOOGLE_TEST_SOURCES_DIR}/.*) else() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake --- a/OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -51,7 +51,7 @@ if (NOT ENABLE_LOCALE) add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT=1) endif() - + source_group(ThirdParty\\JsonCpp REGULAR_EXPRESSION ${JSONCPP_SOURCES_DIR}/.*) else() @@ -72,16 +72,16 @@ # Detect if the version of JsonCpp is >= 1.0.0 if (EXISTS ${JSONCPP_INCLUDE_DIR}/json/version.h) file(STRINGS - "${JSONCPP_INCLUDE_DIR}/json/version.h" + "${JSONCPP_INCLUDE_DIR}/json/version.h" JSONCPP_VERSION_MAJOR1 REGEX ".*define JSONCPP_VERSION_MAJOR.*") if (NOT JSONCPP_VERSION_MAJOR1) message(FATAL_ERROR "Unable to extract the major version of JsonCpp") endif() - + string(REGEX REPLACE - ".*JSONCPP_VERSION_MAJOR.*([0-9]+)$" "\\1" + ".*JSONCPP_VERSION_MAJOR.*([0-9]+)$" "\\1" JSONCPP_VERSION_MAJOR ${JSONCPP_VERSION_MAJOR1}) message("JsonCpp major version: ${JSONCPP_VERSION_MAJOR}") diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LibCurlConfiguration.cmake --- a/OrthancFramework/Resources/CMake/LibCurlConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LibCurlConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -30,7 +30,7 @@ else() set(FirstRun ON) endif() - + DownloadPackage(${CURL_MD5} ${CURL_URL} "${CURL_SOURCES_DIR}") if (FirstRun) @@ -40,12 +40,12 @@ WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE Failure ) - + if (Failure) message(FATAL_ERROR "Error while patching a file") endif() endif() - + include_directories( ${CURL_SOURCES_DIR}/include ) @@ -305,8 +305,8 @@ CHECK_LIBRARY_EXISTS(curl "curl_easy_init" "" HAVE_CURL_LIB) if (NOT HAVE_CURL_LIB) message(FATAL_ERROR "Please install the libcurl package") - endif() - + endif() + link_libraries(curl) else() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LibIconvConfiguration.cmake --- a/OrthancFramework/Resources/CMake/LibIconvConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LibIconvConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -76,9 +76,9 @@ ) set(LIBICONV_SOURCES - ${LIBICONV_SOURCES_DIR}/lib/iconv.c + ${LIBICONV_SOURCES_DIR}/lib/iconv.c ${LIBICONV_SOURCES_DIR}/lib/relocatable.c - ${LIBICONV_SOURCES_DIR}/libcharset/lib/localcharset.c + ${LIBICONV_SOURCES_DIR}/libcharset/lib/localcharset.c ${LIBICONV_SOURCES_DIR}/libcharset/lib/relocatable.c ) @@ -90,7 +90,7 @@ add_definitions(-DHAVE_WORKING_O_NOFOLLOW=1) endif() -else() +else() CHECK_INCLUDE_FILE_CXX(iconv.h HAVE_ICONV_H) if (NOT HAVE_ICONV_H) message(FATAL_ERROR "Please install the libiconv-dev package") diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LibIcuConfiguration.cmake --- a/OrthancFramework/Resources/CMake/LibIcuConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LibIcuConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -80,7 +80,7 @@ source_group(ThirdParty\\libicu REGULAR_EXPRESSION ${LIBICU_SOURCES_DIR}/.*) -else() +else() CHECK_INCLUDE_FILE_CXX(unicode/uvernum.h HAVE_ICU_H) if (NOT HAVE_ICU_H) message(FATAL_ERROR "Please install the libicu-dev package") @@ -89,7 +89,7 @@ find_library(LIBICU_PATH_1 NAMES icuuc) find_library(LIBICU_PATH_2 NAMES icui18n) - if (NOT LIBICU_PATH_1 OR + if (NOT LIBICU_PATH_1 OR NOT LIBICU_PATH_2) message(FATAL_ERROR "Please install the libicu-dev package") else() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LibJpegConfiguration.cmake --- a/OrthancFramework/Resources/CMake/LibJpegConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LibJpegConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -31,7 +31,7 @@ ${LIBJPEG_SOURCES_DIR} ) - list(APPEND LIBJPEG_SOURCES + list(APPEND LIBJPEG_SOURCES ${LIBJPEG_SOURCES_DIR}/jaricom.c ${LIBJPEG_SOURCES_DIR}/jcapimin.c ${LIBJPEG_SOURCES_DIR}/jcapistd.c diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LibP11Configuration.cmake --- a/OrthancFramework/Resources/CMake/LibP11Configuration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LibP11Configuration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -24,11 +24,11 @@ if (NOT STATIC_BUILD AND USE_SYSTEM_OPENSSL) message(FATAL_ERROR "If statically linking against libp11, one must also statically link against OpenSSL") endif() - + SET(LIBP11_SOURCES_DIR ${CMAKE_BINARY_DIR}/libp11-0.4.0) SET(LIBP11_URL "https://orthanc.uclouvain.be/downloads/third-party-downloads/libp11-0.4.0.tar.gz") SET(LIBP11_MD5 "00b3e41db5be840d822bda12f3ab2ca7") - + if (IS_DIRECTORY "${LIBP11_SOURCES_DIR}") set(FirstRun OFF) else() @@ -58,7 +58,7 @@ file(WRITE ${AUTOGENERATED_DIR}/libp11/config.h "") - set(LIBP11_SOURCES + set(LIBP11_SOURCES #${LIBP11_SOURCES_DIR}/src/eng_front.c ${LIBP11_SOURCES_DIR}/src/eng_back.c ${LIBP11_SOURCES_DIR}/src/eng_parse.c @@ -80,7 +80,7 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - list(APPEND LIBP11_SOURCES + list(APPEND LIBP11_SOURCES ${LIBP11_SOURCES_DIR}/src/atfork.c ) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/LuaConfiguration.cmake --- a/OrthancFramework/Resources/CMake/LuaConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/LuaConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -56,13 +56,13 @@ add_definitions( -DLUA_DL_DLL=1 # Enable loading of shared libraries (for Microsoft Windows) ) - + elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") add_definitions( -DLUA_USE_MACOSX=1 -DLUA_DL_DYLD=1 # Enable loading of shared libraries (for Apple OS X) ) - + else() message(FATAL_ERROR "Support your platform here") endif() @@ -144,7 +144,7 @@ if (NOT LUA_VERSION) message(FATAL_ERROR "Please install the liblua-dev package") endif() - + if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "CrossToolNg") set(LUA_INCLUDE_DIR ${CROSSTOOL_NG_IMAGE}/usr/include/lua${LUA_VERSION}) else() @@ -156,7 +156,7 @@ /usr/local/include/lua${LUA_VERSION} ) endif() - + message("Lua include dir: ${LUA_INCLUDE_DIR}") include_directories(${LUA_INCLUDE_DIR}) @@ -164,17 +164,17 @@ CHECK_LIBRARY_EXISTS(lua${LUA_VERSION} "lua_callk" "${LUA_LIB_DIR}" HAVE_LUA_LIB_2) # Lua 5.3 if (NOT HAVE_LUA_LIB_1 AND NOT HAVE_LUA_LIB_2) message(FATAL_ERROR "Please install the liblua package") - endif() + endif() link_libraries(lua${LUA_VERSION}) else() include(FindLua) - + if (NOT LUA_FOUND) message(FATAL_ERROR "Please install the liblua-dev package") endif() - + include_directories(${LUA_INCLUDE_DIR}) link_libraries(${LUA_LIBRARIES}) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/MongooseConfiguration.cmake --- a/OrthancFramework/Resources/CMake/MongooseConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/MongooseConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -35,17 +35,17 @@ "e718fc287b4eb1bd523be3fa00942bb0" "https://orthanc.uclouvain.be/downloads/third-party-downloads/mongoose-3.1.tgz" "${MONGOOSE_SOURCES_DIR}") - + add_definitions(-DMONGOOSE_USE_CALLBACKS=0) set(MONGOOSE_PATCH ${CMAKE_CURRENT_LIST_DIR}/../Patches/mongoose-3.1-patch.diff) - else() + else() # Use Mongoose 3.8 DownloadPackage( "7e3296295072792cdc3c633f9404e0c3" "https://orthanc.uclouvain.be/downloads/third-party-downloads/mongoose-3.8.tgz" "${MONGOOSE_SOURCES_DIR}") - + add_definitions(-DMONGOOSE_USE_CALLBACKS=1) set(MONGOOSE_PATCH ${CMAKE_CURRENT_LIST_DIR}/../Patches/mongoose-3.8-patch.diff) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake --- a/OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ CHECK_LIBRARY_EXISTS(crypto "OPENSSL_init" "" HAVE_OPENSSL_CRYPTO_LIB) if (NOT HAVE_OPENSSL_CRYPTO_LIB) message(FATAL_ERROR "Please install the libopenssl package") - endif() + endif() # The "SSL_library_init" is for OpenSSL <= 1.0.2, whereas # "OPENSSL_init_ssl" is for OpenSSL >= 1.1.0 @@ -52,9 +52,9 @@ CHECK_LIBRARY_EXISTS(ssl "OPENSSL_init_ssl" "" HAVE_OPENSSL_SSL_LIB_2) if (NOT HAVE_OPENSSL_SSL_LIB_2) message(FATAL_ERROR "Please install the libopenssl package") - endif() - endif() - + endif() + endif() + link_libraries(crypto ssl) else() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.1.1.cmake --- a/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.1.1.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.1.1.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -91,22 +91,22 @@ -DOPENSSL_NO_DYNAMIC_ENGINE -DOPENSSL_NO_DEVCRYPTOENG - -DOPENSSL_NO_BF + -DOPENSSL_NO_BF -DOPENSSL_NO_CAMELLIA - -DOPENSSL_NO_CAST + -DOPENSSL_NO_CAST -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_GOST -DOPENSSL_NO_HW -DOPENSSL_NO_JPAKE -DOPENSSL_NO_IDEA - -DOPENSSL_NO_KRB5 - -DOPENSSL_NO_MD2 - -DOPENSSL_NO_MDC2 + -DOPENSSL_NO_KRB5 + -DOPENSSL_NO_MD2 + -DOPENSSL_NO_MDC2 #-DOPENSSL_NO_MD4 # MD4 is necessary for MariaDB/MySQL client - -DOPENSSL_NO_RC2 - -DOPENSSL_NO_RC4 - -DOPENSSL_NO_RC5 + -DOPENSSL_NO_RC2 + -DOPENSSL_NO_RC4 + -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE @@ -266,7 +266,7 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") set(OPENSSL_DEFINITIONS "${OPENSSL_DEFINITIONS};OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN;NO_WINDOWS_BRAINDEATH") - + if (ENABLE_OPENSSL_ENGINES) link_libraries(crypt32) endif() @@ -274,7 +274,7 @@ add_definitions( -DOPENSSL_RAND_SEED_OS # ${OPENSSL_SOURCES_DIR}/crypto/rand/rand_win.c ) - + elseif ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") add_definitions( # In order for "crypto/mem_sec.c" to compile on LSB diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-3.0.cmake --- a/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-3.0.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-3.0.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -105,11 +105,11 @@ -DOPENSSLDIR="/usr/local/ssl" -DMODULESDIR="" # TODO - + -DOPENSSL_BUILDING_OPENSSL -DOPENSSL_THREADS -DOPENSSL_IA32_SSE2 - + -DOPENSSL_NO_AFALGENG -DOPENSSL_NO_ASM -DOPENSSL_NO_CHACHA # Necessary for VC2015-64 since openssl-3.0.1 @@ -308,7 +308,7 @@ ${OPENSSL_SOURCES_DIR}/engines/e_loader_attic.c ${OPENSSL_SOURCES_DIR}/providers/common/securitycheck_fips.c ${OPENSSL_SOURCES_DIR}/providers/implementations/macs/blake2_mac_impl.c - + ${OPENSSL_SOURCES_DIR}/engines/e_afalg.c # Fails on OS X and Visual Studio ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_ieee754.c # Fails on Visual Studio @@ -345,9 +345,9 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") list(APPEND OPENSSL_SOURCES ${OPENSSL_SOURCES_DIR}/providers/implementations/rands/seeding/rand_win.c - ) + ) endif() - + # Check out "${OPENSSL_SOURCES_DIR}/Configurations/README.md": "This # is default if no option is specified, it works on any supported @@ -371,7 +371,7 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") set(OPENSSL_DEFINITIONS "${OPENSSL_DEFINITIONS};OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN;NO_WINDOWS_BRAINDEATH") - + if (ENABLE_OPENSSL_ENGINES) link_libraries(crypt32) endif() @@ -379,7 +379,7 @@ add_definitions( -DOPENSSL_RAND_SEED_OS # ${OPENSSL_SOURCES_DIR}/crypto/rand/rand_win.c ) - + elseif ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") add_definitions( # In order for "crypto/mem_sec.c" to compile on LSB diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake --- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -294,7 +294,7 @@ message(FATAL_ERROR "OpenSSL is required to enable PKCS#11 support") endif() else() - add_definitions(-DORTHANC_ENABLE_PKCS11=0) + add_definitions(-DORTHANC_ENABLE_PKCS11=0) endif() endif() @@ -426,7 +426,7 @@ if (NOT ENABLE_MODULE_IMAGES) message(FATAL_ERROR "Image processing primitives must be enabled if enabling libpng support") endif() - + include(${CMAKE_CURRENT_LIST_DIR}/LibPngConfiguration.cmake) add_definitions(-DORTHANC_ENABLE_PNG=1) @@ -484,7 +484,7 @@ message(FATAL_ERROR "Invalid value for BOOST_LOCALE_BACKEND: ${BOOST_LOCALE_BACKEND}") endif() endif() - + add_definitions(-DORTHANC_ENABLE_LOCALE=1) endif() @@ -687,7 +687,7 @@ else() set(ORTHANC_ENABLE_LOGGING OFF) endif() - + else() set(ORTHANC_ENABLE_LOGGING ON) set(ORTHANC_ENABLE_LOGGING_STDIO OFF) @@ -845,7 +845,7 @@ list(APPEND ORTHANC_DICOM_SOURCES_DEPENDENCIES ${DCMTK_SOURCES} ) - + set(ORTHANC_DICOM_SOURCES ${ORTHANC_DICOM_SOURCES_INTERNAL} ${ORTHANC_DICOM_SOURCES_DEPENDENCIES} diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/ProtobufConfiguration.cmake --- a/OrthancFramework/Resources/CMake/ProtobufConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/ProtobufConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -44,14 +44,14 @@ set(PROTOC_EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/protoc${Suffix}) endif() - include(${CMAKE_CURRENT_LIST_DIR}/../ProtocolBuffers/ProtobufLibrary.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/../ProtocolBuffers/ProtobufLibrary.cmake) source_group(ThirdParty\\Protobuf REGULAR_EXPRESSION ${PROTOBUF_SOURCE_DIR}/.*) else() if (CMAKE_CROSSCOMPILING) message(FATAL_ERROR "If cross-compiling, the static version of Protocol Buffers should be used to avoid version mismatch") endif() - + if (ENABLE_PROTOBUF_COMPILER) find_program(PROTOC_EXECUTABLE protoc) if (${PROTOC_EXECUTABLE} MATCHES "PROTOC_EXECUTABLE-NOTFOUND") @@ -59,7 +59,7 @@ endif() add_custom_target(ProtobufCompiler) endif() - + check_include_file_cxx(google/protobuf/any.h HAVE_PROTOBUF_H) if (NOT HAVE_PROTOBUF_H) message(FATAL_ERROR "Please install the libprotobuf-dev package") @@ -67,7 +67,7 @@ set(CMAKE_REQUIRED_LIBRARIES "protobuf") - include(CheckCXXSourceCompiles) + include(CheckCXXSourceCompiles) check_cxx_source_compiles( " #include @@ -79,7 +79,7 @@ if (NOT HAVE_PROTOBUF_LIB) message(FATAL_ERROR "Cannot find the protobuf library") endif() - + unset(CMAKE_REQUIRED_LIBRARIES) link_libraries(protobuf) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/SQLiteConfiguration.cmake --- a/OrthancFramework/Resources/CMake/SQLiteConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/SQLiteConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ add_definitions( # For SQLite to run in the "Serialized" thread-safe mode # http://www.sqlite.org/threadsafe.html - -DSQLITE_THREADSAFE=1 + -DSQLITE_THREADSAFE=1 -DSQLITE_OMIT_LOAD_EXTENSION # Disable SQLite plugins ) @@ -68,7 +68,7 @@ message("SQLite include dir: ${SQLITE_INCLUDE_DIR}") # Autodetection of the version of SQLite - file(STRINGS "${SQLITE_INCLUDE_DIR}/sqlite3.h" SQLITE_VERSION_NUMBER1 REGEX "#define SQLITE_VERSION_NUMBER.*$") + file(STRINGS "${SQLITE_INCLUDE_DIR}/sqlite3.h" SQLITE_VERSION_NUMBER1 REGEX "#define SQLITE_VERSION_NUMBER.*$") string(REGEX REPLACE "#define SQLITE_VERSION_NUMBER(.*)$" "\\1" SQLITE_VERSION_NUMBER2 ${SQLITE_VERSION_NUMBER1}) # Remove the trailing spaces to convert the string to a proper integer diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/UuidConfiguration.cmake --- a/OrthancFramework/Resources/CMake/UuidConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/UuidConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -35,11 +35,11 @@ DownloadPackage(${E2FSPROGS_MD5} ${E2FSPROGS_URL} "${E2FSPROGS_SOURCES_DIR}") - + ## ## Patch for OS X, in order to be compatible with Cocoa, and for ## WebAssembly (used in Stone) - ## + ## if (FirstRun) execute_process( @@ -114,12 +114,12 @@ #cmakedefine HAVE_UNISTD_H \@HAVE_UNISTD_H\@ ") endif() - + configure_file( ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h.cmake ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h ) - + configure_file( ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid.h.in ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid.h @@ -130,7 +130,7 @@ ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid_types.h "#include \n") endif() - + source_group(ThirdParty\\uuid REGULAR_EXPRESSION ${E2FSPROGS_SOURCES_DIR}/.*) else() @@ -149,7 +149,7 @@ if (NOT HAVE_LIBUUID) message(FATAL_ERROR "Unable to find the uuid library") endif() - + link_libraries(${LIBUUID}) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/WebAssembly/ArithmeticTests/Run2.cpp --- a/OrthancFramework/Resources/CMake/WebAssembly/ArithmeticTests/Run2.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/WebAssembly/ArithmeticTests/Run2.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -9,7 +9,7 @@ std::cerr << std::endl << std::endl; std::cerr << "/**" << std::endl; std::cerr << "#define SIZEOF_CHAR " << sizeof(char) << std::endl; - std::cerr << "#define SIZEOF_DOUBLE " << sizeof(double) << std::endl; + std::cerr << "#define SIZEOF_DOUBLE " << sizeof(double) << std::endl; std::cerr << "#define SIZEOF_FLOAT " << sizeof(float) << std::endl; std::cerr << "#define SIZEOF_INT " << sizeof(int) << std::endl; std::cerr << "#define SIZEOF_LONG " << sizeof(long) << std::endl; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CMake/ZlibConfiguration.cmake --- a/OrthancFramework/Resources/CMake/ZlibConfiguration.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CMake/ZlibConfiguration.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -51,27 +51,27 @@ ${ZLIB_SOURCES_DIR} ) - list(APPEND ZLIB_SOURCES + list(APPEND ZLIB_SOURCES ${ZLIB_SOURCES_DIR}/adler32.c ${ZLIB_SOURCES_DIR}/compress.c - ${ZLIB_SOURCES_DIR}/crc32.c - ${ZLIB_SOURCES_DIR}/deflate.c - ${ZLIB_SOURCES_DIR}/infback.c - ${ZLIB_SOURCES_DIR}/inffast.c - ${ZLIB_SOURCES_DIR}/inflate.c - ${ZLIB_SOURCES_DIR}/inftrees.c - ${ZLIB_SOURCES_DIR}/trees.c - ${ZLIB_SOURCES_DIR}/uncompr.c + ${ZLIB_SOURCES_DIR}/crc32.c + ${ZLIB_SOURCES_DIR}/deflate.c + ${ZLIB_SOURCES_DIR}/infback.c + ${ZLIB_SOURCES_DIR}/inffast.c + ${ZLIB_SOURCES_DIR}/inflate.c + ${ZLIB_SOURCES_DIR}/inftrees.c + ${ZLIB_SOURCES_DIR}/trees.c + ${ZLIB_SOURCES_DIR}/uncompr.c ${ZLIB_SOURCES_DIR}/zutil.c ) if (NOT ORTHANC_SANDBOXED) # The source files below require access to the filesystem list(APPEND ZLIB_SOURCES - ${ZLIB_SOURCES_DIR}/gzlib.c - ${ZLIB_SOURCES_DIR}/gzclose.c - ${ZLIB_SOURCES_DIR}/gzread.c - ${ZLIB_SOURCES_DIR}/gzwrite.c + ${ZLIB_SOURCES_DIR}/gzlib.c + ${ZLIB_SOURCES_DIR}/gzclose.c + ${ZLIB_SOURCES_DIR}/gzread.c + ${ZLIB_SOURCES_DIR}/gzwrite.c ) endif() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CodeGeneration/CheckDcmtkTransferSyntaxes.py --- a/OrthancFramework/Resources/CodeGeneration/CheckDcmtkTransferSyntaxes.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CodeGeneration/CheckDcmtkTransferSyntaxes.py Wed Aug 19 14:11:33 2026 +0200 @@ -33,7 +33,7 @@ orthancSyntaxes = [] - + with open(os.path.join(os.path.dirname(__file__), 'DicomTransferSyntaxes.json'), 'r') as f: for syntax in json.loads(f.read()): @@ -42,7 +42,7 @@ with open(os.path.join(sys.argv[1], 'dcmdata/include/dcmtk/dcmdata/dcuid.h'), 'r') as f: r = re.compile(r'^#define UID_([A-Za-z0-9_]+)TransferSyntax\s+"([0-9.]+)"$') - + for line in f.readlines(): m = r.match(line) if m != None: diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CodeGeneration/DicomTransferSyntaxes.json --- a/OrthancFramework/Resources/CodeGeneration/DicomTransferSyntaxes.json Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CodeGeneration/DicomTransferSyntaxes.json Wed Aug 19 14:11:33 2026 +0200 @@ -7,7 +7,7 @@ "DCMTK" : "EXS_LittleEndianImplicit", "GDCM" : "gdcm::TransferSyntax::ImplicitVRLittleEndian" }, - + { "UID" : "1.2.840.10008.1.2.1", "Name" : "Explicit VR Little Endian", @@ -16,7 +16,7 @@ "DCMTK" : "EXS_LittleEndianExplicit", "GDCM" : "gdcm::TransferSyntax::ExplicitVRLittleEndian" }, - + { "UID" : "1.2.840.10008.1.2.1.99", "Name" : "Deflated Explicit VR Little Endian", @@ -24,7 +24,7 @@ "Retired" : false, "DCMTK" : "EXS_DeflatedLittleEndianExplicit" }, - + { "UID" : "1.2.840.10008.1.2.2", "Name" : "Explicit VR Big Endian", @@ -32,7 +32,7 @@ "Retired" : false, "DCMTK" : "EXS_BigEndianExplicit" }, - + { "UID" : "1.2.840.10008.1.2.4.50", "Name" : "JPEG Baseline (process 1, lossy)", @@ -43,7 +43,7 @@ "DCMTK360" : "EXS_JPEGProcess1TransferSyntax", "GDCM" : "gdcm::TransferSyntax::JPEGBaselineProcess1" }, - + { "UID" : "1.2.840.10008.1.2.4.51", "Name" : "JPEG Extended Sequential (processes 2 & 4)", @@ -118,7 +118,7 @@ "DCMTK" : "EXS_JPEGProcess15", "DCMTK360" : "EXS_JPEGProcess15TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.59", "Name" : "JPEG Extended Sequential, Hierarchical (lossy, 8/12 bit)", @@ -127,7 +127,7 @@ "DCMTK" : "EXS_JPEGProcess16_18", "DCMTK360" : "EXS_JPEGProcess16_18TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.60", "Name" : "JPEG Extended Sequential, Hierarchical (lossy, 8/12 bit), arithmetic coding", @@ -136,7 +136,7 @@ "DCMTK" : "EXS_JPEGProcess17_19", "DCMTK360" : "EXS_JPEGProcess17_19TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.61", "Name" : "JPEG Spectral Selection, Hierarchical (lossy, 8/12 bit)", @@ -145,7 +145,7 @@ "DCMTK" : "EXS_JPEGProcess20_22", "DCMTK360" : "EXS_JPEGProcess20_22TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.62", "Name" : "JPEG Spectral Selection, Hierarchical (lossy, 8/12 bit), arithmetic coding", @@ -154,7 +154,7 @@ "DCMTK" : "EXS_JPEGProcess21_23", "DCMTK360" : "EXS_JPEGProcess21_23TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.63", "Name" : "JPEG Full Progression, Hierarchical (lossy, 8/12 bit)", @@ -163,7 +163,7 @@ "DCMTK" : "EXS_JPEGProcess24_26", "DCMTK360" : "EXS_JPEGProcess24_26TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.64", "Name" : "JPEG Full Progression, Hierarchical (lossy, 8/12 bit), arithmetic coding", @@ -172,7 +172,7 @@ "DCMTK" : "EXS_JPEGProcess25_27", "DCMTK360" : "EXS_JPEGProcess25_27TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.65", "Name" : "JPEG Lossless, Hierarchical", @@ -181,7 +181,7 @@ "DCMTK" : "EXS_JPEGProcess28", "DCMTK360" : "EXS_JPEGProcess28TransferSyntax" }, - + { "UID" : "1.2.840.10008.1.2.4.66", "Name" : "JPEG Lossless, Hierarchical, arithmetic coding", diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CodeGeneration/EncodingTests.py --- a/OrthancFramework/Resources/CodeGeneration/EncodingTests.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CodeGeneration/EncodingTests.py Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ for byte in bytearray(source): result += '\\x%02x' % byte return '"%s"' % result - + for encoding, orthancEnumeration in encodings.iteritems(): l.append('::Orthanc::Encoding_%s' % orthancEnumeration) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CodeGeneration/ErrorCodes.json --- a/OrthancFramework/Resources/CodeGeneration/ErrorCodes.json Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CodeGeneration/ErrorCodes.json Wed Aug 19 14:11:33 2026 +0200 @@ -2,233 +2,233 @@ /** Generic error codes **/ { - "Code": -1, - "Name": "InternalError", + "Code": -1, + "Name": "InternalError", "Description": "Internal error" - }, + }, { - "Code": 0, - "HttpStatus": 200, - "Name": "Success", + "Code": 0, + "HttpStatus": 200, + "Name": "Success", "Description": "Success" - }, + }, { - "Code": 1, - "Name": "Plugin", + "Code": 1, + "Name": "Plugin", "Description": "Error encountered within the plugin engine" }, { - "Code": 2, - "Name": "NotImplemented", + "Code": 2, + "Name": "NotImplemented", "Description": "Not implemented yet" - }, + }, { - "Code": 3, - "HttpStatus": 400, - "Name": "ParameterOutOfRange", + "Code": 3, + "HttpStatus": 400, + "Name": "ParameterOutOfRange", "Description": "Parameter out of range", "SQLite": true - }, + }, { - "Code": 4, - "Name": "NotEnoughMemory", + "Code": 4, + "Name": "NotEnoughMemory", "Description": "The server hosting Orthanc is running out of memory" - }, + }, { - "Code": 5, - "HttpStatus": 400, - "Name": "BadParameterType", + "Code": 5, + "HttpStatus": 400, + "Name": "BadParameterType", "Description": "Bad type for a parameter", "SQLite": true - }, + }, { - "Code": 6, - "Name": "BadSequenceOfCalls", + "Code": 6, + "Name": "BadSequenceOfCalls", "Description": "Bad sequence of calls" - }, + }, { - "Code": 7, - "HttpStatus": 404, - "Name": "InexistentItem", + "Code": 7, + "HttpStatus": 404, + "Name": "InexistentItem", "Description": "Accessing an inexistent item" - }, + }, { - "Code": 8, - "HttpStatus": 400, - "Name": "BadRequest", + "Code": 8, + "HttpStatus": 400, + "Name": "BadRequest", "Description": "Bad request" - }, + }, { - "Code": 9, - "Name": "NetworkProtocol", + "Code": 9, + "Name": "NetworkProtocol", "Description": "Error in the network protocol" - }, + }, { - "Code": 10, - "Name": "SystemCommand", + "Code": 10, + "Name": "SystemCommand", "Description": "Error while calling a system command" - }, + }, { - "Code": 11, - "Name": "Database", + "Code": 11, + "Name": "Database", "Description": "Error with the database engine" - }, + }, { - "Code": 12, - "HttpStatus": 400, - "Name": "UriSyntax", + "Code": 12, + "HttpStatus": 400, + "Name": "UriSyntax", "Description": "Badly formatted URI" - }, + }, { - "Code": 13, - "HttpStatus": 404, - "Name": "InexistentFile", + "Code": 13, + "HttpStatus": 404, + "Name": "InexistentFile", "Description": "Inexistent file" - }, + }, { - "Code": 14, - "Name": "CannotWriteFile", + "Code": 14, + "Name": "CannotWriteFile", "Description": "Cannot write to file" - }, + }, { - "Code": 15, - "HttpStatus": 400, - "Name": "BadFileFormat", + "Code": 15, + "HttpStatus": 400, + "Name": "BadFileFormat", "Description": "Bad file format" - }, + }, { - "Code": 16, - "Name": "Timeout", + "Code": 16, + "Name": "Timeout", "Description": "Timeout" - }, + }, { - "Code": 17, - "HttpStatus": 404, - "Name": "UnknownResource", + "Code": 17, + "HttpStatus": 404, + "Name": "UnknownResource", "Description": "Unknown resource" - }, + }, { - "Code": 18, - "Name": "IncompatibleDatabaseVersion", + "Code": 18, + "Name": "IncompatibleDatabaseVersion", "Description": "Incompatible version of the database" - }, + }, { - "Code": 19, - "Name": "FullStorage", + "Code": 19, + "Name": "FullStorage", "Description": "The file storage is full" - }, + }, { - "Code": 20, - "Name": "CorruptedFile", + "Code": 20, + "Name": "CorruptedFile", "Description": "Corrupted file (e.g. inconsistent MD5 hash)" - }, + }, { - "Code": 21, - "HttpStatus": 404, - "Name": "InexistentTag", + "Code": 21, + "HttpStatus": 404, + "Name": "InexistentTag", "Description": "Inexistent tag" - }, + }, { - "Code": 22, - "Name": "ReadOnly", + "Code": 22, + "Name": "ReadOnly", "Description": "Cannot modify a read-only data structure" - }, + }, { - "Code": 23, - "Name": "IncompatibleImageFormat", + "Code": 23, + "Name": "IncompatibleImageFormat", "Description": "Incompatible format of the images" - }, + }, { - "Code": 24, - "Name": "IncompatibleImageSize", + "Code": 24, + "Name": "IncompatibleImageSize", "Description": "Incompatible size of the images" - }, + }, { - "Code": 25, - "Name": "SharedLibrary", + "Code": 25, + "Name": "SharedLibrary", "Description": "Error while using a shared library (plugin)" - }, + }, { - "Code": 26, - "Name": "UnknownPluginService", + "Code": 26, + "Name": "UnknownPluginService", "Description": "Plugin invoking an unknown service" - }, + }, { - "Code": 27, - "Name": "UnknownDicomTag", + "Code": 27, + "Name": "UnknownDicomTag", "Description": "Unknown DICOM tag" - }, + }, { - "Code": 28, - "HttpStatus": 400, - "Name": "BadJson", + "Code": 28, + "HttpStatus": 400, + "Name": "BadJson", "Description": "Cannot parse a JSON document" - }, + }, { - "Code": 29, - "HttpStatus": 401, - "Name": "Unauthorized", + "Code": 29, + "HttpStatus": 401, + "Name": "Unauthorized", "Description": "Bad credentials were provided to an HTTP request" - }, + }, { - "Code": 30, - "Name": "BadFont", + "Code": 30, + "Name": "BadFont", "Description": "Badly formatted font file" }, { - "Code": 31, - "Name": "DatabasePlugin", + "Code": 31, + "Name": "DatabasePlugin", "Description": "The plugin implementing a custom database back-end does not fulfill the proper interface" - }, + }, { - "Code": 32, - "Name": "StorageAreaPlugin", + "Code": 32, + "Name": "StorageAreaPlugin", "Description": "Error in the plugin implementing a custom storage area" }, { "Code": 33, "Name": "EmptyRequest", "Description": "The request is empty" - }, + }, { - "Code": 34, - "HttpStatus": 406, - "Name": "NotAcceptable", + "Code": 34, + "HttpStatus": 406, + "Name": "NotAcceptable", "Description": "Cannot send a response which is acceptable according to the Accept HTTP header" - }, + }, { - "Code": 35, - "Name": "NullPointer", + "Code": 35, + "Name": "NullPointer", "Description": "Cannot handle a NULL pointer" }, { - "Code": 36, - "HttpStatus": 503, - "Name": "DatabaseUnavailable", + "Code": 36, + "HttpStatus": 503, + "Name": "DatabaseUnavailable", "Description": "The database is currently not available (probably a transient situation)" - }, + }, { - "Code": 37, - "Name": "CanceledJob", + "Code": 37, + "Name": "CanceledJob", "Description": "This job was canceled" - }, + }, { - "Code": 38, - "Name": "BadGeometry", + "Code": 38, + "Name": "BadGeometry", "Description": "Geometry error encountered in Stone" - }, + }, { - "Code": 39, - "Name": "SslInitialization", + "Code": 39, + "Name": "SslInitialization", "Description": "Cannot initialize SSL encryption, check out your certificates" - }, + }, { - "Code": 40, - "Name": "DiscontinuedAbi", + "Code": 40, + "Name": "DiscontinuedAbi", "Description": "Calling a function that has been removed from the Orthanc Framework" - }, + }, { - "Code": 41, + "Code": 41, "HttpStatus" : 416, "Name": "BadRange", "Description": "Incorrect range request" @@ -238,33 +238,33 @@ "HttpStatus": 503, "Name": "DatabaseCannotSerialize", "Description": "Database could not serialize access due to concurrent update, the transaction should be retried" - }, + }, { "Code": 43, "HttpStatus": 409, "Name": "Revision", "Description": "A bad revision number was provided, which might indicate conflict between multiple writers" - }, + }, { "Code": 44, "Name": "MainDicomTagsMultiplyDefined", "Description": "A main DICOM Tag has been defined multiple times for the same resource level" - }, + }, { - "Code": 45, - "HttpStatus": 403, - "Name": "ForbiddenAccess", + "Code": 45, + "HttpStatus": 403, + "Name": "ForbiddenAccess", "Description": "Access to a resource is forbidden" - }, + }, { "Code": 46, "HttpStatus": 409, - "Name": "DuplicateResource", + "Name": "DuplicateResource", "Description": "Duplicate resource" - }, + }, { "Code": 47, - "Name": "IncompatibleConfigurations", + "Name": "IncompatibleConfigurations", "Description": "Your configuration file contains configuration that are mutually incompatible" }, @@ -274,98 +274,98 @@ { - "Code": 1000, + "Code": 1000, "Name": "SQLiteNotOpened", "Description": "SQLite: The database is not opened", "SQLite": true }, { - "Code": 1001, - "Name": "SQLiteAlreadyOpened", + "Code": 1001, + "Name": "SQLiteAlreadyOpened", "Description": "SQLite: Connection is already open", "SQLite": true }, { - "Code": 1002, - "Name": "SQLiteCannotOpen", + "Code": 1002, + "Name": "SQLiteCannotOpen", "Description": "SQLite: Unable to open the database", "SQLite": true }, { - "Code": 1003, - "Name": "SQLiteStatementAlreadyUsed", + "Code": 1003, + "Name": "SQLiteStatementAlreadyUsed", "Description": "SQLite: This cached statement is already being referred to", "SQLite": true }, { - "Code": 1004, - "Name": "SQLiteExecute", + "Code": 1004, + "Name": "SQLiteExecute", "Description": "SQLite: Cannot execute a command", "SQLite": true }, { - "Code": 1005, - "Name": "SQLiteRollbackWithoutTransaction", + "Code": 1005, + "Name": "SQLiteRollbackWithoutTransaction", "Description": "SQLite: Rolling back a nonexistent transaction (have you called Begin()?)", "SQLite": true }, { - "Code": 1006, - "Name": "SQLiteCommitWithoutTransaction", + "Code": 1006, + "Name": "SQLiteCommitWithoutTransaction", "Description": "SQLite: Committing a nonexistent transaction", "SQLite": true }, { - "Code": 1007, - "Name": "SQLiteRegisterFunction", + "Code": 1007, + "Name": "SQLiteRegisterFunction", "Description": "SQLite: Unable to register a function", "SQLite": true }, { - "Code": 1008, - "Name": "SQLiteFlush", + "Code": 1008, + "Name": "SQLiteFlush", "Description": "SQLite: Unable to flush the database", "SQLite": true }, { - "Code": 1009, - "Name": "SQLiteCannotRun", + "Code": 1009, + "Name": "SQLiteCannotRun", "Description": "SQLite: Cannot run a cached statement", "SQLite": true }, { - "Code": 1010, - "Name": "SQLiteCannotStep", + "Code": 1010, + "Name": "SQLiteCannotStep", "Description": "SQLite: Cannot step over a cached statement", "SQLite": true }, { - "Code": 1011, - "Name": "SQLiteBindOutOfRange", + "Code": 1011, + "Name": "SQLiteBindOutOfRange", "Description": "SQLite: Bind a value while out of range (serious error)", "SQLite": true }, { - "Code": 1012, - "Name": "SQLitePrepareStatement", + "Code": 1012, + "Name": "SQLitePrepareStatement", "Description": "SQLite: Cannot prepare a cached statement", "SQLite": true }, { - "Code": 1013, - "Name": "SQLiteTransactionAlreadyStarted", + "Code": 1013, + "Name": "SQLiteTransactionAlreadyStarted", "Description": "SQLite: Beginning the same transaction twice", "SQLite": true }, { - "Code": 1014, - "Name": "SQLiteTransactionCommit", + "Code": 1014, + "Name": "SQLiteTransactionCommit", "Description": "SQLite: Failure when committing the transaction", "SQLite": true }, { - "Code": 1015, - "Name": "SQLiteTransactionBegin", + "Code": 1015, + "Name": "SQLiteTransactionBegin", "Description": "SQLite: Cannot start a transaction", "SQLite": true }, @@ -374,192 +374,192 @@ /** Specific error codes **/ - + { - "Code": 2000, - "Name": "DirectoryOverFile", + "Code": 2000, + "Name": "DirectoryOverFile", "Description": "The directory to be created is already occupied by a regular file" }, { - "Code": 2001, - "Name": "FileStorageCannotWrite", + "Code": 2001, + "Name": "FileStorageCannotWrite", "Description": "Unable to create a subdirectory or a file in the file storage" }, { - "Code": 2002, - "Name": "DirectoryExpected", + "Code": 2002, + "Name": "DirectoryExpected", "Description": "The specified path does not point to a directory" }, { - "Code": 2003, - "Name": "HttpPortInUse", + "Code": 2003, + "Name": "HttpPortInUse", "Description": "The TCP port of the HTTP server is privileged or already in use or one of the HTTP bind addresses does not exist" }, { - "Code": 2004, - "Name": "DicomPortInUse", + "Code": 2004, + "Name": "DicomPortInUse", "Description": "The TCP port of the DICOM server is privileged or already in use" }, { - "Code": 2005, - "Name": "BadHttpStatusInRest", + "Code": 2005, + "Name": "BadHttpStatusInRest", "Description": "This HTTP status is not allowed in a REST API" }, { - "Code": 2006, - "Name": "RegularFileExpected", + "Code": 2006, + "Name": "RegularFileExpected", "Description": "The specified path does not point to a regular file" }, { - "Code": 2007, - "Name": "PathToExecutable", + "Code": 2007, + "Name": "PathToExecutable", "Description": "Unable to get the path to the executable" }, { - "Code": 2008, - "Name": "MakeDirectory", + "Code": 2008, + "Name": "MakeDirectory", "Description": "Cannot create a directory" }, { - "Code": 2009, - "Name": "BadApplicationEntityTitle", + "Code": 2009, + "Name": "BadApplicationEntityTitle", "Description": "An application entity title (AET) cannot be empty or be longer than 16 characters" }, { - "Code": 2010, - "Name": "NoCFindHandler", + "Code": 2010, + "Name": "NoCFindHandler", "Description": "No request handler factory for DICOM C-FIND SCP" }, { - "Code": 2011, - "Name": "NoCMoveHandler", + "Code": 2011, + "Name": "NoCMoveHandler", "Description": "No request handler factory for DICOM C-MOVE SCP" }, { - "Code": 2012, - "Name": "NoCStoreHandler", + "Code": 2012, + "Name": "NoCStoreHandler", "Description": "No request handler factory for DICOM C-STORE SCP" }, { - "Code": 2013, - "Name": "NoApplicationEntityFilter", + "Code": 2013, + "Name": "NoApplicationEntityFilter", "Description": "No application entity filter" }, { - "Code": 2014, - "Name": "NoSopClassOrInstance", + "Code": 2014, + "Name": "NoSopClassOrInstance", "Description": "DicomUserConnection: Unable to find the SOP class and instance" }, { - "Code": 2015, - "Name": "NoPresentationContext", + "Code": 2015, + "Name": "NoPresentationContext", "Description": "DicomUserConnection: No acceptable presentation context for modality" }, { - "Code": 2016, - "Name": "DicomFindUnavailable", + "Code": 2016, + "Name": "DicomFindUnavailable", "Description": "DicomUserConnection: The C-FIND command is not supported by the remote SCP" }, { - "Code": 2017, - "Name": "DicomMoveUnavailable", + "Code": 2017, + "Name": "DicomMoveUnavailable", "Description": "DicomUserConnection: The C-MOVE command is not supported by the remote SCP" }, { - "Code": 2018, - "Name": "CannotStoreInstance", + "Code": 2018, + "Name": "CannotStoreInstance", "Description": "Cannot store an instance" }, { "Code": 2019, - "HttpStatus": 400, - "Name": "CreateDicomNotString", + "HttpStatus": 400, + "Name": "CreateDicomNotString", "Description": "Only string values are supported when creating DICOM instances" }, { "Code": 2020, - "HttpStatus": 400, - "Name": "CreateDicomOverrideTag", + "HttpStatus": 400, + "Name": "CreateDicomOverrideTag", "Description": "Trying to override a value inherited from a parent module" }, { "Code": 2021, - "HttpStatus": 400, - "Name": "CreateDicomUseContent", + "HttpStatus": 400, + "Name": "CreateDicomUseContent", "Description": "Use \\\"Content\\\" to inject an image into a new DICOM instance" }, { "Code": 2022, - "HttpStatus": 400, - "Name": "CreateDicomNoPayload", + "HttpStatus": 400, + "Name": "CreateDicomNoPayload", "Description": "No payload is present for one instance in the series" }, { "Code": 2023, - "HttpStatus": 400, - "Name": "CreateDicomUseDataUriScheme", + "HttpStatus": 400, + "Name": "CreateDicomUseDataUriScheme", "Description": "The payload of the DICOM instance must be specified according to Data URI scheme" }, { "Code": 2024, - "HttpStatus": 400, - "Name": "CreateDicomBadParent", + "HttpStatus": 400, + "Name": "CreateDicomBadParent", "Description": "Trying to attach a new DICOM instance to an inexistent resource" }, { "Code": 2025, - "HttpStatus": 400, - "Name": "CreateDicomParentIsInstance", + "HttpStatus": 400, + "Name": "CreateDicomParentIsInstance", "Description": "Trying to attach a new DICOM instance to an instance (must be a series, study or patient)" }, { - "Code": 2026, - "Name": "CreateDicomParentEncoding", + "Code": 2026, + "Name": "CreateDicomParentEncoding", "Description": "Unable to get the encoding of the parent resource" }, { - "Code": 2027, - "Name": "UnknownModality", + "Code": 2027, + "Name": "UnknownModality", "Description": "Unknown modality" }, { - "Code": 2028, - "Name": "BadJobOrdering", + "Code": 2028, + "Name": "BadJobOrdering", "Description": "Bad ordering of filters in a job" }, { - "Code": 2029, - "Name": "JsonToLuaTable", + "Code": 2029, + "Name": "JsonToLuaTable", "Description": "Cannot convert the given JSON object to a Lua table" }, { - "Code": 2030, - "Name": "CannotCreateLua", + "Code": 2030, + "Name": "CannotCreateLua", "Description": "Cannot create the Lua context" }, { - "Code": 2031, - "Name": "CannotExecuteLua", + "Code": 2031, + "Name": "CannotExecuteLua", "Description": "Cannot execute a Lua command" }, { - "Code": 2032, - "Name": "LuaAlreadyExecuted", + "Code": 2032, + "Name": "LuaAlreadyExecuted", "Description": "Arguments cannot be pushed after the Lua function is executed" }, { - "Code": 2033, - "Name": "LuaBadOutput", + "Code": 2033, + "Name": "LuaBadOutput", "Description": "The Lua function does not give the expected number of outputs" }, { - "Code": 2034, - "Name": "NotLuaPredicate", + "Code": 2034, + "Name": "NotLuaPredicate", "Description": "The Lua function is not a predicate (only true/false outputs allowed)" }, { - "Code": 2035, - "Name": "LuaReturnsNoString", + "Code": 2035, + "Name": "LuaReturnsNoString", "Description": "The Lua function does not return a string" }, { @@ -577,7 +577,7 @@ "Name": "DatabaseNotInitialized", "Description": "Plugin trying to call the database during its initialization" }, - { + { "Code": 2039, "Name": "SslDisabled", "Description": "Orthanc has been built without SSL support" @@ -588,8 +588,8 @@ "Description": "Unable to order the slices of the series" }, { - "Code": 2041, - "Name": "NoWorklistHandler", + "Code": 2041, + "Name": "NoWorklistHandler", "Description": "No request handler factory for DICOM C-Find Modality SCP" }, { @@ -598,18 +598,18 @@ "Description": "Cannot override the value of a tag that already exists" }, { - "Code": 2043, - "Name": "NoStorageCommitmentHandler", + "Code": 2043, + "Name": "NoStorageCommitmentHandler", "Description": "No request handler factory for DICOM N-ACTION SCP (storage commitment)" }, { "Code": 2044, - "Name": "NoCGetHandler", + "Name": "NoCGetHandler", "Description": "No request handler factory for DICOM C-GET SCP" }, { - "Code": 2045, - "Name": "DicomGetUnavailable", + "Code": 2045, + "Name": "DicomGetUnavailable", "Description": "DicomUserConnection: The C-GET command is not supported by the remote SCP" }, @@ -619,7 +619,7 @@ { "Code": 3000, - "HttpStatus": 415, + "HttpStatus": 415, "Name": "UnsupportedMediaType", "Description": "Unsupported media type" } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/CodeGeneration/GenerateErrorCodes.py --- a/OrthancFramework/Resources/CodeGeneration/GenerateErrorCodes.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/CodeGeneration/GenerateErrorCodes.py Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ -## +## ## Read all the available error codes and HTTP status ## diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Graveyard/CheckOrthancFrameworkSymbols.py --- a/OrthancFramework/Resources/Graveyard/CheckOrthancFrameworkSymbols.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Graveyard/CheckOrthancFrameworkSymbols.py Wed Aug 19 14:11:33 2026 +0200 @@ -78,12 +78,12 @@ SOURCES.append(os.path.join(root, name)) AMALGAMATION = '/tmp/CheckOrthancFrameworkSymbols.cpp' - + with open(AMALGAMATION, 'w') as f: f.write('#include "%s"\n' % os.path.join(ROOT, '..', 'Sources', 'OrthancFramework.h')) for source in SOURCES: f.write('#include "%s"\n' % source) - + tu = index.parse(AMALGAMATION, [ '--std=c++11', @@ -147,7 +147,7 @@ # Ignore forward declaration of classes if not child.is_definition(): return - + ## ## Verify that the class is publicly exported (its visibility must @@ -165,8 +165,8 @@ global ALL_TYPES ALL_TYPES.append('::'.join(fqn)) - - + + ## ## Ignore pure abstract interfaces, by checking the following ## criteria: @@ -175,7 +175,7 @@ ## - All its methods must be pure virtual (abstract) and public ## - Its destructor must be public, virtual, and must do nothing ## - + if (child.kind == clang.cindex.CursorKind.CLASS_DECL and child.spelling[0] == 'I' and child.spelling[1].isupper()): @@ -223,12 +223,12 @@ ReportProblem('Not a pure interface', fqn, child) return - + ## ## We are facing a standard C++ class or struct ## - + isPublic = (child.kind == clang.cindex.CursorKind.STRUCT_DECL) membersCount = 0 @@ -238,7 +238,7 @@ if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR or # "default" i.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER): # base class pass - + elif i.kind == clang.cindex.CursorKind.CXX_ACCESS_SPEC_DECL: isPublic = (i.access_specifier == clang.cindex.AccessSpecifier.PUBLIC) @@ -294,7 +294,7 @@ if i.type.get_size() > 0: membersSize += i.type.get_size() membersCount += 1 - + else: if isPublic: raise Exception('Unsupported: %s, %s' % (i.kind, i.location)) @@ -305,7 +305,7 @@ def ExploreNamespace(node, namespace): for child in node.get_children(): fqn = namespace + [ child.spelling ] - + if child.kind == clang.cindex.CursorKind.NAMESPACE: ExploreNamespace(child, fqn) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Patches/OpenSSL-ConfigureHeaders.py --- a/OrthancFramework/Resources/Patches/OpenSSL-ConfigureHeaders.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Patches/OpenSSL-ConfigureHeaders.py Wed Aug 19 14:11:33 2026 +0200 @@ -88,16 +88,16 @@ CURRENT_HEADER = '' - + def Parse(match): s = '' - + for t in re.findall(r'generate_stack_macros\("(.+?)"\)', match.group(1)): s += (GENERATE_STACK_MACROS .replace('${nametype}', t) .replace('${realtype}', t) .replace('${plaintype}', t)) - + for t in re.findall(r'generate_const_stack_macros\("(.+?)"\)', match.group(1)): s += (GENERATE_STACK_MACROS .replace('${nametype}', t) @@ -121,7 +121,7 @@ .replace('${nametype}', 'OPENSSL_BLOCK') .replace('${realtype}', 'void') .replace('${plaintype}', 'void')) - + for t in re.findall(r'generate_lhash_macros\("(.+?)"\)', match.group(1)): s += GENERATE_LHASH_MACROS.replace('${type}', t) @@ -136,7 +136,7 @@ s += '#define DER_OID_V_%s %s\n' % (name, ', '.join(definition)) s += '#define DER_OID_SZ_%s %d\n' % (name, len(definition)) s += 'extern const unsigned char ossl_der_oid_%s[DER_OID_SZ_%s];\n\n' % (name, name) - + return s @@ -146,7 +146,7 @@ for source in os.listdir(directory): if source.endswith('.h.in'): target = re.sub(r'\.h\.in$', '.h', source) - + with open(os.path.join(directory, source), 'r') as f: with open(os.path.join(directory, target), 'w') as g: CURRENT_HEADER = source @@ -159,7 +159,7 @@ f.write('#include "prov/%s"\n' % re.sub(r'\.h\.in$', '.h', header)) f.write('\n') - + for (header, content) in OIDS.items(): for (name, definition) in content.items(): f.write('const unsigned char ossl_der_oid_%s[DER_OID_SZ_%s] = { DER_OID_V_%s };\n' % ( diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.json --- a/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.json Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.json Wed Aug 19 14:11:33 2026 +0200 @@ -1,1224 +1,1224 @@ { "der_digests.h.in": { "id_KMACWithSHAKE128": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x13" - ], + ], "id_KMACWithSHAKE256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x14" - ], + ], "id_md2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x02", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x02", "0x02" - ], + ], "id_md5": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x02", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x02", "0x05" - ], + ], "id_sha1": [ - "DER_P_OBJECT", - "5", - "0x2B", - "0x0E", - "0x03", - "0x02", + "DER_P_OBJECT", + "5", + "0x2B", + "0x0E", + "0x03", + "0x02", "0x1A" - ], + ], "id_sha224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x04" - ], + ], "id_sha256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x01" - ], + ], "id_sha384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x02" - ], + ], "id_sha3_224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x07" - ], + ], "id_sha3_256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x08" - ], + ], "id_sha3_384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x09" - ], + ], "id_sha3_512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x0A" - ], + ], "id_sha512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x03" - ], + ], "id_sha512_224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x05" - ], + ], "id_sha512_256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x06" - ], + ], "id_shake128": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x0B" - ], + ], "id_shake128_len": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x11" - ], + ], "id_shake256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x0C" - ], + ], "id_shake256_len": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x02", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x02", "0x12" - ], + ], "sigAlgs": [ - "DER_P_OBJECT", - "8", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", + "DER_P_OBJECT", + "8", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", "0x03" ] - }, + }, "der_dsa.h.in": { "id_dsa": [ - "DER_P_OBJECT", - "7", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x38", - "0x04", + "DER_P_OBJECT", + "7", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x38", + "0x04", "0x01" - ], + ], "id_dsa_with_sha1": [ - "DER_P_OBJECT", - "7", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x38", - "0x04", + "DER_P_OBJECT", + "7", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x38", + "0x04", "0x03" - ], + ], "id_dsa_with_sha224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x01" - ], + ], "id_dsa_with_sha256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x02" - ], + ], "id_dsa_with_sha384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x03" - ], + ], "id_dsa_with_sha3_224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x05" - ], + ], "id_dsa_with_sha3_256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x06" - ], + ], "id_dsa_with_sha3_384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x07" - ], + ], "id_dsa_with_sha3_512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x08" - ], + ], "id_dsa_with_sha512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x04" ] - }, + }, "der_ec.h.in": { "c2onb191v4": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x08" - ], + ], "c2onb191v5": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x09" - ], + ], "c2onb239v4": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0E" - ], + ], "c2onb239v5": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0F" - ], + ], "c2pnb163v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x01" - ], + ], "c2pnb163v2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x02" - ], + ], "c2pnb163v3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x03" - ], + ], "c2pnb176w1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x04" - ], + ], "c2pnb208w1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0A" - ], + ], "c2pnb272w1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x10" - ], + ], "c2pnb304w1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x11" - ], + ], "c2pnb368w1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x13" - ], + ], "c2tnb191v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x05" - ], + ], "c2tnb191v2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x06" - ], + ], "c2tnb191v3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x07" - ], + ], "c2tnb239v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0B" - ], + ], "c2tnb239v2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0C" - ], + ], "c2tnb239v3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x0D" - ], + ], "c2tnb359v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x12" - ], + ], "c2tnb431r1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x00", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x00", "0x14" - ], + ], "ecdsa_with_SHA1": [ - "DER_P_OBJECT", - "7", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x04", + "DER_P_OBJECT", + "7", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x04", "0x01" - ], + ], "ecdsa_with_SHA224": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x04", - "0x03", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x04", + "0x03", "0x01" - ], + ], "ecdsa_with_SHA256": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x04", - "0x03", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x04", + "0x03", "0x02" - ], + ], "ecdsa_with_SHA384": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x04", - "0x03", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x04", + "0x03", "0x03" - ], + ], "ecdsa_with_SHA512": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x04", - "0x03", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x04", + "0x03", "0x04" - ], + ], "id_ecPublicKey": [ - "DER_P_OBJECT", - "7", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x02", + "DER_P_OBJECT", + "7", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x02", "0x01" - ], + ], "id_ecdsa_with_sha3_224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x09" - ], + ], "id_ecdsa_with_sha3_256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0A" - ], + ], "id_ecdsa_with_sha3_384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0B" - ], + ], "id_ecdsa_with_sha3_512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0C" - ], + ], "prime192v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x01" - ], + ], "prime192v2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x02" - ], + ], "prime192v3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x03" - ], + ], "prime239v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x04" - ], + ], "prime239v2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x05" - ], + ], "prime239v3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x06" - ], + ], "prime256v1": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x86", - "0x48", - "0xCE", - "0x3D", - "0x03", - "0x01", + "DER_P_OBJECT", + "8", + "0x2A", + "0x86", + "0x48", + "0xCE", + "0x3D", + "0x03", + "0x01", "0x07" ] - }, + }, "der_ecx.h.in": { "id_Ed25519": [ - "DER_P_OBJECT", - "3", - "0x2B", - "0x65", + "DER_P_OBJECT", + "3", + "0x2B", + "0x65", "0x70" - ], + ], "id_Ed448": [ - "DER_P_OBJECT", - "3", - "0x2B", - "0x65", + "DER_P_OBJECT", + "3", + "0x2B", + "0x65", "0x71" - ], + ], "id_X25519": [ - "DER_P_OBJECT", - "3", - "0x2B", - "0x65", + "DER_P_OBJECT", + "3", + "0x2B", + "0x65", "0x6E" - ], + ], "id_X448": [ - "DER_P_OBJECT", - "3", - "0x2B", - "0x65", + "DER_P_OBJECT", + "3", + "0x2B", + "0x65", "0x6F" ] - }, + }, "der_rsa.h.in": { "hashAlgs": [ - "DER_P_OBJECT", - "8", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", + "DER_P_OBJECT", + "8", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", "0x02" - ], + ], "id_RSAES_OAEP": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x07" - ], + ], "id_RSASSA_PSS": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0A" - ], + ], "id_mgf1": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x08" - ], + ], "id_pSpecified": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x09" - ], + ], "id_rsassa_pkcs1_v1_5_with_sha3_224": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0D" - ], + ], "id_rsassa_pkcs1_v1_5_with_sha3_256": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0E" - ], + ], "id_rsassa_pkcs1_v1_5_with_sha3_384": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x0F" - ], + ], "id_rsassa_pkcs1_v1_5_with_sha3_512": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x03", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x03", "0x10" - ], + ], "md2WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x02" - ], + ], "md4WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x03" - ], + ], "md5WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x04" - ], + ], "mdc2WithRSASignature": [ - "DER_P_OBJECT", - "5", - "0x2B", - "0x0E", - "0x03", - "0x02", + "DER_P_OBJECT", + "5", + "0x2B", + "0x0E", + "0x03", + "0x02", "0x0E" - ], + ], "ripemd160WithRSAEncryption": [ - "DER_P_OBJECT", - "6", - "0x2B", - "0x24", - "0x03", - "0x03", - "0x01", + "DER_P_OBJECT", + "6", + "0x2B", + "0x24", + "0x03", + "0x03", + "0x01", "0x02" - ], + ], "rsaEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x01" - ], + ], "sha1WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x05" - ], + ], "sha224WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0E" - ], + ], "sha256WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0B" - ], + ], "sha384WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0C" - ], + ], "sha512WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0D" - ], + ], "sha512_224WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x0F" - ], + ], "sha512_256WithRSAEncryption": [ - "DER_P_OBJECT", - "9", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x01", + "DER_P_OBJECT", + "9", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x01", "0x10" ] - }, + }, "der_sm2.h.in": { "curveSM2": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x81", - "0x1C", - "0xCF", - "0x55", - "0x01", - "0x82", + "DER_P_OBJECT", + "8", + "0x2A", + "0x81", + "0x1C", + "0xCF", + "0x55", + "0x01", + "0x82", "0x2D" - ], + ], "sm2_with_SM3": [ - "DER_P_OBJECT", - "8", - "0x2A", - "0x81", - "0x1C", - "0xCF", - "0x55", - "0x01", - "0x83", + "DER_P_OBJECT", + "8", + "0x2A", + "0x81", + "0x1C", + "0xCF", + "0x55", + "0x01", + "0x83", "0x75" ] - }, + }, "der_wrap.h.in": { "id_aes128_wrap": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x01", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x01", "0x05" - ], + ], "id_aes192_wrap": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x01", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x01", "0x19" - ], + ], "id_aes256_wrap": [ - "DER_P_OBJECT", - "9", - "0x60", - "0x86", - "0x48", - "0x01", - "0x65", - "0x03", - "0x04", - "0x01", + "DER_P_OBJECT", + "9", + "0x60", + "0x86", + "0x48", + "0x01", + "0x65", + "0x03", + "0x04", + "0x01", "0x2D" - ], + ], "id_alg_CMS3DESwrap": [ - "DER_P_OBJECT", - "11", - "0x2A", - "0x86", - "0x48", - "0x86", - "0xF7", - "0x0D", - "0x01", - "0x09", - "0x10", - "0x03", + "DER_P_OBJECT", + "11", + "0x2A", + "0x86", + "0x48", + "0x86", + "0xF7", + "0x0D", + "0x01", + "0x09", + "0x10", + "0x03", "0x06" ] } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.py --- a/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.py Wed Aug 19 14:11:33 2026 +0200 @@ -49,11 +49,11 @@ path = os.path.join(BASE, re.sub('.in$', '', source)) content = {} - + with open(path, 'r') as f: for definition in re.findall('#define (DER_OID_V_.+?)#define (DER_OID_SZ_.+?)extern const(.+?)$', f.read(), re.MULTILINE | re.DOTALL): oid = definition[0].strip().split(' ') - + name = oid[0].replace('DER_OID_V_', '') oid = oid[1:] diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/ProtocolBuffers/ProtobufLibrary.cmake --- a/OrthancFramework/Resources/ProtocolBuffers/ProtobufLibrary.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/ProtocolBuffers/ProtobufLibrary.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -50,7 +50,7 @@ include_directories( ${PROTOBUF_SOURCE_DIR}/src ) - + set(PROTOBUF_LIBRARY_SOURCES ${PROTOBUF_SOURCE_DIR}/src/google/protobuf/any.cc ${PROTOBUF_SOURCE_DIR}/src/google/protobuf/any.pb.cc diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Samples/MicroService/Sample.cpp --- a/OrthancFramework/Resources/Samples/MicroService/Sample.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Samples/MicroService/Sample.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -45,10 +45,10 @@ static void Hello(Orthanc::RestApiGetCall& call) { GetSelf(call).SayHello(); - + Json::Value value = Json::arrayValue; value.append("World"); - + call.GetOutput().AnswerJson(value); } @@ -56,7 +56,7 @@ MicroService() { Register("/hello", Hello); - } + } }; int main() @@ -65,14 +65,14 @@ Orthanc::Logging::EnableTraceLevel(true); MicroService rest; - + { Orthanc::HttpServer httpServer; httpServer.SetPortNumber(8000); httpServer.Register(rest); httpServer.SetRemoteAccessAllowed(true); httpServer.Start(); - + LOG(WARNING) << "Micro-service started on port " << httpServer.GetPortNumber(); Orthanc::SystemToolbox::ServerBarrier(); } @@ -80,6 +80,6 @@ LOG(WARNING) << "Micro-service stopped"; Orthanc::Logging::Finalize(); - + return 0; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/ThirdParty/VisualStudio/stdint.h --- a/OrthancFramework/Resources/ThirdParty/VisualStudio/stdint.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/ThirdParty/VisualStudio/stdint.h Wed Aug 19 14:11:33 2026 +0200 @@ -1,33 +1,33 @@ // ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// // Copyright (c) 2006-2013 Alexander Chemeris -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. -// +// // 3. Neither the name of the product nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +// /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/ThirdParty/base64/base64.cpp --- a/OrthancFramework/Resources/ThirdParty/base64/base64.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/ThirdParty/base64/base64.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -1,4 +1,4 @@ -/* +/* base64.cpp and base64.h Copyright (C) 2004-2008 Ren� Nyffenegger @@ -32,7 +32,7 @@ #include #include -static const std::string base64_chars = +static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; @@ -50,7 +50,7 @@ const unsigned char* bytes_to_encode = reinterpret_cast(stringToEncode.c_str()); size_t in_len = stringToEncode.size(); - + result.reserve(result.size() + in_len * 4 / 3 + 10); int i = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/ThirdParty/md5/md5.h --- a/OrthancFramework/Resources/ThirdParty/md5/md5.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/ThirdParty/md5/md5.h Wed Aug 19 14:11:33 2026 +0200 @@ -71,7 +71,7 @@ } md5_state_t; #ifdef __cplusplus -extern "C" +extern "C" { #endif diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Toolchains/CrossToolchain.cmake --- a/OrthancFramework/Resources/Toolchains/CrossToolchain.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Toolchains/CrossToolchain.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -51,7 +51,7 @@ # which compilers to use for C and C++ SET(CMAKE_C_COMPILER ${CROSSTOOL_NG_BASE}/bin/${CROSSTOOL_NG_NAME}-gcc) -if (${CMAKE_VERSION} VERSION_LESS "3.6.0") +if (${CMAKE_VERSION} VERSION_LESS "3.6.0") CMAKE_FORCE_CXX_COMPILER(${CROSSTOOL_NG_BASE}/bin/${CROSSTOOL_NG_NAME}-g++ GNU) else() SET(CMAKE_CXX_COMPILER ${CROSSTOOL_NG_BASE}/bin/${CROSSTOOL_NG_NAME}-g++) @@ -62,7 +62,7 @@ #SET(CMAKE_FIND_ROOT_PATH ${CROSSTOOL_NG_BASE}/${CROSSTOOL_NG_NAME}/sysroot) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake --- a/OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -62,7 +62,7 @@ # which compilers to use for C and C++ SET(CMAKE_C_COMPILER ${LSB_PATH}/bin/lsbcc) -if (${CMAKE_VERSION} VERSION_LESS "3.6.0") +if (${CMAKE_VERSION} VERSION_LESS "3.6.0") CMAKE_FORCE_CXX_COMPILER(${LSB_PATH}/bin/lsbc++ GNU) else() SET(CMAKE_CXX_COMPILER ${LSB_PATH}/bin/lsbc++) @@ -72,7 +72,7 @@ SET(CMAKE_FIND_ROOT_PATH ${LSB_PATH}) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake --- a/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake --- a/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake --- a/OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc) # adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search +# search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Resources/WindowsResources.py --- a/OrthancFramework/Resources/WindowsResources.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Resources/WindowsResources.py Wed Aug 19 14:11:33 2026 +0200 @@ -72,8 +72,8 @@ content = content.replace('${VERSION_PATCH}', v[2]) content = content.replace('${RELEASE}', RELEASE) content = content.replace('${DESCRIPTION}', DESCRIPTION) - content = content.replace('${PRODUCT}', PRODUCT) - content = content.replace('${FILENAME}', FILENAME) + content = content.replace('${PRODUCT}', PRODUCT) + content = content.replace('${FILENAME}', FILENAME) content = content.replace('${YEAR}', str(datetime.datetime.now().year)) content = content.replace('${BLOCK}', BLOCK) content = content.replace('${TYPE}', TYPE) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h --- a/OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h Wed Aug 19 14:11:33 2026 +0200 @@ -141,7 +141,7 @@ } const T& GetOldest() const; - + const Payload& GetOldestPayload() const; void GetAllKeys(std::vector& keys) const @@ -168,7 +168,7 @@ #ifndef NDEBUG assert(index_.size() == queue_.size()); - for (typename Index::const_iterator + for (typename Index::const_iterator it = index_.begin(); it != index_.end(); ++it) { assert(it->second != queue_.end()); @@ -205,7 +205,7 @@ assert(it != index_.end()); std::pair item = *(it->second); - + queue_.erase(it->second); queue_.push_front(item); index_[id] = queue_.begin(); @@ -252,7 +252,7 @@ std::pair item = *(it->second); item.second = updatedPayload; - + queue_.erase(it->second); queue_.push_front(item); index_[id] = queue_.begin(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/MemoryCache.cpp --- a/OrthancFramework/Sources/Cache/MemoryCache.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/MemoryCache.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -70,7 +70,7 @@ } MemoryCache::MemoryCache(ICachePageProvider& provider, - size_t cacheSize) : + size_t cacheSize) : provider_(provider), cacheSize_(cacheSize) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/MemoryObjectCache.cpp --- a/OrthancFramework/Sources/Cache/MemoryObjectCache.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/MemoryObjectCache.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -76,7 +76,7 @@ while (currentSize_ > targetSize) { assert(!content_.IsEmpty()); - + Item* item = NULL; content_.RemoveOldest(item); @@ -90,7 +90,7 @@ // Post-condition: "currentSize_ <= targetSize" } - + MemoryObjectCache::MemoryObjectCache() : currentSize_(0), @@ -123,7 +123,7 @@ return content_.GetSize(); } - + size_t MemoryObjectCache::GetCurrentSize() { @@ -151,7 +151,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + #if ORTHANC_ENABLE_THREADS == 1 // Make sure no accessor is currently open (as its data may be // removed if recycling is needed) @@ -228,7 +228,7 @@ delete item; content_.Invalidate(key); - + assert(currentSize_ >= size); currentSize_ -= size; } @@ -259,7 +259,7 @@ { cache.content_.MakeMostRecent(key); } - + #if ORTHANC_ENABLE_THREADS == 1 cacheLock_.unlock(); @@ -302,6 +302,6 @@ else { throw OrthancException(ErrorCode_BadSequenceOfCalls); - } + } } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/MemoryObjectCache.h --- a/OrthancFramework/Sources/Cache/MemoryObjectCache.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/MemoryObjectCache.h Wed Aug 19 14:11:33 2026 +0200 @@ -68,7 +68,7 @@ LeastRecentlyUsedIndex content_; void Recycle(size_t targetSize); - + public: MemoryObjectCache(); @@ -95,7 +95,7 @@ WriterLock writerLock_; boost::mutex::scoped_lock cacheLock_; #endif - + Item* item_; public: diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/MemoryStringCache.cpp --- a/OrthancFramework/Sources/Cache/MemoryStringCache.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/MemoryStringCache.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -53,7 +53,7 @@ virtual size_t GetMemoryUsage() const { return content_.size(); - } + } }; @@ -204,7 +204,7 @@ delete item; content_.Invalidate(key); - + assert(currentSize_ >= size); currentSize_ -= size; } @@ -262,7 +262,7 @@ while (currentSize_ > targetSize) { assert(!content_.IsEmpty()); - + StringValue* item = NULL; content_.RemoveOldest(item); @@ -283,7 +283,7 @@ return currentSize_; } - + size_t MemoryStringCache::GetNumberOfItems() const { boost::mutex::scoped_lock cacheLock(cacheMutex_); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/MemoryStringCache.h --- a/OrthancFramework/Sources/Cache/MemoryStringCache.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/MemoryStringCache.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,13 +37,13 @@ /** * Class that caches a dictionary * of strings, using the "fetch/add" paradigm of memcached. - * + * * Starting from 1.12.2, if multiple clients are trying to access * an inexistent item at the same time, only one of them will load it * and the others will wait until the first one has loaded the data. - * + * * The MemoryStringCache is only accessible through an Accessor. - * + * * Note: this class is thread safe **/ class ORTHANC_PUBLIC ORTHANC_DEPRECATED_CLASS(MemoryStringCache) : public boost::noncopyable @@ -87,13 +87,13 @@ ~MemoryStringCache(); size_t GetMaximumSize(); - + void SetMaximumSize(size_t size); void Invalidate(const std::string& key); size_t GetCurrentSize() const; - + size_t GetNumberOfItems() const; private: diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/SharedArchive.cpp --- a/OrthancFramework/Sources/Cache/SharedArchive.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/SharedArchive.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -85,10 +85,10 @@ { return *item_; } - } + } - SharedArchive::SharedArchive(size_t maxSize) : + SharedArchive::SharedArchive(size_t maxSize) : maxSize_(maxSize) { if (maxSize == 0) @@ -134,7 +134,7 @@ WriterLock lock(mutex_); boost::mutex::scoped_lock lruLock(lruMutex_); - RemoveInternal(id); + RemoveInternal(id); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Cache/SharedArchive.h --- a/OrthancFramework/Sources/Cache/SharedArchive.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Cache/SharedArchive.h Wed Aug 19 14:11:33 2026 +0200 @@ -69,7 +69,7 @@ const std::string& id); bool IsValid() const; - + IDynamicObject& GetItem() const; }; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/ChunkedBuffer.cpp --- a/OrthancFramework/Sources/ChunkedBuffer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/ChunkedBuffer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -38,7 +38,7 @@ numBytes_ = 0; pendingPos_ = 0; - for (Chunks::iterator it = chunks_.begin(); + for (Chunks::iterator it = chunks_.begin(); it != chunks_.end(); ++it) { delete *it; @@ -74,7 +74,7 @@ void ChunkedBuffer::FlushPendingBuffer() { assert(pendingPos_ <= pendingBuffer_.size()); - + if (!pendingBuffer_.empty()) { AddChunkInternal(pendingBuffer_.c_str(), pendingPos_); @@ -106,21 +106,21 @@ { return numBytes_ + pendingPos_; } - + void ChunkedBuffer::SetPendingBufferSize(size_t size) { FlushPendingBuffer(); pendingBuffer_.resize(size); } - + size_t ChunkedBuffer::GetPendingBufferSize() const { return pendingBuffer_.size(); } - + void ChunkedBuffer::AddChunk(const void* chunkData, size_t chunkSize) { @@ -128,7 +128,7 @@ { #if 1 assert(sizeof(char) == 1); - + // Optimization if Orthanc >= 1.7.3, to speed up in the presence of many small chunks if (pendingPos_ + chunkSize <= pendingBuffer_.size()) { @@ -178,7 +178,7 @@ AddChunk(&begin[0], s); } } - + void ChunkedBuffer::Flatten(std::string& result) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/ChunkedBuffer.h --- a/OrthancFramework/Sources/ChunkedBuffer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/ChunkedBuffer.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,12 +36,12 @@ { private: typedef std::list Chunks; - + size_t numBytes_; Chunks chunks_; std::string pendingBuffer_; // Buffer to speed up if adding many small chunks size_t pendingPos_; - + void Clear(); void AddChunkInternal(const void* chunkData, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compatibility.h --- a/OrthancFramework/Sources/Compatibility.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compatibility.h Wed Aug 19 14:11:33 2026 +0200 @@ -67,7 +67,7 @@ // We thus use an alternate way of checking for 'override' support #ifdef ORTHANC_OVERRIDE_SUPPORTED # error ORTHANC_OVERRIDE_SUPPORTED cannot be defined at this point -#endif +#endif #if __cplusplus >= 201103L // C++11 # define ORTHANC_OVERRIDE_SUPPORTED 1 @@ -82,7 +82,7 @@ #if ORTHANC_OVERRIDE_SUPPORTED // The override keyword (C++11) is enabled -# define ORTHANC_OVERRIDE override +# define ORTHANC_OVERRIDE override # define ORTHANC_FINAL final # define ORTHANC_NOEXCEPT noexcept #else @@ -109,7 +109,7 @@ // To make this header more robust, we use the _MSVC_LANG equivalent macro. // please note that not all C++11 features are supported when _MSC_VER == 1600 -// (or higher). This header file can be made for fine-grained, if required, +// (or higher). This header file can be made for fine-grained, if required, // based on specific _MSC_VER values # if _MSC_VER >= 1600 // Visual Studio 2010 (10.0) @@ -152,12 +152,12 @@ explicit unique_ptr() : boost::movelib::unique_ptr() { - } + } explicit unique_ptr(T* p) : boost::movelib::unique_ptr(p) { - } + } }; } #else diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/DeflateBaseCompressor.h --- a/OrthancFramework/Sources/Compression/DeflateBaseCompressor.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/DeflateBaseCompressor.h Wed Aug 19 14:11:33 2026 +0200 @@ -53,7 +53,7 @@ DeflateBaseCompressor(); void SetCompressionLevel(uint8_t level); - + void SetPrefixWithUncompressedSize(bool prefix); bool HasPrefixWithUncompressedSize() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/GzipCompressor.cpp --- a/OrthancFramework/Sources/Compression/GzipCompressor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/GzipCompressor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -57,12 +57,12 @@ * which is to look at the last four bytes of the gzip file, which * is the uncompressed length of that entry modulo 2^32 in little * endian order. - * + * * It is unreliable because a) the uncompressed data may be longer * than 2^32 bytes, and b) the gzip file may consist of multiple * gzip streams, in which case you would find the length of only * the last of those streams. - * + * * If you are in control of the source of the gzip files, you know * that they consist of single gzip streams, and you know that * they are less than 2^32 bytes uncompressed, then and only then @@ -81,7 +81,7 @@ return ((static_cast(p[0]) << 0) + (static_cast(p[1]) << 8) + (static_cast(p[2]) << 16) + - (static_cast(p[3]) << 24)); + (static_cast(p[3]) << 24)); } @@ -97,7 +97,7 @@ { uLongf compressedSize = compressBound(static_cast(uncompressedSize)) + 1024 /* security margin */; - + if (compressedSize == 0) { compressedSize = 1; @@ -130,10 +130,10 @@ { throw OrthancException(ErrorCode_NotEnoughMemory); } - + // Initialize the compression engine - int error = deflateInit2(&stream, - GetCompressionLevel(), + int error = deflateInit2(&stream, + GetCompressionLevel(), Z_DEFLATED, MAX_WBITS + 16, // ask for gzip output 8, // default memory level @@ -161,7 +161,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } size_t size = stream.total_out; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/HierarchicalZipWriter.cpp --- a/OrthancFramework/Sources/Compression/HierarchicalZipWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/HierarchicalZipWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -67,7 +67,7 @@ { it->second++; return standardized + "-" + boost::lexical_cast(it->second); - } + } } HierarchicalZipWriter::Index::Index() @@ -123,12 +123,12 @@ writer_.Open(); } - + HierarchicalZipWriter::HierarchicalZipWriter(ZipWriter::IOutputStream* stream, bool isZip64) { writer_.AcquireOutputStream(stream, isZip64); - writer_.Open(); + writer_.Open(); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/HierarchicalZipWriter.h --- a/OrthancFramework/Sources/Compression/HierarchicalZipWriter.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/HierarchicalZipWriter.h Wed Aug 19 14:11:33 2026 +0200 @@ -55,7 +55,7 @@ }; typedef std::list Stack; - + Stack stack_; std::string EnsureUniqueFilename(const std::string& name, @@ -109,9 +109,9 @@ uint8_t GetCompressionLevel() const; void SetAppendToExisting(bool append); - + bool IsAppendToExisting() const; - + void OpenFile(const std::string& name); void OpenDirectory(const std::string& name); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/IBufferCompressor.cpp --- a/OrthancFramework/Sources/Compression/IBufferCompressor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/IBufferCompressor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -32,8 +32,8 @@ IBufferCompressor& compressor, const std::string& uncompressed) { - compressor.Compress(compressed, - uncompressed.size() == 0 ? NULL : uncompressed.c_str(), + compressor.Compress(compressed, + uncompressed.size() == 0 ? NULL : uncompressed.c_str(), uncompressed.size()); } @@ -41,8 +41,8 @@ IBufferCompressor& compressor, const std::string& compressed) { - compressor.Uncompress(uncompressed, - compressed.size() == 0 ? NULL : compressed.c_str(), + compressor.Uncompress(uncompressed, + compressed.size() == 0 ? NULL : compressed.c_str(), compressed.size()); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/ZipReader.cpp --- a/OrthancFramework/Sources/Compression/ZipReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/ZipReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -76,7 +76,7 @@ namespace Orthanc { // ZPOS64_T corresponds to "uint64_t" - + class ZipReader::MemoryBuffer : public boost::noncopyable { private: @@ -92,7 +92,7 @@ pos_(0) { } - + explicit MemoryBuffer(const std::string& s) : content_(s.empty() ? NULL : reinterpret_cast(s.c_str())), size_(s.size()), @@ -120,10 +120,10 @@ { memcpy(target, content_ + pos_, s); } - + pos_ += s; return static_cast(s); - } + } } ZPOS64_T Tell() const @@ -135,7 +135,7 @@ int origin) { SSIZE_T next; - + switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: @@ -249,7 +249,7 @@ (c[2] == 0x07 && c[3] == 0x08))); } } - + bool ZipReader::IsZipMemoryBuffer(const std::string& content) { @@ -295,7 +295,7 @@ { } - + ZipReader::~ZipReader() { if (pimpl_->unzip_ != NULL) @@ -305,13 +305,13 @@ } } - + uint64_t ZipReader::GetFilesCount() const { assert(pimpl_->unzip_ != NULL); - + unz_global_info64_s info; - + if (unzGetGlobalInfo64(pimpl_->unzip_, &info) == 0) { return info.number_entry; @@ -322,10 +322,10 @@ } } - + void ZipReader::SeekFirst() { - assert(pimpl_->unzip_ != NULL); + assert(pimpl_->unzip_ != NULL); pimpl_->done_ = (unzGoToFirstFile(pimpl_->unzip_) != 0); } @@ -439,7 +439,7 @@ if (unzOpenCurrentFile(pimpl_->unzip_) == 0) { bool success = ReadInternal(content, pimpl_->unzip_, info.uncompressed_size); - + if (unzCloseCurrentFile(pimpl_->unzip_) != 0 || !success) { @@ -451,14 +451,14 @@ throw OrthancException(ErrorCode_BadFileFormat, "Invalid file or unsupported compression method (e.g. Deflate64)"); } } - + pimpl_->done_ = (unzGoToNextFile(pimpl_->unzip_) != 0); - + return true; } - } + } - + ZipReader* ZipReader::CreateFromMemory(const void* buffer, size_t size) { @@ -475,7 +475,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + zlib_filefunc64_def funcs; memset(&funcs, 0, sizeof(funcs)); @@ -499,7 +499,7 @@ } } } - + #if ORTHANC_SANDBOXED != 1 ZipReader* ZipReader::CreateFromFile(const boost::filesystem::path& path) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/ZipReader.h --- a/OrthancFramework/Sources/Compression/ZipReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/ZipReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -54,7 +54,7 @@ { private: class MemoryBuffer; - + struct PImpl; boost::shared_ptr pimpl_; @@ -69,7 +69,7 @@ bool ReadNextFile(std::string& filename, std::string& content); - + static ZipReader* CreateFromMemory(const void* buffer, size_t size); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/ZipWriter.cpp --- a/OrthancFramework/Sources/Compression/ZipWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/ZipWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -86,14 +86,14 @@ { } - + void ZipWriter::MemoryStream::Write(const std::string& chunk) { chunked_.AddChunk(chunk); archiveSize_ += chunk.size(); } - - + + uint64_t ZipWriter::MemoryStream::GetArchiveSize() const { return archiveSize_; @@ -104,7 +104,7 @@ { chunked_.Flatten(target_); } - + void ZipWriter::BufferWithSeek::CheckInvariants() const { @@ -113,7 +113,7 @@ flattened_.empty()); assert(currentPosition_ <= GetSize()); - + if (currentPosition_ < GetSize()) { assert(chunks_.GetNumBytes() == 0); @@ -121,7 +121,7 @@ } #endif } - + ZipWriter::BufferWithSeek::BufferWithSeek() : currentPosition_(0) @@ -129,19 +129,19 @@ CheckInvariants(); } - + ZipWriter::BufferWithSeek::~BufferWithSeek() { CheckInvariants(); } - - + + size_t ZipWriter::BufferWithSeek::GetPosition() const { return currentPosition_; } - - + + size_t ZipWriter::BufferWithSeek::GetSize() const { if (flattened_.empty()) @@ -154,7 +154,7 @@ } } - + void ZipWriter::BufferWithSeek::Write(const void* data, size_t size) { @@ -181,7 +181,7 @@ chunks_.AddChunk(flattened_); flattened_.clear(); } - + chunks_.AddChunk(data, size); } @@ -191,7 +191,7 @@ CheckInvariants(); } - + void ZipWriter::BufferWithSeek::Write(const std::string& data) { if (!data.empty()) @@ -200,7 +200,7 @@ } } - + void ZipWriter::BufferWithSeek::Seek(size_t position) { CheckInvariants(); @@ -227,7 +227,7 @@ CheckInvariants(); } - + void ZipWriter::BufferWithSeek::Flush(std::string& target) { @@ -254,7 +254,7 @@ * file being prefixed by its "Local file header". The ZIP archive * ends with the "central directory" structure. * https://en.wikipedia.org/wiki/ZIP_(file_format) - * + * * When writing one file, the minizip implementation first TELLS to * know the current size of the archive, then WRITES the header and * data bytes, then SEEKS backward to update the "local file header" @@ -262,7 +262,7 @@ * CRC-32, compressed size and uncompressed size), and finally SEEKS * to get back at the end of the stream in order to continue adding * files. - * + * * The minizip implementation will *never* SEEK *before* the "local * file header" of the current file. However, the current file must * *not* be immediately sent to the stream as new bytes are written, @@ -273,7 +273,7 @@ * cursor at the end of the archive. In the minizip implementation, * such a SEEK indicates that the current file has been properly * added to the archive. - **/ + **/ class ZipWriter::StreamBuffer : public boost::noncopyable { private: @@ -281,7 +281,7 @@ bool success_; ZPOS64_T startCurrentFile_; BufferWithSeek buffer_; - + public: explicit StreamBuffer(IOutputStream& stream) : stream_(stream), @@ -289,7 +289,7 @@ startCurrentFile_(0) { } - + int Close() { try @@ -300,7 +300,7 @@ buffer_.Flush(s); stream_.Write(s); } - + return 0; } catch (...) @@ -339,7 +339,7 @@ } } } - + long Seek(ZPOS64_T offset, int origin) @@ -362,10 +362,10 @@ startCurrentFile_ = fullSize; } else - { + { buffer_.Seek(offset - startCurrentFile_); } - + return 0; // OK } else @@ -384,7 +384,7 @@ { success_ = false; } - + static int CloseWrapper(voidpf opaque, voidpf stream) @@ -433,7 +433,7 @@ return reinterpret_cast(opaque)->Write(buf, size); } }; - + struct ZipWriter::PImpl : public boost::noncopyable { @@ -507,7 +507,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls, "Cannot append to output streams"); } - + hasFileInZip_ = false; zlib_filefunc64_def funcs; @@ -548,7 +548,7 @@ hasFileInZip_ = false; int mode = APPEND_STATUS_CREATE; - if (append_ && + if (append_ && boost::filesystem::exists(path_)) { mode = APPEND_STATUS_ADDINZIP; @@ -691,7 +691,7 @@ const size_t maxBytesInAStep = std::numeric_limits::max(); const char* p = reinterpret_cast(data); - + while (length > 0) { int bytes = static_cast(length <= maxBytesInAStep ? length : maxBytesInAStep); @@ -702,7 +702,7 @@ throw OrthancException(ErrorCode_CannotWriteFile, "Cannot write data to ZIP archive - error code =" + boost::lexical_cast(result)); // we do not log the path anymore since it can contain PHI } - + p += bytes; length -= bytes; } @@ -724,13 +724,13 @@ { return isZip64_; } - + void ZipWriter::AcquireOutputStream(IOutputStream* stream, bool isZip64) { std::unique_ptr protection(stream); - + if (stream == NULL) { throw OrthancException(ErrorCode_NullPointer); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/ZipWriter.h --- a/OrthancFramework/Sources/Compression/ZipWriter.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/ZipWriter.h Wed Aug 19 14:11:33 2026 +0200 @@ -80,12 +80,12 @@ std::string& target_; ChunkedBuffer chunked_; uint64_t archiveSize_; - + public: explicit MemoryStream(std::string& target); - + virtual void Write(const std::string& chunk) ORTHANC_OVERRIDE; - + virtual void Close() ORTHANC_OVERRIDE; virtual uint64_t GetArchiveSize() const ORTHANC_OVERRIDE; @@ -102,14 +102,14 @@ std::string flattened_; void CheckInvariants() const; - + public: BufferWithSeek(); ~BufferWithSeek(); size_t GetPosition() const; - + size_t GetSize() const; void Write(const void* data, @@ -122,10 +122,10 @@ void Flush(std::string& target); }; - + private: class StreamBuffer; - + struct PImpl; boost::shared_ptr pimpl_; @@ -172,9 +172,9 @@ uint8_t GetCompressionLevel() const; void SetAppendToExisting(bool append); - + bool IsAppendToExisting() const; - + void Open(); void Close(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Compression/ZlibCompressor.cpp --- a/OrthancFramework/Sources/Compression/ZlibCompressor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Compression/ZlibCompressor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -71,7 +71,7 @@ int error = compress2(target, &compressedSize, - const_cast(static_cast(uncompressed)), + const_cast(static_cast(uncompressed)), static_cast(uncompressedSize), GetCompressionLevel()); @@ -86,7 +86,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } // The compression was successful @@ -124,7 +124,7 @@ } uint64_t uncompressedSize = ReadUncompressedSizePrefix(compressed, compressedSize); - + // New in Orthanc 1.9.0: Explicitly use litte-endian encoding in size prefix uncompressedSize = le64toh(uncompressedSize); @@ -139,7 +139,7 @@ uLongf tmp = static_cast(uncompressedSize); int error = uncompress - (reinterpret_cast(&uncompressed[0]), + (reinterpret_cast(&uncompressed[0]), &tmp, reinterpret_cast(compressed) + sizeof(uint64_t), static_cast(compressedSize - sizeof(uint64_t))); @@ -158,7 +158,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DataSource/DataSourceMemoryBudget.cpp --- a/OrthancFramework/Sources/DataSource/DataSourceMemoryBudget.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DataSource/DataSourceMemoryBudget.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -82,7 +82,7 @@ void DataSourceMemoryBudget::SetMetricsConfiguration(const MetricsConfiguration& configuration) { metricsConfiguration_ = configuration; - + boost::mutex::scoped_lock lock(mutex_); metricsConfiguration_.Update(maximumMemory_, currentMemory_, reservations_); } @@ -107,7 +107,7 @@ currentMemory_ += memory; reservations_++; - + metricsConfiguration_.Update(maximumMemory_, currentMemory_, reservations_); } @@ -121,9 +121,9 @@ assert(reservations_ > 0); reservations_--; - + metricsConfiguration_.Update(maximumMemory_, currentMemory_, reservations_); - + cond_.notify_all(); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DataSource/DataSourceReader.cpp --- a/OrthancFramework/Sources/DataSource/DataSourceReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DataSource/DataSourceReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -55,7 +55,7 @@ else if (cacheSizeMegabytesName.empty() || cacheCountName.empty() || cacheHitCountName.empty() || - cacheMissCountName.empty() || + cacheMissCountName.empty() || capacityMaxSizeMegabytesName.empty() || capacityCurrentSizeMegabytesName.empty() || capacityCountName.empty() || @@ -321,7 +321,7 @@ unsigned int currentReservations; GetStatistics(maximumMemory, currentMemory, currentReservations); - + return maximumMemory; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DataSource/DataSourceReader.h --- a/OrthancFramework/Sources/DataSource/DataSourceReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DataSource/DataSourceReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -78,7 +78,7 @@ void IncrementCacheHitCount(); void IncrementCacheMissCount(); - + friend DataSourceReader; }; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomArray.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomArray.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomArray.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -34,8 +34,8 @@ DicomArray::DicomArray(const DicomMap& map) { elements_.reserve(map.content_.size()); - - for (DicomMap::Content::const_iterator it = + + for (DicomMap::Content::const_iterator it = map.content_.begin(); it != map.content_.end(); ++it) { elements_.push_back(new DicomElement(it->first, *it->second)); @@ -78,7 +78,7 @@ { tags.insert(elements_[i]->GetTag()); } - + } void DicomArray::Print(FILE* fp) const diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -187,7 +187,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } - + if (values.HasTag(DICOM_TAG_NUMBER_OF_FRAMES)) { if (!values.ParseUnsignedInteger32(numberOfFrames_, DICOM_TAG_NUMBER_OF_FRAMES)) @@ -400,7 +400,7 @@ return true; } } - + if (ignorePhotometricInterpretation || photometric_ == PhotometricInterpretation_Monochrome1 || photometric_ == PhotometricInterpretation_Monochrome2) @@ -410,7 +410,7 @@ format = PixelFormat_Grayscale8; return true; } - + if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && !IsSigned()) { format = PixelFormat_Grayscale16; @@ -422,7 +422,7 @@ format = PixelFormat_SignedGrayscale16; return true; } - + if (GetBitsAllocated() == 32 && GetChannelCount() == 1 && !IsSigned()) { format = PixelFormat_Grayscale32; @@ -466,7 +466,7 @@ if (bitsStored_ == 1) { assert(GetWidth() % 8 == 0); - + if (GetChannelCount() == 1) { totalFrameSize = static_cast(GetHeight()) * static_cast(GetWidth()) / 8; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomImageInformation.h --- a/OrthancFramework/Sources/DicomFormat/DicomImageInformation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomImageInformation.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ namespace Orthanc { class ORTHANC_PUBLIC DicomImageInformation - { + { private: unsigned int width_; unsigned int height_; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h --- a/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ * This class implements the hashing mechanism that is used to * convert DICOM unique identifiers to Orthanc identifiers. Any * Orthanc identifier for a DICOM resource corresponds to the SHA-1 - * hash of the DICOM identifiers. + * hash of the DICOM identifiers. * \note SHA-1 hash is used because it is less sensitive to * collision attacks than MD5. (pixelData_) + + const uint8_t* pixel = (reinterpret_cast(pixelData_) + y * rowOffset_ + frame_ * frameOffset_); - + if (information_.GetBitsStored() == 1) { // New in Orthanc 1.10.0, notably for DICOM SEG assert(information_.GetBitsAllocated() == 1 && information_.GetChannelCount() == 1 && !information_.IsPlanar()); - + uint8_t b = pixel[x / 8]; if (b & (1 << (x % 8))) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h --- a/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h Wed Aug 19 14:11:33 2026 +0200 @@ -63,7 +63,7 @@ void SetCurrentFrame(unsigned int frame); - void GetExtremeValues(int32_t& min, + void GetExtremeValues(int32_t& min, int32_t& max) const; int32_t GetValue(unsigned int x, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomMap.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -44,7 +44,7 @@ namespace Orthanc { - // WARNING: the DEFAULT list of main dicom tags below are the list as they + // WARNING: the DEFAULT list of main dicom tags below are the list as they // were in Orthanc 1.10 before we introduced the dynamic main dicom tags. // This list has not changed since Orthanc 1.4.2 and had a single change since // Orthanc 0.9.5. @@ -65,7 +65,7 @@ // don't add tags here, check ResetDefaultMainDicomTags instead }; - + static const DicomTag DEFAULT_1_11_STUDY_MAIN_DICOM_TAGS[] = { // { DicomTag(0x0010, 0x1020), "PatientSize" }, @@ -76,7 +76,7 @@ DICOM_TAG_STUDY_DESCRIPTION, DICOM_TAG_ACCESSION_NUMBER, DICOM_TAG_STUDY_INSTANCE_UID, - + // New in db v6 (Orthanc 0.9.5) DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION, DICOM_TAG_INSTITUTION_NAME, @@ -242,7 +242,7 @@ ResourceType level) { std::set& existingLevelTags = GetMainDicomTagsByLevelInternal(level); - + if (existingLevelTags.find(tag) != existingLevelTags.end()) { throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined", false); @@ -251,7 +251,7 @@ if (level == ResourceType_Study) // all patients main dicom tags are also copied at study level { std::set& patientLevelTags = GetMainDicomTagsByLevelInternal(ResourceType_Patient); - + if (patientLevelTags.find(tag) != patientLevelTags.end()) { throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined", false); @@ -275,7 +275,7 @@ void ResetDefaultMainDicomTags() { ReaderWriterLock::WriteLock lock(mutex_); - + patientsMainDicomTagsByLevel_.clear(); studiesMainDicomTagsByLevel_.clear(); seriesMainDicomTagsByLevel_.clear(); @@ -297,7 +297,7 @@ // only add new tags here ! // introduced in v 1.12.5 AddMainDicomTagInternal(DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC, ResourceType_Study); // used in default QIDO-RS queries - + AddMainDicomTagInternal(DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC, ResourceType_Series); // used in default QIDO-RS queries AddMainDicomTagInternal(DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_DATE, ResourceType_Series); // used in default QIDO-RS queries AddMainDicomTagInternal(DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_TIME, ResourceType_Series); // used in default QIDO-RS queries @@ -310,7 +310,7 @@ ResourceType level) { ReaderWriterLock::WriteLock lock(mutex_); - + AddMainDicomTagInternal(tag, level); } @@ -359,8 +359,8 @@ }; - void DicomMap::SetValueInternal(uint16_t group, - uint16_t element, + void DicomMap::SetValueInternal(uint16_t group, + uint16_t element, DicomValue* value) { DicomTag tag(group, element); @@ -570,7 +570,7 @@ } - void DicomMap::Remove(const DicomTag& tag) + void DicomMap::Remove(const DicomTag& tag) { Content::iterator it = content_.find(tag); if (it != content_.end()) @@ -580,7 +580,7 @@ } } - void DicomMap::RemoveTags(const std::set& tags) + void DicomMap::RemoveTags(const std::set& tags) { for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) { @@ -902,7 +902,7 @@ case ValueRepresentation_OtherByte: return true; - + case ValueRepresentation_OtherDouble: return value.size() <= (static_cast(1) << 32) - 8; @@ -1090,7 +1090,7 @@ { return false; } - + uint16_t reserved = ReadLittleEndianUint16(dicom + position + 6); if (reserved != 0) { @@ -1136,7 +1136,7 @@ p[130] == 'C' && p[131] == 'M'); } - + bool DicomMap::ParseDicomMetaInformation(DicomMap& result, const void* dicom, @@ -1212,7 +1212,7 @@ std::string DicomMap::FormatMissingTagsForStore() const { std::string patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid; - + if (HasTag(DICOM_TAG_PATIENT_ID)) { patientId = ValueAsString(*this, DICOM_TAG_PATIENT_ID); @@ -1236,7 +1236,7 @@ return FormatMissingTagsForStore(patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid); } - + std::string DicomMap::FormatMissingTagsForStore(const std::string& patientId, const std::string& studyInstanceUid, const std::string& seriesInstanceUid, @@ -1443,19 +1443,19 @@ } } - + void DicomMap::FromDicomAsJson(const Json::Value& dicomAsJson, bool append, bool parseSequences) { if (dicomAsJson.type() != Json::objectValue) { throw OrthancException(ErrorCode_BadFileFormat); } - + if (!append) { Clear(); } - + Json::Value::Members tags = dicomAsJson.getMemberNames(); for (Json::Value::Members::const_iterator it = tags.begin(); it != tags.end(); ++it) @@ -1536,7 +1536,7 @@ } } } - + void DicomMap::ExtractMainDicomTags(const DicomMap& other) { @@ -1545,7 +1545,7 @@ MergeMainDicomTags(other, ResourceType_Study); MergeMainDicomTags(other, ResourceType_Series); MergeMainDicomTags(other, ResourceType_Instance); - } + } bool DicomMap::HasOnlyMainDicomTags() const @@ -1581,7 +1581,7 @@ for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) { assert(it->second != NULL); - + std::string tag = it->first.Format(); Json::Value value; @@ -1590,7 +1590,7 @@ target[tag] = value; } } - + void DicomMap::Unserialize(const Json::Value& source) { @@ -1606,7 +1606,7 @@ for (size_t i = 0; i < tags.size(); i++) { DicomTag tag(0, 0); - + if (!DicomTag::ParseHexadecimal(tag, tags[i].c_str()) || content_.find(tag) != content_.end()) { @@ -1629,14 +1629,14 @@ static const char* const PHONETIC = "Phonetic"; static const char* const VALUE = "Value"; static const char* const VR = "vr"; - + Clear(); if (source.type() != Json::objectValue) { throw OrthancException(ErrorCode_BadFileFormat); } - + Json::Value::Members tags = source.getMemberNames(); for (size_t i = 0; i < tags.size(); i++) @@ -1677,7 +1677,7 @@ if (value.type() == Json::arrayValue) { bool supported = true; - + std::string s; for (Json::Value::ArrayIndex j = 0; j < value.size() && supported; j++) { @@ -1699,14 +1699,14 @@ } bool hasIdeographic = false; - + if (value[j].isMember(IDEOGRAPHIC) && value[j][IDEOGRAPHIC].type() == Json::stringValue) { s += '=' + value[j][IDEOGRAPHIC].asString(); hasIdeographic = true; } - + if (value[j].isMember(PHONETIC) && value[j][PHONETIC].type() == Json::stringValue) { @@ -1714,7 +1714,7 @@ { s += '='; } - + s += '=' + value[j][PHONETIC].asString(); } } @@ -1725,23 +1725,23 @@ } break; - + case Json::stringValue: s += value[j].asString(); break; - + case Json::intValue: s += boost::lexical_cast(value[j].asInt64()); break; - + case Json::uintValue: s += boost::lexical_cast(value[j].asUInt64()); break; - + case Json::realValue: s += boost::lexical_cast(value[j].asDouble()); break; - + default: break; } @@ -1822,13 +1822,13 @@ { std::set mainDicomTags; DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, level); - + target = Json::objectValue; for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) { assert(it->second != NULL); - + if (!it->second->IsBinary() && !it->second->IsNull()) { @@ -1843,9 +1843,9 @@ #endif } } - } + } } - + ValueRepresentation DicomMap::GuessPixelDataValueRepresentation(DicomTransferSyntax transferSyntax) const { @@ -1860,7 +1860,7 @@ return DicomImageInformation::GuessPixelDataValueRepresentation(transferSyntax, bitsAllocated); } - + void DicomMap::Print(FILE* fp) const { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomMap.h --- a/OrthancFramework/Sources/DicomFormat/DicomMap.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h Wed Aug 19 14:11:33 2026 +0200 @@ -48,8 +48,8 @@ Content content_; // Warning: This takes the ownership of "value" - void SetValueInternal(uint16_t group, - uint16_t element, + void SetValueInternal(uint16_t group, + uint16_t element, DicomValue* value); public: @@ -58,7 +58,7 @@ static void ResetDefaultMainDicomTags(); size_t GetSize() const; - + DicomMap* Clone() const; void Assign(const DicomMap& other); @@ -67,9 +67,9 @@ void SetNullValue(uint16_t group, uint16_t element); - + void SetNullValue(const DicomTag& tag); - + void SetValue(uint16_t group, uint16_t element, const DicomValue& value); @@ -166,7 +166,7 @@ static bool IsDicomFile(const void* dicom, size_t size); - + static bool ParseDicomMetaInformation(DicomMap& result, const void* dicom, size_t size); @@ -190,7 +190,7 @@ const DicomTag& tag) const; bool ParseInteger64(int64_t& result, - const DicomTag& tag) const; + const DicomTag& tag) const; bool ParseUnsignedInteger32(uint32_t& result, const DicomTag& tag) const; @@ -207,7 +207,7 @@ bool ParseDouble(double& result, const DicomTag& tag) const; - void FromDicomAsJson(const Json::Value& dicomAsJson, + void FromDicomAsJson(const Json::Value& dicomAsJson, bool append = false, bool parseSequences = false); @@ -219,7 +219,7 @@ void ExtractMainDicomTags(const DicomMap& other); bool HasOnlyMainDicomTags() const; - + void Serialize(Json::Value& target) const; void Unserialize(const Json::Value& source); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomPath.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomPath.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomPath.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -50,7 +50,7 @@ index_(index) { } - + size_t DicomPath::PrefixItem::GetIndex() const { @@ -64,7 +64,7 @@ } } - + void DicomPath::PrefixItem::SetIndex(size_t index) { isUniversal_ = false; @@ -75,7 +75,7 @@ DicomTag DicomPath::ParseTag(const std::string& token) { DicomTag tag(0,0); - + if (token[0] == '(' && token[token.size() - 1] == ')') { @@ -128,7 +128,7 @@ AddIndexedTagToPrefix(sequence, index); } - + DicomPath::DicomPath(const Orthanc::DicomTag& sequence1, size_t index1, const Orthanc::DicomTag& sequence2, @@ -171,7 +171,7 @@ for (size_t i = 0; i < parentTags.size(); i++) { - prefix_.push_back(PrefixItem::CreateIndexed(parentTags[i], parentIndexes[i])); + prefix_.push_back(PrefixItem::CreateIndexed(parentTags[i], parentIndexes[i])); } } } @@ -188,31 +188,31 @@ { prefix_.push_back(PrefixItem::CreateUniversal(tag)); } - + size_t DicomPath::GetPrefixLength() const { return prefix_.size(); } - + const Orthanc::DicomTag& DicomPath::GetFinalTag() const { return finalTag_; } - + const Orthanc::DicomTag& DicomPath::GetPrefixTag(size_t level) const { return GetLevel(level).GetTag(); } - + bool DicomPath::IsPrefixUniversal(size_t level) const { return GetLevel(level).IsUniversal(); } - + size_t DicomPath::GetPrefixIndex(size_t level) const { @@ -269,7 +269,7 @@ return s + "(" + finalTag_.Format() + ")"; } - + DicomPath DicomPath::Parse(const std::string& s) { std::vector tokens; @@ -299,7 +299,7 @@ if (left.empty()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "Parent path doesn't contain a tag"); - } + } else if (right.empty() || right[right.size() - 1] != ']') { @@ -385,7 +385,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if (prefixTags.size() < pattern.GetPrefixLength()) { return false; @@ -411,5 +411,5 @@ return (prefixTags[pattern.GetPrefixLength()] == pattern.GetFinalTag()); } } - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomPath.h --- a/OrthancFramework/Sources/DicomFormat/DicomPath.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomPath.h Wed Aug 19 14:11:33 2026 +0200 @@ -44,7 +44,7 @@ PrefixItem(DicomTag tag, bool isUniversal, size_t index); - + public: static PrefixItem CreateUniversal(const DicomTag& tag) { @@ -76,9 +76,9 @@ Orthanc::DicomTag finalTag_; static DicomTag ParseTag(const std::string& token); - + const PrefixItem& GetLevel(size_t i) const; - + public: explicit DicomPath(const Orthanc::DicomTag& tag); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -59,7 +59,7 @@ vr == ValueRepresentation_UnlimitedText)); } - + static void NormalizeValue(std::string& inplace, ValueRepresentation vr) { @@ -70,7 +70,7 @@ } } - + static uint16_t ReadUnsignedInteger16(const char* dicom, bool littleEndian) { @@ -198,7 +198,7 @@ while (pos + 8 <= block.size()) { DicomTag tag = ReadTag(p + pos, true); - + ValueRepresentation vr = StringToValueRepresentation(std::string(p + pos + 4, 2), true); if (IsShortExplicitTag(vr)) @@ -217,7 +217,7 @@ if (tag.GetGroup() == 0x0002) { visitor.VisitMetaHeaderTag(tag, vr, value); - } + } if (tag == DICOM_TAG_TRANSFER_SYNTAX_UID) { @@ -230,7 +230,7 @@ throw OrthancException(ErrorCode_NotImplemented, "Unsupported transfer syntax: " + value); } } - + pos += length + 8; } else if (pos + 12 <= block.size()) @@ -240,7 +240,7 @@ { break; } - + uint32_t length = ReadUnsignedInteger32(p + pos + 8, true); if (pos + 12 + static_cast(length) > block.size()) @@ -254,8 +254,8 @@ value.assign(p + pos + 12, length); NormalizeValue(value, vr); visitor.VisitMetaHeaderTag(tag, vr, value); - } - + } + pos += length + 12; } else @@ -279,7 +279,7 @@ reader_.Schedule(8); state_ = State_DatasetTag; } - + void DicomStreamReader::HandleDatasetTag(const std::string& block, const DicomTag& untilTag) @@ -299,7 +299,7 @@ state_ = State_Done; return; } - + if (tag == DICOM_TAG_SEQUENCE_ITEM || tag == DICOM_TAG_SEQUENCE_DELIMITATION_ITEM || tag == DICOM_TAG_SEQUENCE_DELIMITATION_SEQUENCE) @@ -337,7 +337,7 @@ } reader_.Schedule(8); - state_ = State_DatasetTag; + state_ = State_DatasetTag; } else { @@ -348,9 +348,9 @@ { assert(reader_.GetProcessedBytes() >= block.size()); const uint64_t tagOffset = reader_.GetProcessedBytes() - block.size(); - + ValueRepresentation vr = ValueRepresentation_Unknown; - + if (transferSyntax_ == DicomTransferSyntax_LittleEndianImplicit) { if (sequenceDepth_ == 0) @@ -425,9 +425,9 @@ reader_.Schedule(length); state_ = State_DatasetValue; } - } + } - + void DicomStreamReader::HandleDatasetExplicitLength(IVisitor& visitor, const std::string& block) { @@ -442,7 +442,7 @@ state_ = State_Done; } } - + void DicomStreamReader::HandleSequenceExplicitLength(const std::string& block) { @@ -461,7 +461,7 @@ } } - + void DicomStreamReader::HandleSequenceExplicitValue() { if (sequenceDepth_ == 0) @@ -492,7 +492,7 @@ { c = visitor.VisitDatasetTag(danglingTag_, danglingVR_, block, IsLittleEndian(), danglingOffset_); } - + if (!c) { state_ = State_Done; @@ -503,8 +503,8 @@ reader_.Schedule(8); state_ = State_DatasetTag; } - - + + DicomStreamReader::DicomStreamReader(std::istream& stream) : reader_(stream), state_(State_Preamble), @@ -522,7 +522,7 @@ 4 /* actual length of the meta-header */); } - + void DicomStreamReader::Consume(IVisitor& visitor, const DicomTag& untilTag) { @@ -585,7 +585,7 @@ return (state_ == State_Done); } - + uint64_t DicomStreamReader::GetProcessedBytes() const { return reader_.GetProcessedBytes(); @@ -599,7 +599,7 @@ uint64_t pixelDataOffset_; ValueRepresentation pixelDataVR_; DicomTransferSyntax transferSyntax_; - + public: PixelDataVisitor() : hasPixelData_(false), @@ -608,7 +608,7 @@ transferSyntax_(DicomTransferSyntax_LittleEndianImplicit) // Default DICOM transfer syntax { } - + virtual void VisitMetaHeaderTag(const DicomTag& tag, const ValueRepresentation& vr, const std::string& value) ORTHANC_OVERRIDE @@ -619,7 +619,7 @@ { transferSyntax_ = transferSyntax; } - + virtual bool VisitDatasetTag(const DicomTag& tag, const ValueRepresentation& vr, const std::string& value, @@ -701,7 +701,7 @@ } stream.seekg(static_cast(visitor.GetPixelDataOffset()), stream.beg); - + std::string s; s.resize(4); stream.read(&s[0], static_cast(s.size())); @@ -711,9 +711,9 @@ // Byte swapping if reading a file whose transfer syntax is // 1.2.840.10008.1.2.2 (big endian explicit) std::swap(s[0], s[1]); - std::swap(s[2], s[3]); + std::swap(s[2], s[3]); } - + if (stream.gcount() == static_cast(s.size()) && s[0] == char(0xe0) && s[1] == char(0x7f) && @@ -736,7 +736,7 @@ } }; - + bool DicomStreamReader::LookupPixelDataOffset(uint64_t& offset, ValueRepresentation& vr, const std::string& dicom) @@ -744,7 +744,7 @@ std::stringstream stream(dicom); return PixelDataVisitor::LookupPixelDataOffset(offset, vr, stream); } - + bool DicomStreamReader::LookupPixelDataOffset(uint64_t& offset, ValueRepresentation& vr, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomStreamReader.h --- a/OrthancFramework/Sources/DicomFormat/DicomStreamReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomStreamReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -63,10 +63,10 @@ bool isLittleEndian, uint64_t fileOffset) = 0; }; - + private: class PixelDataVisitor; - + enum State { State_Preamble, @@ -86,12 +86,12 @@ ValueRepresentation danglingVR_; uint64_t danglingOffset_; unsigned int sequenceDepth_; - + bool IsLittleEndian() const; - + void HandlePreamble(const IVisitor& visitor, const std::string& block); - + void HandleMetaHeader(IVisitor& visitor, const std::string& block); @@ -99,17 +99,17 @@ const DicomTag& untilTag); void HandleDatasetExplicitLength(uint32_t length); - + void HandleDatasetExplicitLength(IVisitor& visitor, const std::string& block); void HandleSequenceExplicitLength(const std::string& block); void HandleSequenceExplicitValue(); - + void HandleDatasetValue(IVisitor& visitor, const std::string& block); - + public: explicit DicomStreamReader(std::istream& stream); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomTag.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomTag.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomTag.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -33,7 +33,7 @@ #include namespace Orthanc -{ +{ static inline uint16_t GetCharValue(char c) { if (c >= '0' && c <= '9') @@ -49,9 +49,9 @@ static inline uint16_t GetTagValue(const char* c) { - return ((GetCharValue(c[0]) << 12) + - (GetCharValue(c[1]) << 8) + - (GetCharValue(c[2]) << 4) + + return ((GetCharValue(c[0]) << 12) + + (GetCharValue(c[1]) << 8) + + (GetCharValue(c[2]) << 4) + GetCharValue(c[3])); } @@ -160,7 +160,7 @@ isxdigit(value[5]) && isxdigit(value[6]) && isxdigit(value[7]) && - isxdigit(value[8])) + isxdigit(value[8])) { uint16_t group = GetTagValue(value); uint16_t element = GetTagValue(value + 5); @@ -175,7 +175,7 @@ isxdigit(value[4]) && isxdigit(value[5]) && isxdigit(value[6]) && - isxdigit(value[7])) + isxdigit(value[7])) { uint16_t group = GetTagValue(value); uint16_t element = GetTagValue(value + 4); @@ -249,59 +249,59 @@ case DicomModule_Series: // This is Table C.7-5 "General Series Module Attributes" (p. 385) - target.insert(DicomTag(0x0008, 0x0060)); // Modality - target.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID - target.insert(DicomTag(0x0020, 0x0011)); // Series Number - target.insert(DicomTag(0x0020, 0x0060)); // Laterality - target.insert(DicomTag(0x0008, 0x0021)); // Series Date - target.insert(DicomTag(0x0008, 0x0031)); // Series Time - target.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians’ Name - target.insert(DicomTag(0x0008, 0x1052)); // Performing Physician Identification Sequence + target.insert(DicomTag(0x0008, 0x0060)); // Modality + target.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID + target.insert(DicomTag(0x0020, 0x0011)); // Series Number + target.insert(DicomTag(0x0020, 0x0060)); // Laterality + target.insert(DicomTag(0x0008, 0x0021)); // Series Date + target.insert(DicomTag(0x0008, 0x0031)); // Series Time + target.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians’ Name + target.insert(DicomTag(0x0008, 0x1052)); // Performing Physician Identification Sequence target.insert(DicomTag(0x0018, 0x1030)); // Protocol Name - target.insert(DicomTag(0x0008, 0x103e)); // Series Description - target.insert(DicomTag(0x0008, 0x103f)); // Series Description Code Sequence - target.insert(DicomTag(0x0008, 0x1070)); // Operators' Name - target.insert(DicomTag(0x0008, 0x1072)); // Operator Identification Sequence + target.insert(DicomTag(0x0008, 0x103e)); // Series Description + target.insert(DicomTag(0x0008, 0x103f)); // Series Description Code Sequence + target.insert(DicomTag(0x0008, 0x1070)); // Operators' Name + target.insert(DicomTag(0x0008, 0x1072)); // Operator Identification Sequence target.insert(DicomTag(0x0008, 0x1111)); // Referenced Performed Procedure Step Sequence target.insert(DicomTag(0x0008, 0x1250)); // Related Series Sequence target.insert(DicomTag(0x0018, 0x0015)); // Body Part Examined target.insert(DicomTag(0x0018, 0x5100)); // Patient Position - target.insert(DicomTag(0x0028, 0x0108)); // Smallest Pixel Value in Series - target.insert(DicomTag(0x0029, 0x0109)); // Largest Pixel Value in Series - target.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence + target.insert(DicomTag(0x0028, 0x0108)); // Smallest Pixel Value in Series + target.insert(DicomTag(0x0029, 0x0109)); // Largest Pixel Value in Series + target.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence target.insert(DicomTag(0x0010, 0x2210)); // Anatomical Orientation Type // Table 10-16 PERFORMED PROCEDURE STEP SUMMARY MACRO ATTRIBUTES - target.insert(DicomTag(0x0040, 0x0253)); // Performed Procedure Step ID - target.insert(DicomTag(0x0040, 0x0244)); // Performed Procedure Step Start Date - target.insert(DicomTag(0x0040, 0x0245)); // Performed Procedure Step Start Time - target.insert(DicomTag(0x0040, 0x0254)); // Performed Procedure Step Description - target.insert(DicomTag(0x0040, 0x0260)); // Performed Protocol Code Sequence + target.insert(DicomTag(0x0040, 0x0253)); // Performed Procedure Step ID + target.insert(DicomTag(0x0040, 0x0244)); // Performed Procedure Step Start Date + target.insert(DicomTag(0x0040, 0x0245)); // Performed Procedure Step Start Time + target.insert(DicomTag(0x0040, 0x0254)); // Performed Procedure Step Description + target.insert(DicomTag(0x0040, 0x0260)); // Performed Protocol Code Sequence target.insert(DicomTag(0x0040, 0x0280)); // Comments on the Performed Procedure Step break; case DicomModule_Instance: // This is Table C.12-1 "SOP Common Module Attributes" (p. 1207) target.insert(DicomTag(0x0008, 0x0016)); // SOP Class UID - target.insert(DicomTag(0x0008, 0x0018)); // SOP Instance UID - target.insert(DicomTag(0x0008, 0x0005)); // Specific Character Set - target.insert(DicomTag(0x0008, 0x0012)); // Instance Creation Date - target.insert(DicomTag(0x0008, 0x0013)); // Instance Creation Time - target.insert(DicomTag(0x0008, 0x0014)); // Instance Creator UID - target.insert(DicomTag(0x0008, 0x001a)); // Related General SOP Class UID - target.insert(DicomTag(0x0008, 0x001b)); // Original Specialized SOP Class UID - target.insert(DicomTag(0x0008, 0x0110)); // Coding Scheme Identification Sequence - target.insert(DicomTag(0x0008, 0x0201)); // Timezone Offset From UTC + target.insert(DicomTag(0x0008, 0x0018)); // SOP Instance UID + target.insert(DicomTag(0x0008, 0x0005)); // Specific Character Set + target.insert(DicomTag(0x0008, 0x0012)); // Instance Creation Date + target.insert(DicomTag(0x0008, 0x0013)); // Instance Creation Time + target.insert(DicomTag(0x0008, 0x0014)); // Instance Creator UID + target.insert(DicomTag(0x0008, 0x001a)); // Related General SOP Class UID + target.insert(DicomTag(0x0008, 0x001b)); // Original Specialized SOP Class UID + target.insert(DicomTag(0x0008, 0x0110)); // Coding Scheme Identification Sequence + target.insert(DicomTag(0x0008, 0x0201)); // Timezone Offset From UTC target.insert(DicomTag(0x0018, 0xa001)); // Contributing Equipment Sequence - target.insert(DicomTag(0x0020, 0x0013)); // Instance Number - target.insert(DicomTag(0x0100, 0x0410)); // SOP Instance Status - target.insert(DicomTag(0x0100, 0x0420)); // SOP Authorization DateTime - target.insert(DicomTag(0x0100, 0x0424)); // SOP Authorization Comment + target.insert(DicomTag(0x0020, 0x0013)); // Instance Number + target.insert(DicomTag(0x0100, 0x0410)); // SOP Instance Status + target.insert(DicomTag(0x0100, 0x0420)); // SOP Authorization DateTime + target.insert(DicomTag(0x0100, 0x0424)); // SOP Authorization Comment target.insert(DicomTag(0x0100, 0x0426)); // Authorization Equipment Certification Number target.insert(DicomTag(0x0400, 0x0500)); // Encrypted Attributes Sequence - target.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence + target.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence target.insert(DicomTag(0x0040, 0xa390)); // HL7 Structured Document Reference Sequence - target.insert(DicomTag(0x0028, 0x0303)); // Longitudinal Temporal Information Modified + target.insert(DicomTag(0x0028, 0x0303)); // Longitudinal Temporal Information Modified // Table C.12-6 "DIGITAL SIGNATURES MACRO ATTRIBUTES" (p. 1216) target.insert(DicomTag(0x4ffe, 0x0001)); // MAC Parameters sequence diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomTag.h --- a/OrthancFramework/Sources/DicomFormat/DicomTag.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomTag.h Wed Aug 19 14:11:33 2026 +0200 @@ -35,7 +35,7 @@ { class ORTHANC_PUBLIC DicomTag { - // This must stay a POD (plain old data structure) + // This must stay a POD (plain old data structure) private: uint16_t group_; @@ -108,7 +108,7 @@ static const DicomTag DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID(0x0002, 0x0003); static const DicomTag DICOM_TAG_PATIENT_IDENTITY_REMOVED(0x0012, 0x0062); static const DicomTag DICOM_TAG_DEIDENTIFICATION_METHOD(0x0012, 0x0063); - + // DICOM tags used for fMRI (thanks to Will Ryder) static const DicomTag DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS(0x0020, 0x0105); static const DicomTag DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER(0x0020, 0x0100); @@ -208,16 +208,16 @@ static const DicomTag DICOM_TAG_BLUE_PALETTE_COLOR_LOOKUP_TABLE_DESCRIPTOR(0x0028, 0x1103); static const DicomTag DICOM_TAG_CONTOUR_DATA(0x3006, 0x0050); static const DicomTag DICOM_TAG_CINE_RATE(0x0018, 0x0040); - + // Counting patients, studies and series // https://www.medicalconnections.co.uk/kb/Counting_Studies_Series_and_Instances - static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES(0x0020, 0x1200); - static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES(0x0020, 0x1202); - static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES(0x0020, 0x1204); - static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES(0x0020, 0x1206); - static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES(0x0020, 0x1208); - static const DicomTag DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES(0x0020, 0x1209); - static const DicomTag DICOM_TAG_SOP_CLASSES_IN_STUDY(0x0008, 0x0062); + static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES(0x0020, 0x1200); + static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES(0x0020, 0x1202); + static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES(0x0020, 0x1204); + static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES(0x0020, 0x1206); + static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES(0x0020, 0x1208); + static const DicomTag DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES(0x0020, 0x1209); + static const DicomTag DICOM_TAG_SOP_CLASSES_IN_STUDY(0x0008, 0x0062); // Tags to preserve relationships during anonymization static const DicomTag DICOM_TAG_REFERENCED_IMAGE_SEQUENCE(0x0008, 0x1140); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomValue.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomValue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomValue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -51,8 +51,8 @@ content_(content) { } - - + + DicomValue::DicomValue(const char* data, size_t size, bool isBinary) : @@ -60,7 +60,7 @@ { content_.assign(data, size); } - + DicomValue::DicomValue(const Json::Value& value) : type_(Type_SequenceAsJson), sequenceJson_(value) @@ -70,7 +70,7 @@ throw OrthancException(ErrorCode_BadParameterType); } } - + const std::string& DicomValue::GetContent() const { if (type_ == Type_Null || type_ == Type_SequenceAsJson) @@ -121,7 +121,7 @@ return new DicomValue(*this); } - + #if ORTHANC_ENABLE_BASE64 == 1 void DicomValue::FormatDataUriScheme(std::string& target, const std::string& mime) const @@ -259,12 +259,12 @@ result.assign(content_); return true; } - } + } static const char* KEY_TYPE = "Type"; static const char* KEY_CONTENT = "Content"; - + void DicomValue::Serialize(Json::Value& target) const { target = Json::objectValue; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/DicomValue.h --- a/OrthancFramework/Sources/DicomFormat/DicomValue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomValue.h Wed Aug 19 14:11:33 2026 +0200 @@ -56,16 +56,16 @@ public: DicomValue(); - + DicomValue(const std::string& content, bool isBinary); - + DicomValue(const char* data, size_t size, bool isBinary); - + explicit DicomValue(const Json::Value& value); - + const std::string& GetContent() const; const Json::Value& GetSequenceContent() const; @@ -77,7 +77,7 @@ bool IsString() const; bool IsSequence() const; - + DicomValue* Clone() const; #if ORTHANC_ENABLE_BASE64 == 1 @@ -89,16 +89,16 @@ bool CopyToString(std::string& result, bool allowBinary) const; - + bool ParseInteger32(int32_t& result) const; - bool ParseInteger64(int64_t& result) const; + bool ParseInteger64(int64_t& result) const; bool ParseUnsignedInteger32(uint32_t& result) const; - bool ParseUnsignedInteger64(uint64_t& result) const; + bool ParseUnsignedInteger64(uint64_t& result) const; - bool ParseFloat(float& result) const; + bool ParseFloat(float& result) const; bool ParseDouble(double& result) const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/StreamBlockReader.cpp --- a/OrthancFramework/Sources/DicomFormat/StreamBlockReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/StreamBlockReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -61,7 +61,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - + block.clear(); return true; } @@ -74,10 +74,10 @@ * work properly on non-buffered stream (which is the case in * "DicomStreamReader::LookupPixelDataOffset()" for buffers) **/ - + size_t remainingBytes = std::min(block_.size() - blockPos_, static_cast(std::numeric_limits::max())); // avoid overflowing std::streamsize stream_.read(&block_[blockPos_], static_cast(remainingBytes)); - + std::streamsize r = stream_.gcount(); if (r == 0) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomFormat/StreamBlockReader.h --- a/OrthancFramework/Sources/DicomFormat/StreamBlockReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomFormat/StreamBlockReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -62,7 +62,7 @@ * available from the stream yet: In this case, try again later. **/ bool Read(std::string& block); - + uint64_t GetProcessedBytes() const; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomAssociation.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomAssociation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -79,7 +79,7 @@ } } } - } + } void DicomAssociation::CheckConnecting(const DicomAssociationParameters& parameters, @@ -97,7 +97,7 @@ CLOG(TRACE, DICOM) << "Association Rejected:" << std::endl << ASC_printRejectParameters(str, &rej); } - + CheckCondition(cond, parameters, "connecting"); } catch (OrthancException&) @@ -107,7 +107,7 @@ } } - + void DicomAssociation::CloseInternal() { CLOG(INFO, DICOM) << "Closing DICOM association"; @@ -115,7 +115,7 @@ #if ORTHANC_ENABLE_SSL == 1 tls_.reset(NULL); // Transport layer must be destroyed before the association itself #endif - + if (assoc_ != NULL) { ASC_releaseAssociation(assoc_); @@ -142,7 +142,7 @@ isOpen_ = false; } - + void DicomAssociation::AddAccepted(const std::string& abstractSyntax, DicomTransferSyntax syntax, uint8_t presentationContextId) @@ -154,7 +154,7 @@ std::map syntaxes; syntaxes[syntax] = presentationContextId; accepted_[abstractSyntax] = syntaxes; - } + } else { if (found->second.find(syntax) != found->second.end()) @@ -175,14 +175,14 @@ DicomAssociation::DicomAssociation() { isOpen_ = false; - net_ = NULL; + net_ = NULL; params_ = NULL; assoc_ = NULL; // Must be after "isOpen_ = false" ClearPresentationContexts(); } - + DicomAssociation::~DicomAssociation() { @@ -248,7 +248,7 @@ { dcmConnectionTimeout.set(acseTimeout); } - + assert(net_ == NULL && params_ == NULL && @@ -271,7 +271,7 @@ << " from AET \"" << localAet << "\" to AET \"" << parameters.GetRemoteModality().GetApplicationEntityTitle() << "\" on host " << parameters.GetRemoteModality().GetHost() - << ":" << parameters.GetRemoteModality().GetPortNumber() + << ":" << parameters.GetRemoteModality().GetPortNumber() << " (manufacturer: " << EnumerationToString(parameters.GetRemoteModality().GetManufacturer()) << ", " << (parameters.HasTimeout() ? "timeout: " + boost::lexical_cast(parameters.GetTimeout()) + "s" : @@ -344,10 +344,10 @@ const char* abstractSyntax = proposed_[i].abstractSyntax_.c_str(); const std::list& source = proposed_[i].transferSyntaxes_; - + std::vector transferSyntaxes; transferSyntaxes.reserve(source.size()); - + for (std::list::const_iterator it = source.begin(); it != source.end(); ++it) { @@ -357,8 +357,8 @@ assert(!transferSyntaxes.empty()); CheckConnecting(parameters, ASC_addPresentationContext( params_, presentationContextId, abstractSyntax, - &transferSyntaxes[0], - static_cast(transferSyntaxes.size()), + &transferSyntaxes[0], + static_cast(transferSyntaxes.size()), GetDcmtkRole(proposed_[i].role_))); presentationContextId += 2; @@ -407,7 +407,7 @@ << "\": " << pc->acceptedTransferSyntax; } } - + pc = reinterpret_cast(LST_Next(l)); } } @@ -428,7 +428,7 @@ } } - + bool DicomAssociation::LookupAcceptedPresentationContext(std::map& target, const std::string& abstractSyntax) const { @@ -436,7 +436,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls, "Connection not opened"); } - + AcceptedPresentationContexts::const_iterator found = accepted_.find(abstractSyntax); if (found == accepted_.end()) @@ -459,13 +459,13 @@ ts.push_back(DicomTransferSyntax_BigEndianExplicit); // Retired but was historicaly proposed by Orthanc ProposePresentationContext(abstractSyntax, ts, role); } - + void DicomAssociation::ProposeGenericPresentationContext(const std::string& abstractSyntax) { ProposeGenericPresentationContext(abstractSyntax, DicomAssociationRole_Default); } - + void DicomAssociation::ProposePresentationContext(const std::string& abstractSyntax, DicomTransferSyntax transferSyntax) { @@ -487,7 +487,7 @@ assert(proposed_.size() <= MAX_PROPOSED_PRESENTATIONS); return MAX_PROPOSED_PRESENTATIONS - proposed_.size(); } - + void DicomAssociation::ProposePresentationContext( const std::string& abstractSyntax, const std::list& transferSyntaxes) @@ -506,13 +506,13 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "No transfer syntax provided"); } - + if (proposed_.size() >= MAX_PROPOSED_PRESENTATIONS) { throw OrthancException(ErrorCode_ParameterOutOfRange, "Too many proposed presentation contexts"); } - + if (IsOpen()) { Close(); @@ -526,7 +526,7 @@ proposed_.push_back(context); } - + T_ASC_Association& DicomAssociation::GetDcmtkAssociation() const { if (isOpen_) @@ -570,7 +570,7 @@ return false; } - + T_ASC_Network& DicomAssociation::GetDcmtkNetwork() const { if (isOpen_) @@ -585,7 +585,7 @@ } } - + void DicomAssociation::CheckCondition(const OFCondition& cond, const DicomAssociationParameters& parameters, const std::string& command) @@ -594,7 +594,7 @@ { // Reformat the error message from DCMTK by turning multiline // errors into a single line - + std::string s(cond.text()); std::string info; info.reserve(s.size()); @@ -635,7 +635,7 @@ "\": " + info); } } - + void DicomAssociation::ReportStorageCommitment( const DicomAssociationParameters& parameters, @@ -649,7 +649,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + std::vector successSopClassUids, successSopInstanceUids, failedSopClassUids, failedSopInstanceUids; std::vector failedReasons; @@ -689,7 +689,7 @@ } } } - + DicomAssociation association; { @@ -700,7 +700,7 @@ association.ProposePresentationContext(UID_StorageCommitmentPushModelSOPClass, transferSyntaxes, DicomAssociationRole_Scp); } - + association.Open(parameters); /** @@ -719,10 +719,10 @@ CLOG(INFO, DICOM) << "Reporting modality \"" << parameters.GetRemoteModality().GetApplicationEntityTitle() << "\" about storage commitment transaction: " << transactionUid - << " (" << successSopClassUids.size() << " successes, " + << " (" << successSopClassUids.size() << " successes, " << failedSopClassUids.size() << " failures)"; const DIC_US messageId = association.GetDcmtkAssociation().nextMsgID++; - + { T_DIMSE_Message message; memset(&message, 0, sizeof(message)); @@ -813,7 +813,7 @@ CLOG(TRACE, DICOM) << "Received Storage Commitment Report Response:" << std::endl << DIMSE_dumpMessage(str, message, DIMSE_INCOMING, NULL, presID); } - + const T_DIMSE_N_EventReportRSP& content = message.msg.NEventReportRSP; if (content.MessageIDBeingRespondedTo != messageId || !(content.opts & O_NEVENTREPORT_AFFECTEDSOPCLASSUID) || @@ -839,7 +839,7 @@ association.Close(); } - + void DicomAssociation::RequestStorageCommitment( const DicomAssociationParameters& parameters, const std::string& transactionUid, @@ -874,14 +874,14 @@ std::list transferSyntaxes; transferSyntaxes.push_back(DicomTransferSyntax_LittleEndianExplicit); transferSyntaxes.push_back(DicomTransferSyntax_LittleEndianImplicit); - + // association.SetRole(DicomAssociationRole_Default); association.ProposePresentationContext(UID_StorageCommitmentPushModelSOPClass, transferSyntaxes, DicomAssociationRole_Default); } - + association.Open(parameters); - + /** * N-ACTION * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.2.html @@ -900,7 +900,7 @@ << "\" about storage commitment for " << sopClassUids.size() << " instances, with transaction UID: " << transactionUid; const DIC_US messageId = association.GetDcmtkAssociation().nextMsgID++; - + { T_DIMSE_Message message; memset(&message, 0, sizeof(message)); @@ -923,7 +923,7 @@ std::vector empty; FillSopSequence(dataset, DCM_ReferencedSOPSequence, sopClassUids, sopInstanceUids, empty, false); } - + int presID = ASC_findAcceptedPresentationContextID( &association.GetDcmtkAssociation(), UID_StorageCommitmentPushModelSOPClass); if (presID == 0) @@ -959,7 +959,7 @@ { T_ASC_PresentationContextID presID = 0; T_DIMSE_Message message; - + if (!DIMSE_receiveCommand(&association.GetDcmtkAssociation(), (parameters.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), static_cast(parameters.GetTimeout()), &presID, &message, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomAssociation.h --- a/OrthancFramework/Sources/DicomNetworking/DicomAssociation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociation.h Wed Aug 19 14:11:33 2026 +0200 @@ -55,7 +55,7 @@ // number of odd integers between 1 and 255) // http://dicom.nema.org/medical/dicom/2019e/output/chtml/part08/sect_9.3.2.2.html static const size_t MAX_PROPOSED_PRESENTATIONS = 128; - + struct ProposedPresentationContext { std::string abstractSyntax_; @@ -79,7 +79,7 @@ void CheckConnecting(const DicomAssociationParameters& parameters, const OFCondition& cond); - + void CloseInternal(); void AddAccepted(const std::string& abstractSyntax, @@ -99,7 +99,7 @@ void ClearPresentationContexts(); void Open(const DicomAssociationParameters& parameters); - + void Close(); bool LookupAcceptedPresentationContext( @@ -147,7 +147,7 @@ const std::vector& sopClassUids, const std::vector& sopInstanceUids, const std::vector& failureReasons); - + static void RequestStorageCommitment( const DicomAssociationParameters& parameters, const std::string& transactionUid, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -59,7 +59,7 @@ } } - + uint32_t DicomAssociationParameters::GetDefaultTimeout() { boost::mutex::scoped_lock lock(defaultConfigurationMutex_); @@ -88,7 +88,7 @@ remote_.SetApplicationEntityTitle("ANY-SCP"); } - + DicomAssociationParameters::DicomAssociationParameters(const std::string& localAet, const RemoteModalityParameters& remote) : localAet_(localAet), @@ -202,7 +202,7 @@ "DICOM TLS - No path to the trusted remote certificates was provided"); } } - + void DicomAssociationParameters::SetOwnCertificatePath(const std::string& privateKeyPath, const std::string& certificatePath) { @@ -220,7 +220,7 @@ CheckDicomTlsConfiguration(); return ownPrivateKeyPath_; } - + const std::string& DicomAssociationParameters::GetOwnCertificatePath() const { CheckDicomTlsConfiguration(); @@ -258,7 +258,7 @@ { return minimumTlsVersion_; } - + void DicomAssociationParameters::SetMinimumTlsVersion(unsigned int version) { minimumTlsVersion_ = version; @@ -284,7 +284,7 @@ static const char* const MAXIMUM_PDU_LENGTH = "MaximumPduLength"; // New in Orthanc 1.9.0 static const char* const REMOTE_CERTIFICATE_REQUIRED = "RemoteCertificateRequired"; // New in Orthanc 1.9.3 - + void DicomAssociationParameters::SerializeJob(Json::Value& target) const { if (target.type() != Json::objectValue) @@ -308,7 +308,7 @@ { target[OWN_PRIVATE_KEY] = ownPrivateKeyPath_; } - + if (ownCertificatePath_.empty()) { target.removeMember(OWN_CERTIFICATE); @@ -317,7 +317,7 @@ { target[OWN_CERTIFICATE] = ownCertificatePath_; } - + if (trustedCertificatesPath_.empty()) { target.removeMember(TRUSTED_CERTIFICATES); @@ -383,7 +383,7 @@ { result.remoteCertificateRequired_ = SerializationToolbox::ReadBoolean(serialized, REMOTE_CERTIFICATE_REQUIRED); } - + return result; } else @@ -391,11 +391,11 @@ throw OrthancException(ErrorCode_BadFileFormat); } } - + void DicomAssociationParameters::SetDefaultTimeout(uint32_t seconds) { - CLOG(INFO, DICOM) << "Default timeout for DICOM connections if Orthanc acts as SCU (client): " + CLOG(INFO, DICOM) << "Default timeout for DICOM connections if Orthanc acts as SCU (client): " << seconds << " seconds (0 = no timeout)"; { @@ -411,20 +411,20 @@ if (!privateKeyPath.empty() && !certificatePath.empty()) { - CLOG(INFO, DICOM) << "Setting the default TLS certificate for DICOM SCU connections: " + CLOG(INFO, DICOM) << "Setting the default TLS certificate for DICOM SCU connections: " << privateKeyPath << " (key), " << certificatePath << " (certificate)"; if (certificatePath.empty()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "No path to the default DICOM TLS certificate was provided"); } - + if (privateKeyPath.empty()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "No path to the private key for the default DICOM TLS certificate was provided"); } - + if (!SystemToolbox::IsRegularFile(privateKeyPath)) { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + privateKeyPath); @@ -434,7 +434,7 @@ { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + certificatePath); } - + { boost::mutex::scoped_lock lock(defaultConfigurationMutex_); defaultOwnPrivateKeyPath_ = privateKeyPath; @@ -447,9 +447,9 @@ defaultOwnPrivateKeyPath_.clear(); defaultOwnCertificatePath_.clear(); } - } + } - + void DicomAssociationParameters::SetDefaultTrustedCertificatesPath(const std::string& path) { if (!path.empty()) @@ -460,7 +460,7 @@ { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + path); } - + { boost::mutex::scoped_lock lock(defaultConfigurationMutex_); defaultTrustedCertificatesPath_ = path; @@ -513,7 +513,7 @@ boost::mutex::scoped_lock lock(defaultConfigurationMutex_); defaultRemoteCertificateRequired_ = required; } - + bool DicomAssociationParameters::GetDefaultRemoteCertificateRequired() { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h --- a/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h Wed Aug 19 14:11:33 2026 +0200 @@ -47,15 +47,15 @@ static void CheckHost(const std::string& host); void SetDefaultParameters(); - + void CheckDicomTlsConfiguration() const; public: DicomAssociationParameters(); - + DicomAssociationParameters(const std::string& localAet, const RemoteModalityParameters& remote); - + const std::string& GetLocalApplicationEntityTitle() const; void SetLocalApplicationEntityTitle(const std::string& aet); @@ -63,7 +63,7 @@ const RemoteModalityParameters& GetRemoteModality() const; void SetRemoteModality(const RemoteModalityParameters& parameters); - + void SetRemoteApplicationEntityTitle(const std::string& aet); void SetRemoteHost(const std::string& host); @@ -93,7 +93,7 @@ void SetTrustedCertificatesPath(const std::string& path); const std::string& GetOwnPrivateKeyPath() const; - + const std::string& GetOwnCertificatePath() const; const std::string& GetTrustedCertificatesPath() const; @@ -101,7 +101,7 @@ unsigned int GetMaximumPduLength() const; void SetMaximumPduLength(unsigned int pdu); - + void SetRemoteCertificateRequired(bool required); bool IsRemoteCertificateRequired() const; @@ -109,7 +109,7 @@ void SerializeJob(Json::Value& target) const; static DicomAssociationParameters UnserializeJob(const Json::Value& serialized); - + static void SetDefaultTimeout(uint32_t seconds); static uint32_t GetDefaultTimeout(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -93,14 +93,14 @@ CLOG(TRACE, DICOM) << "Received Find Response " << responseCount << ":" << std::endl << DIMSE_dumpMessage(str, *response, DIMSE_INCOMING); } - + if (responseIdentifiers != NULL) { std::stringstream s; // DcmObject::PrintHelper cannot be used with VS2008 responseIdentifiers->print(s); CLOG(TRACE, DICOM) << "Response Identifiers " << responseCount << ":" << std::endl << s.str(); } - + if (responseIdentifiers != NULL) { FindPayload& payload = *reinterpret_cast(callbackData); @@ -115,7 +115,7 @@ DicomMap m; std::set ignoreTagLength; FromDcmtkBridge::ExtractDicomSummary(m, *responseIdentifiers, 0 /* don't truncate tags */, ignoreTagLength); - + if (!m.HasTag(DICOM_TAG_QUERY_RETRIEVE_LEVEL)) { m.SetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL, payload.level, false); @@ -228,7 +228,7 @@ { const DicomValue* value = fix->TestAndGetValue(*it); - if (value != NULL && + if (value != NULL && !value->IsNull() && value->GetContent() == "*") { @@ -309,7 +309,7 @@ } } } - + void DicomControlUserConnection::FindInternal(DicomFindAnswers& answers, DcmDataset* dataset, @@ -370,7 +370,7 @@ /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ static_cast(parameters_.GetTimeout()), &response, &statusDetail); - + if (statusDetail) { delete statusDetail; @@ -384,15 +384,15 @@ << DIMSE_dumpMessage(str, response, DIMSE_INCOMING); } - + /** * New in Orthanc 1.6.0: Deal with failures during C-FIND. * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.html#table_C.4-1 **/ - + if (response.DimseStatus != 0x0000 && // Success - response.DimseStatus != 0xFF00 && // Pending - Matches are continuing - response.DimseStatus != 0xFF01) // Pending - Matches are continuing + response.DimseStatus != 0xFF00 && // Pending - Matches are continuing + response.DimseStatus != 0xFF01) // Pending - Matches are continuing { if (response.DimseStatus == STATUS_FIND_Failed_UnableToProcess) { @@ -416,7 +416,7 @@ void MoveProgressCallback(void *callbackData, T_DIMSE_C_MoveRQ *request, - int responseCount, + int responseCount, T_DIMSE_C_MoveRSP *response) { DicomControlUserConnection::IProgressListener* listener = reinterpret_cast(callbackData); @@ -433,7 +433,7 @@ } } - + void DicomControlUserConnection::MoveInternal(const std::string& targetAet, ResourceType level, const DicomMap& fields, @@ -467,7 +467,7 @@ { request.MessageID = messageId; } - + strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN); request.Priority = DIMSE_PRIORITY_MEDIUM; request.DataSetType = DIMSE_DATASET_PRESENT; @@ -478,12 +478,12 @@ CLOG(TRACE, DICOM) << "Sending Move Request:" << std::endl << DIMSE_dumpMessage(str, request, DIMSE_OUTGOING, NULL, presID); } - + T_DIMSE_C_MoveRSP response; DcmDataset* statusDetail = NULL; DcmDataset* responseIdentifiers = NULL; OFCondition cond = DIMSE_moveUser( - &association_->GetDcmtkAssociation(), presID, &request, dataset, + &association_->GetDcmtkAssociation(), presID, &request, dataset, (progressListener_ != NULL ? MoveProgressCallback : NULL), progressListener_, /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ static_cast(parameters_.GetTimeout()), @@ -515,12 +515,12 @@ response.NumberOfWarningSubOperations); } } - + /** * New in Orthanc 1.6.0: Deal with failures during C-MOVE. * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.2.html#table_C.4-2 **/ - + if (response.DimseStatus != STATUS_MOVE_Success_SubOperationsCompleteNoFailures && response.DimseStatus != STATUS_MOVE_Pending_SubOperationsAreContinuing) { @@ -543,7 +543,7 @@ } } } - + void DicomControlUserConnection::Get(const DicomMap& getQuery, CGetInstanceReceivedCallback instanceReceivedCallback, @@ -602,11 +602,11 @@ CLOG(TRACE, DICOM) << "Sending Get Request:" << std::endl << DIMSE_dumpMessage(str, *request, DIMSE_OUTGOING, NULL, cgetPresID); } - + OFCondition cond = DIMSE_sendMessageUsingMemoryData( &(association_->GetDcmtkAssociation()), cgetPresID, &msgGetRequest, NULL /* statusDetail */, queryDataset, NULL, NULL, NULL /* commandSet */); - + if (cond.bad()) { OFString tempStr; @@ -738,8 +738,8 @@ storeRsp.AffectedSOPInstanceUID, storeRequest->AffectedSOPInstanceUID, sizeof(storeRsp.AffectedSOPInstanceUID)); storeRsp.opts = O_STORE_AFFECTEDSOPCLASSUID | O_STORE_AFFECTEDSOPINSTANCEUID; - result = DIMSE_sendMessageUsingMemoryData(&(association_->GetDcmtkAssociation()), - cmdPresId, + result = DIMSE_sendMessageUsingMemoryData(&(association_->GetDcmtkAssociation()), + cmdPresId, &storeResponse, NULL /* statusDetail */, NULL /* dataObject */, NULL, NULL, NULL /* commandSet */); if (result.bad()) @@ -761,7 +761,7 @@ CLOG(WARNING, DICOM) << "Expected C-GET response or C-STORE request but received DIMSE command 0x" << std::hex << std::setfill('0') << std::setw(4) << static_cast(rsp.CommandField); - + throw OrthancException(ErrorCode_NetworkProtocol, "C-GET SCU to AET \"" + parameters_.GetRemoteModality().GetApplicationEntityTitle() + "\": Expected C-GET response or C-STORE request but received DIMSE command " + DimseToHexString(rsp.CommandField)); @@ -783,8 +783,8 @@ SetupPresentationContexts(scuOperation, emptyStorageSopClasses, emptyStorageTransferSyntaxes); } - - DicomControlUserConnection::DicomControlUserConnection(const DicomAssociationParameters& params, + + DicomControlUserConnection::DicomControlUserConnection(const DicomAssociationParameters& params, ScuOperationFlags scuOperation, const std::set& acceptedStorageSopClasses, const std::list& proposedStorageTransferSyntaxes) : @@ -794,7 +794,7 @@ { SetupPresentationContexts(scuOperation, acceptedStorageSopClasses, proposedStorageTransferSyntaxes); } - + void DicomControlUserConnection::Close() { @@ -811,12 +811,12 @@ DIC_US status; DicomAssociation::CheckCondition( DIMSE_echoUser(&association_->GetDcmtkAssociation(), - association_->GetDcmtkAssociation().nextMsgID++, + association_->GetDcmtkAssociation().nextMsgID++, /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ static_cast(parameters_.GetTimeout()), &status, NULL), parameters_, "C-ECHO"); - + return status == STATUS_Success; } @@ -839,7 +839,7 @@ query.reset(new ParsedDicomFile(originalFields, GetDefaultDicomEncoding(), false /* be strict */)); } - + DcmDataset* dataset = query->GetDcmtkObject().getDataset(); assert(dataset != NULL); @@ -879,8 +879,8 @@ else { universal = ""; - } - + } + // Add the expected tags for this query level. // WARNING: Do not reorder or add "break" in this switch-case! @@ -914,7 +914,7 @@ { DU_putStringDOElement(dataset, DCM_PatientID, universal); } - + break; default: @@ -924,7 +924,7 @@ assert(clevel != NULL && sopClass != NULL); FindInternal(result, dataset, sopClass, false, clevel); } - + void DicomControlUserConnection::Move(const std::string& targetAet, ResourceType level, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h --- a/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,7 +37,7 @@ namespace Orthanc { class DicomAssociation; // Forward declaration for PImpl design pattern - + typedef uint16_t (*CGetInstanceReceivedCallback) (void *callbackContext, DcmDataset& dataset, const std::string& remoteAet, @@ -87,17 +87,17 @@ const char* sopClass, bool isWorklist, const char* level); - + void MoveInternal(const std::string& targetAet, ResourceType level, const DicomMap& fields, uint16_t messageId); - + public: explicit DicomControlUserConnection(const DicomAssociationParameters& params, ScuOperationFlags scuOperation); // specific constructor for CGet SCU - explicit DicomControlUserConnection(const DicomAssociationParameters& params, + explicit DicomControlUserConnection(const DicomAssociationParameters& params, ScuOperationFlags scuOperation, const std::set& acceptedStorageSopClasses, const std::list& proposedStorageTransferSyntaxes); @@ -129,11 +129,11 @@ ResourceType level, const DicomMap& moveQuery, uint16_t messageId = 0); - + void Move(const std::string& targetAet, const DicomMap& moveQuery, uint16_t messageId = 0); - + void FindWorklist(DicomFindAnswers& result, ParsedDicomFile& query); }; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -53,7 +53,7 @@ } - DicomFindAnswers::DicomFindAnswers(bool isWorklist) : + DicomFindAnswers::DicomFindAnswers(bool isWorklist) : encoding_(GetDefaultDicomEncoding()), isWorklist_(isWorklist), complete_(true) @@ -192,7 +192,7 @@ target->insert(dynamic_cast(element->clone())); } } - + return target.release(); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomServer.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomServer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomServer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -139,7 +139,7 @@ void DicomServer::SetAssociationTimeout(uint32_t seconds) { - CLOG(INFO, DICOM) << "Setting timeout for DICOM connections if Orthanc acts as SCP (server): " + CLOG(INFO, DICOM) << "Setting timeout for DICOM connections if Orthanc acts as SCP (server): " << seconds << " seconds (0 = no timeout)"; Stop(); @@ -201,7 +201,7 @@ Stop(); modalities_ = &modalities; } - + DicomServer::IRemoteModalities& DicomServer::GetRemoteModalities() const { if (modalities_ == NULL) @@ -213,7 +213,7 @@ return *modalities_; } } - + void DicomServer::SetFindRequestHandlerFactory(IFindRequestHandlerFactory& factory) { Stop(); @@ -393,7 +393,7 @@ "DICOM TLS is enabled in Orthanc SCP, but no certificate was provided"); } } - + Stop(); /* initialize network, i.e. create an instance of T_ASC_Network*. */ @@ -484,7 +484,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - + if (!HasCalledApplicationEntityTitleCheck()) { // OK, no check on the AET. @@ -502,7 +502,7 @@ Stop(); useDicomTls_ = enabled; } - + bool DicomServer::IsDicomTlsEnabled() const { return useDicomTls_; @@ -528,20 +528,20 @@ if (!privateKeyPath.empty() && !certificatePath.empty()) { - CLOG(INFO, DICOM) << "Setting the TLS certificate for DICOM SCP connections: " + CLOG(INFO, DICOM) << "Setting the TLS certificate for DICOM SCP connections: " << privateKeyPath << " (key), " << certificatePath << " (certificate)"; if (certificatePath.empty()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "No path to the default DICOM TLS certificate was provided"); } - + if (privateKeyPath.empty()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "No path to the private key for the default DICOM TLS certificate was provided"); } - + if (!SystemToolbox::IsRegularFile(SystemToolbox::PathFromUtf8(privateKeyPath))) { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + privateKeyPath); @@ -551,7 +551,7 @@ { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + certificatePath); } - + ownPrivateKeyPath_ = privateKeyPath; ownCertificatePath_ = certificatePath; } @@ -561,17 +561,17 @@ ownCertificatePath_.clear(); } } - + const std::string& DicomServer::GetOwnPrivateKeyPath() const { return ownPrivateKeyPath_; } - + const std::string& DicomServer::GetOwnCertificatePath() const { return ownCertificatePath_; } - + void DicomServer::SetTrustedCertificatesPath(const std::string& path) { Stop(); @@ -584,7 +584,7 @@ { throw OrthancException(ErrorCode_InexistentFile, "Inexistent file: " + path); } - + trustedCertificatesPath_ = path; } else @@ -592,7 +592,7 @@ trustedCertificatesPath_.clear(); } } - + const std::string& DicomServer::GetTrustedCertificatesPath() const { return trustedCertificatesPath_; @@ -616,7 +616,7 @@ Stop(); remoteCertificateRequired_ = required; } - + bool DicomServer::IsRemoteCertificateRequired() const { return remoteCertificateRequired_; @@ -628,7 +628,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + Stop(); threadsCount_ = threads; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomServer.h --- a/OrthancFramework/Sources/DicomNetworking/DicomServer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomServer.h Wed Aug 19 14:11:33 2026 +0200 @@ -59,14 +59,14 @@ virtual ~IRemoteModalities() { } - + virtual bool IsSameAETitle(const std::string& aet1, const std::string& aet2) = 0; virtual bool LookupAETitle(RemoteModalityParameters& modality, const std::string& aet) = 0; }; - + private: struct PImpl; boost::shared_ptr pimpl_; @@ -123,7 +123,7 @@ void SetRemoteModalities(IRemoteModalities& modalities); IRemoteModalities& GetRemoteModalities() const; - + void SetFindRequestHandlerFactory(IFindRequestHandlerFactory& handler); bool HasFindRequestHandlerFactory() const; IFindRequestHandlerFactory& GetFindRequestHandlerFactory() const; @@ -153,7 +153,7 @@ IApplicationEntityFilter& GetApplicationEntityFilter() const; void Start(); - + void Stop(); bool IsMyAETitle(const std::string& aet) const; @@ -166,9 +166,9 @@ void SetOwnCertificatePath(const std::string& privateKeyPath, const std::string& certificatePath); - const std::string& GetOwnPrivateKeyPath() const; + const std::string& GetOwnPrivateKeyPath() const; const std::string& GetOwnCertificatePath() const; - + void SetTrustedCertificatesPath(const std::string& path); const std::string& GetTrustedCertificatesPath() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -236,7 +236,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + OFString a, b; if (!dicom.getDataset()->findAndGetOFString(DCM_SOPClassUID, a).good() || !dicom.getDataset()->findAndGetOFString(DCM_SOPInstanceUID, b).good()) @@ -255,7 +255,7 @@ "Unknown transfer syntax from DCMTK"); } } - + bool DicomStoreUserConnection::NegotiatePresentationContext( uint8_t& presentationContextId, @@ -303,7 +303,7 @@ proposedOriginalClasses_.clear(); RegisterStorageClass(sopClassUid, transferSyntax); // (*) - + /** * Step 2: Propose at least the mandatory SOP class. **/ @@ -327,12 +327,12 @@ } } - + /** * Step 3: Propose all the previously spotted SOP classes, as * registered through the "RegisterStorageClass()" method. **/ - + for (RegisteredClasses::const_iterator it = registeredClasses_.begin(); it != registeredClasses_.end(); ++it) { @@ -341,7 +341,7 @@ ProposeStorageClass(it->first, it->second, hasPreferred, preferred); } } - + /** * Step 4: As long as there is room left in the proposed @@ -356,11 +356,11 @@ // The method "ProposeStorageClass()" will automatically add // "LittleEndianImplicit" std::set ts; - + for (int i = 0; i < numberOfDcmShortSCUStorageSOPClassUIDs; i++) { std::string c(dcmShortSCUStorageSOPClassUIDs[i]); - + if (c != sopClassUid && registeredClasses_.find(c) == registeredClasses_.end()) { @@ -403,7 +403,7 @@ "while sending to modality [" + parameters_.GetRemoteModality().GetApplicationEntityTitle() + "]"); } - + // Prepare the transmission of data T_DIMSE_C_StoreRQ request; memset(&request, 0, sizeof(request)); @@ -414,8 +414,8 @@ strncpy(request.AffectedSOPInstanceUID, sopInstanceUid.c_str(), DIC_UI_LEN); if (hasMoveOriginator) - { - strncpy(request.MoveOriginatorApplicationEntityTitle, + { + strncpy(request.MoveOriginatorApplicationEntityTitle, moveOriginatorAET.c_str(), DIC_AE_LEN); request.opts = O_STORE_MOVEORIGINATORAETITLE; @@ -439,7 +439,7 @@ &response, &statusDetail, NULL), GetParameters(), "C-STORE"); - if (statusDetail != NULL) + if (statusDetail != NULL) { delete statusDetail; } @@ -449,12 +449,12 @@ CLOG(TRACE, DICOM) << "Received Store Response:" << std::endl << DIMSE_dumpMessage(str, response, DIMSE_INCOMING, NULL, presID); } - + /** * New in Orthanc 1.6.0: Deal with failures during C-STORE. * http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_B.2.3.html#table_B.2-1 **/ - + if (response.DimseStatus != 0x0000 && // Success response.DimseStatus != 0xB000 && // Warning - Coercion of Data Elements response.DimseStatus != 0xB007 && // Warning - Data Set does not match SOP Class @@ -485,7 +485,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID); } @@ -501,7 +501,7 @@ std::map contexts; // Make sure a negotiation has already occurred for this transfer - // syntax if we have not negotiated yet. + // syntax if we have not negotiated yet. // We don't use the return code: Transcoding is possible even if the "sourceSyntax" is not supported. if (!association_->IsOpen() || !association_->LookupAcceptedPresentationContext(contexts, sopClassUid)) { @@ -519,7 +519,7 @@ } } #endif - + #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 void DicomStoreUserConnection::Transcode(std::string& sopClassUid /* out */, @@ -547,7 +547,7 @@ if (accepted.size() == 0) { - throw OrthancException(ErrorCode_NoPresentationContext, "Cannot C-Store an instance of SOPClassUID " + + throw OrthancException(ErrorCode_NoPresentationContext, "Cannot C-Store an instance of SOPClassUID " + sopClassUid + ", the destination has not accepted any TransferSyntax for this SOPClassUID."); } @@ -565,7 +565,7 @@ source.SetExternalBuffer(buffer, size); const std::string sourceUid = IDicomTranscoder::GetSopInstanceUid(source.GetParsed()); - + IDicomTranscoder::DicomImage transcoded; bool success = false; bool isDestructiveCompressionAllowed = false; @@ -636,7 +636,7 @@ } DicomTransferSyntax transcodedSyntax; - + // Sanity check if (!FromDcmtkBridge::LookupOrthancTransferSyntax(transcodedSyntax, transcoded.GetParsed()) || accepted.find(transcodedSyntax) == accepted.end()) @@ -657,8 +657,8 @@ { s += " " + std::string(GetTransferSyntaxUid(*it)); } - - throw OrthancException(ErrorCode_InternalError, "Cannot transcode instance of SOPClassUID " + + + throw OrthancException(ErrorCode_InternalError, "Cannot transcode instance of SOPClassUID " + sopClassUid + " from " + std::string(GetTransferSyntaxUid(sourceSyntax)) + " to one of [" + s + " ]"); @@ -666,8 +666,8 @@ } } #endif - - + + #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 void DicomStoreUserConnection::Transcode(std::string& sopClassUid /* out */, std::string& sopInstanceUid /* out */, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Wed Aug 19 14:11:33 2026 +0200 @@ -90,7 +90,7 @@ bool LookupPresentationContext(uint8_t& presentationContextId, const std::string& sopClassUid, DicomTransferSyntax transferSyntax); - + bool NegotiatePresentationContext(uint8_t& presentationContextId, const std::string& sopClassUid, DicomTransferSyntax transferSyntax, @@ -107,7 +107,7 @@ public: explicit DicomStoreUserConnection(const DicomAssociationParameters& params); - + const DicomAssociationParameters& GetParameters() const; void SetCommonClassesProposed(bool proposed); @@ -156,7 +156,7 @@ const std::string& moveOriginatorAET, uint16_t moveOriginatorID); #endif - + #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 void Transcode(std::string& sopClassUid /* out */, std::string& sopInstanceUid /* out */, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h --- a/OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -44,18 +44,18 @@ const std::string& originatorAet, const std::string& calledAet, uint32_t timeout) = 0; - + virtual unsigned int GetSubOperationCount() const = 0; // Must return "false" iff. a "Cancel" was returned by the remote SCU virtual bool DoNext(T_ASC_Association *) = 0; - + virtual unsigned int GetCompletedCount() const = 0; - + virtual unsigned int GetWarningCount() const = 0; - + virtual unsigned int GetFailedCount() const = 0; - + virtual const std::string& GetFailedUids() const = 0; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -162,7 +162,7 @@ } } } - + if (accepted) { cond = ASC_acceptPresentationContext( @@ -295,7 +295,7 @@ std::string remoteAet; std::string remoteIp; std::string calledAet; - + { DIC_AE remoteAet_C; DIC_AE calledAet_C; @@ -330,14 +330,14 @@ if (!Toolbox::IsValidAet(remoteAet)) { - LOG(ERROR) << "Association Received from an invalid AET (sanitized: " << Toolbox::NormalizeAet(remoteAet) << ")" + LOG(ERROR) << "Association Received from an invalid AET (sanitized: " << Toolbox::NormalizeAet(remoteAet) << ")" << " on IP " << remoteIp << ", rejecting the association"; return NULL; } remoteAet = Toolbox::NormalizeAet(remoteAet); // removes leading/trailing spaces that are not significant according to the standard - CLOG(INFO, DICOM) << "Association Received from AET " << remoteAet + CLOG(INFO, DICOM) << "Association Received from AET " << remoteAet << " on IP " << remoteIp; @@ -393,7 +393,7 @@ return NULL; } - + /* storage commitment support, new in Orthanc 1.6.0 */ if (server.HasStorageCommitmentRequestHandlerFactory()) { @@ -401,8 +401,8 @@ * "ASC_SC_ROLE_SCUSCP": The "SCU" role is needed to accept * remote storage commitment requests, and the "SCP" role is * needed to receive storage commitments answers. - **/ - const char* as[1] = { UID_StorageCommitmentPushModelSOPClass }; + **/ + const char* as[1] = { UID_StorageCommitmentPushModelSOPClass }; cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, as, 1, &genericTransferSyntaxes[0], static_cast(genericTransferSyntaxes.size()), ASC_SC_ROLE_SCUSCP); @@ -414,11 +414,11 @@ } } } - + { /* accept the abstract syntaxes for C-STORE, if presented */ - + std::set storageTransferSyntaxes; if (server.HasApplicationEntityFilter()) @@ -466,7 +466,7 @@ { storageTransferSyntaxesC.push_back(GetTransferSyntaxUid(PREFERRED_TRANSFER_SYNTAX)); } - + for (std::set::const_iterator syntax = storageTransferSyntaxes.begin(); syntax != storageTransferSyntaxes.end(); ++syntax) { @@ -484,14 +484,14 @@ { count++; } - + #if DCMTK_VERSION_NUMBER >= 362 // The global variable "numberOfDcmAllStorageSOPClassUIDs" is // only published if DCMTK >= 3.6.2: // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=137 assert(static_cast(count) == numberOfDcmAllStorageSOPClassUIDs); #endif - + if (!server.HasGetRequestHandlerFactory()) // dcmqrsrv.cc line 828 { // This branch exactly corresponds to Orthanc <= 1.6.1 (in @@ -531,7 +531,7 @@ * we can be the SCU of the Storage Service Class. **/ const T_ASC_SC_ROLE role = pc.proposedRole; - + /** * Accept in the order "least wanted" to "most wanted" * transfer syntax. Accepting a transfer syntax will @@ -643,7 +643,7 @@ return NULL; } - if (opt_rejectWithoutImplementationUID && + if (opt_rejectWithoutImplementationUID && strlen(assoc->params->theirImplementationClassUID) == 0) { /* reject: the no implementation Class UID provided */ @@ -677,7 +677,7 @@ std::string suffix; if (ASC_countAcceptedPresentationContexts(assoc->params) == 0) suffix = " (but no valid presentation contexts)"; - + CLOG(INFO, DICOM) << "Association Acknowledged (Max Send PDV: " << assoc->sendPDVLength << ") to AET " << remoteAet << " on IP " << remoteIp << suffix; } @@ -742,7 +742,7 @@ OFCondition cond = DIMSE_receiveCommand(assoc_, DIMSE_NONBLOCKING, 1, &presID, &msg, &statusDetail); elapsedTimeSinceLastCommand_++; - + // if the command which was received has extra status // detail information, dump this information if (statusDetail != NULL) @@ -761,7 +761,7 @@ else if (cond == DIMSE_NODATAAVAILABLE) { // Timeout due to DIMSE_NONBLOCKING - if (associationTimeout_ != 0 && + if (associationTimeout_ != 0 && elapsedTimeSinceLastCommand_ >= associationTimeout_) { // This timeout is actually a association timeout @@ -775,7 +775,7 @@ CLOG(TRACE, DICOM) << "Received Command:" << std::endl << DIMSE_dumpMessage(str, msg, DIMSE_INCOMING, NULL, presID); } - + // Reset the association timeout counter elapsedTimeSinceLastCommand_ = 0; @@ -798,7 +798,7 @@ request = DicomRequestType_Move; supported = true; break; - + case DIMSE_C_GET_RQ: request = DicomRequestType_Get; supported = true; @@ -818,7 +818,7 @@ supported = true; break; } - + case DIMSE_N_ACTION_RQ: request = DicomRequestType_NAction; supported = true; @@ -838,7 +838,7 @@ // Check whether this request is allowed by the security filter - if (supported && + if (supported && filter_ != NULL && !filter_->IsAllowedRequest(remoteIp_, remoteAet_, calledAet_, request)) { @@ -887,13 +887,13 @@ } } break; - + case DicomRequestType_Get: if (server_.HasGetRequestHandlerFactory()) // Should always be true { std::unique_ptr handler (server_.GetGetRequestHandlerFactory().ConstructGetRequestHandler()); - + if (handler.get() != NULL) { cond = Internals::getScp(assoc_, &msg, presID, *handler, remoteIp_, remoteAet_, calledAet_, static_cast(associationTimeout_)); @@ -925,11 +925,11 @@ case DicomRequestType_NAction: cond = NActionScp(&msg, presID); - break; + break; case DicomRequestType_NEventReport: cond = NEventReportScp(&msg, presID); - break; + break; default: // Should never happen @@ -946,7 +946,7 @@ CLOG(INFO, DICOM) << "Finishing association with AET " << remoteAet_ << " on IP " << remoteIp_ << ": " << cond.text(); } - + if (finished) { if (cond == DUL_PEERREQUESTEDRELEASE) @@ -993,7 +993,7 @@ { DcmDataset *tmp = NULL; T_ASC_PresentationContextID presIdData; - + OFCondition cond = DIMSE_receiveDataSetInMemory( assoc, (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), timeout, &presIdData, &tmp, NULL, NULL); @@ -1045,7 +1045,7 @@ sequence == NULL) { if (mandatory) - { + { char buf[64]; sprintf(buf, "Missing mandatory sequence in dataset: (%04X,%04X)", tag.getGroup(), tag.getElement()); @@ -1097,7 +1097,7 @@ } } - + OFCondition CommandDispatcher::NActionScp(T_DIMSE_Message* msg, T_ASC_PresentationContextID presID) { @@ -1108,7 +1108,7 @@ * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.2.html * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part07/chapter_10.html#table_10.1-4 **/ - + if (msg->CommandField != DIMSE_N_ACTION_RQ /* value == 304 == 0x0130 */ || !server_.HasStorageCommitmentRequestHandlerFactory()) { @@ -1119,7 +1119,7 @@ /** * Check that the storage commitment request is correctly formatted. **/ - + const T_DIMSE_N_ActionRQ& request = msg->msg.NActionRQ; if (request.ActionTypeID != 1) @@ -1148,7 +1148,7 @@ * J.3-1. Storage Commitment Request - Action Information": * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.2.html#table_J.3-1 **/ - + std::unique_ptr dataset( ReadDataset(assoc_, "Cannot read the dataset in N-ACTION SCP", static_cast(associationTimeout_))); assert(dataset.get() != NULL); @@ -1158,7 +1158,7 @@ dataset->print(s); CLOG(TRACE, DICOM) << "Received Storage Commitment Request:" << std::endl << s.str(); } - + std::string transactionUid = ReadString(*dataset, DCM_TransactionUID); std::vector sopClassUid, sopInstanceUid; @@ -1182,7 +1182,7 @@ **/ DIC_US dimseStatus; - + try { std::unique_ptr handler @@ -1192,7 +1192,7 @@ DicomConnectionInfo connection(remoteIp_, remoteAet_, calledAet_); handler->HandleRequest(transactionUid, sopClassUid, sopInstanceUid, connection); - + dimseStatus = 0; // Success } catch (OrthancException& e) @@ -1227,7 +1227,7 @@ CLOG(TRACE, DICOM) << "Sending Storage Commitment Request Response:" << std::endl << DIMSE_dumpMessage(str, response, DIMSE_OUTGOING); } - + return DIMSE_sendMessageUsingMemoryData( assoc_, presID, &response, NULL /* no dataset */, NULL /* dataObject */, NULL /* callback */, NULL /* callback context */, NULL /* commandSet */); @@ -1255,7 +1255,7 @@ /** * Check that the storage commitment report is correctly formatted. **/ - + const T_DIMSE_N_EventReportRQ& report = msg->msg.NEventReportRQ; if (report.EventTypeID != 1 /* successful */ && @@ -1285,7 +1285,7 @@ * J.3-2. Storage Commitment Result - Event Information": * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.3.html#table_J.3-2 **/ - + std::unique_ptr dataset( ReadDataset(assoc_, "Cannot read the dataset in N-EVENT-REPORT SCP", static_cast(associationTimeout_))); assert(dataset.get() != NULL); @@ -1295,7 +1295,7 @@ dataset->print(s); CLOG(TRACE, DICOM) << "Received Storage Commitment Report:" << std::endl << s.str(); } - + std::string transactionUid = ReadString(*dataset, DCM_TransactionUID); std::vector successSopClassUid, successSopInstanceUid; @@ -1347,7 +1347,7 @@ handler->HandleReport(transactionUid, successSopClassUid, successSopInstanceUid, failedSopClassUid, failedSopInstanceUid, failureReasons, connection); - + dimseStatus = 0; // Success } catch (OrthancException& e) @@ -1358,7 +1358,7 @@ dimseStatus = STATUS_N_ProcessingFailure; } - + /** * Send the DIMSE status back to the SCU. **/ diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h --- a/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h Wed Aug 19 14:11:33 2026 +0200 @@ -47,12 +47,12 @@ std::string calledAet_; IApplicationEntityFilter* filter_; - OFCondition NActionScp(T_DIMSE_Message* msg, + OFCondition NActionScp(T_DIMSE_Message* msg, T_ASC_PresentationContextID presID); - OFCondition NEventReportScp(T_DIMSE_Message* msg, + OFCondition NEventReportScp(T_DIMSE_Message* msg, T_ASC_PresentationContextID presID); - + public: CommandDispatcher(const DicomServer& server, T_ASC_Association* assoc, @@ -67,13 +67,13 @@ virtual bool Step() ORTHANC_OVERRIDE; }; - CommandDispatcher* AcceptAssociation(const DicomServer& server, + CommandDispatcher* AcceptAssociation(const DicomServer& server, T_ASC_Network *net, unsigned int maximumPduLength, bool useDicomTls); - OFCondition EchoScp(T_ASC_Association* assoc, - T_DIMSE_Message* msg, + OFCondition EchoScp(T_ASC_Association* assoc, + T_DIMSE_Message* msg, T_ASC_PresentationContextID presID); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -125,7 +125,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange, "Unknown role"); } - + if (requireRemoteCertificate && !SystemToolbox::IsRegularFile(trustedCertificatesPath)) { throw OrthancException(ErrorCode_InexistentFile, "Cannot read file with trusted certificates for DICOM TLS: " + @@ -156,16 +156,16 @@ case NET_ACCEPTOR: tmpRole = DICOM_APPLICATION_ACCEPTOR; break; - + case NET_REQUESTOR: tmpRole = DICOM_APPLICATION_REQUESTOR; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); - } + } #endif - + std::unique_ptr tls( new DcmTLSTransportLayer(tmpRole /*opt_networkRole*/, NULL /*opt_readSeedFile*/, OFFalse /*initializeOpenSSL, done by Orthanc::Toolbox::InitializeOpenSsl()*/)); @@ -217,7 +217,7 @@ { throw OrthancException(ErrorCode_InternalError, "Cannot set the DICOM TLS profile"); } - + if (IsFailure(tls->activateCipherSuites())) { throw OrthancException(ErrorCode_InternalError, "Cannot activate the cipher suites for DICOM TLS"); @@ -233,19 +233,19 @@ DcmTLSTransportLayer::native_handle_type sslNativeHandle = tls->getNativeHandle(); SSL_CTX_clear_options(sslNativeHandle, SSL_OP_NO_SSL_MASK); - if (minimalTlsVersion > 1) + if (minimalTlsVersion > 1) { SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_SSLv3); } - if (minimalTlsVersion > 2) + if (minimalTlsVersion > 2) { SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1); } - if (minimalTlsVersion > 3) + if (minimalTlsVersion > 3) { SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1_1); } - if (minimalTlsVersion > 4) + if (minimalTlsVersion > 4) { SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1_2); } @@ -263,7 +263,7 @@ ciphersTls.insert(it->c_str()); isValid = true; } - + // list of TLS v1.3 ciphers according to https://www.openssl.org/docs/man3.3/man1/openssl-ciphers.html if (strstr("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256", it->c_str()) != NULL) { @@ -313,7 +313,7 @@ // From 1.12.4, do not even request remote certificate (prior to 1.12.4, we were requesting a certificates, checking it if present and succeeding if not present) tls->setCertificateVerification(DCV_ignoreCertificate /*opt_certVerification*/); } - + if (ASC_setTransportLayer(network, tls.get(), 0).bad()) { throw OrthancException(ErrorCode_InternalError, "Cannot enable DICOM TLS in the Orthanc " + diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -91,7 +91,7 @@ * "dcmtk-3.6.0/dcmwlm/libsrc/wldsfs.cc". **/ -static void HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(DcmDataset *dataset, +static void HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(DcmDataset *dataset, const DcmTagKey &sequenceTagKey) // Date : May 3, 2005 // Author : Thomas Wilkens @@ -128,7 +128,7 @@ namespace Orthanc { namespace - { + { struct FindScpData { IFindRequestHandler* findHandler_; @@ -159,7 +159,7 @@ // WlmDataSourceFileSystem::HandleExistentButEmptyDescriptionAndCodeSequenceAttributes()" // in DCMTK 3.6.0 - DcmDataset* dataset = query.GetDcmtkObject().getDataset(); + DcmDataset* dataset = query.GetDcmtkObject().getDataset(); HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedStudySequence); HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedPatientSequence); } @@ -175,14 +175,14 @@ // http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.html#sect_C.4.1.1.3 // https://groups.google.com/d/msg/orthanc-users/D3kpPuX8yV0/_zgHOzkMEQAJ - // GroupLength are removed as well since they make no sense in the filtering as well as in the response. + // GroupLength are removed as well since they make no sense in the filtering as well as in the response. // Note that it seems that only some GE devices include them. DicomArray a(source); for (size_t i = 0; i < a.GetSize(); i++) { - if (a.GetElement(i).GetTag().GetGroup() >= 0x0008 + if (a.GetElement(i).GetTag().GetGroup() >= 0x0008 && a.GetElement(i).GetTag().GetElement() != 0x0000) { target.SetValue(a.GetElement(i).GetTag(), a.GetElement(i).GetValue()); @@ -193,11 +193,11 @@ void FindScpCallback( - /* in */ - void *callbackData, - OFBool cancelled, - T_DIMSE_C_FindRQ *request, - DcmDataset *requestIdentifiers, + /* in */ + void *callbackData, + OFBool cancelled, + T_DIMSE_C_FindRQ *request, + DcmDataset *requestIdentifiers, int responseCount, /* out */ T_DIMSE_C_FindRSP *response, @@ -206,7 +206,7 @@ { assert(response != NULL); assert(requestIdentifiers != NULL); - + memset(response, 0, sizeof(T_DIMSE_C_FindRSP)); *statusDetail = NULL; @@ -220,7 +220,7 @@ requestIdentifiers->print(s); CLOG(TRACE, DICOM) << "Received C-FIND Request:" << std::endl << s.str(); } - + bool ok = false; try @@ -269,7 +269,7 @@ if (sequence.card() != 0) { CLOG(WARNING, DICOM) << "Orthanc only supports sequence matching on worklists, " - << "ignoring C-FIND SCU constraint on tag (" << tag.Format() + << "ignoring C-FIND SCU constraint on tag (" << tag.Format() << ") " << FromDcmtkBridge::GetTagName(*element); } @@ -305,7 +305,7 @@ if (!ok) { response->DimseStatus = STATUS_FIND_Failed_UnableToProcess; - *responseIdentifiers = NULL; + *responseIdentifiers = NULL; return; } @@ -315,7 +315,7 @@ { // Internal error! response->DimseStatus = STATUS_FIND_Failed_UnableToProcess; - *responseIdentifiers = NULL; + *responseIdentifiers = NULL; return; } @@ -352,8 +352,8 @@ } - OFCondition Internals::findScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition Internals::findScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IFindRequestHandler* findHandler, IWorklistRequestHandler* worklistHandler, @@ -370,7 +370,7 @@ data.remoteAet_ = &remoteAet; data.calledAet_ = &calledAet; - OFCondition cond = DIMSE_findProvider(assoc, presID, &msg->msg.CFindRQ, + OFCondition cond = DIMSE_findProvider(assoc, presID, &msg->msg.CFindRQ, FindScpCallback, &data, /*opt_blockMode*/ (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ timeout); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h --- a/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,8 +32,8 @@ { namespace Internals { - OFCondition findScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition findScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IFindRequestHandler* findHandler, // can be NULL IWorklistRequestHandler* worklistHandler, // can be NULL diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/GetScp.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -110,7 +110,7 @@ { }; }; - + static DcmDataset *BuildFailedInstanceList(const std::string& failedUIDs) { if (failedUIDs.empty()) @@ -120,7 +120,7 @@ else { std::unique_ptr rspIds(new DcmDataset()); - + if (!DU_putStringDOElement(rspIds.get(), DCM_FailedSOPInstanceUIDList, failedUIDs.c_str())) { throw OrthancException(ErrorCode_InternalError, @@ -153,9 +153,9 @@ response.NumberOfWarningSubOperations = handler.GetWarningCount(); // http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.3.3.html - + if (handler.GetFailedCount() > 0 || - handler.GetWarningCount() > 0) + handler.GetWarningCount() > 0) { /** * "Warning if one or more sub-operations were successfully @@ -176,17 +176,17 @@ */ response.DimseStatus = STATUS_GET_Refused_OutOfResourcesSubOperations; } - + *failedIdentifiers = BuildFailedInstanceList(handler.GetFailedUids()); } - + static void GetScpCallback( - /* in */ - void *callbackData, - OFBool cancelled, - T_DIMSE_C_GetRQ *request, - DcmDataset *requestIdentifiers, + /* in */ + void *callbackData, + OFBool cancelled, + T_DIMSE_C_GetRQ *request, + DcmDataset *requestIdentifiers, int responseCount, /* out */ T_DIMSE_C_GetRSP *response, @@ -196,10 +196,10 @@ assert(response != NULL); assert(responseIdentifiers != NULL); assert(requestIdentifiers != NULL); - + memset(response, 0, sizeof(T_DIMSE_C_GetRSP)); *statusDetail = NULL; - *responseIdentifiers = NULL; + *responseIdentifiers = NULL; GetScpData& data = *reinterpret_cast(callbackData); if (data.lastRequest_ == NULL) @@ -248,7 +248,7 @@ response->DimseStatus = STATUS_GET_Failed_UnableToProcess; return; } - + if (data.handler_->GetSubOperationCount() == data.handler_->GetCompletedCount() + data.handler_->GetFailedCount() + @@ -260,7 +260,7 @@ else { bool isContinue; - + try { isContinue = data.handler_->DoNext(data.assoc_); @@ -292,7 +292,7 @@ } OFCondition Internals::getScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IGetRequestHandler& handler, const std::string& remoteIp, @@ -309,11 +309,11 @@ data.calledAet_ = calledAet; data.timeout_ = timeout; - OFCondition cond = DIMSE_getProvider(assoc, presID, &msg->msg.CGetRQ, + OFCondition cond = DIMSE_getProvider(assoc, presID, &msg->msg.CGetRQ, GetScpCallback, &data, /*opt_blockMode*/ (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ timeout); - + // if some error occured, dump corresponding information and remove the outfile if necessary if (cond.bad()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h --- a/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h Wed Aug 19 14:11:33 2026 +0200 @@ -31,7 +31,7 @@ namespace Internals { OFCondition getScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IGetRequestHandler& handler, const std::string& remoteIp, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -96,7 +96,7 @@ namespace Orthanc { namespace - { + { struct MoveScpData { std::string target_; @@ -149,11 +149,11 @@ void MoveScpCallback( - /* in */ - void *callbackData, - OFBool cancelled, - T_DIMSE_C_MoveRQ *request, - DcmDataset *requestIdentifiers, + /* in */ + void *callbackData, + OFBool cancelled, + T_DIMSE_C_MoveRQ *request, + DcmDataset *requestIdentifiers, int responseCount, /* out */ T_DIMSE_C_MoveRSP *response, @@ -162,10 +162,10 @@ { assert(response != NULL); assert(requestIdentifiers != NULL); - + memset(response, 0, sizeof(T_DIMSE_C_MoveRSP)); *statusDetail = NULL; - *responseIdentifiers = NULL; + *responseIdentifiers = NULL; MoveScpData& data = *reinterpret_cast(callbackData); if (data.lastRequest_ == NULL) @@ -219,7 +219,7 @@ response->DimseStatus = STATUS_MOVE_Failed_UnableToProcess; return; } - + if (data.subOperationCount_ == 0) { response->DimseStatus = STATUS_Success; @@ -273,8 +273,8 @@ } - OFCondition Internals::moveScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition Internals::moveScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IMoveRequestHandler& handler, const std::string& remoteIp, @@ -290,7 +290,7 @@ data.remoteAet_ = &remoteAet; data.calledAet_ = &calledAet; - OFCondition cond = DIMSE_moveProvider(assoc, presID, &msg->msg.CMoveRQ, + OFCondition cond = DIMSE_moveProvider(assoc, presID, &msg->msg.CMoveRQ, MoveScpCallback, &data, /*opt_blockMode*/ (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ timeout); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h --- a/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,8 +32,8 @@ { namespace Internals { - OFCondition moveScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition moveScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IMoveRequestHandler& handler, const std::string& remoteIp, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp --- a/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -93,7 +93,7 @@ namespace Orthanc { namespace - { + { struct StoreCallbackData { IStoreRequestHandler* handler; @@ -105,7 +105,7 @@ uint32_t messageID; }; - + static void storeScpCallback( void *callbackData, @@ -161,7 +161,7 @@ if (rsp->DimseStatus == STATUS_Success) { // which SOP class and SOP instance ? - + #if DCMTK_VERSION_NUMBER >= 364 if (!DU_findSOPClassAndInstanceInDataSet(*imageDataSet, sopClass, sizeof(sopClass), sopInstance, sizeof(sopInstance), /*opt_correctUIDPadding*/ OFFalse)) @@ -216,8 +216,8 @@ * presID - [in] The ID of the presentation context which was specified in the PDV which contained * the DIMSE command. */ - OFCondition Internals::storeScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition Internals::storeScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IStoreRequestHandler& handler, const std::string& remoteIp, @@ -263,7 +263,7 @@ DcmDataset *dset = dcmff.getDataset(); cond = DIMSE_storeProvider(assoc, presID, req, NULL, /*opt_useMetaheader*/OFFalse, &dset, - storeScpCallback, &data, + storeScpCallback, &data, /*opt_blockMode*/ (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), /*opt_dimse_timeout*/ timeout); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h --- a/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,8 +32,8 @@ { namespace Internals { - OFCondition storeScp(T_ASC_Association * assoc, - T_DIMSE_Message * msg, + OFCondition storeScp(T_ASC_Association * assoc, + T_DIMSE_Message * msg, T_ASC_PresentationContextID presID, IStoreRequestHandler& handler, const std::string& remoteIp, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h --- a/OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h Wed Aug 19 14:11:33 2026 +0200 @@ -27,13 +27,13 @@ #ifdef _WIN32 /** - * "The maximum length, in bytes, of the string returned in the buffer + * "The maximum length, in bytes, of the string returned in the buffer * pointed to by the name parameter is dependent on the namespace provider, * but this string must be 256 bytes or less. * http://msdn.microsoft.com/en-us/library/windows/desktop/ms738527(v=vs.85).aspx **/ # define HOST_NAME_MAX 256 -#endif +#endif #if !defined(HOST_NAME_MAX) && defined(_POSIX_HOST_NAME_MAX) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -219,7 +219,7 @@ } } - + void RemoteModalityParameters::UnserializeObject(const Json::Value& serialized) { assert(serialized.type() == Json::objectValue); @@ -240,7 +240,7 @@ { manufacturer_ = StringToModalityManufacturer (SerializationToolbox::ReadString(serialized, KEY_MANUFACTURER)); - } + } else { manufacturer_ = ModalityManufacturer_Generic; @@ -317,7 +317,7 @@ { retrieveMethod_ = StringToRetrieveMethod (SerializationToolbox::ReadString(serialized, KEY_RETRIEVE_METHOD)); - } + } else { retrieveMethod_ = RetrieveMethod_SystemDefault; @@ -418,7 +418,7 @@ HasLocalAet()); } - + void RemoteModalityParameters::Serialize(Json::Value& target, bool forceAdvancedFormat) const { @@ -454,7 +454,7 @@ } } - + void RemoteModalityParameters::Unserialize(const Json::Value& serialized) { Clear(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h --- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Wed Aug 19 14:11:33 2026 +0200 @@ -76,7 +76,7 @@ const std::string& GetHost() const; void SetHost(const std::string& host); - + uint16_t GetPortNumber() const; void SetPortNumber(uint16_t port); @@ -118,7 +118,7 @@ uint32_t GetTimeout() const; - bool HasTimeout() const; + bool HasTimeout() const; RetrieveMethod GetRetrieveMethod() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.cpp --- a/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ TimeoutDicomConnectionManager::Lock::Lock(TimeoutDicomConnectionManager& that, const std::string& localAet, - const RemoteModalityParameters& remote) : + const RemoteModalityParameters& remote) : that_(that), lock_(that_.mutex_) { @@ -49,13 +49,13 @@ that_.OpenInternal(localAet, remote); } - + TimeoutDicomConnectionManager::Lock::~Lock() { that_.TouchInternal(); } - + DicomStoreUserConnection& TimeoutDicomConnectionManager::Lock::GetConnection() { if (that_.connection_.get() == NULL) @@ -82,7 +82,7 @@ const RemoteModalityParameters& remote) { DicomAssociationParameters other(localAet, remote); - + if (connection_.get() == NULL || !connection_->GetParameters().IsEqual(other)) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h --- a/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h Wed Aug 19 14:11:33 2026 +0200 @@ -73,7 +73,7 @@ Lock(TimeoutDicomConnectionManager& that, const std::string& localAet, const RemoteModalityParameters& remote); - + ~Lock(); DicomStoreUserConnection& GetConnection(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp --- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -64,7 +64,7 @@ return dataset.findAndGetUint16(DCM_BitsStored, bitsStored).good(); } - + void DcmtkTranscoder::SetDefaultLossyQuality(unsigned int quality) { if (quality == 0 || @@ -112,7 +112,7 @@ DcmFileFormat& dicom, /* in/out */ const std::set& allowedSyntaxes, TranscodingSopInstanceUidMode mode, - unsigned int lossyQuality) + unsigned int lossyQuality) { std::vector failureReasons; @@ -133,7 +133,7 @@ // No transcoding is needed return true; } - + if (TryTranscode(failureReasons, selectedSyntax, dicom, allowedSyntaxes, DicomTransferSyntax_LittleEndianImplicit)) { return true; @@ -181,7 +181,7 @@ { // Check out "dcmjpeg/apps/dcmcjpeg.cc" DJ_RPLossy parameters(static_cast(lossyQuality)); - + if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGProcess1, ¶meters)) { fixer.Apply(dicom); @@ -192,7 +192,7 @@ } } #endif - + #if ORTHANC_ENABLE_DCMTK_JPEG == 1 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != allowedSyntaxes.end()) { @@ -218,7 +218,7 @@ } } #endif - + #if ORTHANC_ENABLE_DCMTK_JPEG == 1 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess14) != allowedSyntaxes.end()) { @@ -234,7 +234,7 @@ failureReasons.push_back(std::string("Internal error while transcoding to ") + GetTransferSyntaxUid(DicomTransferSyntax_JPEGProcess14)); } #endif - + #if ORTHANC_ENABLE_DCMTK_JPEG == 1 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGProcess14SV1) != allowedSyntaxes.end()) { @@ -249,7 +249,7 @@ failureReasons.push_back(std::string("Internal error while transcoding to ") + GetTransferSyntaxUid(DicomTransferSyntax_JPEGProcess14SV1)); } #endif - + #if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1 if (allowedSyntaxes.find(DicomTransferSyntax_JPEGLSLossless) != allowedSyntaxes.end()) { @@ -260,7 +260,7 @@ /** * WARNING: This call results in a segmentation fault if using * the DCMTK package 3.6.2 from Ubuntu 18.04. - **/ + **/ if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGLSLossless, ¶meters)) { selectedSyntax = DicomTransferSyntax_JPEGLSLossless; @@ -269,7 +269,7 @@ failureReasons.push_back(std::string("Internal error while transcoding to ") + GetTransferSyntaxUid(DicomTransferSyntax_JPEGLSLossless)); } #endif - + #if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1 if (allowNewSopInstanceUid && allowedSyntaxes.find(DicomTransferSyntax_JPEGLSLossy) != allowedSyntaxes.end()) @@ -281,7 +281,7 @@ /** * WARNING: This call results in a segmentation fault if using * the DCMTK package 3.6.2 from Ubuntu 18.04. - **/ + **/ if (FromDcmtkBridge::Transcode(dicom, DicomTransferSyntax_JPEGLSLossy, ¶meters)) { fixer.Apply(dicom); @@ -323,7 +323,7 @@ return true; } #endif - + return false; } @@ -345,7 +345,7 @@ Semaphore::Locker lock(maxConcurrentExecutionsSemaphore_); // limit the number of concurrent executions target.Clear(); - + DicomTransferSyntax sourceSyntax; if (!FromDcmtkBridge::LookupOrthancTransferSyntax(sourceSyntax, source.GetParsed())) { @@ -388,7 +388,7 @@ } else if (InplaceTranscode(targetSyntax, failureReason, source.GetParsed(), allowedSyntaxes, mode, lossyQuality)) - { + { // Sanity check DicomTransferSyntax targetSyntax2; if (FromDcmtkBridge::LookupOrthancTransferSyntax(targetSyntax2, source.GetParsed()) && @@ -397,7 +397,7 @@ { target.AcquireParsed(source); source.Clear(); - + #if !defined(NDEBUG) { // Only run the sanity check in debug mode @@ -407,13 +407,13 @@ allowedSyntaxes, allowNewSopInstanceUid); } #endif - + return true; } else { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } else { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h --- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h Wed Aug 19 14:11:33 2026 +0200 @@ -50,14 +50,14 @@ const std::set& allowedSyntaxes, TranscodingSopInstanceUidMode mode, unsigned int lossyQuality); - + public: explicit DcmtkTranscoder(unsigned int maxConcurrentExecutions); void SetDefaultLossyQuality(unsigned int quality); unsigned int GetDefaultLossyQuality() const; - + static bool IsSupported(DicomTransferSyntax syntax); virtual bool Transcode(DicomImage& target, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DicomDirWriter.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomDirWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomDirWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -74,7 +74,7 @@ /*** - + Validation: # sudo apt-get install dicom3tools @@ -135,7 +135,7 @@ { if (dir_.get() == NULL) { - dir_.reset(new DcmDicomDir(SystemToolbox::PathToUtf8(file_.GetPath()).c_str(), + dir_.reset(new DcmDicomDir(SystemToolbox::PathToUtf8(file_.GetPath()).c_str(), fileSetId_.c_str())); //SetTagValue(dir_->getRootRecord(), DCM_SpecificCharacterSet, GetDicomSpecificCharacterSet(Encoding_Utf8)); } @@ -170,7 +170,7 @@ const bool skipBacklashes = true; // cf. "ISO_IR 13": In this method, the VR will never be UT, ST, or LT result = Toolbox::ConvertToUtf8(s, encoding, hasCodeExtensions, skipBacklashes); } - + return true; } } @@ -190,7 +190,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + static bool CopyString(DcmDirectoryRecord& target, @@ -267,7 +267,7 @@ extendedSopClass_(false) { } - + bool IsUtcUsed() const { return utc_; @@ -278,7 +278,7 @@ { utc_ = utc; } - + void EnableExtendedSopClass(bool enable) { if (enable) @@ -286,7 +286,7 @@ LOG(WARNING) << "Generating a DICOMDIR with type 3 attributes, " << "which leads to an Extended SOP Class"; } - + extendedSopClass_ = enable; } @@ -324,7 +324,7 @@ { studyDate = nowDate; } - + std::string studyTime; if (!GetUtf8TagValue(studyTime, dicom, encoding, hasCodeExtensions, DCM_StudyTime) && !GetUtf8TagValue(studyTime, dicom, encoding, hasCodeExtensions, DCM_SeriesTime) && @@ -395,7 +395,7 @@ SetTagValue(record, DCM_ReferencedTransferSyntaxUIDInFile, transferSyntaxUid); } - + bool CreateResource(DcmDirectoryRecord*& target, ResourceType level, @@ -494,8 +494,8 @@ void Write(std::string& s) { - if (!GetDicomDir().write(DICOMDIR_DEFAULT_TRANSFERSYNTAX, - EET_UndefinedLength /*encodingType*/, + if (!GetDicomDir().write(DICOMDIR_DEFAULT_TRANSFERSYNTAX, + EET_UndefinedLength /*encodingType*/, EGL_withoutGL /*groupLength*/).good()) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); @@ -520,7 +520,7 @@ { pimpl_->SetUtcUsed(utc); } - + bool DicomDirWriter::IsUtcUsed() const { return pimpl_->IsUtcUsed(); @@ -564,7 +564,7 @@ DcmDirectoryRecord* study; bool isNewStudy = pimpl_->CreateResource(study, ResourceType_Study, dicom, filename.c_str(), NULL); study->insertSub(series); - + if (isNewStudy) { DcmDirectoryRecord* patient; @@ -586,7 +586,7 @@ pimpl_->EnableExtendedSopClass(enable); } - + bool DicomDirWriter::IsExtendedSopClass() const { return pimpl_->IsExtendedSopClass(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DicomModification.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -61,7 +61,7 @@ }; } - + DicomModification::DicomTagRange::DicomTagRange(uint16_t groupFrom, uint16_t groupTo, uint16_t elementFrom, @@ -73,7 +73,7 @@ { } - + bool DicomModification::DicomTagRange::Contains(const DicomTag& tag) const { return (tag.GetGroup() >= groupFrom_ && @@ -241,7 +241,7 @@ { assert(vr == ValueRepresentation_LongString || vr == ValueRepresentation_PersonName); - newValue = that_.MapDicomIdentifier(value, ResourceType_Patient); + newValue = that_.MapDicomIdentifier(value, ResourceType_Patient); } else { @@ -250,7 +250,7 @@ vr == ValueRepresentation_NotSupported /* for older versions of DCMTK */); newValue = that_.MapDicomIdentifier(value, ResourceType_Instance); } - + return Action_Replace; } else @@ -300,7 +300,7 @@ return Action_Replace; } else if (tag == DICOM_TAG_SOP_INSTANCE_UID) - { + { newValue = that_.MapDicomIdentifier(value, ResourceType_Instance); return Action_Replace; } @@ -366,7 +366,7 @@ { dicom.Remove(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE); } - + if (!IsManuallyModified(DICOM_TAG_SOURCE_IMAGE_SEQUENCE)) { dicom.Remove(DICOM_TAG_SOURCE_IMAGE_SEQUENCE); @@ -378,7 +378,7 @@ void DicomModification::CancelReplacement(const DicomTag& tag) { Replacements::iterator it = replacements_.find(tag); - + if (it != replacements_.end()) { assert(it->second != NULL); @@ -464,7 +464,7 @@ ResourceType level) { const std::string stripped = Toolbox::StripSpaces(original); - + std::string mapped; UidMap::const_iterator previous = uidMap_.find(std::make_pair(level, stripped)); @@ -526,12 +526,12 @@ std::string mapped = MapDicomIdentifier(original, level); - dicom.Replace(*tag, mapped, - false /* don't try and decode data URI scheme for UIDs */, + dicom.Replace(*tag, mapped, + false /* don't try and decode data URI scheme for UIDs */, DicomReplaceMode_InsertIfAbsent, privateCreator_); } - + DicomModification::DicomModification() : removePrivateTags_(false), keepLabels_(false), @@ -667,7 +667,7 @@ { assert(it->second != NULL); return *it->second; - } + } } @@ -682,7 +682,7 @@ else { return json.asString(); - } + } } @@ -735,7 +735,7 @@ uids.insert(tag); removals.erase(tag); // Necessary if unserializing a job from 1.9.3 } - + void DicomModification::SetupUidsFromOrthanc_1_9_3() { @@ -750,7 +750,7 @@ // (*) "PatientID" and "PatientName" are handled as UIDs since Orthanc 1.9.4 uids_.insert(DICOM_TAG_PATIENT_ID); uids_.insert(DICOM_TAG_PATIENT_NAME); - + SetupUidsFromOrthancInternal(uids_, removals_, DicomTag(0x0008, 0x0014)); // Instance Creator UID <= from SetupAnonymization2008() SetupUidsFromOrthancInternal(uids_, removals_, DicomTag(0x0008, 0x1155)); // Referenced SOP Instance UID <= from VisitString() + RemoveRelationships() SetupUidsFromOrthancInternal(uids_, removals_, DicomTag(0x0020, 0x0052)); // Frame of Reference UID <= from VisitString() + RemoveRelationships() @@ -768,52 +768,52 @@ // https://raw.githubusercontent.com/jodogne/dicom-specification/master/2008/08_15pu.pdf SetupUidsFromOrthanc_1_9_3(); - + //uids_.insert(DicomTag(0x0008, 0x0014)); // Instance Creator UID => set in SetupUidsFromOrthanc_1_9_3() //removals_.insert(DicomTag(0x0008, 0x0018)); // SOP Instance UID => set in Apply() removals_.insert(DicomTag(0x0008, 0x0050)); // Accession Number removals_.insert(DicomTag(0x0008, 0x0080)); // Institution Name removals_.insert(DicomTag(0x0008, 0x0081)); // Institution Address - removals_.insert(DicomTag(0x0008, 0x0090)); // Referring Physician's Name - removals_.insert(DicomTag(0x0008, 0x0092)); // Referring Physician's Address - removals_.insert(DicomTag(0x0008, 0x0094)); // Referring Physician's Telephone Numbers - removals_.insert(DicomTag(0x0008, 0x1010)); // Station Name - removals_.insert(DicomTag(0x0008, 0x1030)); // Study Description - removals_.insert(DicomTag(0x0008, 0x103e)); // Series Description - removals_.insert(DicomTag(0x0008, 0x1040)); // Institutional Department Name - removals_.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of Record - removals_.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians' Name - removals_.insert(DicomTag(0x0008, 0x1060)); // Name of Physician(s) Reading Study - removals_.insert(DicomTag(0x0008, 0x1070)); // Operators' Name - removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description + removals_.insert(DicomTag(0x0008, 0x0090)); // Referring Physician's Name + removals_.insert(DicomTag(0x0008, 0x0092)); // Referring Physician's Address + removals_.insert(DicomTag(0x0008, 0x0094)); // Referring Physician's Telephone Numbers + removals_.insert(DicomTag(0x0008, 0x1010)); // Station Name + removals_.insert(DicomTag(0x0008, 0x1030)); // Study Description + removals_.insert(DicomTag(0x0008, 0x103e)); // Series Description + removals_.insert(DicomTag(0x0008, 0x1040)); // Institutional Department Name + removals_.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of Record + removals_.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians' Name + removals_.insert(DicomTag(0x0008, 0x1060)); // Name of Physician(s) Reading Study + removals_.insert(DicomTag(0x0008, 0x1070)); // Operators' Name + removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description //uids_.insert(DicomTag(0x0008, 0x1155)); // Referenced SOP Instance UID => set in SetupUidsFromOrthanc_1_9_3() - removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description + removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description //removals_.insert(DicomTag(0x0010, 0x0010)); // Patient's Name => cf. below (*) //removals_.insert(DicomTag(0x0010, 0x0020)); // Patient ID => cf. below (*) - removals_.insert(DicomTag(0x0010, 0x0030)); // Patient's Birth Date - removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time - removals_.insert(DicomTag(0x0010, 0x0040)); // Patient's Sex - removals_.insert(DicomTag(0x0010, 0x1000)); // Other Patient Ids - removals_.insert(DicomTag(0x0010, 0x1001)); // Other Patient Names - removals_.insert(DicomTag(0x0010, 0x1010)); // Patient's Age - removals_.insert(DicomTag(0x0010, 0x1020)); // Patient's Size - removals_.insert(DicomTag(0x0010, 0x1030)); // Patient's Weight - removals_.insert(DicomTag(0x0010, 0x1090)); // Medical Record Locator - removals_.insert(DicomTag(0x0010, 0x2160)); // Ethnic Group - removals_.insert(DicomTag(0x0010, 0x2180)); // Occupation - removals_.insert(DicomTag(0x0010, 0x21b0)); // Additional Patient's History - removals_.insert(DicomTag(0x0010, 0x4000)); // Patient Comments - removals_.insert(DicomTag(0x0018, 0x1000)); // Device Serial Number - removals_.insert(DicomTag(0x0018, 0x1030)); // Protocol Name + removals_.insert(DicomTag(0x0010, 0x0030)); // Patient's Birth Date + removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time + removals_.insert(DicomTag(0x0010, 0x0040)); // Patient's Sex + removals_.insert(DicomTag(0x0010, 0x1000)); // Other Patient Ids + removals_.insert(DicomTag(0x0010, 0x1001)); // Other Patient Names + removals_.insert(DicomTag(0x0010, 0x1010)); // Patient's Age + removals_.insert(DicomTag(0x0010, 0x1020)); // Patient's Size + removals_.insert(DicomTag(0x0010, 0x1030)); // Patient's Weight + removals_.insert(DicomTag(0x0010, 0x1090)); // Medical Record Locator + removals_.insert(DicomTag(0x0010, 0x2160)); // Ethnic Group + removals_.insert(DicomTag(0x0010, 0x2180)); // Occupation + removals_.insert(DicomTag(0x0010, 0x21b0)); // Additional Patient's History + removals_.insert(DicomTag(0x0010, 0x4000)); // Patient Comments + removals_.insert(DicomTag(0x0018, 0x1000)); // Device Serial Number + removals_.insert(DicomTag(0x0018, 0x1030)); // Protocol Name //removals_.insert(DicomTag(0x0020, 0x000d)); // Study Instance UID => set in Apply() //removals_.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID => set in Apply() - removals_.insert(DicomTag(0x0020, 0x0010)); // Study ID + removals_.insert(DicomTag(0x0020, 0x0010)); // Study ID //uids_.insert(DicomTag(0x0020, 0x0052)); // Frame of Reference UID => set in SetupUidsFromOrthanc_1_9_3() //uids_.insert(DicomTag(0x0020, 0x0200)); // Synchronization Frame of Reference UID => set in SetupUidsFromOrthanc_1_9_3() - removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments - removals_.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence + removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments + removals_.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence //uids_.insert(DicomTag(0x0040, 0xa124)); // UID => set in SetupUidsFromOrthanc_1_9_3() - removals_.insert(DicomTag(0x0040, 0xa730)); // Content Sequence + removals_.insert(DicomTag(0x0040, 0xa730)); // Content Sequence //uids_.insert(DicomTag(0x0088, 0x0140)); // Storage Media File-set UID => set in SetupUidsFromOrthanc_1_9_3() //uids_.insert(DicomTag(0x3006, 0x0024)); // Referenced Frame of Reference UID => set in SetupUidsFromOrthanc_1_9_3() //uids_.insert(DicomTag(0x3006, 0x00c2)); // Related Frame of Reference UID => set in SetupUidsFromOrthanc_1_9_3() @@ -827,7 +827,7 @@ // Set the DeidentificationMethod tag ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2008); } - + void DicomModification::SetupAnonymization2017c() { @@ -838,13 +838,13 @@ * "../../../OrthancServer/Resources/GenerateAnonymizationProfile.py * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2017c/part15.xml" **/ - + #include "DicomModification_Anonymization2017c.impl.h" - + // Set the DeidentificationMethod tag ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2017c); } - + void DicomModification::SetupAnonymization2021b() { @@ -855,13 +855,13 @@ * "../../../OrthancServer/Resources/GenerateAnonymizationProfile.py * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2021b/part15.xml" **/ - + #include "DicomModification_Anonymization2021b.impl.h" - + // Set the DeidentificationMethod tag ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2021b); } - + void DicomModification::SetupAnonymization2023b() { @@ -875,18 +875,18 @@ * http://dicom.nema.org/medical/dicom/current/output/chtml/part15/chapter_E.html#table_E.1-1a * http://dicom.nema.org/medical/dicom/current/output/chtml/part15/chapter_E.html#table_E.1-1 **/ - + #include "DicomModification_Anonymization2023b.impl.h" - + // Set the DeidentificationMethod tag ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2023b); } - + void DicomModification::SetupAnonymization(DicomVersion version) { isAnonymization_ = true; - + keep_.clear(); removals_.clear(); clearings_.clear(); @@ -898,7 +898,7 @@ uidMap_.clear(); privateTagsToKeep_.clear(); keepSequences_.clear(); - removeSequences_.clear(); + removeSequences_.clear(); switch (version) { @@ -954,7 +954,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - } + } } void DicomModification::Apply(std::unique_ptr& toModify) @@ -976,7 +976,7 @@ { throw OrthancException(ErrorCode_BadRequest, "It is forbidden to remove one of the main Dicom identifiers"); } - + if (!allowManualIdentifiers_) { // Sanity checks at the patient level @@ -1071,21 +1071,21 @@ } // (3) Clear the tags specified by the user - for (SetOfTags::const_iterator it = clearings_.begin(); + for (SetOfTags::const_iterator it = clearings_.begin(); it != clearings_.end(); ++it) { toModify->Clear(*it, true /* only clear if the tag exists in the original file */); } // (4) Remove the tags specified by the user - for (SetOfTags::const_iterator it = removals_.begin(); + for (SetOfTags::const_iterator it = removals_.begin(); it != removals_.end(); ++it) { toModify->Remove(*it); } // (5) Replace the tags - for (Replacements::const_iterator it = replacements_.begin(); + for (Replacements::const_iterator it = replacements_.begin(); it != replacements_.end(); ++it) { assert(it->second != NULL); @@ -1203,7 +1203,7 @@ { throw OrthancException(ErrorCode_BadRequest); } - + std::string name = query[i].asString(); const DicomPath path(DicomPath::Parse(name)); @@ -1262,10 +1262,10 @@ "Marking tag \"" + name + "\" as to be replaced " + "requires the \"Force\" option to be set to true"); } - + target.Replace(path, value, false /* not safe for anonymization */); - LOG(TRACE) << "Replace: " << name << " = " << path.Format() + LOG(TRACE) << "Replace: " << name << " = " << path.Format() << " by: " << value.toStyledString(); } } @@ -1299,7 +1299,7 @@ } bool force = GetBooleanValue("Force", request, false); - + if (GetBooleanValue("RemovePrivateTags", request, false)) { SetRemovePrivateTags(true); @@ -1348,7 +1348,7 @@ **/ bool isReplacedPatientId = (IsReplaced(DICOM_TAG_PATIENT_ID) || uids_.find(DICOM_TAG_PATIENT_ID) != uids_.end()); - + if (level_ == ResourceType_Patient && !isReplacedPatientId) { throw OrthancException(ErrorCode_BadRequest, @@ -1378,7 +1378,7 @@ throw OrthancException(ErrorCode_BadRequest, "When modifying an instance, the parent PatientID cannot be manually modified"); } - + if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) { throw OrthancException(ErrorCode_BadRequest, @@ -1403,12 +1403,12 @@ } bool force = GetBooleanValue("Force", request, false); - + // DicomVersion version = DicomVersion_2008; // For Orthanc <= 1.2.0 // DicomVersion version = DicomVersion_2017c; // For Orthanc between 1.3.0 and 1.9.3 // DicomVersion version = DicomVersion_2021b; // For Orthanc >= 1.9.4 DicomVersion version = DicomVersion_2023b; // For Orthanc >= 1.12.1 - + if (request.isMember("DicomVersion")) { if (request["DicomVersion"].type() != Json::stringValue) @@ -1420,7 +1420,7 @@ version = StringToDicomVersion(request["DicomVersion"].asString()); } } - + SetupAnonymization(version); if (GetBooleanValue("KeepPrivateTags", request, false)) @@ -1449,7 +1449,7 @@ } patientNameOverridden = (uids_.find(DICOM_TAG_PATIENT_NAME) == uids_.end()); - + // New in Orthanc 1.6.0 if (request.isMember("PrivateCreator")) { @@ -1494,7 +1494,7 @@ static const char* KEEP_SEQUENCES = "KeepSequences"; // New in Orthanc 1.9.4 static const char* REMOVE_SEQUENCES = "RemoveSequences"; // New in Orthanc 1.9.4 static const char* SEQUENCE_REPLACEMENTS = "SequenceReplacements"; // New in Orthanc 1.9.4 - + void DicomModification::Serialize(Json::Value& value) const { if (identifierGenerator_ != NULL) @@ -1574,7 +1574,7 @@ // New in Orthanc 1.9.4 Json::Value ranges = Json::arrayValue; - + for (RemovedRanges::const_iterator it = removedRanges_.begin(); it != removedRanges_.end(); ++it) { Json::Value item = Json::arrayValue; @@ -1629,7 +1629,7 @@ } Json::Value::Members names = serialized[field].getMemberNames(); - + for (Json::Value::Members::const_iterator it = names.begin(); it != names.end(); ++it) { const Json::Value& value = serialized[field][*it]; @@ -1645,7 +1645,7 @@ } } - + DicomModification::DicomModification(const Json::Value& serialized) { removePrivateTags_ = SerializationToolbox::ReadBoolean(serialized, REMOVE_PRIVATE_TAGS); @@ -1724,7 +1724,7 @@ if (serialized.isMember(REMOVED_RANGES)) // Backward compatibility with Orthanc <= 1.9.3 { const Json::Value& ranges = serialized[REMOVED_RANGES]; - + if (ranges.type() != Json::arrayValue) { throw OrthancException(ErrorCode_BadFileFormat); @@ -1769,7 +1769,7 @@ if (serialized.isMember(KEEP_SEQUENCES)) { const Json::Value& keep = serialized[KEEP_SEQUENCES]; - + if (keep.type() != Json::arrayValue) { throw OrthancException(ErrorCode_BadFileFormat); @@ -1794,7 +1794,7 @@ if (serialized.isMember(REMOVE_SEQUENCES)) { const Json::Value& remove = serialized[REMOVE_SEQUENCES]; - + if (remove.type() != Json::arrayValue) { throw OrthancException(ErrorCode_BadFileFormat); @@ -1819,7 +1819,7 @@ if (serialized.isMember(SEQUENCE_REPLACEMENTS)) { const Json::Value& replace = serialized[SEQUENCE_REPLACEMENTS]; - + if (replace.type() != Json::objectValue) { throw OrthancException(ErrorCode_BadFileFormat); @@ -1858,7 +1858,7 @@ keepSequences_.push_back(path); MarkNotOrthancAnonymization(); } - + void DicomModification::Remove(const DicomPath& path) { @@ -1872,7 +1872,7 @@ MarkNotOrthancAnonymization(); } } - + void DicomModification::Replace(const DicomPath& path, const Json::Value& value, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DicomModification.h --- a/OrthancFramework/Sources/DicomParsing/DicomModification.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomModification.h Wed Aug 19 14:11:33 2026 +0200 @@ -52,7 +52,7 @@ virtual bool Apply(std::string& target, const std::string& sourceIdentifier, ResourceType level, - const DicomMap& sourceDicom) = 0; + const DicomMap& sourceDicom) = 0; }; class ORTHANC_PUBLIC IDicomModifier : public boost::noncopyable @@ -131,7 +131,7 @@ return value_; } }; - + typedef std::set SetOfTags; typedef std::map Replacements; typedef std::list RemovedRanges; @@ -139,7 +139,7 @@ typedef std::list SequenceReplacements; typedef std::map< std::pair, std::string> UidMap; - + SetOfTags removals_; SetOfTags clearings_; SetOfTags keep_; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -62,28 +62,28 @@ { target.append_child("FamilyName").text() = tokens[0].c_str(); } - + if (tokens.size() >= 2) { target.append_child("GivenName").text() = tokens[1].c_str(); } - + if (tokens.size() >= 3) { target.append_child("MiddleName").text() = tokens[2].c_str(); } - + if (tokens.size() >= 4) { target.append_child("NamePrefix").text() = tokens[3].c_str(); } - + if (tokens.size() >= 5) { target.append_child("NameSuffix").text() = tokens[4].c_str(); } } - + static void ExploreXmlDataset(pugi::xml_node& target, const Json::Value& source) { @@ -102,7 +102,7 @@ const std::string vr = content[KEY_VR].asString(); const std::string keyword = FromDcmtkBridge::GetTagName(tag, ""); - + pugi::xml_node node = target.append_child("DicomAttribute"); node.append_attribute(KEY_TAG).set_value(members[i].c_str()); node.append_attribute(KEY_VR).set_value(vr.c_str()); @@ -115,7 +115,7 @@ if (content.isMember(KEY_VALUE)) { assert(content[KEY_VALUE].type() == Json::arrayValue); - + for (Json::Value::ArrayIndex j = 0; j < content[KEY_VALUE].size(); j++) { std::string number = boost::lexical_cast(j + 1); @@ -237,7 +237,7 @@ return std::string(buf); } - + Json::Value& DicomWebJsonVisitor::CreateNode(const std::vector& parentTags, const std::vector& parentIndexes, const DicomTag& tag) @@ -261,7 +261,7 @@ Json::Value& DicomWebJsonVisitor::CreateEmptyNode(const std::vector& parentTags, const std::vector& parentIndexes) { - assert(parentTags.size() == parentIndexes.size()); + assert(parentTags.size() == parentIndexes.size()); Json::Value* node = &result_; @@ -304,7 +304,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + node = &(*node) [t][KEY_VALUE][Json::ArrayIndex(parentIndexes[i])]; } } @@ -314,7 +314,7 @@ return *node; } - + Json::Value DicomWebJsonVisitor::FormatInteger(int64_t value) { if (value < 0) @@ -327,7 +327,7 @@ } } - + Json::Value DicomWebJsonVisitor::FormatDouble(double value) { long long a; @@ -362,7 +362,7 @@ if (d <= std::numeric_limits::epsilon() * 100.0) { - return FormatInteger(a); // if the decimal number is an integer, you can represent it as an integer + return FormatInteger(a); // if the decimal number is an integer, you can represent it as an integer } else { @@ -505,7 +505,7 @@ return Action_None; } - + ITagVisitor::Action DicomWebJsonVisitor::VisitEmptyElement(const std::vector& parentTags, const std::vector& parentIndexes) @@ -531,7 +531,7 @@ { BinaryMode mode; std::string bulkDataUri; - + if (formatter_ == NULL) { mode = BinaryMode_InlineBinary; @@ -565,7 +565,7 @@ case BinaryMode_InlineBinary: { std::string tmp(static_cast(data), size); - + std::string base64; Toolbox::EncodeBase64(base64, tmp); @@ -741,7 +741,7 @@ { content.append(FormatDouble(values[i])); } - + node[KEY_VALUE] = content; } } @@ -750,7 +750,7 @@ return Action_None; } - + ITagVisitor::Action DicomWebJsonVisitor::VisitAttributes(const std::vector& parentTags, const std::vector& parentIndexes, @@ -769,7 +769,7 @@ { content.append(FormatTag(values[i])); } - + node[KEY_VALUE] = content; } } @@ -777,7 +777,7 @@ return Action_None; } - + ITagVisitor::Action DicomWebJsonVisitor::VisitString(std::string& newValue, const std::vector& parentTags, @@ -813,7 +813,7 @@ #endif { std::string truncated; - + if (!value.empty() && value[value.size() - 1] == '\0') { @@ -868,11 +868,11 @@ tmp[KEY_PHONETIC] = components[2]; } } - + node[KEY_VALUE].append(tmp); break; } - + case ValueRepresentation_IntegerString: { /** @@ -893,15 +893,15 @@ int64_t tmp = boost::lexical_cast(t); node[KEY_VALUE].append(FormatInteger(tmp)); } - + break; } - + case ValueRepresentation_DecimalString: { std::string t = Toolbox::StripSpaces(tokens[i]); boost::replace_all(t, ",", "."); // some invalid files uses "," instead of "." - + // remove invalid/useless trailing decimal separator if (t.size() > 0 && t[t.size()-1] == '.') { @@ -941,7 +941,7 @@ { node[KEY_VALUE].append(tokens[i]); } - + break; } } @@ -953,7 +953,7 @@ { tmp = ": " + value; } - + LOG(WARNING) << "Ignoring DICOM tag (" << tag.Format() << ") with invalid content for VR " << EnumerationToString(vr) << tmp; } @@ -961,7 +961,7 @@ } } } - + return Action_None; } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h --- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ BinaryMode_InlineBinary, BinaryMode_ArrayOfValues // New in Orthanc 1.13.0 }; - + class IBinaryFormatter : public boost::noncopyable { public: @@ -62,13 +62,13 @@ const DicomTag& tag, ValueRepresentation vr) = 0; }; - + private: Json::Value result_; IBinaryFormatter *formatter_; static std::string FormatTag(const DicomTag& tag); - + Json::Value& CreateNode(const std::vector& parentTags, const std::vector& parentIndexes, const DicomTag& tag); @@ -86,7 +86,7 @@ DicomWebJsonVisitor(); void SetFormatter(IBinaryFormatter& formatter); - + void Clear(); const Json::Value& GetResult() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp --- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -200,14 +200,14 @@ if (!dictionary.loadDictionary(SystemToolbox::PathToUtf8(tmp.GetPath()).c_str())) { throw OrthancException(ErrorCode_InternalError, - "Cannot read embedded dictionary. Under Windows, make sure that " + "Cannot read embedded dictionary. Under Windows, make sure that " "your TEMP directory does not contain special characters."); } #else if (!dictionary.loadFromMemory(content)) { throw OrthancException(ErrorCode_InternalError, - "Cannot read embedded dictionary. Under Windows, make sure that " + "Cannot read embedded dictionary. Under Windows, make sure that " "your TEMP directory does not contain special characters."); } #endif @@ -301,7 +301,7 @@ **/ //return boost::lexical_cast(v); // This was used in Orthanc <= 1.9.0 - + std::ostringstream ss; ss << std::setprecision(17) << v; return ss.str(); @@ -312,7 +312,7 @@ static std::string DoubleToString(double v) { //return boost::lexical_cast(v); // This was used in Orthanc <= 1.9.0 - + std::ostringstream ss; ss << std::setprecision(17) << v; return ss.str(); @@ -1190,7 +1190,7 @@ void FromDcmtkBridge::InitializeDictionary(bool loadPrivateDictionary) { CLOG(INFO, DICOM) << "Using DCMTK version: " << DCMTK_VERSION_NUMBER; - + #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1 { DictionaryWriterLock lock; @@ -1220,7 +1220,7 @@ #else { std::vector dictionaries; - + const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE); if (env != NULL) { @@ -1278,12 +1278,12 @@ for (size_t i = 0; i < dictionaries.size(); i++) { LOG(WARNING) << "Loading external DICOM dictionary: \"" << dictionaries[i] << "\""; - + if (!lock.GetDictionary().loadDictionary(dictionaries[i].c_str())) { throw OrthancException(ErrorCode_InexistentFile); } - } + } hasExternalDictionaries_ = true; } @@ -1311,12 +1311,12 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + DcmEVR evr = ToDcmtkBridge::Convert(vr); CLOG(INFO, DICOM) << "Registering tag in dictionary: (" << tag.Format() << ") " - << (DcmVR(evr).getValidVRName()) << " " - << name << " (multiplicity: " << minMultiplicity << "-" + << (DcmVR(evr).getValidVRName()) << " " + << name << " (multiplicity: " << minMultiplicity << "-" << (arbitrary ? "n" : boost::lexical_cast(maxMultiplicity)) << ")"; std::unique_ptr entry; @@ -1326,7 +1326,7 @@ { char buf[128]; sprintf(buf, "Warning: You are registering a private tag (%04x,%04x), " - "but no private creator was associated with it", + "but no private creator was associated with it", tag.GetGroup(), tag.GetElement()); LOG(WARNING) << buf; } @@ -1410,7 +1410,7 @@ if (!characterSet.empty()) { Encoding encoding; - + if (GetDicomEncoding(encoding, characterSet.c_str())) { // The specific character set is supported by the Orthanc core @@ -1429,7 +1429,7 @@ { hasCodeExtensions = false; } - + // No specific character set tag: Use the default encoding return defaultEncoding; } @@ -1449,7 +1449,7 @@ const std::set& ignoreTagLength) { const Encoding defaultEncoding = GetDefaultDicomEncoding(); - + bool hasCodeExtensions; Encoding encoding = DetectEncoding(hasCodeExtensions, dataset, defaultEncoding); @@ -1461,13 +1461,13 @@ { target.SetValueInternal(element->getTag().getGTag(), element->getTag().getETag(), - ConvertLeafElement(*element, DicomToJsonFlags_Default, maxStringLength, maxStringLength /* maxBinaryArrayLength: consider the same value as the maxStringLength */, + ConvertLeafElement(*element, DicomToJsonFlags_Default, maxStringLength, maxStringLength /* maxBinaryArrayLength: consider the same value as the maxStringLength */, encoding, hasCodeExtensions, ignoreTagLength, Convert(element->getVR()))); } else { DcmSequenceOfItems* sequence = dynamic_cast(element); - + if (sequence) { Json::Value jsonSequence = Json::arrayValue; @@ -1475,7 +1475,7 @@ { DcmItem* child = sequence->getItem(s); Json::Value& v = jsonSequence.append(Json::objectValue); - DatasetToJson(v, *child, DicomToJsonFormat_Full, DicomToJsonFlags_Default, + DatasetToJson(v, *child, DicomToJsonFormat_Full, DicomToJsonFlags_Default, maxStringLength, encoding, hasCodeExtensions, ignoreTagLength, 1); } @@ -1567,7 +1567,7 @@ // The "entry" value is only valid while "lock" is active const DcmDictEntry* entry = lock.GetDictionary().findEntry(element.getTag().getXTag(), element.getTag().getPrivateCreator()); - if (entry != NULL && + if (entry != NULL && entry->getVR().isaString()) { Uint8* data = NULL; @@ -1620,7 +1620,7 @@ } } - + try { // http://support.dcmtk.org/docs/dcvr_8h-source.html @@ -1671,11 +1671,11 @@ return new DicomValue; } - + /** * Numeric types - **/ - + **/ + case EVR_SL: // signed long { return ApplyDcmtkToCTypeConverter(element); @@ -1774,7 +1774,7 @@ /** * Internal to DCMTK. - **/ + **/ case EVR_xs: // SS or US depending on context case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) @@ -1795,7 +1795,7 @@ /** * Default case. - **/ + **/ default: return new DicomValue; @@ -1829,7 +1829,7 @@ // This code gives access to the name of the private tags std::string tagName = FromDcmtkBridge::GetTagName(element); - + switch (format) { case DicomToJsonFormat_Human: @@ -1884,7 +1884,7 @@ assert(target.type() == Json::nullValue); targetValue = ⌖ break; - } + } case DicomToJsonFormat_Full: { @@ -1946,7 +1946,7 @@ *targetType = "TooLong"; } } - } + } void FromDcmtkBridge::ElementToJson(Json::Value& parent, @@ -1970,7 +1970,7 @@ if (element.isLeaf()) { // The "maxStringLength=0" below lets "LeafValueToJson()" take care of "TooLong" values - // And the "maxBinaryArrayLength=maxStringLength" is there to limit the size of binary arrays that are actually returned + // And the "maxBinaryArrayLength=maxStringLength" is there to limit the size of binary arrays that are actually returned // as string that is later clipped in LeafValueToJson. // Since we have seen files with 100M float values, we don't want to generate a 1GB string that would be clipped to 256 bytes // in LeafValueToJson. @@ -2052,7 +2052,7 @@ /*element->getTag().isPrivate()*/ if (tag.IsPrivate() && - !(flags & DicomToJsonFlags_IncludePrivateTags)) + !(flags & DicomToJsonFlags_IncludePrivateTags)) { continue; } @@ -2082,7 +2082,7 @@ } - void FromDcmtkBridge::ExtractDicomAsJson(Json::Value& target, + void FromDcmtkBridge::ExtractDicomAsJson(Json::Value& target, DcmDataset& dataset, DicomToJsonFormat format, DicomToJsonFlags flags, @@ -2090,7 +2090,7 @@ const std::set& ignoreTagLength) { const Encoding defaultEncoding = GetDefaultDicomEncoding(); - + bool hasCodeExtensions; Encoding encoding = DetectEncoding(hasCodeExtensions, dataset, defaultEncoding); @@ -2099,7 +2099,7 @@ } - void FromDcmtkBridge::ExtractHeaderAsJson(Json::Value& target, + void FromDcmtkBridge::ExtractHeaderAsJson(Json::Value& target, DcmMetaInfo& dataset, DicomToJsonFormat format, DicomToJsonFlags flags, @@ -2122,7 +2122,7 @@ * loaded, notably for compatibility with DICONDE. In Orthanc <= * 1.9.3, this was done by method "DicomTag::GetMainTagsName()". **/ - + DicomTag tmp(tag.getGroup(), tag.getElement()); if (tmp == DICOM_TAG_ACCESSION_NUMBER) @@ -2138,7 +2138,7 @@ return "SeriesInstanceUID"; if (tmp == DICOM_TAG_STUDY_INSTANCE_UID) - return "StudyInstanceUID"; + return "StudyInstanceUID"; if (tmp == DICOM_TAG_PIXEL_DATA) return "PixelData"; @@ -2219,7 +2219,7 @@ std::string FromDcmtkBridge::GetTagName(const DicomTag& t, const std::string& privateCreator) { - + DcmTag tag(t.GetGroup(), t.GetElement()); if (!privateCreator.empty()) @@ -2235,7 +2235,7 @@ { // Copy the tag to ensure const-correctness of DcmElement. Note // that the private creator information is also copied. - DcmTag tag(element.getTag()); + DcmTag tag(element.getTag()); return GetTagNameInternal(tag); } @@ -2393,7 +2393,7 @@ result.clear(); - for (DicomMap::Content::const_iterator + for (DicomMap::Content::const_iterator it = values.content_.begin(); it != values.content_.end(); ++it) { switch (format) @@ -2669,7 +2669,7 @@ { DicomTransferSyntax sourceSyntax; bool known = LookupOrthancTransferSyntax(sourceSyntax, dicom); - + if (!dicom.chooseRepresentation(xfer, representation).good() || !dicom.canWriteXfer(xfer) || !dicom.validateMetaInfo(xfer, EWM_updateMeta).good()) @@ -2691,7 +2691,7 @@ CLOG(INFO, DICOM) << "Transcoded an image from unknown transfer syntax to " << GetTransferSyntaxUid(syntax); } - + return true; } } @@ -2843,7 +2843,7 @@ // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=140 LOG(WARNING) << "Private creator should not be empty while creating a private tag: " << tag.Format(); } - + #if DCMTK_VERSION_NUMBER >= 362 DcmTag key(tag.GetGroup(), tag.GetElement()); if (tag.IsPrivate()) @@ -2854,7 +2854,7 @@ { return DcmItem::newDicomElement(key, NULL); } - + #else DcmTag key(tag.GetGroup(), tag.GetElement()); if (tag.IsPrivate()) @@ -2869,7 +2869,7 @@ { return newDicomElement(key); } -#endif +#endif } @@ -2930,7 +2930,7 @@ } bool ok = false; - + try { switch (element.getTag().getEVR()) @@ -2950,7 +2950,7 @@ /** * String types. **/ - + case EVR_DS: // decimal string case EVR_IS: // integer string case EVR_AS: // age string @@ -2975,11 +2975,11 @@ break; } - + /** * Numerical types - **/ - + **/ + case EVR_SL: // signed long ok = IElementFiller::Apply(element, ValueRepresentationFiller_SL(), *decoded); break; @@ -3013,7 +3013,7 @@ } else { - ok = element.putUint16(boost::lexical_cast(*decoded)).good(); + ok = element.putUint16(boost::lexical_cast(*decoded)).good(); } break; } @@ -3049,13 +3049,13 @@ /** * Other types **/ - + case EVR_AT: // attribute tag, new in Orthanc 1.9.4 // Multiple values are supported since Orthanc 1.13.0 ok = IElementFiller::Apply(element, ValueRepresentationFiller_AT(), *decoded); break; - + /** * Sequence types, should never occur at this point. **/ @@ -3069,7 +3069,7 @@ /** * Internal to DCMTK. - **/ + **/ case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) case EVR_na: // na="not applicable", for data which has no VR @@ -3133,7 +3133,7 @@ { p = privateCreator.c_str(); } - + DcmTag key(tag.GetGroup(), tag.GetElement(), p); if (key.getEVR() != EVR_SQ) { @@ -3143,7 +3143,7 @@ DcmSequenceOfItems* sequence = new DcmSequenceOfItems(key); element.reset(sequence); - + for (Json::Value::ArrayIndex i = 0; i < value.size(); i++) { std::unique_ptr item(new DcmItem); @@ -3202,7 +3202,7 @@ E_TransferSyntax repType; const DcmRepresentationParameter *repParam = NULL; pixelData.getCurrentRepresentationKey(repType, repParam); - + DcmPixelSequence* pixelSequence = NULL; if (!pixelData.getEncapsulatedRepresentation(repType, repParam, pixelSequence).good()) { @@ -3226,7 +3226,7 @@ Encoding encoding = defaultEncoding; const Json::Value::Members tags = json.getMemberNames(); - + // Look for SpecificCharacterSet (0008,0005) in the JSON file for (size_t i = 0; i < tags.size(); i++) { @@ -3251,7 +3251,7 @@ } return encoding; - } + } static void SetString(DcmDataset& target, @@ -3277,7 +3277,7 @@ SetString(*result, DCM_SpecificCharacterSet, GetDicomSpecificCharacterSet(encoding)); const Json::Value::Members tags = json.getMemberNames(); - + bool hasPatientId = false; bool hasStudyInstanceUid = false; bool hasSeriesInstanceUid = false; @@ -3389,7 +3389,7 @@ { if (source.type() != Json::objectValue) { - if (fieldName != NULL) + if (fieldName != NULL) { throw OrthancException(ErrorCode_BadFileFormat, std::string("Expecting an object in field '") + std::string(fieldName) + std::string("'")); } @@ -3411,7 +3411,7 @@ { throw OrthancException(ErrorCode_BadFileFormat, std::string("Expecting a string in field '") + members[i] + std::string("'")); } - + target.SetValue(ParseTag(members[i]), value.asString(), false); } } @@ -3441,7 +3441,7 @@ { char *c = NULL; if (element->isaString() && - element->getString(c).good() && + element->getString(c).good() && c != NULL) { std::string a = Toolbox::ConvertDicomStringToUtf8(c, source, hasSourceCodeExtensions, Convert(element->getVR())); @@ -3485,7 +3485,7 @@ #endif CLOG(INFO, DICOM) << "Registering RLE codecs in DCMTK"; - DcmRLEDecoderRegistration::registerCodecs(); + DcmRLEDecoderRegistration::registerCodecs(); #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 DcmRLEEncoderRegistration::registerCodecs(); #endif @@ -3510,7 +3510,7 @@ # endif #endif - DcmRLEDecoderRegistration::cleanup(); + DcmRLEDecoderRegistration::cleanup(); #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 DcmRLEEncoderRegistration::cleanup(); #endif @@ -3525,7 +3525,7 @@ const std::vector& parentIndexes, Encoding encoding, bool hasCodeExtensions); - + static void ApplyVisitorToDataset(DcmItem& dataset, ITagVisitor& visitor, const std::vector& parentTags, @@ -3536,7 +3536,7 @@ assert(parentTags.size() == parentIndexes.size()); std::set toRemove; - + if (dataset.card() > 0) { for (unsigned long i = 0; i < dataset.card(); i++) @@ -3552,7 +3552,7 @@ { toRemove.insert(element->getTag()); } - } + } } } else @@ -3584,9 +3584,9 @@ DcmEVR evr = element.getTag().getEVR(); - + /** - * Fix the EVR for types internal to DCMTK + * Fix the EVR for types internal to DCMTK **/ if (evr == EVR_ox) // OB or OW depending on context @@ -3599,12 +3599,12 @@ // However, e.g. in a LUTDescriptor (3 values), the middle value can be a SS depending on other tag values while first and third value are always US. // This patch, although not perfect fixes https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=214. // It might need some rework once we encounter a LUTDescriptor with a SS value. ref: https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.11.2.html#sect_C.11.2.1.1 - evr = EVR_US; + evr = EVR_US; } else if (evr == EVR_lt) // US, SS or OW depending on context, used for LUT Data (thus the name) { // best guess is OW: final user should be able to interpret it correctly depending on the context - evr = EVR_OW; + evr = EVR_OW; } if (evr == EVR_UNKNOWN || // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) @@ -3630,7 +3630,7 @@ const ValueRepresentation vr = FromDcmtkBridge::Convert(evr); - + /** * Deal with binary data (including PixelData). **/ @@ -3641,7 +3641,7 @@ Uint8* data = NULL; ITagVisitor::Action action; - + if (evr == EVR_OW && element.getUint16Array(data16).good()) { @@ -3727,7 +3727,7 @@ ITagVisitor::Action action; - + try { // http://support.dcmtk.org/docs/dcvr_8h-source.html @@ -3757,7 +3757,7 @@ case EVR_UC: // Unlimited Characters { Uint8* data = NULL; - + if (element.getUint8Array(data).good()) { const Uint32 length = element.getLength(); @@ -3788,11 +3788,11 @@ break; } - + /** * Numeric types - **/ - + **/ + case EVR_SL: // signed long { DcmSignedLong& content = dynamic_cast(element); @@ -4053,11 +4053,11 @@ { return true; } - - + + /** * Internal to DCMTK. - **/ + **/ case EVR_xs: // SS or US depending on context case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) @@ -4077,11 +4077,11 @@ action = visitor.VisitNotSupported(parentTags, parentIndexes, tag, vr); break; } - + /** * Default case. - **/ + **/ default: return true; @@ -4250,7 +4250,7 @@ { sopInstanceUid.assign(c); } - + return DicomMap::FormatMissingTagsForStore(patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid); } @@ -4261,7 +4261,7 @@ const DicomPath& actualPath) { const size_t level = actualPath.GetPrefixLength(); - + if (level == pattern.GetPrefixLength()) { visitor.Visit(item, actualPath); @@ -4287,7 +4287,7 @@ { DicomPath childPath = actualPath; childPath.AddIndexedTagToPrefix(pattern.GetPrefixTag(level), static_cast(i)); - + ApplyInternal(visitor, *child, pattern, childPath); } } @@ -4319,11 +4319,11 @@ std::unique_ptr removed(item.remove(key)); } }; - + Visitor visitor; IDicomPathVisitor::Apply(visitor, dataset, path); } - + void FromDcmtkBridge::ClearPath(DcmDataset& dataset, const DicomPath& path, @@ -4333,13 +4333,13 @@ { public: bool onlyIfExists_; - + public: explicit Visitor(bool onlyIfExists) : onlyIfExists_(onlyIfExists) { } - + virtual void Visit(DcmItem& item, const DicomPath& path) ORTHANC_OVERRIDE { @@ -4359,11 +4359,11 @@ } } }; - + Visitor visitor(onlyIfExists); IDicomPathVisitor::Apply(visitor, dataset, path); } - + void FromDcmtkBridge::ReplacePath(DcmDataset& dataset, const DicomPath& path, @@ -4375,7 +4375,7 @@ private: std::unique_ptr element_; DicomReplaceMode mode_; - + public: Visitor(const DcmElement& element, DicomReplaceMode mode) : @@ -4387,7 +4387,7 @@ throw OrthancException(ErrorCode_InternalError, "Cannot clone DcmElement"); } } - + virtual void Visit(DcmItem& item, const DicomPath& path) ORTHANC_OVERRIDE { @@ -4397,7 +4397,7 @@ throw OrthancException(ErrorCode_InternalError, "Cannot clone DcmElement"); } else - { + { DcmTagKey key(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement()); if (!item.tagExists(key)) @@ -4406,18 +4406,18 @@ { case DicomReplaceMode_InsertIfAbsent: break; // Fine, we can proceed with insertion - + case DicomReplaceMode_ThrowIfAbsent: throw OrthancException(ErrorCode_InexistentItem, "Cannot replace inexistent tag: " + GetTagName(*element_)); - + case DicomReplaceMode_IgnoreIfAbsent: return; // Don't proceed with insertion - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + if (!item.insert(cloned.release(), OFTrue /* replace old */).good()) { throw OrthancException(ErrorCode_InternalError, "Cannot replace an element: " + GetTagName(*element_)); @@ -4427,7 +4427,7 @@ }; DcmTagKey key(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement()); - + if (element.getTag() != key) { throw OrthancException(ErrorCode_ParameterOutOfRange, @@ -4452,7 +4452,7 @@ bool found_; DicomMap& target_; size_t sequenceIndex_; - + public: Visitor(DicomMap& target, size_t sequenceIndex) : @@ -4461,14 +4461,14 @@ sequenceIndex_(sequenceIndex) { } - + virtual void Visit(DcmItem& item, const DicomPath& path) ORTHANC_OVERRIDE { DcmTagKey tag(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement()); DcmSequenceOfItems *sequence = NULL; - + if (item.findAndGetSequence(tag, sequence).good() && sequence != NULL && sequenceIndex_ < sequence->card()) @@ -4496,7 +4496,7 @@ const DicomTag& key) { DcmTagKey dcmkey(key.GetGroup(), key.GetElement()); - + const char* str = NULL; const Uint8* data = NULL; unsigned long size = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h --- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h Wed Aug 19 14:11:33 2026 +0200 @@ -72,7 +72,7 @@ DcmItem& item, const DicomPath& pattern, const DicomPath& actualPath); - + public: virtual ~IDicomPathVisitor() { @@ -85,7 +85,7 @@ DcmDataset& dataset, const DicomPath& path); }; - + class ORTHANC_PUBLIC DictionaryWriterLock : public boost::noncopyable { @@ -196,7 +196,7 @@ const std::set& ignoreTagLength, ValueRepresentation vr); - static void ExtractHeaderAsJson(Json::Value& target, + static void ExtractHeaderAsJson(Json::Value& target, DcmMetaInfo& header, DicomToJsonFormat format, DicomToJsonFlags flags, @@ -255,7 +255,7 @@ static DcmElement* CreateElementForTag(const DicomTag& tag, const std::string& privateCreator); - + static void FillElementWithString(DcmElement& element, const std::string& utf8alue, // Encoded using UTF-8 bool decodeDataUriScheme, @@ -285,12 +285,12 @@ const Json::Value& result, const char* fieldName = NULL); - static void ExtractDicomSummary(DicomMap& target, + static void ExtractDicomSummary(DicomMap& target, DcmItem& dataset, unsigned int maxStringLength, const std::set& ignoreTagLength); - static void ExtractDicomAsJson(Json::Value& target, + static void ExtractDicomAsJson(Json::Value& target, DcmDataset& dataset, DicomToJsonFormat format, DicomToJsonFlags flags, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/FromDcmtkBridge_TransferSyntaxes.impl.h --- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge_TransferSyntaxes.impl.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge_TransferSyntaxes.impl.h Wed Aug 19 14:11:33 2026 +0200 @@ -316,7 +316,7 @@ return false; } } - + bool FromDcmtkBridge::LookupOrthancTransferSyntax(DicomTransferSyntax& target, E_TransferSyntax source) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/IDicomTranscoder.cpp --- a/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -74,7 +74,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + DcmDataset& dataset = *dicom.getDataset(); std::string s; @@ -96,7 +96,7 @@ bool allowNewSopInstanceUid) { DcmFileFormat& parsed = transcoded.GetParsed(); - + if (parsed.getDataset() == NULL) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); @@ -134,12 +134,12 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + if (allowedSyntaxes.find(targetSyntax) == allowedSyntaxes.end()) { throw OrthancException(ErrorCode_InternalError, "An incorrect output transfer syntax was chosen"); } - + if (parsed.getDataset()->tagExists(DCM_PixelData)) { switch (GetTranscodingType(targetSyntax, sourceSyntax)) @@ -182,21 +182,21 @@ { parsed_.reset(FromDcmtkBridge::LoadFromMemoryBuffer( buffer_->empty() ? NULL : buffer_->c_str(), buffer_->size())); - + if (parsed_.get() == NULL) { throw OrthancException(ErrorCode_BadFileFormat); - } + } } } else if (isExternalBuffer_) { parsed_.reset(FromDcmtkBridge::LoadFromMemoryBuffer(externalBuffer_, externalSize_)); - + if (parsed_.get() == NULL) { throw OrthancException(ErrorCode_BadFileFormat); - } + } } else { @@ -204,8 +204,8 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - - + + void IDicomTranscoder::DicomImage::Serialize() { if (parsed_.get() == NULL || @@ -225,7 +225,7 @@ } } - + IDicomTranscoder::DicomImage::DicomImage() : isExternalBuffer_(false), externalBuffer_(NULL), @@ -241,13 +241,13 @@ isExternalBuffer_ = false; } - + void IDicomTranscoder::DicomImage::AcquireParsed(ParsedDicomFile& parsed) { AcquireParsed(parsed.ReleaseDcmtkObject()); } - - + + void IDicomTranscoder::DicomImage::AcquireParsed(DcmFileFormat* parsed) { if (parsed == NULL) @@ -267,13 +267,13 @@ parsed_.reset(parsed); } } - + void IDicomTranscoder::DicomImage::AcquireParsed(DicomImage& other) { AcquireParsed(other.ReleaseParsed()); } - + void IDicomTranscoder::DicomImage::AcquireBuffer(std::string& buffer /* will be swapped */) { @@ -311,10 +311,10 @@ else { buffer_.reset(NULL); - } + } } - + void IDicomTranscoder::DicomImage::SetExternalBuffer(const void* buffer, size_t size) { @@ -357,7 +357,7 @@ "AcquireParsed(), AcquireBuffer() or SetExternalBuffer() should have been called"); } } - + DcmFileFormat* IDicomTranscoder::DicomImage::ReleaseParsed() { @@ -387,7 +387,7 @@ return ParsedDicomFile::AcquireDcmtkObject(ReleaseParsed()); } - + const void* IDicomTranscoder::DicomImage::GetBufferData() { if (isExternalBuffer_) @@ -396,7 +396,7 @@ return externalBuffer_; } else - { + { if (buffer_.get() == NULL) { Serialize(); @@ -407,7 +407,7 @@ } } - + size_t IDicomTranscoder::DicomImage::GetBufferSize() { if (isExternalBuffer_) @@ -416,7 +416,7 @@ return externalSize_; } else - { + { if (buffer_.get() == NULL) { Serialize(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h --- a/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h Wed Aug 19 14:11:33 2026 +0200 @@ -40,7 +40,7 @@ namespace Orthanc { class ParsedDicomFile; - + /** * WARNING: This class might be called from several threads at * once. Make sure to implement proper locking. @@ -63,12 +63,12 @@ public: DicomImage(); - + void Clear(); - + // Calling this method will invalidate the "ParsedDicomFile" object void AcquireParsed(ParsedDicomFile& parsed); - + void AcquireParsed(DcmFileFormat* parsed); void AcquireParsed(DicomImage& other); @@ -122,8 +122,8 @@ const std::string& sourceSopInstanceUid, const std::set& allowedSyntaxes, bool allowNewSopInstanceUid); - - public: + + public: virtual ~IDicomTranscoder() { } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.cpp --- a/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -68,7 +68,7 @@ if (length % 4 != 0) { // Error: Each fragment is index with 4 bytes (uint32_t) - throw OrthancException(ErrorCode_BadFileFormat); + throw OrthancException(ErrorCode_BadFileFormat); } uint8_t* content = NULL; @@ -132,7 +132,7 @@ // Parse the offset table std::vector offsetOfFrame; GetOffsetTable(offsetOfFrame); - + if (offsetOfFrame.size() != countFrames || offsetOfFrame[0] != 0) { @@ -261,7 +261,7 @@ uint8_t* pixelData_; size_t frameSize_; - public: + public: UncompressedIndex(DcmDataset& dataset, unsigned int countFrames, size_t frameSize) : @@ -316,7 +316,7 @@ std::string pixelData_; size_t frameSize_; - public: + public: PsmctRle1Index(DcmDataset& dataset, unsigned int countFrames, size_t frameSize) : @@ -368,7 +368,7 @@ * video itself). **/ return 1; - } + } const char* tmp = NULL; if (!dicom.findAndGetString(DCM_NumberOfFrames, tmp).good() || diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp --- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -175,7 +175,7 @@ e->getUint8Array(pixData) != EC_Normal) { return false; - } + } // The "unsigned" below IS VERY IMPORTANT const uint8_t* inbuffer = reinterpret_cast(pixData); @@ -280,7 +280,7 @@ { Uint8* pixData = NULL; if (e->getUint8Array(pixData) == EC_Normal) - { + { slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); } } @@ -295,7 +295,7 @@ slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, psmct_.size())); } - + if (slowAccessor_.get() == NULL) { throw OrthancException(ErrorCode_BadFileFormat); @@ -345,11 +345,11 @@ DicomImageInformation info(m); PixelFormat format; - + if (!info.ExtractPixelFormat(format, ignorePhotometricInterpretation)) { - LOG(WARNING) << "Unsupported DICOM image: " << info.GetBitsStored() - << "bpp, " << info.GetChannelCount() << " channels, " + LOG(WARNING) << "Unsupported DICOM image: " << info.GetBitsStored() + << "bpp, " << info.GetChannelCount() << " channels, " << (info.IsSigned() ? "signed" : "unsigned") << (info.IsPlanar() ? ", planar, " : ", non-planar, ") << EnumerationToString(info.GetPhotometricInterpretation()) @@ -373,7 +373,7 @@ const unsigned int height = source.GetInformation().GetHeight(); const unsigned int width = source.GetInformation().GetWidth(); const unsigned int channels = source.GetInformation().GetChannelCount(); - + for (unsigned int y = 0; y < height; y++) { PixelType* pixel = reinterpret_cast(target.GetRow(y)); @@ -483,7 +483,7 @@ { throw OrthancException(ErrorCode_NotImplemented, std::string("Palette Color Lookup Table Descriptor invalid length: '") + r.c_str() + "'"); } - + const unsigned int paletteSize = boost::lexical_cast(splitR[0]); const unsigned int firstInputValueMapped = boost::lexical_cast(splitR[1]); const unsigned int nbBitsUsedInLut = boost::lexical_cast(splitR[2]); // The LUT is always 16bits but only part of it might be used @@ -504,7 +504,7 @@ const uint64_t expectedFrameSourceSize = (static_cast(target->GetWidth()) * static_cast(target->GetHeight())); - + if (pixelDataLength != (expectedFrameSourceSize * numberOfFramesInPixelData)) { DcmElement *elem = NULL; @@ -512,13 +512,13 @@ if (!dataset.findAndGetUint16(DCM_BitsAllocated, bitsAllocated).good()) { - THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); + THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } if (!dataset.findAndGetElement(DCM_PixelData, elem).good() || elem == NULL) { - THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); + THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } // In implicit VR files, pixelLength is expressed in words (OW) although pixels can actually be 8 bits @@ -533,7 +533,7 @@ } const uint8_t* source = reinterpret_cast(pixelData + expectedFrameSourceSize * frameToDecode); - + for (unsigned int y = 0; y < height; y++) { uint8_t* p = reinterpret_cast(target->GetRow(y)); @@ -574,7 +574,7 @@ } const uint16_t* source = reinterpret_cast(pixelData + expectedFrameSourceSize * frameToDecode); - + for (unsigned int y = 0; y < static_cast(height); y++) { uint16_t* p = reinterpret_cast(target->GetRow(y)); @@ -597,7 +597,7 @@ } THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } ImageAccessor* DicomImageDecoder::DecodeUncompressedImage(DcmDataset& dataset, @@ -618,7 +618,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + /** * Deal with lookup tables **/ @@ -628,7 +628,7 @@ if (info.GetPhotometricInterpretation() == PhotometricInterpretation_Palette) { return DecodeLookupTable(target, info, dataset, NULL, 0, 0 /* we don't know the number of frames in the buffer */, frame); - } + } /** @@ -668,8 +668,8 @@ const uint8_t* buffer = reinterpret_cast(source.GetAccessor().GetPixelData()); ImageAccessor sourceImage; - sourceImage.AssignReadOnly(sourceFormat, - info.GetWidth(), + sourceImage.AssignReadOnly(sourceFormat, + info.GetWidth(), info.GetHeight(), info.GetWidth() * GetBytesPerPixel(sourceFormat), buffer + frame * frameSize); @@ -692,7 +692,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + ImageProcessing::ShiftRight(*target, info.GetShift()); fastVersionSuccess = true; } @@ -717,7 +717,7 @@ case PixelFormat_Grayscale8: CopyPixels(*target, source.GetAccessor()); break; - + case PixelFormat_Grayscale16: CopyPixels(*target, source.GetAccessor()); break; @@ -799,11 +799,11 @@ std::unique_ptr target(CreateImage(dataset, true)); - Uint32 startFragment = 0; // Default + Uint32 startFragment = 0; // Default OFString decompressedColorModel; // Out OFCondition c; - + if (info.GetPhotometricInterpretation() == PhotometricInterpretation_Palette && info.GetChannelCount() == 1) { @@ -828,8 +828,8 @@ } if (uncompressed.size() == 0 || - !codec.decodeFrame(&representationParameter, - pixelSequence, ¶meters, + !codec.decodeFrame(&representationParameter, + pixelSequence, ¶meters, &dataset, frame, startFragment, &uncompressed[0], uncompressed.size(), decompressedColorModel).good()) { @@ -850,9 +850,9 @@ throw OrthancException(ErrorCode_BadFileFormat, errorMessage.str()); } - if (!codec.decodeFrame(&representationParameter, - pixelSequence, ¶meters, - &dataset, frame, startFragment, target->GetBuffer(), + if (!codec.decodeFrame(&representationParameter, + pixelSequence, ¶meters, + &dataset, frame, startFragment, target->GetBuffer(), target->GetSize(), decompressedColorModel).good()) { throw OrthancException(ErrorCode_BadFileFormat, @@ -903,7 +903,7 @@ } } } - + ImageAccessor* DicomImageDecoder::Decode(DcmDataset& dataset, unsigned int frame) @@ -945,7 +945,7 @@ LOG(INFO) << "Decoding a JPEG-LS lossless DICOM image"; decoder.reset(new DJLSLosslessDecoder); break; - + case EXS_JPEGLSLossy: LOG(INFO) << "Decoding a JPEG-LS near-lossless DICOM image"; decoder.reset(new DJLSNearLosslessDecoder); @@ -954,7 +954,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + std::unique_ptr result(ApplyCodec(*decoder, parameters, representationParameter, dataset, frame)); UndoBigEndianSwapping(*result); // New in Orthanc 1.9.1 to decode on big-endian architectures return result.release(); @@ -989,32 +989,32 @@ LOG(INFO) << "Decoding a JPEG baseline (process 1) DICOM image"; decoder.reset(new DJDecoderBaseline); break; - + case EXS_JPEGProcess2_4 : LOG(INFO) << "Decoding a JPEG baseline (processes 2 and 4) DICOM image"; decoder.reset(new DJDecoderExtended); break; - + case EXS_JPEGProcess6_8: // Retired LOG(INFO) << "Decoding a JPEG spectral section, nonhierarchical (processes 6 and 8) DICOM image"; decoder.reset(new DJDecoderSpectralSelection); break; - + case EXS_JPEGProcess10_12: // Retired LOG(INFO) << "Decoding a JPEG full progression, nonhierarchical (processes 10 and 12) DICOM image"; decoder.reset(new DJDecoderProgressive); break; - + case EXS_JPEGProcess14: LOG(INFO) << "Decoding a JPEG lossless, nonhierarchical (process 14) DICOM image"; decoder.reset(new DJDecoderLossless); break; - + case EXS_JPEGProcess14SV1: LOG(INFO) << "Decoding a JPEG lossless, nonhierarchical, first-order prediction (process 14 selection value 1) DICOM image"; decoder.reset(new DJDecoderP14SV1); break; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -1044,7 +1044,7 @@ * second example of the following page: * http://support.dcmtk.org/docs/mod_dcmjpeg.html#Examples **/ - + { LOG(INFO) << "Trying to decode a compressed image by transcoding it to Little Endian Explicit"; @@ -1174,7 +1174,7 @@ return true; } - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h --- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h Wed Aug 19 14:11:33 2026 +0200 @@ -54,7 +54,7 @@ namespace Orthanc { class ParsedDicomFile; - + class ORTHANC_PUBLIC DicomImageDecoder : public boost::noncopyable { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp --- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -56,7 +56,7 @@ } #endif } - + bool MemoryBufferTranscoder::Transcode(DicomImage& target, DicomImage& source, const std::set& allowedSyntaxes, @@ -72,7 +72,7 @@ TranscodingSopInstanceUidMode mode) { target.Clear(); - + #if !defined(NDEBUG) // Don't run this code in release mode, as it implies parsing the DICOM file DicomTransferSyntax sourceSyntax; @@ -81,7 +81,7 @@ LOG(ERROR) << "Unsupport transfer syntax for transcoding"; return false; } - + const std::string sourceSopInstanceUid = GetSopInstanceUid(source.GetParsed()); #endif @@ -96,7 +96,7 @@ CheckTargetSyntax(buffer, allowedSyntaxes); // For debug only target.AcquireBuffer(buffer); - + #if !defined(NDEBUG) // Only run the sanity check in debug mode CheckTranscoding(target, sourceSyntax, sourceSopInstanceUid, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h --- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,7 +37,7 @@ size_t size, const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) = 0; - + public: virtual bool Transcode(DicomImage& target /* out */, DicomImage& source, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -74,7 +74,7 @@ } } - + size_t ParsedDicomCache::GetNumberOfItems() { Mutex::ScopedLock lock(mutex_); @@ -108,11 +108,11 @@ } } - + void ParsedDicomCache::Invalidate(const std::string& id) { Mutex::ScopedLock lock(mutex_); - + if (cache_.get() != NULL) { cache_->Invalidate(id); @@ -125,13 +125,13 @@ } } - + void ParsedDicomCache::Acquire(const std::string& id, ParsedDicomFile* dicom, // Takes ownership size_t fileSize) { Mutex::ScopedLock lock(mutex_); - + if (fileSize >= cacheSize_) { cache_.reset(NULL); @@ -173,7 +173,7 @@ accessor_.reset(new MemoryObjectCache::Accessor( *that.cache_, id, true /* unique */)); if (accessor_->IsValid()) - { + { const Item& item = dynamic_cast(accessor_->GetValue()); file_ = &item.GetDicom(); fileSize_ = item.GetMemoryUsage(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h Wed Aug 19 14:11:33 2026 +0200 @@ -64,7 +64,7 @@ size_t fileSize_; std::unique_ptr accessor_; - + public: Accessor(ParsedDicomCache& that, const std::string& id); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/ParsedDicomDir.cpp --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -44,7 +44,7 @@ } } - + bool ParsedDicomDir::LookupIndexOfOffset(size_t& target, unsigned int offset) const { @@ -106,7 +106,7 @@ item->writeXML(std::cout); throw OrthancException(ErrorCode_BadFileFormat, "Missing offsets in DICOMDIR"); - } + } nextOffsets_[i] = next; lowerOffsets_[i] = lower; @@ -141,7 +141,7 @@ { offsetToIndex_[*it] = index; index ++; - } + } } ParsedDicomDir::~ParsedDicomDir() diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -165,7 +165,7 @@ key = DcmTagKey(t.GetGroup(), t.GetElement()); } - + static unsigned int GetPixelDataBlockCount(DcmPixelData& pixelData, E_TransferSyntax transferSyntax) { @@ -181,7 +181,7 @@ } } - + static void SendPathValueForDictionary(RestApiOutput& output, DcmItem& dicom) { @@ -227,7 +227,7 @@ uint32_t offset_; std::string chunk_; size_t chunkSize_; - + public: DicomFieldStream(DcmElement& element, E_TransferSyntax transferSyntax) : @@ -262,7 +262,7 @@ { return length_; } - + virtual bool ReadNextChunk() ORTHANC_OVERRIDE { assert(offset_ <= length_); @@ -296,12 +296,12 @@ return true; } } - + virtual const char *GetChunkContent() ORTHANC_OVERRIDE { return chunk_.c_str(); } - + virtual size_t GetChunkSize() ORTHANC_OVERRIDE { return chunkSize_; @@ -338,13 +338,13 @@ { result.append(boost::lexical_cast(i)); } - + output.AnswerJson(result); return true; } unsigned int block; - + if (!SerializationToolbox::ParseUnsignedInteger(block, *blockUri)) { throw OrthancException(ErrorCode_BadFileFormat, "Invalid Block URI: not a number"); @@ -404,7 +404,7 @@ ParseTagAndGroup(k, tag); DcmSequenceOfItems* sequence = NULL; - if (dicom.findAndGetSequence(k, sequence).good() && + if (dicom.findAndGetSequence(k, sequence).good() && sequence != NULL && sequence->getVR() == EVR_SQ) { @@ -413,7 +413,7 @@ } DcmElement* element = NULL; - if (dicom.findAndGetElement(k, element).good() && + if (dicom.findAndGetElement(k, element).good() && element != NULL && //element->getVR() != EVR_UNKNOWN && // This would forbid private tags element->getVR() != EVR_SQ) @@ -424,7 +424,7 @@ } #endif - + #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 void ParsedDicomFile::SendPathValue(RestApiOutput& output, const UriComponents& uri) const @@ -433,7 +433,7 @@ E_TransferSyntax transferSyntax = GetDcmtkObjectConst().getDataset()->getCurrentXfer(); // Special case: Accessing the pixel data - if (uri.size() == 1 || + if (uri.size() == 1 || uri.size() == 2) { DcmTagKey tag; @@ -445,7 +445,7 @@ AnswerPixelData(output, *dicom, transferSyntax, uri.size() == 1 ? NULL : &uri[1]); return; } - } + } // Go down in the tag hierarchy according to the URI for (size_t pos = 0; pos < uri.size() / 2; pos++) @@ -479,7 +479,7 @@ } } #endif - + void ParsedDicomFile::Remove(const DicomTag& tag) { @@ -523,7 +523,7 @@ remove = false; // Keep it } } - + if (remove) { privateTags.push_back(element); @@ -532,7 +532,7 @@ } // Loop over the detected private tags to remove them - for (Tags::iterator it = privateTags.begin(); + for (Tags::iterator it = privateTags.begin(); it != privateTags.end(); ++it) { DcmElement* tmp = dataset.remove(*it); @@ -714,7 +714,7 @@ if (tag == DICOM_TAG_SOP_INSTANCE_UID) { ReplacePlainString(DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, *decoded); - } + } } @@ -786,7 +786,7 @@ } } - + void ParsedDicomFile::Replace(const DicomTag& tag, const Json::Value& value, bool decodeDataUriScheme, @@ -827,7 +827,7 @@ } } - + #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 void ParsedDicomFile::Answer(RestApiOutput& output) const { @@ -884,12 +884,12 @@ bool hasCodeExtensions; Encoding encoding = DetectEncoding(hasCodeExtensions); - + std::set tmp; std::unique_ptr v(FromDcmtkBridge::ConvertLeafElement - (*element, DicomToJsonFlags_Default, + (*element, DicomToJsonFlags_Default, 0, 0, encoding, hasCodeExtensions, tmp, FromDcmtkBridge::Convert(element->getVR()))); - + if (v.get() == NULL || v->IsNull()) { @@ -900,7 +900,7 @@ // TODO v->IsBinary() value = v->GetContent(); } - + return true; } } @@ -920,8 +920,8 @@ * https://orthanc.uclouvain.be/hg/orthanc/rev/4c45e018bd3de3cfa21d6efc6734673aaaee4435 **/ patientId.clear(); - } - + } + if (!GetTagValue(studyUid, DICOM_TAG_STUDY_INSTANCE_UID) || !GetTagValue(seriesUid, DICOM_TAG_SERIES_INSTANCE_UID) || !GetTagValue(instanceUid, DICOM_TAG_SOP_INSTANCE_UID)) @@ -1013,7 +1013,7 @@ } } - for (DicomMap::Content::const_iterator + for (DicomMap::Content::const_iterator it = source.content_.begin(); it != source.content_.end(); ++it) { if (it->first != DICOM_TAG_SPECIFIC_CHARACTER_SET && @@ -1025,7 +1025,7 @@ const std::string& utf8Value = it->second->GetContent(); std::map::const_iterator found = privateCreators.find(it->first.GetGroup()); - + if (it->first.IsPrivate() && found != privateCreators.end()) { @@ -1068,7 +1068,7 @@ } - ParsedDicomFile::ParsedDicomFile(const void* content, + ParsedDicomFile::ParsedDicomFile(const void* content, size_t size) : pimpl_(new PImpl) { pimpl_->file_.reset(FromDcmtkBridge::LoadFromMemoryBuffer(content, size)); @@ -1088,7 +1088,7 @@ ParsedDicomFile::ParsedDicomFile(const ParsedDicomFile& other, - bool keepSopInstanceUid) : + bool keepSopInstanceUid) : pimpl_(new PImpl) { pimpl_->file_.reset(dynamic_cast(other.GetDcmtkObjectConst().clone())); @@ -1210,7 +1210,7 @@ { throw OrthancException(ErrorCode_BadFileFormat, "Not a PDF file"); } - + EncapsulateDocument(MimeType_Pdf, content); // In Orthanc <= 1.9.7, the "Modality" would have always be overwritten as "OT" @@ -1266,7 +1266,7 @@ { switch (mime) { - + #if ORTHANC_ENABLE_JPEG == 1 case MimeType_Jpeg: { @@ -1276,7 +1276,7 @@ break; } #endif - + #if ORTHANC_ENABLE_PNG == 1 case MimeType_Png: { @@ -1413,7 +1413,7 @@ unsigned int bytesPerPixel = 0; ConfigureTagsForUncompressedImage(bytesPerPixel, accessor); - DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), + DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), DICOM_TAG_PIXEL_DATA.GetElement()); std::unique_ptr pixels(new DcmPixelData(key)); @@ -1471,7 +1471,7 @@ break; } - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } @@ -1491,12 +1491,12 @@ if (!GetDcmtkObject().getDataset()->insert(pixels.release(), false, false).good()) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } void ParsedDicomFile::EmbedRawPixelData(const std::string& content) { - DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), + DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), DICOM_TAG_PIXEL_DATA.GetElement()); std::unique_ptr pixels(new DcmPixelData(key)); @@ -1533,7 +1533,7 @@ ReplacePlainString(DICOM_TAG_SPECIFIC_CHARACTER_SET, s); } - void ParsedDicomFile::DatasetToJson(Json::Value& target, + void ParsedDicomFile::DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength) const @@ -1544,7 +1544,7 @@ } - void ParsedDicomFile::DatasetToJson(Json::Value& target, + void ParsedDicomFile::DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength, @@ -1555,7 +1555,7 @@ } - void ParsedDicomFile::HeaderToJson(Json::Value& target, + void ParsedDicomFile::HeaderToJson(Json::Value& target, DicomToJsonFormat format) const { FromDcmtkBridge::ExtractHeaderAsJson(target, *GetDcmtkObjectConst().getMetaInfo(), format, DicomToJsonFlags_None, 0); @@ -1598,7 +1598,7 @@ } memcpy(bytes, document.c_str(), document.size()); - + DcmPolymorphOBOW* obj = element.release(); result = GetDcmtkObject().getDataset()->insert(obj); @@ -1613,7 +1613,7 @@ bool ParsedDicomFile::ExtractPdf(std::string& pdf) const { std::string sop, mime; - + if (!GetTagValue(sop, DICOM_TAG_SOP_CLASS_UID) || !GetTagValue(mime, FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument)) || sop != UID_EncapsulatedPDFStorage || @@ -1657,7 +1657,7 @@ result->SetEncoding(FromDcmtkBridge::ExtractEncoding(json, GetDefaultDicomEncoding())); const Json::Value::Members tags = json.getMemberNames(); - + for (size_t i = 0; i < tags.size(); i++) { DicomTag tag = FromDcmtkBridge::ParseTag(tags[i]); @@ -1716,7 +1716,7 @@ case EXS_JPEGProcess1: mime = MimeType_Jpeg; break; - + case EXS_JPEG2000LosslessOnly: case EXS_JPEG2000: mime = MimeType_Jpeg2000; @@ -1864,11 +1864,11 @@ DicomImageInformation info(m); PixelFormat format; - + if (!info.ExtractPixelFormat(format, false)) { - LOG(WARNING) << "Unsupported DICOM image: " << info.GetBitsStored() - << "bpp, " << info.GetChannelCount() << " channels, " + LOG(WARNING) << "Unsupported DICOM image: " << info.GetBitsStored() + << "bpp, " << info.GetChannelCount() << " channels, " << (info.IsSigned() ? "signed" : "unsigned") << (info.IsPlanar() ? ", planar, " : ", non-planar, ") << EnumerationToString(info.GetPhotometricInterpretation()) @@ -1890,10 +1890,10 @@ return true; } } - + return (path.GetFinalTag().GetElement() == 0x0000); } - + void ParsedDicomFile::ReplacePath(const DicomPath& path, const Json::Value& value, @@ -1923,7 +1923,7 @@ FromDcmtkBridge::ReplacePath(*GetDcmtkObject().getDataset(), path, *element, mode); } } - + void ParsedDicomFile::RemovePath(const DicomPath& path) { @@ -1956,7 +1956,7 @@ DcmDataset& dataset = *const_cast(*this).GetDcmtkObject().getDataset(); return FromDcmtkBridge::LookupSequenceItem(target, dataset, path, sequenceIndex); } - + void ParsedDicomFile::GetDefaultWindowing(double& windowCenter, double& windowWidth, @@ -2007,7 +2007,7 @@ } } - + void ParsedDicomFile::GetRescale(double& rescaleIntercept, double& rescaleSlope, unsigned int frame) const @@ -2089,7 +2089,7 @@ return a / b + 1; } } - + ImageAccessor* ParsedDicomFile::DecodeOverlay(int& originX, int& originY, @@ -2104,7 +2104,7 @@ unsigned long originSize = 0; DcmElement* overlayElement = NULL; Uint8* overlayData = NULL; - + if (dataset.findAndGetUint16(DcmTagKey(group, 0x0010), rows).good() && dataset.findAndGetUint16(DcmTagKey(group, 0x0011), columns).good() && dataset.findAndGetSint16Array(DcmTagKey(group, 0x0050), origin, &originSize).good() && @@ -2153,7 +2153,7 @@ { throw OrthancException(ErrorCode_CorruptedFile, "Overlay doesn't have a valid number of bits"); } - + originX = origin[1]; originY = origin[0]; @@ -2163,7 +2163,7 @@ for (int y = 0; y < rows; y++) { uint8_t* target = reinterpret_cast(overlay->GetRow(y)); - + for (int x = 0; x < columns; x++) { uint8_t source = overlayData[posBit / 8]; @@ -2175,7 +2175,7 @@ posBit++; } } - + return overlay.release(); } else @@ -2184,7 +2184,7 @@ } } - + ImageAccessor* ParsedDicomFile::DecodeAllOverlays(int& originX, int& originY) const { @@ -2201,7 +2201,7 @@ { std::set::const_iterator it = groups.begin(); assert(it != groups.end()); - + std::unique_ptr result(DecodeOverlay(originX, originY, *it)); assert(result.get() != NULL); ++it; @@ -2223,7 +2223,7 @@ assert(right >= mergedX && bottom >= mergedY); unsigned int width = static_cast(right - mergedX); unsigned int height = static_cast(bottom - mergedY); - + std::unique_ptr merged(new Image(PixelFormat_Grayscale8, width, height, false)); ImageProcessing::Set(*merged, 0); @@ -2237,7 +2237,7 @@ originX = mergedX; originY = mergedY; result.reset(merged.release()); - + ++it; } @@ -2245,7 +2245,7 @@ } } - + void ParsedDicomFile::InjectEmptyPixelData(ValueRepresentation vr) { DcmItem& dataset = *GetDcmtkObject().getDataset(); @@ -2299,7 +2299,7 @@ } } } - + ValueRepresentation ParsedDicomFile::GuessPixelDataValueRepresentation() const { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h Wed Aug 19 14:11:33 2026 +0200 @@ -213,18 +213,18 @@ // convert the encoding of the tags. Use "ChangeEncoding()" if need be. void SetEncoding(Encoding encoding); - void DatasetToJson(Json::Value& target, + void DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength) const; - void DatasetToJson(Json::Value& target, + void DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength, const std::set& ignoreTagLength) const; - - void HeaderToJson(Json::Value& target, + + void HeaderToJson(Json::Value& target, DicomToJsonFormat format) const; bool HasTag(const DicomTag& tag) const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Endianness.h --- a/OrthancFramework/Sources/Endianness.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Endianness.h Wed Aug 19 14:11:33 2026 +0200 @@ -139,7 +139,7 @@ /** * Note that an alternative implementation was included in Orthanc * 1.4.0 and 1.4.1: - * + * * # hg log -p -r 2706 * * This alternative implementation only hid an underlying problem diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Enumerations.cpp --- a/OrthancFramework/Sources/Enumerations.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Enumerations.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -594,7 +594,7 @@ case ResourceType_Instance: return "Instance"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -710,16 +710,16 @@ return "YBR_FULL_422"; case PhotometricInterpretation_YBRPartial420: - return "YBR_PARTIAL_420"; + return "YBR_PARTIAL_420"; case PhotometricInterpretation_YBRPartial422: - return "YBR_PARTIAL_422"; + return "YBR_PARTIAL_422"; case PhotometricInterpretation_YBR_ICT: - return "YBR_ICT"; + return "YBR_ICT"; case PhotometricInterpretation_YBR_RCT: - return "YBR_RCT"; + return "YBR_RCT"; case PhotometricInterpretation_Unknown: return "Unknown"; @@ -813,13 +813,13 @@ case ModalityManufacturer_Vitrea: return "Vitrea"; - + case ModalityManufacturer_GE: return "GE"; case ModalityManufacturer_SiemensSyngoCT: return "SiemensSyngoCT"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -862,7 +862,7 @@ return "N-EVENT-REPORT"; break; - default: + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } @@ -884,7 +884,7 @@ case DicomVersion_2023b: return "2023b"; - default: + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } @@ -999,7 +999,7 @@ case ValueRepresentation_NotSupported: return "Not supported"; - default: + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } @@ -1011,22 +1011,22 @@ { case JobState_Pending: return "Pending"; - + case JobState_Running: return "Running"; - + case JobState_Success: return "Success"; - + case JobState_Failure: return "Failure"; - + case JobState_Paused: return "Paused"; - + case JobState_Retry: return "Retry"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -1039,64 +1039,64 @@ { case MimeType_Binary: return MIME_BINARY; - + case MimeType_Dicom: return MIME_DICOM; - + case MimeType_Jpeg: return MIME_JPEG; - + case MimeType_Jpeg2000: return MIME_JPEG2000; - + case MimeType_Json: return MIME_JSON; - + case MimeType_Pdf: return MIME_PDF; - + case MimeType_Png: return MIME_PNG; - + case MimeType_Xml: return MIME_XML; - + case MimeType_PlainText: return MIME_PLAIN_TEXT; - + case MimeType_Pam: return MIME_PAM; - + case MimeType_Html: return MIME_HTML; - + case MimeType_Gzip: return MIME_GZIP; - + case MimeType_JavaScript: return MIME_JAVASCRIPT; - + case MimeType_Css: return MIME_CSS; - + case MimeType_WebAssembly: return MIME_WEB_ASSEMBLY; - + case MimeType_Gif: return MIME_GIF; - + case MimeType_Zip: return MIME_ZIP; - + case MimeType_NaCl: return MIME_NACL; - + case MimeType_PNaCl: return MIME_PNACL; - + case MimeType_Svg: return MIME_SVG; - + case MimeType_Woff: return MIME_WOFF; @@ -1109,7 +1109,7 @@ case MimeType_DicomWebJson: return MIME_DICOM_WEB_JSON; - + case MimeType_DicomWebXml: return MIME_DICOM_WEB_XML; @@ -1129,7 +1129,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + const char* EnumerationToString(Endianness endianness) { @@ -1143,7 +1143,7 @@ case Endianness_Unknown: return "Unknown endianness"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -1163,7 +1163,7 @@ case StorageCommitmentFailureReason_NoSuchObjectInstance: return "One or more of the elements in the Referenced SOP " "Instance Sequence was not available"; - + case StorageCommitmentFailureReason_ResourceLimitation: return "The SCP does not currently have enough resources to " "store the requested SOP Instance(s)"; @@ -1336,7 +1336,7 @@ { return ResourceType_Series; } - else if (s == "INSTANCE" || s == "IMAGE" || + else if (s == "INSTANCE" || s == "IMAGE" || s == "INSTANCES" || s == "IMAGES") { return ResourceType_Instance; @@ -1546,7 +1546,7 @@ { return PhotometricInterpretation_Monochrome1; } - + if (s == "MONOCHROME2") { return PhotometricInterpretation_Monochrome2; @@ -1556,52 +1556,52 @@ { return PhotometricInterpretation_Palette; } - + if (s == "RGB") { return PhotometricInterpretation_RGB; } - + if (s == "HSV") { return PhotometricInterpretation_HSV; } - + if (s == "ARGB") { return PhotometricInterpretation_ARGB; - } + } if (s == "CMYK") { return PhotometricInterpretation_CMYK; - } + } if (s == "YBR_FULL") { return PhotometricInterpretation_YBRFull; } - + if (s == "YBR_FULL_422") { return PhotometricInterpretation_YBRFull422; } - + if (s == "YBR_PARTIAL_422") { return PhotometricInterpretation_YBRPartial422; } - + if (s == "YBR_PARTIAL_420") { return PhotometricInterpretation_YBRPartial420; } - + if (s == "YBR_ICT") { return PhotometricInterpretation_YBR_ICT; } - + if (s == "YBR_RCT") { return PhotometricInterpretation_YBR_RCT; @@ -1609,13 +1609,13 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - + ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer) { ModalityManufacturer result; bool obsolete = false; - + if (manufacturer == "Generic") { return ModalityManufacturer_Generic; @@ -1922,7 +1922,7 @@ } - + MimeType StringToMimeType(const std::string& mime) { MimeType result; @@ -1935,7 +1935,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + DicomToJsonFormat StringToDicomToJsonFormat(const std::string& format) { @@ -2136,7 +2136,7 @@ case ResourceType_Study: return ResourceType_Series; - + case ResourceType_Series: return ResourceType_Instance; @@ -2152,7 +2152,7 @@ { case ResourceType_Study: return ResourceType_Patient; - + case ResourceType_Series: return ResourceType_Study; @@ -2203,7 +2203,7 @@ case ResourceType_Study: return DicomModule_Study; - + case ResourceType_Series: return DicomModule_Series; @@ -2432,12 +2432,12 @@ default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - } + } static Mutex defaultEncodingMutex_; // Should not be necessary static Encoding defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING; - + Encoding GetDefaultDicomEncoding() { Mutex::ScopedLock lock(defaultEncodingMutex_); @@ -2447,7 +2447,7 @@ void SetDefaultDicomEncoding(Encoding encoding) { std::string name = EnumerationToString(encoding); - + { Mutex::ScopedLock lock(defaultEncodingMutex_); defaultEncoding_ = encoding; @@ -2476,7 +2476,7 @@ case ResourceType_Instance: return "instances"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -2496,7 +2496,7 @@ case ResourceType_Instance: return "Instances"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -2516,7 +2516,7 @@ case ResourceType_Instance: return "instance"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -2536,7 +2536,7 @@ case ResourceType_Instance: return "Instance"; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -2579,7 +2579,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange, "RetrieveMethod can be \"C-MOVE\", \"C-GET\" or \"SystemDefault\": " + str); - } + } } const char* EnumerationToString(RetrieveMethod method) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Enumerations.h --- a/OrthancFramework/Sources/Enumerations.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Enumerations.h Wed Aug 19 14:11:33 2026 +0200 @@ -112,7 +112,7 @@ MimeType_Stl // STL - New in Orthanc 1.12.1 }; - + enum Endianness { Endianness_Unknown, @@ -324,19 +324,19 @@ * {description}{The image is graylevel. Each pixel is unsigned and stored in one byte.} **/ PixelFormat_Grayscale8 = 3, - + /** * {summary}{Graylevel, unsigned 16bpp image.} * {description}{The image is graylevel. Each pixel is unsigned and stored in two bytes.} **/ PixelFormat_Grayscale16 = 4, - + /** * {summary}{Graylevel, signed 16bpp image.} * {description}{The image is graylevel. Each pixel is signed and stored in two bytes.} **/ PixelFormat_SignedGrayscale16 = 5, - + /** * {summary}{Graylevel, floating-point image.} * {description}{The image is graylevel. Each pixel is floating-point and stored in 4 bytes.} @@ -351,7 +351,7 @@ * {description}{The image is graylevel. Each pixel is unsigned and stored in 4 bytes.} **/ PixelFormat_Grayscale32 = 8, - + /** * {summary}{Color image in RGB48 format.} * {description}{This format describes a color image. The pixels are stored in 6 @@ -647,13 +647,13 @@ // Some predefined combinations DicomToJsonFlags_None = 0, DicomToJsonFlags_Default = (DicomToJsonFlags_IncludeBinary | - DicomToJsonFlags_IncludePixelData | - DicomToJsonFlags_IncludePrivateTags | - DicomToJsonFlags_IncludeUnknownTags | + DicomToJsonFlags_IncludePixelData | + DicomToJsonFlags_IncludePrivateTags | + DicomToJsonFlags_IncludeUnknownTags | DicomToJsonFlags_ConvertBinaryToNull | DicomToJsonFlags_StopAfterPixelData /* added in 1.9.1 */) }; - + enum DicomFromJsonFlags { DicomFromJsonFlags_DecodeDataUriScheme = (1 << 0), @@ -722,7 +722,7 @@ JobStopReason_Retry }; - + // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.14.html#sect_C.14.1.1 enum StorageCommitmentFailureReason { @@ -917,23 +917,23 @@ ORTHANC_PUBLIC JobState StringToJobState(const std::string& state); - + ORTHANC_PUBLIC RequestOrigin StringToRequestOrigin(const std::string& origin); ORTHANC_PUBLIC MimeType StringToMimeType(const std::string& mime); - + ORTHANC_PUBLIC DicomToJsonFormat StringToDicomToJsonFormat(const std::string& format); ORTHANC_PUBLIC ErrorPayloadType StringToErrorPayloadType(const std::string& type); - + ORTHANC_PUBLIC bool LookupMimeType(MimeType& target, const std::string& source); - + ORTHANC_PUBLIC unsigned int GetBytesPerPixel(PixelFormat format); @@ -968,7 +968,7 @@ ORTHANC_PUBLIC bool IsBinaryValueRepresentation(ValueRepresentation vr); - + ORTHANC_PUBLIC Encoding GetDefaultDicomEncoding(); @@ -996,6 +996,6 @@ ORTHANC_PUBLIC void GetAllDicomTransferSyntaxes(std::set& target); - ORTHANC_PUBLIC + ORTHANC_PUBLIC RetrieveMethod StringToRetrieveMethod(const std::string& str); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Enumerations_TransferSyntaxes.impl.h --- a/OrthancFramework/Sources/Enumerations_TransferSyntaxes.impl.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Enumerations_TransferSyntaxes.impl.h Wed Aug 19 14:11:33 2026 +0200 @@ -341,289 +341,289 @@ target = DicomTransferSyntax_LittleEndianImplicit; return true; } - + if (uid == "1.2.840.10008.1.2.1") { target = DicomTransferSyntax_LittleEndianExplicit; return true; } - + if (uid == "1.2.840.10008.1.2.1.99") { target = DicomTransferSyntax_DeflatedLittleEndianExplicit; return true; } - + if (uid == "1.2.840.10008.1.2.2") { target = DicomTransferSyntax_BigEndianExplicit; return true; } - + if (uid == "1.2.840.10008.1.2.4.50") { target = DicomTransferSyntax_JPEGProcess1; return true; } - + if (uid == "1.2.840.10008.1.2.4.51") { target = DicomTransferSyntax_JPEGProcess2_4; return true; } - + if (uid == "1.2.840.10008.1.2.4.52") { target = DicomTransferSyntax_JPEGProcess3_5; return true; } - + if (uid == "1.2.840.10008.1.2.4.53") { target = DicomTransferSyntax_JPEGProcess6_8; return true; } - + if (uid == "1.2.840.10008.1.2.4.54") { target = DicomTransferSyntax_JPEGProcess7_9; return true; } - + if (uid == "1.2.840.10008.1.2.4.55") { target = DicomTransferSyntax_JPEGProcess10_12; return true; } - + if (uid == "1.2.840.10008.1.2.4.56") { target = DicomTransferSyntax_JPEGProcess11_13; return true; } - + if (uid == "1.2.840.10008.1.2.4.57") { target = DicomTransferSyntax_JPEGProcess14; return true; } - + if (uid == "1.2.840.10008.1.2.4.58") { target = DicomTransferSyntax_JPEGProcess15; return true; } - + if (uid == "1.2.840.10008.1.2.4.59") { target = DicomTransferSyntax_JPEGProcess16_18; return true; } - + if (uid == "1.2.840.10008.1.2.4.60") { target = DicomTransferSyntax_JPEGProcess17_19; return true; } - + if (uid == "1.2.840.10008.1.2.4.61") { target = DicomTransferSyntax_JPEGProcess20_22; return true; } - + if (uid == "1.2.840.10008.1.2.4.62") { target = DicomTransferSyntax_JPEGProcess21_23; return true; } - + if (uid == "1.2.840.10008.1.2.4.63") { target = DicomTransferSyntax_JPEGProcess24_26; return true; } - + if (uid == "1.2.840.10008.1.2.4.64") { target = DicomTransferSyntax_JPEGProcess25_27; return true; } - + if (uid == "1.2.840.10008.1.2.4.65") { target = DicomTransferSyntax_JPEGProcess28; return true; } - + if (uid == "1.2.840.10008.1.2.4.66") { target = DicomTransferSyntax_JPEGProcess29; return true; } - + if (uid == "1.2.840.10008.1.2.4.70") { target = DicomTransferSyntax_JPEGProcess14SV1; return true; } - + if (uid == "1.2.840.10008.1.2.4.80") { target = DicomTransferSyntax_JPEGLSLossless; return true; } - + if (uid == "1.2.840.10008.1.2.4.81") { target = DicomTransferSyntax_JPEGLSLossy; return true; } - + if (uid == "1.2.840.10008.1.2.4.90") { target = DicomTransferSyntax_JPEG2000LosslessOnly; return true; } - + if (uid == "1.2.840.10008.1.2.4.91") { target = DicomTransferSyntax_JPEG2000; return true; } - + if (uid == "1.2.840.10008.1.2.4.92") { target = DicomTransferSyntax_JPEG2000MulticomponentLosslessOnly; return true; } - + if (uid == "1.2.840.10008.1.2.4.93") { target = DicomTransferSyntax_JPEG2000Multicomponent; return true; } - + if (uid == "1.2.840.10008.1.2.4.94") { target = DicomTransferSyntax_JPIPReferenced; return true; } - + if (uid == "1.2.840.10008.1.2.4.95") { target = DicomTransferSyntax_JPIPReferencedDeflate; return true; } - + if (uid == "1.2.840.10008.1.2.4.100") { target = DicomTransferSyntax_MPEG2MainProfileAtMainLevel; return true; } - + if (uid == "1.2.840.10008.1.2.4.101") { target = DicomTransferSyntax_MPEG2MainProfileAtHighLevel; return true; } - + if (uid == "1.2.840.10008.1.2.4.102") { target = DicomTransferSyntax_MPEG4HighProfileLevel4_1; return true; } - + if (uid == "1.2.840.10008.1.2.4.103") { target = DicomTransferSyntax_MPEG4BDcompatibleHighProfileLevel4_1; return true; } - + if (uid == "1.2.840.10008.1.2.4.104") { target = DicomTransferSyntax_MPEG4HighProfileLevel4_2_For2DVideo; return true; } - + if (uid == "1.2.840.10008.1.2.4.105") { target = DicomTransferSyntax_MPEG4HighProfileLevel4_2_For3DVideo; return true; } - + if (uid == "1.2.840.10008.1.2.4.106") { target = DicomTransferSyntax_MPEG4StereoHighProfileLevel4_2; return true; } - + if (uid == "1.2.840.10008.1.2.4.107") { target = DicomTransferSyntax_HEVCMainProfileLevel5_1; return true; } - + if (uid == "1.2.840.10008.1.2.4.108") { target = DicomTransferSyntax_HEVCMain10ProfileLevel5_1; return true; } - + if (uid == "1.2.840.10008.1.2.5") { target = DicomTransferSyntax_RLELossless; return true; } - + if (uid == "1.2.840.10008.1.2.6.1") { target = DicomTransferSyntax_RFC2557MimeEncapsulation; return true; } - + if (uid == "1.2.840.10008.1.2.6.2") { target = DicomTransferSyntax_XML; return true; } - + if (uid == "1.2.840.10008.1.2.4.110") { target = DicomTransferSyntax_JPEGXLLossless; return true; } - + if (uid == "1.2.840.10008.1.2.4.111") { target = DicomTransferSyntax_JPEGXLJPEGRecompression; return true; } - + if (uid == "1.2.840.10008.1.2.4.112") { target = DicomTransferSyntax_JPEGXL; return true; } - + if (uid == "1.2.840.10008.1.2.4.201") { target = DicomTransferSyntax_HighThroughputJPEG2000LosslessOnly; return true; } - + if (uid == "1.2.840.10008.1.2.4.202") { target = DicomTransferSyntax_HighThroughputJPEG2000withRPCLOptionsLosslessOnly; return true; } - + if (uid == "1.2.840.10008.1.2.4.203") { target = DicomTransferSyntax_HighThroughputJPEG2000; return true; } - + return false; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileBuffer.cpp --- a/OrthancFramework/Sources/FileBuffer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileBuffer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -97,7 +97,7 @@ } }; - + FileBuffer::FileBuffer() : pimpl_(new PImpl) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/FileInfo.cpp --- a/OrthancFramework/Sources/FileStorage/FileInfo.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/FileInfo.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -38,7 +38,7 @@ { } - + FileInfo::FileInfo(const std::string& uuid, FileContentType contentType, uint64_t size, @@ -73,13 +73,13 @@ { } - + bool FileInfo::IsValid() const { return valid_; } - + const std::string& FileInfo::GetUuid() const { if (valid_) @@ -92,7 +92,7 @@ } } - + FileContentType FileInfo::GetContentType() const { if (valid_) @@ -104,7 +104,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - + uint64_t FileInfo::GetUncompressedSize() const { @@ -117,7 +117,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - + CompressionType FileInfo::GetCompressionType() const { @@ -130,7 +130,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - + uint64_t FileInfo::GetCompressedSize() const { @@ -144,7 +144,7 @@ } } - + const std::string& FileInfo::GetCompressedMD5() const { if (valid_) @@ -157,7 +157,7 @@ } } - + const std::string& FileInfo::GetUncompressedMD5() const { if (valid_) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/FileInfo.h --- a/OrthancFramework/Sources/FileStorage/FileInfo.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/FileInfo.h Wed Aug 19 14:11:33 2026 +0200 @@ -67,7 +67,7 @@ const std::string& compressedMD5); bool IsValid() const; - + const std::string& GetUuid() const; FileContentType GetContentType() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp --- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -121,16 +121,16 @@ void FilesystemStorage::Create(const std::string& uuid, - const void* content, + const void* content, size_t size, FileContentType type) { ElapsedTimer timer; - LOG(INFO) << "Creating attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) + LOG(INFO) << "Creating attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) << "\" type"; boost::filesystem::path path; - + path = GetPath(uuid); if (boost::filesystem::exists(path)) @@ -144,25 +144,25 @@ // directory while another thread needs it -> introduce 3 retries at 1 ms interval int retryCount = 0; const int maxRetryCount = 3; - + while (retryCount < maxRetryCount) { retryCount++; if (retryCount > 1) { boost::this_thread::sleep(boost::posix_time::milliseconds(2 * retryCount + (rand() % 10))); - LOG(INFO) << "Retrying to create attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) + LOG(INFO) << "Retrying to create attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) << "\" type"; } - try + try { boost::filesystem::create_directories(path.parent_path()); // the function ensures that the directory exists or throws } catch (boost::filesystem::filesystem_error& er) { if (er.code() == boost::system::errc::file_exists // the last element of the parent_path is a file - || er.code() == boost::system::errc::not_a_directory) // one of the element of the parent_path is not a directory + || er.code() == boost::system::errc::not_a_directory) // one of the element of the parent_path is not a directory { throw OrthancException(ErrorCode_DirectoryOverFile, "One of the element of the path is a file"); // no need to retry this error } @@ -170,10 +170,10 @@ // ignore other errors and retry } - try + try { SystemToolbox::WriteFile(content, size, path, fsyncOnWrite_); - + LOG(INFO) << "Created attachment \"" << uuid << "\" (" << timer.GetHumanTransferSpeed(true, size) << ")"; return; } @@ -192,7 +192,7 @@ FileContentType type) { ElapsedTimer timer; - LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) + LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) << "\" content type"; std::string content; @@ -210,7 +210,7 @@ uint64_t end /* exclusive */) { ElapsedTimer timer; - LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) + LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) << "\" content type (range from " << start << " to " << end << ")"; std::string content; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/FilesystemStorage.h --- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Wed Aug 19 14:11:33 2026 +0200 @@ -56,7 +56,7 @@ boost::filesystem::path GetPath(const std::string& uuid) const; void Setup(const boost::filesystem::path& root); - + public: explicit FilesystemStorage(const boost::filesystem::path& root); @@ -64,7 +64,7 @@ bool fsyncOnWrite); virtual void Create(const std::string& uuid, - const void* content, + const void* content, size_t size, FileContentType type) ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp --- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -45,7 +45,7 @@ } } } - + void MemoryStorageArea::Create(const std::string& uuid, const void* content, size_t size, @@ -71,7 +71,7 @@ } } - + IMemoryBuffer* MemoryStorageArea::ReadRange(const std::string& uuid, FileContentType type, uint64_t start /* inclusive */, @@ -133,7 +133,7 @@ Mutex::ScopedLock lock(mutex_); Content::iterator found = content_.find(uuid); - + if (found == content_.end()) { // Ignore second removal diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/MemoryStorageArea.h --- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,13 +37,13 @@ { private: typedef std::map Content; - + Mutex mutex_; Content content_; - + public: virtual ~MemoryStorageArea() ORTHANC_OVERRIDE; - + virtual void Create(const std::string& uuid, const void* content, size_t size, @@ -53,7 +53,7 @@ FileContentType type, uint64_t start /* inclusive */, uint64_t end /* exclusive */) ORTHANC_OVERRIDE; - + virtual bool HasEfficientReadRange() const ORTHANC_OVERRIDE { return true; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/FileStorage/StorageAccessor.cpp --- a/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -72,7 +72,7 @@ metrics_(NULL) { } - + StorageAccessor::StorageAccessor(IPluginStorageArea& area, MetricsRegistry& metrics) : @@ -127,7 +127,7 @@ { metrics_->IncrementIntegerValue(METRICS_WRITTEN_BYTES, static_cast(size)); } - + info = FileInfo(uuid, type, size, md5); info.SetCustomData(customData); return; @@ -141,7 +141,7 @@ zlib.Compress(compressed, data, size); std::string compressedMD5; - + if (storeMd5) { Toolbox::ComputeMD5(compressedMD5, compressed); @@ -206,12 +206,12 @@ ZlibCompressor zlib; std::unique_ptr compressed; - + { MetricsTimer timer(*this, METRICS_READ_DURATION); compressed.reset(area_.ReadRange(info.GetUuid(), info.GetContentType(), 0, info.GetCompressedSize(), info.GetCustomData())); } - + if (metrics_ != NULL) { metrics_->IncrementIntegerValue(METRICS_READ_BYTES, static_cast(compressed->GetSize())); @@ -260,7 +260,7 @@ area_.Remove(fileUuid, type, customData); } } - + void StorageAccessor::Remove(const FileInfo &info) { @@ -388,7 +388,7 @@ BufferHttpSender sender; SetupSender(sender, info, mime); sender.SetContentFilename(contentFilename); - + HttpStreamTranscoder transcoder(sender, CompressionType_None); // since 1.11.2, the storage accessor only returns uncompressed buffers output.Answer(transcoder); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpClient.cpp --- a/OrthancFramework/Sources/HttpClient.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpClient.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -66,7 +66,7 @@ // This is a dummy wrapper function to suppress any OpenSSL-related // problem in valgrind. Inlining is prevented. #if defined(__GNUC__) || defined(__clang__) -__attribute__((noinline)) +__attribute__((noinline)) #endif static CURLcode OrthancHttpClientPerformSSL(CURL* curl, long* status, const std::string& url) { @@ -180,11 +180,11 @@ { isChunkedTransfer_ = true; } - + std::string item = key + ": " + value; struct curl_slist *tmp = curl_slist_append(content_, item.c_str()); - + if (tmp == NULL) { throw OrthancException(ErrorCode_NotEnoughMemory); @@ -248,10 +248,10 @@ { buffer.AddChunk(&pending_[pendingPos_], pending_.size() - pendingPos_); } - + // Read chunks from the body stream so as to fill the target buffer std::string chunk; - + while (buffer.GetNumBytes() < curlBufferSize && body_->ReadNextChunk(chunk)) { @@ -269,7 +269,7 @@ return pendingPos_; } } - + public: CurlRequestBody() : body_(NULL), @@ -446,7 +446,7 @@ (*headers_) [key] = value; } } - + virtual void AddChunk(const void* data, size_t size) ORTHANC_OVERRIDE { @@ -465,7 +465,7 @@ long timeout_; bool verbose_; - GlobalParameters() : + GlobalParameters() : httpsVerifyPeers_(true), timeout_(DEFAULT_HTTP_TIMEOUT), verbose_(false) @@ -549,7 +549,7 @@ return verbose_; } - void SetDefaultVerbose(bool verbose) + void SetDefaultVerbose(bool verbose) { verbose_ = verbose; } @@ -640,7 +640,7 @@ SetVerbose(GlobalParameters::GetInstance().IsDefaultVerbose()); timeout_ = GlobalParameters::GetInstance().GetDefaultTimeout(); GlobalParameters::GetInstance().GetDefaultProxy(proxy_); - GlobalParameters::GetInstance().GetSslConfiguration(verifyPeers_, caCertificates_); + GlobalParameters::GetInstance().GetSslConfiguration(verifyPeers_, caCertificates_); hasExternalBody_ = false; externalBodyData_ = NULL; @@ -648,7 +648,7 @@ } - HttpClient::HttpClient() : + HttpClient::HttpClient() : pimpl_(new PImpl), verifyPeers_(true), pkcs11Enabled_(false), @@ -660,7 +660,7 @@ HttpClient::HttpClient(const WebServiceParameters& service, - const std::string& uri) : + const std::string& uri) : pimpl_(new PImpl), verifyPeers_(true), headersToLowerCase_(true), @@ -668,10 +668,10 @@ { Setup(); - if (service.GetUsername().size() != 0 && + if (service.GetUsername().size() != 0 && service.GetPassword().size() != 0) { - SetCredentials(service.GetUsername().c_str(), + SetCredentials(service.GetUsername().c_str(), service.GetPassword().c_str()); } @@ -686,7 +686,7 @@ SetUrl(Toolbox::JoinUri(service.GetUrl(), uri)); - for (WebServiceParameters::Dictionary::const_iterator + for (WebServiceParameters::Dictionary::const_iterator it = service.GetHttpHeaders().begin(); it != service.GetHttpHeaders().end(); ++it) { @@ -773,7 +773,7 @@ hasExternalBody_ = false; } - + void HttpClient::SetExternalBody(const void* data, size_t size) { @@ -791,7 +791,7 @@ externalBodySize_ = size; } } - + void HttpClient::SetExternalBody(const std::string& data) { @@ -853,7 +853,7 @@ CLOG(INFO, HTTP) << "New HTTP request to: " << url_ << " (timeout: " << (timeout_ <= 0 ? "no timeout" : boost::lexical_cast(timeout_) + "s") << ")"; - + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str())); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, &answer)); @@ -862,25 +862,25 @@ if (verifyPeers_) { -#if defined(CURLSSLOPT_NATIVE_CA) // from curl v 8.2.0 +#if defined(CURLSSLOPT_NATIVE_CA) // from curl v 8.2.0 if (caCertificates_.empty()) // use native CA store (equivalent to --ca-native) { CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA)); } - else + else #endif { // use provided CA file (equivalent to --cacert) CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CAINFO, caCertificates_.c_str())); } - + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYHOST, 2)); // libcurl default is strict verifyhost - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1)); } else { - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYHOST, 0)); - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYHOST, 0)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0)); } #endif @@ -1019,7 +1019,7 @@ CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_READDATA, &pimpl_->requestBody_)); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POST, 1L)); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDSIZE, -1L)); - + if (pimpl_->userHeaders_.IsEmpty()) { pimpl_->defaultChunkedHeaders_.Assign(pimpl_->curl_); @@ -1073,7 +1073,7 @@ CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &answer)); const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time(); - + if (boost::starts_with(url_, "https://")) { code = OrthancHttpClientPerformSSL(pimpl_->curl_, &status, url_); @@ -1084,7 +1084,7 @@ } const boost::posix_time::ptime end = boost::posix_time::microsec_clock::universal_time(); - + CLOG(INFO, HTTP) << "HTTP status code " << status << " in " << ((end - start).total_milliseconds()) << " ms after " << EnumerationToString(method_) << " request on: " << url_; @@ -1112,7 +1112,7 @@ } else { - LOG(ERROR) << "Error in HTTP request, received HTTP status " << status + LOG(ERROR) << "Error in HTTP request, received HTTP status " << status << " (" << EnumerationToString(lastStatus_) << ") after " << EnumerationToString(method_) << " request on: " << url_; return false; @@ -1219,7 +1219,7 @@ GlobalParameters::GetInstance().ConfigureSsl(httpsVerifyPeers, httpsVerifyCertificates); } - + void HttpClient::GlobalInitialize() { #if ORTHANC_ENABLE_SSL == 1 @@ -1238,7 +1238,7 @@ Pkcs11::Finalize(); #endif } - + void HttpClient::SetDefaultVerbose(bool verbose) { @@ -1311,7 +1311,7 @@ } } - + void HttpClient::ApplyAndThrowException(Json::Value& answerBody) { if (!Apply(answerBody)) @@ -1329,7 +1329,7 @@ ThrowException(GetLastStatus()); } } - + void HttpClient::ApplyAndThrowException(Json::Value& answerBody, HttpHeaders& answerHeaders) @@ -1341,7 +1341,7 @@ } - void HttpClient::SetClientCertificate(const boost::filesystem::path& certificateFile, + void HttpClient::SetClientCertificate(const boost::filesystem::path& certificateFile, const boost::filesystem::path &certificateKeyFile, const std::string& certificateKeyPassword) { @@ -1356,7 +1356,7 @@ "Cannot open certificate file: " + SystemToolbox::PathToUtf8(certificateFile)); } - if (!certificateKeyFile.empty() && + if (!certificateKeyFile.empty() && !SystemToolbox::IsRegularFile(certificateKeyFile)) { throw OrthancException(ErrorCode_InexistentFile, @@ -1419,9 +1419,9 @@ bool verbose) { #if ORTHANC_ENABLE_PKCS11 == 1 - CLOG(INFO, HTTP) << "Initializing PKCS#11 using " << module + CLOG(INFO, HTTP) << "Initializing PKCS#11 using " << module << (pin.empty() ? " (no PIN provided)" : " (PIN is provided)"); - GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose); + GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose); #else throw OrthancException(ErrorCode_InternalError, "This version of Orthanc is compiled without support for PKCS#11"); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpClient.h --- a/OrthancFramework/Sources/HttpClient.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpClient.h Wed Aug 19 14:11:33 2026 +0200 @@ -64,7 +64,7 @@ virtual ~IRequestBody() { } - + virtual bool ReadNextChunk(std::string& chunk) = 0; }; @@ -77,7 +77,7 @@ virtual void AddHeader(const std::string& key, const std::string& value) = 0; - + virtual void AddChunk(const void* data, size_t size) = 0; }; @@ -201,7 +201,7 @@ const boost::filesystem::path& GetHttpsCACertificates() const; - void SetClientCertificate(const boost::filesystem::path& certificateFile, + void SetClientCertificate(const boost::filesystem::path& certificateFile, const boost::filesystem::path& certificateKeyFile, const std::string& certificateKeyPassword); @@ -224,7 +224,7 @@ bool IsRedirectionFollowed() const; static void GlobalInitialize(); - + static void GlobalFinalize(); static void InitializePkcs11(const std::string& module, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/BufferHttpSender.cpp --- a/OrthancFramework/Sources/HttpServer/BufferHttpSender.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/BufferHttpSender.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -50,7 +50,7 @@ BufferHttpSender::BufferHttpSender() : data_(NULL), size_(0), - position_(0), + position_(0), chunkSize_(0), currentChunkSize_(0) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/CStringMatcher.cpp --- a/OrthancFramework/Sources/HttpServer/CStringMatcher.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/CStringMatcher.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -81,7 +81,7 @@ { return valid_; } - + bool CStringMatcher::Apply(const char* start, const char* end) @@ -94,7 +94,7 @@ } matchBegin_ = search_->Apply(start, end); - + if (matchBegin_ == end) { valid_ = false; @@ -109,7 +109,7 @@ return valid_; } - + bool CStringMatcher::Apply(const std::string& corpus) { if (corpus.empty()) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/CStringMatcher.h --- a/OrthancFramework/Sources/HttpServer/CStringMatcher.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/CStringMatcher.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,13 +37,13 @@ { private: class Search; - + boost::shared_ptr search_; // PImpl pattern std::string pattern_; bool valid_; const char* matchBegin_; const char* matchEnd_; - + public: explicit CStringMatcher(const std::string& pattern); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.cpp --- a/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -73,9 +73,9 @@ std::string h = Toolbox::FlattenUri(uri) + "/" + f; if (fs::is_directory(it->status())) s += "
  • " + f + "
  • "; - } + } - s += " "; + s += " "; s += "

    Files

    "; s += "
      "; @@ -92,7 +92,7 @@ { s += "
    • " + f + "
    • "; } - } + } s += "
    "; s += " "; @@ -109,9 +109,9 @@ Toolbox::SplitUriComponents(pimpl_->baseUri_, baseUri); pimpl_->root_ = root; listDirectoryContent_ = false; - + namespace fs = boost::filesystem; - if (!fs::exists(pimpl_->root_) || + if (!fs::exists(pimpl_->root_) || !fs::is_directory(pimpl_->root_)) { throw OrthancException(ErrorCode_DirectoryExpected); @@ -158,7 +158,7 @@ output.Answer(sender); } else if (listDirectoryContent_ && - fs::exists(p) && + fs::exists(p) && fs::is_directory(p)) { OutputDirectoryContent(output, headers, uri, p); @@ -169,5 +169,5 @@ } return true; - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/FilesystemHttpSender.cpp --- a/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -63,7 +63,7 @@ Initialize(path); } - FilesystemHttpSender::FilesystemHttpSender(const boost::filesystem::path& path, + FilesystemHttpSender::FilesystemHttpSender(const boost::filesystem::path& path, MimeType contentType) { SetContentType(contentType); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h --- a/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h Wed Aug 19 14:11:33 2026 +0200 @@ -49,7 +49,7 @@ FilesystemHttpSender(const std::string& path, MimeType contentType); - FilesystemHttpSender(const boost::filesystem::path& path, + FilesystemHttpSender(const boost::filesystem::path& path, MimeType contentType); FilesystemHttpSender(const FilesystemStorage& storage, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpContentNegociation.cpp --- a/OrthancFramework/Sources/HttpServer/HttpContentNegociation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpContentNegociation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -128,7 +128,7 @@ { handler_.Call(parameters_); } - + bool operator< (const Reference& other) const { if (level_ < other.level_) @@ -162,7 +162,7 @@ { first = Toolbox::StripSpaces(source.substr(0, pos)); second = Toolbox::StripSpaces(source.substr(pos + 1)); - return true; + return true; } } @@ -204,7 +204,7 @@ } } - + bool HttpContentNegociation::Apply(const Dictionary& headers) { Dictionary::const_iterator accept = headers.find("accept"); @@ -242,7 +242,7 @@ for (size_t i = 1; i < tokens.size(); i++) { std::string key, value; - + if (SplitPair(key, value, tokens[i], '=')) { // Remove the enclosing quotes, if present @@ -261,7 +261,7 @@ parameters[key] = value; } - + std::string type, subtype; if (SplitPair(type, subtype, tokens[0], '/')) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpContentNegociation.h --- a/OrthancFramework/Sources/HttpServer/HttpContentNegociation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpContentNegociation.h Wed Aug 19 14:11:33 2026 +0200 @@ -97,7 +97,7 @@ public: void Register(const std::string& mime, IHandler& handler); - + bool Apply(const Dictionary& headers); bool Apply(const std::string& accept); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpFileSender.cpp --- a/OrthancFramework/Sources/HttpServer/HttpFileSender.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpFileSender.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -80,7 +80,7 @@ return true; } } - + std::string HttpFileSender::GetContentType() { if (contentType_.empty()) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpFileSender.h --- a/OrthancFramework/Sources/HttpServer/HttpFileSender.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpFileSender.h Wed Aug 19 14:11:33 2026 +0200 @@ -55,7 +55,7 @@ bool /*deflateAllowed*/) ORTHANC_OVERRIDE; virtual bool HasContentFilename(std::string& filename) ORTHANC_OVERRIDE; - + virtual std::string GetContentType() ORTHANC_OVERRIDE; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpOutput.cpp --- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -52,7 +52,7 @@ { HttpOutput::StateMachine::StateMachine(IHttpOutputStream& stream, bool isKeepAlive, - unsigned int keepAliveTimeout) : + unsigned int keepAliveTimeout) : stream_(stream), state_(State_WritingHeader), isContentCompressible_(false), @@ -130,7 +130,7 @@ void HttpOutput::StateMachine::SetContentFilename(const char* filename) { - std::string sanitized = SanitizeFileName(filename); // since the filename might come from the API, we need to sanitize it to make + std::string sanitized = SanitizeFileName(filename); // since the filename might come from the API, we need to sanitize it to make // sure it does not add extra headers in the response with e.g: 'filename=toto.dcm"\r\nSet-Cookie:evil=1" AddHeader("Content-Disposition", "filename=\"" + sanitized + "\""); } @@ -201,7 +201,7 @@ stream_.OnHttpStatusReceived(status_); - std::string s = "HTTP/1.1 " + + std::string s = "HTTP/1.1 " + boost::lexical_cast(status_) + " " + std::string(EnumerationToString(status_)) + "\r\n"; @@ -308,7 +308,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } @@ -387,7 +387,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Please use the dedicated methods to this HTTP status code in HttpOutput"); } - + stateMachine_.SetHttpStatus(status); if (messageSize > 0 && @@ -486,7 +486,7 @@ { return stateMachine_.GetState() == StateMachine::State_WritingStream; } - + void HttpOutput::Answer(const void* buffer, size_t length) { @@ -514,7 +514,7 @@ encoding = "deflate"; ZlibCompressor compressor; // Do not prefix the buffer with its uncompressed size, to be compatible with "deflate" - compressor.SetPrefixWithUncompressedSize(false); + compressor.SetPrefixWithUncompressedSize(false); compressor.Compress(compressed, buffer, length); break; } @@ -626,9 +626,9 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + boundary.resize(70); - + contentTypeHeader = ("multipart/" + subType + "; type=" + tmp + "; boundary=" + boundary); } @@ -656,7 +656,7 @@ throw OrthancException(ErrorCode_NotImplemented, "Multipart answers are not implemented together " "with keep-alive connections if using Mongoose"); - + #elif ORTHANC_ENABLE_CIVETWEB == 1 # if CIVETWEB_HAS_DISABLE_KEEP_ALIVE == 1 // Turn off Keep-Alive for multipart answers @@ -668,7 +668,7 @@ // let's continue with Keep-Alive. Performance of WADO-RS will // decrease. header += "Connection: keep-alive\r\n"; -# endif +# endif #else # error Please support your embedded Web server here @@ -784,7 +784,7 @@ stream_.Send(false, item, length); } - stream_.Send(false, "\r\n", 2); + stream_.Send(false, "\r\n", 2); } @@ -827,12 +827,12 @@ } } } - + void HttpOutput::StateMachine::CloseStream() { LOG(TRACE) << "CloseStream"; - + if (state_ != State_WritingStream) { throw OrthancException(ErrorCode_BadSequenceOfCalls); @@ -861,7 +861,7 @@ buffer.Flatten(s); output.SetContentType(stream.GetContentType()); - + std::string filename; if (stream.HasContentFilename(filename)) { @@ -888,7 +888,7 @@ AnswerStreamAsBuffer(*this, stream); return; } - + break; } @@ -954,12 +954,12 @@ for (size_t i = 0; i < parts.size(); i++) { std::string partHeader; - PrepareMultipartItemHeader(partHeader, sizes[i], headers[i] == NULL ? empty : *headers[i], + PrepareMultipartItemHeader(partHeader, sizes[i], headers[i] == NULL ? empty : *headers[i], boundary, contentType); chunked.AddChunk(partHeader); chunked.AddChunk(parts[i], sizes[i]); - chunked.AddChunk("\r\n"); + chunked.AddChunk("\r\n"); } chunked.AddChunk("--" + boundary + "--\r\n"); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpOutput.h --- a/OrthancFramework/Sources/HttpServer/HttpOutput.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.h Wed Aug 19 14:11:33 2026 +0200 @@ -46,7 +46,7 @@ public: enum State { - State_WritingHeader, + State_WritingHeader, State_WritingBody, State_WritingMultipart, State_Done, @@ -103,7 +103,7 @@ void StartMultipart(const std::string& subType, const std::string& contentType); - void SendMultipartItem(const void* item, + void SendMultipartItem(const void* item, size_t length, const std::map& headers); @@ -167,7 +167,7 @@ const std::string& message); void SetContentType(MimeType contentType); - + void SetContentType(const std::string& contentType); void SetContentFilename(const char* filename); @@ -178,7 +178,7 @@ void AddHeader(const std::string& key, const std::string& value); - void Answer(const void* buffer, + void Answer(const void* buffer, size_t length); void Answer(const std::string& str); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpServer.cpp --- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -141,7 +141,7 @@ offset += packetSize; remainingSize -= packetSize; - } + } } } @@ -323,7 +323,7 @@ return PostDataStatus_Pending; } - /*void Print() + /*void Print() { boost::mutex::scoped_lock lock(mutex_); @@ -370,14 +370,14 @@ StringHttpOutput stringOutput; HttpOutput fakeOutput(stringOutput, false /* assume no keep-alive */, 0); HttpToolbox::GetArguments getArguments; - - if (!handler_.Handle(fakeOutput, RequestOrigin_RestApi, remoteIp_.c_str(), username_.c_str(), + + if (!handler_.Handle(fakeOutput, RequestOrigin_RestApi, remoteIp_.c_str(), username_.c_str(), HttpMethod_Post, uri_, headers, getArguments, part, size, authenticationPayload_)) { throw OrthancException(ErrorCode_UnknownResource); } } - + public: MultipartFormDataHandler(IHttpHandler& handler, ChunkStore& chunkStore, @@ -396,7 +396,7 @@ authenticationPayload_(authenticationPayload) { typedef HttpToolbox::Arguments::const_iterator Iterator; - + Iterator requestedWith = headers.find("x-requested-with"); if (requestedWith != headers.end() && requestedWith->second != "XMLHttpRequest") @@ -445,7 +445,7 @@ } } } - + virtual void HandlePart(const MultipartStreamReader::HttpHeaders& headers, const void* part, size_t size) ORTHANC_OVERRIDE @@ -490,10 +490,10 @@ const std::string& authenticationPayload) { MultipartFormDataHandler handler(GetHandler(), pimpl_->chunkStore_, remoteIp, username, uri, headers, authenticationPayload); - + MultipartStreamReader reader(boundary); reader.SetHandler(handler); - reader.AddChunk(body); + reader.AddChunk(body); reader.CloseStream(); } @@ -637,7 +637,7 @@ { return ReadBodyUsingFile(body, connection, hasMaxBodySize, maxBodySize); } - + static PostDataStatus ReadBodyToString(std::string& body, struct mg_connection *connection, @@ -686,7 +686,7 @@ { // No Content-Length: This is a chunked transfer. Stream the HTTP connection. std::string tmp(static_cast(1024) * 1024, 0); - + for (;;) { int r = mg_read(connection, &tmp[0], tmp.size()); @@ -708,14 +708,14 @@ } } - + enum AccessMode { AccessMode_Unauthorized, AccessMode_AuthorizationToken, AccessMode_RegisteredUser }; - + static AccessMode IsAccessGranted(const HttpServer& that, const HttpToolbox::Arguments& headers) @@ -858,7 +858,7 @@ else { return false; - } + } return true; } @@ -900,9 +900,9 @@ { CLOG(ERROR, HTTP) << "Orthanc was compiled without support for read-write access to WebDAV: " << uri; output.SendStatus(HttpStatus_403_Forbidden); - } + } # endif - + static bool HandleWebDav(HttpOutput& output, const HttpServer::WebDavBuckets& buckets, const std::string& method, @@ -916,13 +916,13 @@ { return false; // Speed up things if WebDAV is not used } - + /** * The "buckets" maps an URI relative to the root of the * bucket, to the content of the bucket. The root URI does *not* * contain a trailing slash. **/ - + if (method == "OPTIONS") { // Remove the trailing slash, if any (necessary for davfs2) @@ -932,7 +932,7 @@ { s.resize(s.size() - 1); } - + HttpServer::WebDavBuckets::const_iterator bucket = buckets.find(s); if (bucket == buckets.end()) { @@ -969,7 +969,7 @@ assert(!bucket->first.empty() && bucket->first[bucket->first.size() - 1] != '/' && bucket->second != NULL); - + if (uri == bucket->first || boost::starts_with(uri, bucket->first + "/")) { @@ -986,7 +986,7 @@ /** * WebDAV - PROPFIND **/ - + if (method == "PROPFIND") { HttpToolbox::Arguments::const_iterator i = headers.find("depth"); @@ -1003,9 +1003,9 @@ ErrorCode_NetworkProtocol, "WebDAV PROPFIND at unsupported depth (can only be 0 or 1): " + i->second); } - + std::string answer; - + MimeType mime; std::string content; boost::posix_time::ptime modificationTime = boost::posix_time::second_clock::universal_time(); @@ -1020,13 +1020,13 @@ else if (depth == 1) { IWebDavBucket::Collection c; - + if (!bucket->second->ListCollection(c, path)) { output.SendStatus(HttpStatus_404_NotFound); return true; } - + c.Format(answer, uri); } else @@ -1073,19 +1073,19 @@ output.SendStatus(HttpStatus_207_MultiStatus, answer); return true; } - + /** * WebDAV - GET and HEAD **/ - + else if (method == "GET" || method == "HEAD") { MimeType mime; std::string content; boost::posix_time::ptime modificationTime; - + if (bucket->second->GetFileContent(mime, content, modificationTime, path)) { output.AddHeader("Content-Type", EnumerationToString(mime)); @@ -1111,14 +1111,14 @@ return true; } - + /** * WebDAV - PUT **/ - + else if (method == "PUT") { -#if CIVETWEB_HAS_WEBDAV_WRITING == 1 +#if CIVETWEB_HAS_WEBDAV_WRITING == 1 std::string body; if (ReadBodyToString(body, connection, headers, hasMaxBodySize, maxBodySize) == PostDataStatus_Success) { @@ -1143,12 +1143,12 @@ return true; } - + /** * WebDAV - DELETE **/ - + else if (method == "DELETE") { if (bucket->second->DeleteItem(path)) @@ -1161,15 +1161,15 @@ } return true; } - + /** * WebDAV - MKCOL **/ - + else if (method == "MKCOL") { -#if CIVETWEB_HAS_WEBDAV_WRITING == 1 +#if CIVETWEB_HAS_WEBDAV_WRITING == 1 if (bucket->second->CreateFolder(path)) { //output.SendStatus(HttpStatus_200_Ok); @@ -1185,15 +1185,15 @@ return true; } - + /** * WebDAV - Faking PROPPATCH, LOCK and UNLOCK **/ - + else if (method == "PROPPATCH") { -#if CIVETWEB_HAS_WEBDAV_WRITING == 1 +#if CIVETWEB_HAS_WEBDAV_WRITING == 1 IWebDavBucket::AnswerFakedProppatch(output, uri); #else AnswerWebDavReadOnly(output, uri); @@ -1202,7 +1202,7 @@ } else if (method == "LOCK") { -#if CIVETWEB_HAS_WEBDAV_WRITING == 1 +#if CIVETWEB_HAS_WEBDAV_WRITING == 1 IWebDavBucket::AnswerFakedLock(output, uri); #else AnswerWebDavReadOnly(output, uri); @@ -1211,7 +1211,7 @@ } else if (method == "UNLOCK") { -#if CIVETWEB_HAS_WEBDAV_WRITING == 1 +#if CIVETWEB_HAS_WEBDAV_WRITING == 1 IWebDavBucket::AnswerFakedUnlock(output); #else AnswerWebDavReadOnly(output, uri); @@ -1224,7 +1224,7 @@ } } } - + return false; } else @@ -1232,10 +1232,10 @@ /** * WebDAV - Unapplicable method (such as POST and DELETE) **/ - + return false; } - } + } #endif /* ORTHANC_ENABLE_PUGIXML == 1 */ @@ -1280,10 +1280,10 @@ struct mg_connection *connection, const struct mg_request_info *request) { - // Since we don't control the thread creation ourselves, we set and clear - // the thread name everytime otherwise, the thread name will persist even + // Since we don't control the thread creation ourselves, we set and clear + // the thread name everytime otherwise, the thread name will persist even // after a call to /tools/reset and Orthanc would stop because the same thread name is used multiple times - Logging::ScopedCurrentThreadNameSetter setter(server.GetCurrentThreadName()); + Logging::ScopedCurrentThreadNameSetter setter(server.GetCurrentThreadName()); std::unique_ptr counter(server.CreateAvailableHttpThreadsDecounter()); @@ -1299,7 +1299,7 @@ #else # error #endif - + // Check remote calls if (!server.IsRemoteAccessAllowed() && !localhost) @@ -1341,14 +1341,14 @@ #if ORTHANC_ENABLE_MONGOOSE == 1 // Apply the filter, if it is installed char remoteIp[24]; - sprintf(remoteIp, "%d.%d.%d.%d", - reinterpret_cast(&request->remote_ip) [3], - reinterpret_cast(&request->remote_ip) [2], - reinterpret_cast(&request->remote_ip) [1], + sprintf(remoteIp, "%d.%d.%d.%d", + reinterpret_cast(&request->remote_ip) [3], + reinterpret_cast(&request->remote_ip) [2], + reinterpret_cast(&request->remote_ip) [1], reinterpret_cast(&request->remote_ip) [0]); const char* requestUri = request->uri; - + #elif ORTHANC_ENABLE_CIVETWEB == 1 const char* remoteIp = request->remote_addr; const char* requestUri = request->local_uri; @@ -1360,7 +1360,7 @@ { requestUri = ""; } - + const IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter(); @@ -1429,7 +1429,7 @@ #if ORTHANC_ENABLE_PUGIXML == 1 bool isWebDav = false; #endif - + HttpMethod filterMethod; std::unique_ptr apiLogTimer; // to log the time spent in the API call @@ -1437,7 +1437,7 @@ if (ExtractMethod(method, request, headers, argumentsGET)) { apiLogTimer.reset(new ApiElapsedTimeLogger(std::string(EnumerationToString(method)) + " " + Toolbox::FlattenUri(uri))); - + filterMethod = method; } #if ORTHANC_ENABLE_PUGIXML == 1 @@ -1465,7 +1465,7 @@ output.SendStatus(HttpStatus_400_BadRequest); return; } - + const std::string username = GetAuthenticatedUsername(headers); @@ -1477,7 +1477,7 @@ assert(accessMode == AccessMode_Unauthorized || // Could be the case if "!server.IsAuthenticationEnabled()" accessMode == AccessMode_RegisteredUser); - + if (filter != NULL && !filter->IsAllowed(filterMethod, requestUri, remoteIp, username.c_str(), headers, argumentsGET)) @@ -1524,7 +1524,7 @@ MultipartStreamReader::ParseMultipartContentType(type, subType, boundary, ct->second) && type == "multipart/form-data") { - /** + /** * The user uses the "upload" form of Orthanc Explorer, for * file uploads through a HTML form. **/ @@ -1548,7 +1548,7 @@ found = server.GetHandler().CreateChunkedRequestReader (stream, RequestOrigin_RestApi, remoteIp, username.c_str(), method, uri, headers, authenticationPayload); } - + if (found) { if (stream.get() == NULL) @@ -1595,10 +1595,10 @@ } } - if (!found && + if (!found && server.HasHandler()) { - found = server.GetHandler().Handle(output, RequestOrigin_RestApi, remoteIp, username.c_str(), + found = server.GetHandler().Handle(output, RequestOrigin_RestApi, remoteIp, username.c_str(), method, uri, headers, argumentsGET, body.c_str(), body.size(), authenticationPayload); } @@ -1629,7 +1629,7 @@ { requestUri = ""; } - + HttpServer* server = reinterpret_cast(that); if (server == NULL) @@ -1717,7 +1717,7 @@ struct mg_connection *connection, const struct mg_request_info *request) { - if (event == MG_NEW_REQUEST) + if (event == MG_NEW_REQUEST) { ProtectedCallback(connection, request); @@ -1788,7 +1788,7 @@ // Check for the Heartbleed exploit // https://en.wikipedia.org/wiki/OpenSSL#Heartbleed_bug if (OPENSSL_VERSION_NUMBER < 0x1000107fL /* openssl-1.0.1g */ && - OPENSSL_VERSION_NUMBER >= 0x1000100fL /* openssl-1.0.1 */) + OPENSSL_VERSION_NUMBER >= 0x1000100fL /* openssl-1.0.1 */) { CLOG(WARNING, HTTP) << "This version of OpenSSL is vulnerable to the Heartbleed exploit"; } @@ -1800,7 +1800,7 @@ { Stop(); -#if ORTHANC_ENABLE_PUGIXML == 1 +#if ORTHANC_ENABLE_PUGIXML == 1 for (WebDavBuckets::iterator it = webDavBuckets_.begin(); it != webDavBuckets_.end(); ++it) { assert(it->second != NULL); @@ -1840,7 +1840,7 @@ CLOG(INFO, HTTP) << "Starting embedded Web server using Civetweb"; #else # error -#endif +#endif if (!IsRunning()) { @@ -1877,7 +1877,7 @@ // Set the TCP port for the HTTP server options.push_back("listening_ports"); options.push_back(listeningPorts.c_str()); - + // Optimization reported by Chris Hafey // https://groups.google.com/d/msg/orthanc-users/CKueKX0pJ9E/_UCbl8T-VjIJ options.push_back("enable_keep_alive"); @@ -1908,7 +1908,7 @@ // Set the number of threads options.push_back("num_threads"); options.push_back(numThreads.c_str()); - + // Set the timeout for the HTTP server options.push_back("request_timeout_ms"); options.push_back(requestTimeoutMilliseconds.c_str()); @@ -1924,7 +1924,7 @@ options.push_back("ssl_ca_file"); options.push_back(dynamicStrings.back().c_str()); } - + if (ssl_) { // Restrict minimum SSL/TLS protocol version @@ -1988,7 +1988,7 @@ ERR_error_string_n(code, message, sizeof(message) - 1); CLOG(ERROR, HTTP) << "OpenSSL error: " << message; } - } + } #endif if (isSslError) @@ -2006,7 +2006,7 @@ { errorMsgDetails = listeningPorts; } - + if (errno != 0) // there might be additional details about the error in errno { errorMsgDetails += ", errno = " + boost::lexical_cast(errno) + ", " + strerror(errno); @@ -2017,7 +2017,7 @@ } } -#if ORTHANC_ENABLE_PUGIXML == 1 +#if ORTHANC_ENABLE_PUGIXML == 1 for (WebDavBuckets::iterator it = webDavBuckets_.begin(); it != webDavBuckets_.end(); ++it) { assert(it->second != NULL); @@ -2039,8 +2039,8 @@ if (IsRunning()) { mg_stop(pimpl_->context_); - -#if ORTHANC_ENABLE_PUGIXML == 1 + +#if ORTHANC_ENABLE_PUGIXML == 1 for (WebDavBuckets::iterator it = webDavBuckets_.begin(); it != webDavBuckets_.end(); ++it) { assert(it->second != NULL); @@ -2131,7 +2131,7 @@ sslMinimumVersion_ = version; std::string info; - + switch (version) { case 0: @@ -2181,12 +2181,12 @@ { sslCiphers_ += ':'; } - + sslCiphers_ += (*it); - } + } CLOG(INFO, HTTP) << "List of accepted SSL ciphers: " << sslCiphers_; - + if (sslCiphers_.empty()) { CLOG(WARNING, HTTP) << "No cipher is accepted for SSL"; @@ -2287,7 +2287,7 @@ { return filter_; } - + void HttpServer::SetIncomingHttpRequestFilter(IIncomingHttpRequestFilter& filter) { Stop(); @@ -2352,7 +2352,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + Stop(); threadsCount_ = threads; @@ -2369,7 +2369,7 @@ return threadsCount_; } - + void HttpServer::SetTcpNoDelay(bool tcpNoDelay) { Stop(); @@ -2423,7 +2423,7 @@ } Stop(); - + #if CIVETWEB_HAS_WEBDAV_WRITING == 0 if (webDavBuckets_.size() == 0) { @@ -2431,7 +2431,7 @@ << "without support for writing into WebDAV collections"; } #endif - + const std::string s = Toolbox::FlattenUri(root); if (webDavBuckets_.find(s) != webDavBuckets_.end()) @@ -2483,10 +2483,10 @@ if (threadNames_.find(threadId) == threadNames_.end()) { boost::upgrade_to_unique_lock writerLock(readerLock); - + std::string thisThreadName = std::string("HTTP-") + boost::lexical_cast(threadCounter_++); threadNames_[threadId] = thisThreadName; - + return thisThreadName; } else diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpServer.h --- a/OrthancFramework/Sources/HttpServer/HttpServer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.h Wed Aug 19 14:11:33 2026 +0200 @@ -83,7 +83,7 @@ #if ORTHANC_ENABLE_PUGIXML == 1 typedef std::map WebDavBuckets; #endif - + private: // http://stackoverflow.com/questions/311166/stdauto-ptr-or-boostshared-ptr-for-pimpl-idiom struct PImpl; @@ -130,7 +130,7 @@ #if ORTHANC_ENABLE_PUGIXML == 1 WebDavBuckets webDavBuckets_; #endif - + bool IsRunning() const; public: @@ -168,7 +168,7 @@ void SetSslMinimumVersion(unsigned int version); void SetSslCiphers(const std::list& ciphers); - + void SetSslTrustedClientCertificates(const boost::filesystem::path& path); bool IsKeepAliveEnabled() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.cpp --- a/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + uint64_t size = source_.GetContentLength(); if (static_cast(static_cast(size)) != size) { @@ -212,7 +212,7 @@ else if (s == remaining) { // We have skipped enough bytes, but we must read a new chunk - currentChunkOffset_ = 0; + currentChunkOffset_ = 0; skipped_ = bytesToSkip_; return source_.ReadNextChunk(); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpToolbox.cpp --- a/OrthancFramework/Sources/HttpServer/HttpToolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpToolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -39,7 +39,7 @@ const char* end) { std::string name, value; - + const char* equal = strchr(start, '='); if (equal == NULL || equal >= end) { @@ -64,7 +64,7 @@ } - void HttpToolbox::ParseGetArguments(GetArguments& result, + void HttpToolbox::ParseGetArguments(GetArguments& result, const char* query) { const char* pos = query; @@ -88,7 +88,7 @@ void HttpToolbox::ParseGetQuery(UriComponents& uri, - GetArguments& getArguments, + GetArguments& getArguments, const char* query) { const char *questionMark = ::strchr(query, '?'); @@ -102,10 +102,10 @@ { Toolbox::SplitUriComponents(uri, std::string(query, questionMark)); HttpToolbox::ParseGetArguments(getArguments, questionMark + 1); - } + } } - + std::string HttpToolbox::GetArgument(const Arguments& getArguments, const std::string& name, const std::string& defaultValue) @@ -139,7 +139,7 @@ - void HttpToolbox::ParseCookies(Arguments& result, + void HttpToolbox::ParseCookies(Arguments& result, const Arguments& httpHeaders) { result.clear(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/HttpToolbox.h --- a/OrthancFramework/Sources/HttpServer/HttpToolbox.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpToolbox.h Wed Aug 19 14:11:33 2026 +0200 @@ -35,18 +35,18 @@ namespace Orthanc { class IHttpHandler; - + class ORTHANC_PUBLIC HttpToolbox : public boost::noncopyable { public: typedef std::map Arguments; typedef std::vector< std::pair > GetArguments; - static void ParseGetArguments(GetArguments& result, + static void ParseGetArguments(GetArguments& result, const char* query); static void ParseGetQuery(UriComponents& uri, - GetArguments& getArguments, + GetArguments& getArguments, const char* query); static std::string GetArgument(const Arguments& getArguments, @@ -57,7 +57,7 @@ const std::string& name, const std::string& defaultValue); - static void ParseCookies(Arguments& result, + static void ParseCookies(Arguments& result, const Arguments& httpHeaders); static void CompileGetArguments(Arguments& compiled, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/IHttpHandler.cpp --- a/OrthancFramework/Sources/HttpServer/IHttpHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/IHttpHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ StringHttpOutput stream; HttpOutput http(stream, false /* assume no keep-alive */, 0); - if (handler.Handle(http, origin, LOCALHOST, "", HttpMethod_Get, curi, + if (handler.Handle(http, origin, LOCALHOST, "", HttpMethod_Get, curi, httpHeaders, getArguments, NULL /* no body for GET */, 0, "" /* no authentication payload */)) { if (stream.GetStatus() == HttpStatus_200_Ok) @@ -60,7 +60,7 @@ { stream.GetHeaders(*answerHeaders, true /* convert key to lower case */); } - + return stream.GetStatus(); } else @@ -88,7 +88,7 @@ StringHttpOutput stream; HttpOutput http(stream, false /* assume no keep-alive */, 0); - if (handler.Handle(http, origin, LOCALHOST, "", method, curi, + if (handler.Handle(http, origin, LOCALHOST, "", method, curi, httpHeaders, getArguments, bodyData, bodySize, "" /* no authentication payload */)) { stream.GetBody(answerBody); @@ -97,7 +97,7 @@ { stream.GetHeaders(*answerHeaders, true /* convert key to lower case */); } - + return stream.GetStatus(); } else @@ -148,7 +148,7 @@ StringHttpOutput stream; HttpOutput http(stream, false /* assume no keep-alive */, 0); - if (handler.Handle(http, origin, LOCALHOST, "", HttpMethod_Delete, curi, + if (handler.Handle(http, origin, LOCALHOST, "", HttpMethod_Delete, curi, httpHeaders, getArguments, NULL /* no body for DELETE */, 0, "" /* no authentication payload */)) { stream.GetBody(answerBody); @@ -157,7 +157,7 @@ { stream.GetHeaders(*answerHeaders, true /* convert key to lower case */); } - + return stream.GetStatus(); } else diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h --- a/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h Wed Aug 19 14:11:33 2026 +0200 @@ -54,7 +54,7 @@ const char* ip, const HttpToolbox::Arguments& httpHeaders, const HttpToolbox::GetArguments& getArguments) const = 0; - + // This method corresponds to HTTP authorization alone virtual bool IsAllowed(HttpMethod method, const char* uri, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp --- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -91,7 +91,7 @@ else { creationTime_ = t; - + if (!hasModificationTime_) { modificationTime_ = t; @@ -148,7 +148,7 @@ prop.append_child("D:quota-available-bytes"); prop.append_child("D:quota-used-bytes"); #endif - + #if 0 prop.append_child("D:lockdiscovery"); pugi::xml_node lock = prop.append_child("D:supportedlock"); @@ -163,7 +163,7 @@ #endif } - + IWebDavBucket::File::File(const std::string& displayName) : Resource(displayName), hasContentLength_(false), @@ -172,7 +172,7 @@ { } - + void IWebDavBucket::File::SetContentLength(uint64_t contentLength) { hasContentLength_ = true; @@ -221,7 +221,7 @@ href = AddLeadingSlash(href); FormatInternal(node, href, GetDisplayName(), GetCreationTime(), GetModificationTime()); - + pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); prop.append_child("D:resourcetype").append_child("D:collection"); @@ -275,13 +275,13 @@ std::vector tokens; Toolbox::SplitUriComponents(tokens, parentPath); - + std::string folder; if (!tokens.empty()) { folder = tokens.back(); } - + std::string href; Toolbox::UriEncode(href, tokens); href = AddTrailingSlash(AddLeadingSlash(href)); @@ -316,7 +316,7 @@ * This is a fake implementation. The goal is to make happy the * WebDAV clients that set properties (such as Windows >= 7). **/ - + pugi::xml_document doc; pugi::xml_node root = doc.append_child("D:multistatus"); @@ -335,7 +335,7 @@ Toolbox::XmlToString(s, doc); output.AddHeader("Content-Type", "application/xml"); - output.SendStatus(HttpStatus_207_MultiStatus, s); + output.SendStatus(HttpStatus_207_MultiStatus, s); } @@ -347,7 +347,7 @@ * created. The goal is to make happy the WebDAV clients * that use locking (such as Windows >= 7). **/ - + pugi::xml_document doc; pugi::xml_node root = doc.append_child("D:prop"); @@ -366,10 +366,10 @@ std::string token = Toolbox::GenerateUuid(); boost::erase_all(token, "-"); token = "opaquelocktoken:0x" + token; - + activelock.append_child("D:locktoken").append_child("D:href"). append_child(pugi::node_pcdata).set_value(token.c_str()); - + pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); decl.append_attribute("version").set_value("1.0"); decl.append_attribute("encoding").set_value("UTF-8"); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/IWebDavBucket.h --- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.h Wed Aug 19 14:11:33 2026 +0200 @@ -46,7 +46,7 @@ namespace Orthanc { class HttpOutput; - + class IWebDavBucket : public boost::noncopyable { public: @@ -128,7 +128,7 @@ Resource(displayName) { } - + virtual void Format(pugi::xml_node& node, const std::string& parentPath) const ORTHANC_OVERRIDE; }; @@ -167,7 +167,7 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, + boost::posix_time::ptime& modificationTime, const std::vector& path) = 0; // "false" returns indicate a read-only target diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp --- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -77,7 +77,7 @@ else { int64_t value; - + try { value = boost::lexical_cast(it->second); @@ -134,27 +134,27 @@ assert(current <= corpusEnd); buffer_.AddChunk(current, corpusEnd - current); return; - } - } - + } + } + for (;;) { assert(current <= corpusEnd); - + size_t patternSize = boundaryMatcher_.GetPattern().size(); size_t remainingSize = corpusEnd - current; if (remainingSize < patternSize + 2) { break; // Not enough data available } - + std::string boundary(current, current + patternSize + 2); if (boundary == boundaryMatcher_.GetPattern() + "--") { state_ = State_Done; return; } - + if (boundary != boundaryMatcher_.GetPattern() + "\r\n") { throw OrthancException(ErrorCode_NetworkProtocol, @@ -162,7 +162,7 @@ } const char* start = current + patternSize + 2; - + if (!headersMatcher_.Apply(start, corpusEnd)) { break; // Not enough data available @@ -207,7 +207,7 @@ throw OrthancException(ErrorCode_NetworkProtocol, "No endline at the end of a part"); } - + handler_->HandlePart(headers, headersMatcher_.GetMatchEnd(), contentLength); current = headersMatcher_.GetMatchEnd() + contentLength + 2; } @@ -217,9 +217,9 @@ assert(current < corpusEnd); buffer_.AddChunk(current, corpusEnd - current); } - } + } } - + void MultipartStreamReader::ParseStream() { @@ -260,7 +260,7 @@ else { blockSize_ = size; - } + } } size_t MultipartStreamReader::GetBlockSize() const @@ -348,7 +348,7 @@ value = value.substr(1, value.size() - 2); } } - + bool MultipartStreamReader::ParseMultipartContentType(std::string& contentType, std::string& subType, @@ -387,7 +387,7 @@ // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=190 RemoveSurroundingQuotes(boundary); - + valid = !boundary.empty(); } else if (boost::iequals("type", Toolbox::StripSpaces(items[0]))) @@ -405,7 +405,7 @@ return valid; } - + bool MultipartStreamReader::ParseHeaderArguments(std::string& main, std::map& arguments, const std::string& header) @@ -426,7 +426,7 @@ } arguments.clear(); - + for (size_t i = 1; i < tokens.size(); i++) { std::vector items; @@ -440,7 +440,7 @@ { std::string key = Toolbox::StripSpaces(items[0]); Toolbox::ToLowerCase(key); - + if (arguments.find(key) != arguments.end()) { LOG(ERROR) << "The same argument was provided twice in an HTTP header: \"" diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/MultipartStreamReader.h --- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -35,19 +35,19 @@ { public: typedef std::map HttpHeaders; - + class IHandler : public boost::noncopyable { public: virtual ~IHandler() { } - + virtual void HandlePart(const HttpHeaders& headers, const void* part, size_t size) = 0; }; - + private: enum State { @@ -55,7 +55,7 @@ State_Content, State_Done }; - + State state_; IHandler* handler_; CStringMatcher headersMatcher_; @@ -65,7 +65,7 @@ void ParseBlock(const void* data, size_t size); - + void ParseStream(); public: @@ -76,7 +76,7 @@ size_t GetBlockSize() const; void SetHandler(IHandler& handler); - + void AddChunk(const void* chunk, size_t size); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/StringHttpOutput.cpp --- a/OrthancFramework/Sources/HttpServer/StringHttpOutput.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/StringHttpOutput.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -64,7 +64,7 @@ } } - + void StringHttpOutput::GetBody(std::string& output) { if (!validBody_) @@ -112,7 +112,7 @@ { Toolbox::ToLowerCase(key); } - + const std::string value = lines[i].substr(colon + 1); target[Toolbox::StripSpaces(key)] = Toolbox::StripSpaces(value); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/StringMatcher.cpp --- a/OrthancFramework/Sources/HttpServer/StringMatcher.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/StringMatcher.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -59,7 +59,7 @@ #endif } }; - + StringMatcher::StringMatcher(const std::string& pattern) : pattern_(pattern), @@ -81,7 +81,7 @@ { return valid_; } - + bool StringMatcher::Apply(Iterator start, Iterator end) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/StringMatcher.h --- a/OrthancFramework/Sources/HttpServer/StringMatcher.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/StringMatcher.h Wed Aug 19 14:11:33 2026 +0200 @@ -40,13 +40,13 @@ private: class Search; - + boost::shared_ptr search_; // PImpl pattern std::string pattern_; bool valid_; Iterator matchBegin_; Iterator matchEnd_; - + public: explicit StringMatcher(const std::string& pattern); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/WebDavStorage.cpp --- a/OrthancFramework/Sources/HttpServer/WebDavStorage.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/WebDavStorage.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -45,14 +45,14 @@ { time_ = boost::posix_time::second_clock::universal_time(); } - + public: StorageFile() : mime_(MimeType_Binary) { Touch(); } - + void SetContent(const std::string& content, MimeType mime, bool isMemory) @@ -68,7 +68,7 @@ file_.reset(new TemporaryFile); file_->Write(content); } - + mime_ = mime; Touch(); } @@ -147,20 +147,20 @@ { Touch(); } - + ~StorageFolder() { for (Files::iterator it = files_.begin(); it != files_.end(); ++it) { assert(it->second != NULL); delete it->second; - } + } for (Subfolders::iterator it = subfolders_.begin(); it != subfolders_.end(); ++it) { assert(it->second != NULL); delete it->second; - } + } } size_t GetSize() const @@ -172,7 +172,7 @@ { return time_; } - + const StorageFile* LookupFile(const std::string& name) const { Files::const_iterator found = files_.find(name); @@ -229,7 +229,7 @@ assert(found->second != NULL); found->second->SetContent(content, mime, isMemory); } - + Touch(); return true; } @@ -262,7 +262,7 @@ for (Files::const_iterator it = files_.begin(); it != files_.end(); ++it) { assert(it->second != NULL); - + std::unique_ptr f(new File(it->first)); f->SetContentLength(it->second->GetContentLength()); f->SetCreationTime(it->second->GetTime()); @@ -340,7 +340,7 @@ void RemoveEmptyFolders() { std::list emptyFolders; - + for (Subfolders::const_iterator it = subfolders_.begin(); it != subfolders_.end(); ++it) { assert(it->second != NULL); @@ -350,7 +350,7 @@ { assert(it->second != NULL); delete it->second; - + emptyFolders.push_back(it->first); } } @@ -372,31 +372,31 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - std::vector p(path.begin(), path.end() - 1); + std::vector p(path.begin(), path.end() - 1); return root_->LookupFolder(p); } - + WebDavStorage::WebDavStorage(bool isMemory) : root_(new StorageFolder), isMemory_(isMemory) { } - + bool WebDavStorage::IsExistingFolder(const std::vector& path) { boost::recursive_mutex::scoped_lock lock(mutex_); - + return (root_->LookupFolder(path) != NULL); } - + bool WebDavStorage::ListCollection(Collection& collection, const std::vector& path) { boost::recursive_mutex::scoped_lock lock(mutex_); - + const StorageFolder* folder = root_->LookupFolder(path); if (folder == NULL) { @@ -409,15 +409,15 @@ } } - + bool WebDavStorage::GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, + boost::posix_time::ptime& modificationTime, const std::vector& path) { boost::recursive_mutex::scoped_lock lock(mutex_); - - const StorageFolder* folder = LookupParentFolder(path); + + const StorageFolder* folder = LookupParentFolder(path); if (folder == NULL) { return false; @@ -439,12 +439,12 @@ } } - + bool WebDavStorage::StoreFile(const std::string& content, const std::vector& path) { boost::recursive_mutex::scoped_lock lock(mutex_); - + StorageFolder* folder = LookupParentFolder(path); if (folder == NULL) { @@ -461,12 +461,12 @@ } } - + bool WebDavStorage::CreateFolder(const std::vector& path) { boost::recursive_mutex::scoped_lock lock(mutex_); - StorageFolder* folder = LookupParentFolder(path); + StorageFolder* folder = LookupParentFolder(path); if (folder == NULL) { LOG(WARNING) << "Inexisting folder in WebDAV: " << Toolbox::FlattenUri(path); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/HttpServer/WebDavStorage.h --- a/OrthancFramework/Sources/HttpServer/WebDavStorage.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/HttpServer/WebDavStorage.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ private: class StorageFile; class StorageFolder; - + StorageFolder* LookupParentFolder(const std::vector& path); boost::shared_ptr root_; // PImpl @@ -45,7 +45,7 @@ public: explicit WebDavStorage(bool isMemory); - + virtual bool IsExistingFolder(const std::vector& path) ORTHANC_OVERRIDE; virtual bool ListCollection(Collection& collection, @@ -53,9 +53,9 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, + boost::posix_time::ptime& modificationTime, const std::vector& path) ORTHANC_OVERRIDE; - + virtual bool StoreFile(const std::string& content, const std::vector& path) ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/IDynamicObject.h --- a/OrthancFramework/Sources/IDynamicObject.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/IDynamicObject.h Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ { } }; - + /** * This class is a simple implementation of a IDynamicObject that @@ -54,7 +54,7 @@ { private: T value_; - + public: explicit SingleValueObject(const T& value) : value_(value) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/Font.cpp --- a/OrthancFramework/Sources/Images/Font.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/Font.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -102,7 +102,7 @@ } std::unique_ptr c(new Character); - + c->advance_ = info["Advance"].asUInt(); c->height_ = info["Height"].asUInt(); c->top_ = info["Top"].asUInt(); @@ -113,7 +113,7 @@ { maxHeight_ = c->height_; } - + for (Json::Value::ArrayIndex j = 0; j < info["Bitmap"].size(); j++) { if (info["Bitmap"][j].type() != Json::intValue) @@ -341,7 +341,7 @@ color[3] = 255; break; } - + DrawInternal(target, utf8, x, y, color); } @@ -352,7 +352,7 @@ { width = 0; height = 0; - + #if ORTHANC_ENABLE_LOCALE == 1 std::string s = Toolbox::ConvertFromUtf8(utf8, Encoding_Latin1); #else @@ -364,7 +364,7 @@ // Compute the text extent unsigned int x = 0; unsigned int y = 0; - + for (size_t i = 0; i < s.size(); i++) { if (s[i] == '\n') @@ -385,7 +385,7 @@ { height = bottom; } - + if (x > width) { width = x; @@ -404,7 +404,7 @@ { unsigned int width, height; ComputeTextExtent(width, height, utf8); - + std::unique_ptr target(new Image(format, width, height, false)); ImageProcessing::Set(*target, 0, 0, 0, 255); Draw(*target, utf8, 0, 0, r, g, b); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/Image.cpp --- a/OrthancFramework/Sources/Images/Image.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/Image.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -39,7 +39,7 @@ { ImageAccessor accessor; image_.GetWriteableAccessor(accessor); - + AssignWritable(format, width, height, accessor.GetPitch(), accessor.GetBuffer()); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageAccessor.cpp --- a/OrthancFramework/Sources/Images/ImageAccessor.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageAccessor.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -83,22 +83,22 @@ for (unsigned int y = 0; y < height; y++) { const uint8_t* p = reinterpret_cast(source.GetConstRow(y)); - + std::string s; s.reserve(static_cast(width) * 3 * 8); - + for (unsigned int x = 0; x < 3 * width; x++, p++) { s += boost::lexical_cast(static_cast(*p)) + " "; } - + target.AddChunk(s); } target.AddChunk("], [ 3 " + boost::lexical_cast(height) + " " + boost::lexical_cast(width) + " ]), [ 3 2 1 ]))"); } - + ImageAccessor::ImageAccessor() { @@ -318,7 +318,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); - } + } buffer.Flatten(target); } @@ -336,7 +336,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if (width == 0 || height == 0) { @@ -344,7 +344,7 @@ } else { - uint8_t* p = (buffer_ + + uint8_t* p = (buffer_ + static_cast(y) * static_cast(pitch_) + static_cast(x) * static_cast(GetBytesPerPixel())); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageAccessor.h --- a/OrthancFramework/Sources/Images/ImageAccessor.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageAccessor.h Wed Aug 19 14:11:33 2026 +0200 @@ -38,7 +38,7 @@ private: template friend struct ImageTraits; - + bool readOnly_; PixelFormat format_; unsigned int width_; @@ -108,7 +108,7 @@ void GetWriteableAccessor(ImageAccessor& target) const; - void ToMatlabString(std::string& target) const; + void ToMatlabString(std::string& target) const; void GetRegion(ImageAccessor& accessor, unsigned int x, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageBuffer.cpp --- a/OrthancFramework/Sources/Images/ImageBuffer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageBuffer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -153,7 +153,7 @@ if (width != width_) { changed_ = true; - width_ = width; + width_ = width; } } @@ -168,7 +168,7 @@ if (height != height_) { changed_ = true; - height_ = height; + height_ = height; } } @@ -177,13 +177,13 @@ return ::Orthanc::GetBytesPerPixel(format_); } - + void ImageBuffer::GetReadOnlyAccessor(ImageAccessor& accessor) { Allocate(); accessor.AssignReadOnly(format_, width_, height_, pitch_, buffer_); } - + void ImageBuffer::GetWriteableAccessor(ImageAccessor& accessor) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageBuffer.h --- a/OrthancFramework/Sources/Images/ImageBuffer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageBuffer.h Wed Aug 19 14:11:33 2026 +0200 @@ -45,7 +45,7 @@ void *buffer_; void Initialize(); - + void Allocate(); void Deallocate(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageProcessing.cpp --- a/OrthancFramework/Sources/Images/ImageProcessing.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -95,7 +95,7 @@ const unsigned int width = source.GetWidth(); const unsigned int height = source.GetHeight(); - + for (unsigned int y = 0; y < height; y++) { TargetType* t = reinterpret_cast(target.GetRow(y)); @@ -128,7 +128,7 @@ const unsigned int width = source.GetWidth(); const unsigned int height = source.GetHeight(); - + for (unsigned int y = 0; y < height; y++) { float* t = reinterpret_cast(target.GetRow(y)); @@ -147,7 +147,7 @@ const ImageAccessor& source) { typedef typename PixelTraits::PixelType TargetType; - + assert(sizeof(float) == 4); const unsigned int width = source.GetWidth(); @@ -180,7 +180,7 @@ const unsigned int width = source.GetWidth(); const unsigned int height = source.GetHeight(); - + for (unsigned int y = 0; y < height; y++) { TargetType* t = reinterpret_cast(target.GetRow(y)); @@ -192,7 +192,7 @@ int32_t v = (2126 * static_cast(s[0]) + 7152 * static_cast(s[1]) + 0722 * static_cast(s[2])) / 10000; - + if (static_cast(v) < static_cast(minValue)) { *t = minValue; @@ -217,7 +217,7 @@ const size_t pitch = image.GetPitch(); uint8_t *p = reinterpret_cast(image.GetBuffer()); - + for (unsigned int y = 0; y < height; y++) { memset(p, 0, lineSize); @@ -316,7 +316,7 @@ const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight(); - + for (unsigned int y = 0; y < height; y++) { PixelType* p = reinterpret_cast(image.GetRow(y)); @@ -411,7 +411,7 @@ // This function can be applied inplace (source == target) { assert(target.GetFormat() != PixelFormat_Float32); - + if (source.GetWidth() != target.GetWidth() || source.GetHeight() != target.GetHeight()) { @@ -423,7 +423,7 @@ { throw OrthancException(ErrorCode_IncompatibleImageFormat); } - + const TargetType minPixelValue = std::numeric_limits::min(); const TargetType maxPixelValue = std::numeric_limits::max(); const float minFloatValue = static_cast(minPixelValue); @@ -431,7 +431,7 @@ const unsigned int height = target.GetHeight(); const unsigned int width = target.GetWidth(); - + for (unsigned int y = 0; y < height; y++) { TargetType* p = reinterpret_cast(target.GetRow(y)); @@ -450,7 +450,7 @@ *p = minPixelValue; } else if (UseRound) - { + { // The "round" operation is very costly assert(sizeof(TargetType) < sizeof(int)); *p = static_cast(Math::iround(v)); @@ -477,7 +477,7 @@ // This function can be applied inplace (source == target) { assert(target.GetFormat() == PixelFormat_Float32); - + if (source.GetWidth() != target.GetWidth() || source.GetHeight() != target.GetHeight()) { @@ -489,10 +489,10 @@ { throw OrthancException(ErrorCode_IncompatibleImageFormat); } - + const unsigned int height = target.GetHeight(); const unsigned int width = target.GetWidth(); - + for (unsigned int y = 0; y < height; y++) { float* p = reinterpret_cast(target.GetRow(y)); @@ -504,7 +504,7 @@ } } } - + template static void ShiftRightInternal(ImageAccessor& image, @@ -577,10 +577,10 @@ { assert(sizeof(SourceType) == source.GetBytesPerPixel() && sizeof(TargetType) == target.GetBytesPerPixel()); - + const TargetType maxTargetValue = std::numeric_limits::max(); const float maxFloatValue = static_cast(maxTargetValue); - + const float windowIntercept = windowCenter - windowWidth / 2.0f; const float windowSlope = (maxFloatValue + 1.0f) / windowWidth; @@ -784,7 +784,7 @@ return; } - + if (target.GetFormat() == PixelFormat_Grayscale8 && source.GetFormat() == PixelFormat_RGBA32) { @@ -1138,13 +1138,13 @@ case PixelFormat_Grayscale8: { // New in Orthanc 1.9.0 - uint8_t grayscale = (2126 * static_cast(red) + + uint8_t grayscale = (2126 * static_cast(red) + 7152 * static_cast(green) + 0722 * static_cast(blue)) / 10000; Orthanc::ImageProcessing::Set(image, grayscale); return; } - + case PixelFormat_RGBA32: p[0] = red; p[1] = green; @@ -1502,7 +1502,7 @@ return (std::abs(offset) <= 10.0f * std::numeric_limits::epsilon() && std::abs(scaling - 1.0f) <= 10.0f * std::numeric_limits::epsilon()); } - + void ImageProcessing::ShiftScale2(ImageAccessor& image, float offset, @@ -1517,7 +1517,7 @@ { return; } - + switch (image.GetFormat()) { case PixelFormat_Grayscale8: @@ -1579,14 +1579,14 @@ // We compute "a * x + b" const float a = scaling; const float b = offset; - + if (target.GetFormat() == source.GetFormat() && IsIdentityRescaling(offset, scaling)) { Copy(target, source); return; } - + switch (target.GetFormat()) { case PixelFormat_Grayscale8: @@ -1640,7 +1640,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } @@ -1766,7 +1766,7 @@ for (int x = x0; x <= x1; x++) { Write(x, y); - + if (d > 0) { y = y + yi; @@ -1776,7 +1776,7 @@ d = d + 2*dy; } } - + void PlotLineHigh(int x0, int y0, int x1, @@ -1798,7 +1798,7 @@ for (int y = y0; y <= y1; y++) { Write(x, y); - + if (d > 0) { x = x + xi; @@ -1871,7 +1871,7 @@ }; } - + void ImageProcessing::DrawLineSegment(ImageAccessor& image, int x0, int y0, @@ -1907,7 +1907,7 @@ } } - + void ImageProcessing::DrawLineSegment(ImageAccessor& image, int x0, int y0, @@ -2019,7 +2019,7 @@ static_cast(upper.GetY() - lower.GetY())); xIntersect = lower.GetX(); #endif - + if (upper.GetY() < yComp) { yUpper = upper.GetY() - 1; @@ -2069,7 +2069,7 @@ return static_cast(std::ceil(xIntersect)); #endif } - + int GetExitX() const { #if USE_POLYGON_FRACTIONS == 1 @@ -2079,7 +2079,7 @@ return static_cast(std::floor(xIntersect)); #endif } - + int GetUpperY() const { return yUpper; @@ -2098,7 +2098,7 @@ } }; } - + // For an index, return y-coordinate of next nonhorizontal line static int GetPolygonNextY(const std::vector& points, @@ -2106,7 +2106,7 @@ { // cf. "yNext()" in textbook size_t j = k; - + for (;;) { j++; @@ -2156,7 +2156,7 @@ * 117-124) of textbook "Computer Graphics - C Version (2nd * Edition)" by Hearn and Baker, 1997. **/ - + typedef std::map > EdgeTable; if (points.size() < 2) @@ -2223,10 +2223,10 @@ // Error in the textbook: "yPrev" must NOT be updated on horizontal lines yPrev = v1.GetY(); } - + v1 = v2; } - + assert(!globalEdgeTable.empty()); std::vector activeEdges; @@ -2308,7 +2308,7 @@ } } - + void ImageProcessing::FillPolygon(ImageAccessor& image, const std::vector& points, int64_t value) @@ -2326,13 +2326,13 @@ value_(value) { } - + virtual void Fill(int y, int x1, int x2) ORTHANC_OVERRIDE { assert(x1 <= x2); - + if (x1 < static_cast(image_.GetWidth()) && x2 >= 0 && y >= 0 && @@ -2351,7 +2351,7 @@ } }; - + if (image.GetFormat() == PixelFormat_Grayscale8 || image.GetFormat() == PixelFormat_Grayscale16 || image.GetFormat() == PixelFormat_SignedGrayscale16) @@ -2372,7 +2372,7 @@ { assert(target.GetFormat() == source.GetFormat() && target.GetFormat() == Format); - + const unsigned int sourceWidth = source.GetWidth(); const unsigned int sourceHeight = source.GetHeight(); const unsigned int targetWidth = target.GetWidth(); @@ -2389,7 +2389,7 @@ ImageProcessing::Set(target, 0); return; } - + const float scaleX = static_cast(sourceWidth) / static_cast(targetWidth); const float scaleY = static_cast(sourceHeight) / static_cast(targetHeight); @@ -2399,9 +2399,9 @@ * in the source image, given the (x,y) position in the target * image. **/ - + std::vector lookupX(targetWidth); - + for (unsigned int x = 0; x < targetWidth; x++) { int sourceX = static_cast(std::floor((static_cast(x) + 0.5f) * scaleX)); @@ -2416,9 +2416,9 @@ lookupX[x] = static_cast(sourceX); } - + std::vector lookupY(targetHeight); - + for (unsigned int y = 0; y < targetHeight; y++) { int sourceY = static_cast(std::floor((static_cast(y) + 0.5f) * scaleY)); @@ -2438,7 +2438,7 @@ /** * Actual resizing **/ - + for (unsigned int targetY = 0; targetY < targetHeight; targetY++) { unsigned int sourceY = lookupY[targetY]; @@ -2451,7 +2451,7 @@ ImageTraits::GetPixel(pixel, source, sourceX, sourceY); ImageTraits::SetPixel(target, pixel, targetX, targetY); } - } + } } @@ -2500,10 +2500,10 @@ return target.release(); } - + template static void FlipXInternal(ImageAccessor& image) - { + { const unsigned int height = image.GetHeight(); const unsigned int width = image.GetWidth(); @@ -2512,17 +2512,17 @@ for (unsigned int x1 = 0; x1 < width / 2; x1++) { unsigned int x2 = width - 1 - x1; - + typename ImageTraits::PixelType a, b; ImageTraits::GetPixel(a, image, x1, y); ImageTraits::GetPixel(b, image, x2, y); ImageTraits::SetPixel(image, a, x2, y); ImageTraits::SetPixel(image, b, x1, y); } - } + } } - + void ImageProcessing::FlipX(ImageAccessor& image) { switch (image.GetFormat()) @@ -2540,17 +2540,17 @@ } } - + template static void FlipYInternal(ImageAccessor& image) - { + { const unsigned int height = image.GetHeight(); const unsigned int width = image.GetWidth(); for (unsigned int y1 = 0; y1 < height / 2; y1++) { unsigned int y2 = height - 1 - y1; - + for (unsigned int x = 0; x < width; x++) { typename ImageTraits::PixelType a, b; @@ -2559,10 +2559,10 @@ ImageTraits::SetPixel(image, a, x, y2); ImageTraits::SetPixel(image, b, x, y1); } - } + } } - + void ImageProcessing::FlipY(ImageAccessor& image) { switch (image.GetFormat()) @@ -2620,9 +2620,9 @@ return p; } - - - + + + // This is an implementation of separable convolution that uses // floating-point arithmetics, and an intermediate Float32 // image. The out-of-image values are taken as the border @@ -2641,7 +2641,7 @@ const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight(); - + /** * Horizontal convolution @@ -2654,7 +2654,7 @@ const RawPixel* row = reinterpret_cast(image.GetConstRow(y)); float leftBorder[ChannelsCount], rightBorder[ChannelsCount]; - + for (unsigned int c = 0; c < ChannelsCount; c++) { leftBorder[c] = row[c]; @@ -2741,13 +2741,13 @@ } RawPixel* p = reinterpret_cast(image.GetRow(y)); - + for (unsigned int x = 0; x < width; x++) { for (unsigned int c = 0; c < ChannelsCount; c++, p++) { float accumulator = 0; - + for (unsigned int k = 0; k < vertical.size(); k++) { accumulator += rows[k][ChannelsCount * x + c] * vertical[k]; @@ -2795,23 +2795,23 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if (image.GetWidth() == 0 || image.GetHeight() == 0) { return; } - + /** * Compute normalization **/ - + float sumHorizontal = 0; for (size_t i = 0; i < horizontal.size(); i++) { sumHorizontal += horizontal[i]; } - + float sumVertical = 0; for (size_t i = 0; i < vertical.size(); i++) { @@ -2822,7 +2822,7 @@ fabsf(sumVertical) <= std::numeric_limits::epsilon()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "Singular convolution kernel"); - } + } const float normalization = 1.0f / (sumHorizontal * sumVertical); @@ -2891,7 +2891,7 @@ { std::vector hKernel(horizontalKernelWidth, 1.0f); std::vector vKernel(verticalKernelWidth, 1.0f); - + SeparableConvolution(image, hKernel, horizontalKernelWidth / 2, vKernel, verticalKernelWidth / 2, false); } @@ -2924,7 +2924,7 @@ unsigned int sh = std::min(static_cast(Math::iround(ch * r)), target.GetHeight()); Image resized(target.GetFormat(), sw, sh, false); - + //ImageProcessing::SmoothGaussian5x5(source); ImageProcessing::Resize(resized, source); @@ -2948,7 +2948,7 @@ return target.release(); } - + ImageAccessor* ImageProcessing::FitSizeKeepAspectRatio(const ImageAccessor& source, unsigned int width, unsigned int height) @@ -2986,7 +2986,7 @@ { // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2 // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion - + // TODO - Check out the outcome of Mathieu's discussion about // truncation of YCbCr-to-RGB conversion: // https://groups.google.com/forum/#!msg/comp.protocols.dicom/JHuGeyWbTz8/ARoTWrJzAQAJ @@ -3004,7 +3004,7 @@ for (unsigned int y = 0; y < height; y++) { uint8_t* p = reinterpret_cast(image.GetRow(y)); - + for (unsigned int x = 0; x < width; x++, p += 3) { const float Y = p[0]; @@ -3031,7 +3031,7 @@ { p[i] = static_cast(result[i]); } - } + } } } } @@ -3041,7 +3041,7 @@ { const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight(); - + switch (image.GetFormat()) { case PixelFormat_Grayscale8: @@ -3063,7 +3063,7 @@ t[1] = a; t += 2; } - } + } break; case PixelFormat_Grayscale32: @@ -3081,7 +3081,7 @@ t[3] = a; t += 4; } - } + } break; case PixelFormat_RGB48: // uint16_t per channel @@ -3095,12 +3095,12 @@ t[1] = a; t += 2; } - } + } break; default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); - } + } } @@ -3112,7 +3112,7 @@ { const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight(); - + if (width != other.GetWidth() || height != other.GetHeight()) { @@ -3129,7 +3129,7 @@ { PixelType* p = reinterpret_cast(image.GetRow(y)); const PixelType* q = reinterpret_cast(other.GetConstRow(y)); - + for (unsigned int x = 0; x < width; x++, p++, q++) { f(*p, *q); @@ -3143,7 +3143,7 @@ { // For older version of gcc, templated functors cannot be defined // as types internal to functions, hence the anonymous namespace - + struct MaximumFunctor { void operator() (uint8_t& a, const uint8_t& b) @@ -3157,7 +3157,7 @@ } }; } - + void ImageProcessing::Maximum(ImageAccessor& image, const ImageAccessor& other) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/ImageProcessing.h --- a/OrthancFramework/Sources/Images/ImageProcessing.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/ImageProcessing.h Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ private: int32_t x_; int32_t y_; - + public: ImagePoint(int32_t x, int32_t y); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/JpegErrorManager.cpp --- a/OrthancFramework/Sources/Images/JpegErrorManager.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/JpegErrorManager.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -46,7 +46,7 @@ JpegErrorManager* that = reinterpret_cast(cinfo->err); longjmp(that->setjmp_buffer, 1); } - + JpegErrorManager::JpegErrorManager() { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/JpegErrorManager.h --- a/OrthancFramework/Sources/Images/JpegErrorManager.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/JpegErrorManager.h Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ { namespace Internals { - class JpegErrorManager + class JpegErrorManager { private: struct jpeg_error_mgr pub; /* "public" fields */ diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/JpegReader.cpp --- a/OrthancFramework/Sources/Images/JpegReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/JpegReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -86,11 +86,11 @@ throw OrthancException(ErrorCode_NotEnoughMemory); } - accessor.AssignWritable(format, cinfo.output_width, cinfo.output_height, pitch, + accessor.AssignWritable(format, cinfo.output_width, cinfo.output_height, pitch, content.empty() ? NULL : &content[0]); uint8_t* target = reinterpret_cast(&content[0]); - while (cinfo.output_scanline < cinfo.output_height) + while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, buffer, 1); memcpy(target, buffer[0], static_cast(pitch)); @@ -117,8 +117,8 @@ Internals::JpegErrorManager jerr; cinfo.err = jerr.GetPublic(); - - if (setjmp(jerr.GetJumpBuffer())) + + if (setjmp(jerr.GetJumpBuffer())) { jpeg_destroy_decompress(&cinfo); fclose(fp); @@ -157,8 +157,8 @@ Internals::JpegErrorManager jerr; cinfo.err = jerr.GetPublic(); - - if (setjmp(jerr.GetJumpBuffer())) + + if (setjmp(jerr.GetJumpBuffer())) { jpeg_destroy_decompress(&cinfo); throw OrthancException(ErrorCode_InternalError, @@ -167,7 +167,7 @@ // Below this line, we are under the scope of a "setjmp" jpeg_create_decompress(&cinfo); - jpeg_mem_src(&cinfo, + jpeg_mem_src(&cinfo, const_cast( reinterpret_cast(buffer)), size); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/JpegWriter.cpp --- a/OrthancFramework/Sources/Images/JpegWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/JpegWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -92,12 +92,12 @@ // https://github.com/simonfuhrmann/mve/issues/371 jpeg_set_quality(&cinfo, quality, static_cast(true)); jpeg_start_compress(&cinfo, static_cast(true)); - + jpeg_write_scanlines(&cinfo, &lines[0], height); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); } - + JpegWriter::JpegWriter() : quality_(90) { @@ -138,7 +138,7 @@ Internals::JpegErrorManager jerr; cinfo.err = jerr.GetPublic(); - if (setjmp(jerr.GetJumpBuffer())) + if (setjmp(jerr.GetJumpBuffer())) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. @@ -190,7 +190,7 @@ size_t size; #endif - if (setjmp(jerr.GetJumpBuffer())) + if (setjmp(jerr.GetJumpBuffer())) { jpeg_destroy_compress(&cinfo); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/NumpyWriter.cpp --- a/OrthancFramework/Sources/Images/NumpyWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/NumpyWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -59,7 +59,7 @@ case Endianness_Little: datatype = "<"; break; - + case Endianness_Big: datatype = ">"; break; @@ -67,7 +67,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + unsigned int channels; switch (format) @@ -106,7 +106,7 @@ { depthString = boost::lexical_cast(depth) + ", "; } - + const std::string info = ("{'descr': '" + datatype + "', 'fortran_order': False, " + "'shape': (" + depthString + boost::lexical_cast(height) + "," + boost::lexical_cast(width) + @@ -127,7 +127,7 @@ uint16_t headerLength = info.size() + countZeros + 1 /* trailing '\n' */; uint8_t highByte = headerLength / 256; uint8_t lowByte = headerLength % 256; - + target.AddChunk(VERSION, sizeof(VERSION)); target.AddChunk(&lowByte, 1); target.AddChunk(&highByte, 1); @@ -147,7 +147,7 @@ target.AddChunk(image.GetConstRow(y), rowSize); } } - + void NumpyWriter::Finalize(std::string& target, ChunkedBuffer& source, @@ -160,7 +160,7 @@ // specified as positional arguments in "numpy.savez()" // https://numpy.org/doc/stable/reference/generated/numpy.savez.html const char* ARRAY_NAME = "arr_0"; - + std::string uncompressed; source.Flatten(uncompressed); @@ -193,12 +193,12 @@ { std::string content; WriteToMemoryInternal(content, width, height, pitch, format, buffer); - + SystemToolbox::WriteFile(content, filename); } #endif - + void NumpyWriter::WriteToMemoryInternal(std::string& content, unsigned int width, unsigned int height, @@ -222,7 +222,7 @@ compressed_ = false; } - + void NumpyWriter::SetCompressed(bool compressed) { #if ORTHANC_ENABLE_ZLIB == 1 diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PamReader.cpp --- a/OrthancFramework/Sources/Images/PamReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PamReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -93,10 +93,10 @@ } } - + typedef std::map Parameters; - + static std::string LookupStringParameter(const Parameters& parameters, const std::string& key) { @@ -111,7 +111,7 @@ return found->second; } } - + static unsigned int LookupIntegerParameter(const Parameters& parameters, const std::string& key) @@ -134,12 +134,12 @@ throw OrthancException(ErrorCode_BadFileFormat); } } - + void PamReader::ParseContent() { static const std::string headerDelimiter = "ENDHDR\n"; - + boost::iterator_range headerRange = boost::algorithm::find_first(content_, headerDelimiter); @@ -161,7 +161,7 @@ } Parameters parameters; - + for (size_t i = 1; i + 1 < lines.size(); i++) { std::vector tokens; @@ -222,7 +222,7 @@ else LOG(TRACE) << "PamReader::ParseContent() image address = " << bufferAddr << " (not a multiple of 8!)"; } - + // if we want to enforce alignment, we need to use a freshly allocated // buffer, since we have no alignment guarantees on the original one if (enforceAligned_) @@ -233,12 +233,12 @@ } alignedImageBuffer_ = malloc(pitch * height); - + if (alignedImageBuffer_ == NULL) { throw OrthancException(ErrorCode_NotEnoughMemory); } - + memcpy(alignedImageBuffer_, &content_[offset], pitch* height); content_ = ""; AssignWritable(format, width, height, pitch, alignedImageBuffer_); @@ -261,7 +261,7 @@ for (unsigned int h = 0; h < height; ++h) { uint16_t* pixel = reinterpret_cast(GetRow(h)); - + for (unsigned int w = 0; w < width; ++w, ++pixel) { /** @@ -276,7 +276,7 @@ * #99: https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=99 * * Here is the crash log on WebAssembly (2019-08-05): - * + * * Uncaught abort(alignment fault) at Error * at jsStackTrace * at stackTrace @@ -300,7 +300,7 @@ { } - + #if ORTHANC_SANDBOXED == 0 void PamReader::ReadFromFile(const boost::filesystem::path& filename) { @@ -308,7 +308,7 @@ ParseContent(); } #endif - + void PamReader::ReadFromMemory(const std::string& buffer) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PamReader.h --- a/OrthancFramework/Sources/Images/PamReader.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PamReader.h Wed Aug 19 14:11:33 2026 +0200 @@ -40,7 +40,7 @@ { private: void ParseContent(); - + /** Whether we want to use the default malloc alignment in the image buffer, at the expense of an extra copy @@ -54,14 +54,14 @@ constructor. */ void* alignedImageBuffer_; - + /** - Points somewhere in the content_ buffer. + Points somewhere in the content_ buffer. */ ImageAccessor wrappedContent_; /** - Raw content (file bytes or answer from the server, for instance). + Raw content (file bytes or answer from the server, for instance). */ std::string content_; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PamWriter.cpp --- a/OrthancFramework/Sources/Images/PamWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PamWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -49,7 +49,7 @@ bytesPerChannel = 1; tupleType = "GRAYSCALE"; break; - + case PixelFormat_SignedGrayscale16: case PixelFormat_Grayscale16: maxValue = 65535; @@ -77,7 +77,7 @@ } } - + void PamWriter::WriteToMemoryInternal(std::string& target, unsigned int width, unsigned int height, @@ -90,11 +90,11 @@ GetPixelFormatInfo(format, maxValue, channelCount, bytesPerChannel, tupleType); target = (std::string("P7") + - std::string("\nWIDTH ") + boost::lexical_cast(width) + - std::string("\nHEIGHT ") + boost::lexical_cast(height) + - std::string("\nDEPTH ") + boost::lexical_cast(channelCount) + - std::string("\nMAXVAL ") + boost::lexical_cast(maxValue) + - std::string("\nTUPLTYPE ") + tupleType + + std::string("\nWIDTH ") + boost::lexical_cast(width) + + std::string("\nHEIGHT ") + boost::lexical_cast(height) + + std::string("\nDEPTH ") + boost::lexical_cast(channelCount) + + std::string("\nMAXVAL ") + boost::lexical_cast(maxValue) + + std::string("\nTUPLTYPE ") + tupleType + std::string("\nENDHDR\n")); if (bytesPerChannel != 1 && @@ -138,7 +138,7 @@ uint8_t* b = reinterpret_cast(q); b[0] = a[1]; b[1] = a[0]; - + p++; q++; } @@ -149,7 +149,7 @@ // Either "bytesPerChannel == 1" (and endianness is not // relevant), or we run on a big endian architecture (and no // byte swapping is necessary, as PAM uses big endian) - + for (unsigned int h = 0; h < height; ++h) { const void* p = reinterpret_cast(buffer) + static_cast(h) * sourcePitch; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PixelTraits.h --- a/OrthancFramework/Sources/Images/PixelTraits.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PixelTraits.h Wed Aug 19 14:11:33 2026 +0200 @@ -52,7 +52,7 @@ } else if (value > static_cast(std::numeric_limits::max())) { - return std::numeric_limits::max(); + return std::numeric_limits::max(); } else { @@ -129,14 +129,14 @@ { }; - + template <> struct PixelTraits : public IntegerPixelTraits { }; - + template <> struct PixelTraits : public IntegerPixelTraits @@ -270,7 +270,7 @@ target.blue_ = v; target.green_ = v; target.red_ = v; - target.alpha_ = 255; + target.alpha_ = 255; } }; @@ -331,7 +331,7 @@ target.red_ = v; target.green_ = v; target.blue_ = v; - target.alpha_ = 255; + target.alpha_ = 255; } }; @@ -373,7 +373,7 @@ return tmp <= std::numeric_limits::epsilon(); } - + ORTHANC_FORCE_INLINE static void SetMinValue(PixelType& target) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PngReader.cpp --- a/OrthancFramework/Sources/Images/PngReader.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PngReader.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -42,7 +42,7 @@ namespace Orthanc { #if ORTHANC_SANDBOXED == 0 - namespace + namespace { struct FileRabi : public boost::noncopyable { @@ -118,8 +118,8 @@ Destruct(); } - static void MemoryCallback(png_structp png_ptr, - png_bytep data, + static void MemoryCallback(png_structp png_ptr, + png_bytep data, png_size_t size); }; @@ -212,7 +212,7 @@ AssignEmpty(format); return; } - + png_read_update_info(rabi.png_, rabi.info_); std::vector rows(height); @@ -267,8 +267,8 @@ } - void PngReader::PngRabi::MemoryCallback(png_structp png_ptr, - png_bytep outBytes, + void PngReader::PngRabi::MemoryCallback(png_structp png_ptr, + png_bytep outBytes, png_size_t byteCountToRead) { MemoryBuffer* from = reinterpret_cast(png_get_io_ptr(png_ptr)); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Images/PngWriter.cpp --- a/OrthancFramework/Sources/Images/PngWriter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Images/PngWriter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -111,7 +111,7 @@ } } - + ~Context() { if (info_) @@ -124,14 +124,14 @@ png_destroy_write_struct(&png_, NULL); } } - + png_structp GetObject() const { return png_; } - + void Prepare(unsigned int width, unsigned int height, unsigned int pitch, @@ -166,7 +166,7 @@ bitDepth_ = 16; colorType_ = PNG_COLOR_TYPE_GRAY; break; - + case PixelFormat_RGBA64: bitDepth_ = 16; colorType_ = PNG_COLOR_TYPE_RGBA; @@ -177,7 +177,7 @@ } } - + void Compress(unsigned int width, unsigned int height, unsigned int pitch, @@ -228,21 +228,21 @@ const void* buffer) { Context context; - + context.Prepare(width, height, pitch, format, buffer); FILE* fp = SystemToolbox::OpenFile(filename, FileMode_WriteBinary); if (!fp) { throw OrthancException(ErrorCode_CannotWriteFile); - } + } png_init_io(context.GetObject(), fp); if (setjmp(png_jmpbuf(context.GetObject()))) { // Error during writing PNG - throw OrthancException(ErrorCode_CannotWriteFile); + throw OrthancException(ErrorCode_CannotWriteFile); } context.Compress(width, height, pitch, format); @@ -252,8 +252,8 @@ #endif - static void MemoryCallback(png_structp png_ptr, - png_bytep data, + static void MemoryCallback(png_structp png_ptr, + png_bytep data, png_size_t size) { ChunkedBuffer* buffer = reinterpret_cast(png_get_io_ptr(png_ptr)); @@ -269,7 +269,7 @@ const void* buffer) { Context context; - + ChunkedBuffer chunks; context.Prepare(width, height, pitch, format, buffer); @@ -277,7 +277,7 @@ if (setjmp(png_jmpbuf(context.GetObject()))) { // Error during writing PNG - THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); + THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } png_set_write_fn(context.GetObject(), &chunks, MemoryCallback, NULL); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/IJob.h --- a/OrthancFramework/Sources/JobsEngine/IJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/IJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ // Method called once the job enters the jobs engine virtual void Start() = 0; - + virtual JobStepResult Step(const std::string& jobId) = 0; // Method called once the job is resubmitted after a failure @@ -58,7 +58,7 @@ } virtual void GetJobType(std::string& target) const = 0; - + virtual void GetPublicContent(Json::Value& value) const = 0; virtual bool Serialize(Json::Value& value) const = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobInfo.cpp --- a/OrthancFramework/Sources/JobsEngine/JobInfo.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobInfo.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -174,7 +174,7 @@ target["CreationTime"] = boost::posix_time::to_iso_string(creationTime_); target["EffectiveRuntime"] = static_cast(runtime_.total_milliseconds()) / 1000.0; target["Progress"] = Math::iround(status_.GetProgress() * 100.0f); - + if (status_.HasUserData()) { target["UserData"] = status_.GetUserData(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobStatus.cpp --- a/OrthancFramework/Sources/JobsEngine/JobStatus.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobStatus.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -38,7 +38,7 @@ { } - + JobStatus::JobStatus(ErrorCode code, const std::string& details, const IJob& job) : @@ -52,7 +52,7 @@ { progress_ = 0; } - + if (progress_ > 1) { progress_ = 1; @@ -61,7 +61,7 @@ job.GetJobType(jobType_); job.GetPublicContent(publicContent_); job.GetUserData(userData_); - + hasSerialized_ = job.Serialize(serialized_); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobStepResult.cpp --- a/OrthancFramework/Sources/JobsEngine/JobStepResult.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobStepResult.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -64,7 +64,7 @@ { result.failureDetails_ = details; } - + return result; } @@ -98,7 +98,7 @@ { return code_; } - + unsigned int JobStepResult::GetRetryTimeout() const { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobStepResult.h --- a/OrthancFramework/Sources/JobsEngine/JobStepResult.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobStepResult.h Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ ErrorCode error_; std::string failureDetails_; ErrorPayload failurePayload_; - + explicit JobStepResult(JobStepCode code) : code_(code), timeout_(0), diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobsEngine.cpp --- a/OrthancFramework/Sources/JobsEngine/JobsEngine.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobsEngine.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -37,8 +37,8 @@ boost::mutex::scoped_lock lock(stateMutex_); return (state_ == State_Running); } - - + + bool JobsEngine::ExecuteStep(JobsRegistry::RunningJob& running, size_t workerIndex) { @@ -100,13 +100,13 @@ case JobStepCode_Continue: running.UpdateStatus(ErrorCode_Success, ""); return true; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + void JobsEngine::RetryHandler(JobsEngine* engine) { Logging::ScopedCurrentThreadNameSetter setter("JOBS-RETRY"); @@ -120,7 +120,7 @@ } } - + void JobsEngine::Worker(JobsEngine* engine, size_t workerIndex) { @@ -150,7 +150,7 @@ } } } - } + } } @@ -162,7 +162,7 @@ { } - + JobsEngine::~JobsEngine() { if (state_ != State_Setup && @@ -173,7 +173,7 @@ } } - + JobsRegistry& JobsEngine::GetRegistry() { if (registry_.get() == NULL) @@ -183,13 +183,13 @@ return *registry_; } - - + + void JobsEngine::LoadRegistryFromJson(IJobUnserializer& unserializer, const Json::Value& serialized) { boost::mutex::scoped_lock lock(stateMutex_); - + if (state_ != State_Setup) { // Can only be invoked before calling "Start()" @@ -241,7 +241,7 @@ void JobsEngine::SetThreadSleep(unsigned int sleep) { boost::mutex::scoped_lock lock(stateMutex_); - + if (state_ != State_Setup) { // Can only be invoked before calling "Start()" @@ -286,17 +286,17 @@ { return; } - + state_ = State_Stopping; } CLOG(INFO, JOBS) << "Stopping the jobs engine"; - + if (retryHandler_.joinable()) { retryHandler_.join(); } - + for (size_t i = 0; i < workers_.size(); i++) { assert(workers_[i] != NULL); @@ -308,7 +308,7 @@ delete workers_[i]; } - + { boost::mutex::scoped_lock lock(stateMutex_); state_ = State_Done; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobsEngine.h --- a/OrthancFramework/Sources/JobsEngine/JobsEngine.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobsEngine.h Wed Aug 19 14:11:33 2026 +0200 @@ -51,10 +51,10 @@ std::vector workers_; bool IsRunning(); - + bool ExecuteStep(JobsRegistry::RunningJob& running, size_t workerIndex); - + static void RetryHandler(JobsEngine* engine); static void Worker(JobsEngine* engine, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp --- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -115,7 +115,7 @@ cancelScheduled_(false) { Logging::ScopedCurrentThreadContextSetter logContext(std::string("job ") + id_); - + if (job == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -316,14 +316,14 @@ // New in Orthanc 1.9.5 target[ERROR_CODE] = static_cast(lastStatus_.GetErrorCode()); target[ERROR_DETAILS] = lastStatus_.GetDetails(); - + // New in Orthanc 1.12.9 Json::Value userData; if (job_->GetUserData(userData)) { target[USER_DATA] = userData; } - + if (lastStatus_.GetErrorPayload().HasContent()) { target[ERROR_PAYLOAD_TYPE] = lastStatus_.GetErrorPayload().GetType(); @@ -729,7 +729,7 @@ { found->second->GetJob().DeleteAllOutputs(); delete found->second; - + completedJobs_.erase(it); jobsIndex_.erase(id); return true; @@ -930,7 +930,7 @@ { ErrorCode code = it->second->GetLastStatus().GetErrorCode(); const std::string& details = it->second->GetLastStatus().GetDetails(); - + // Prefer the error payload from the job level if there is one since it should contain more information than the step error payload. ErrorPayload jobErrorPayload; it->second->GetJob().LookupErrorPayload(jobErrorPayload); @@ -1680,7 +1680,7 @@ void JobsRegistry::GetLastModificationTime(boost::posix_time::ptime& modificationTime) const { boost::mutex::scoped_lock lock(mutex_); - + modificationTime = lastModificationTime_; } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/JobsRegistry.h --- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.h Wed Aug 19 14:11:33 2026 +0200 @@ -199,7 +199,7 @@ unsigned int& running); void GetLastModificationTime(boost::posix_time::ptime& modificationTime) const; - + class ORTHANC_PUBLIC RunningJob : public boost::noncopyable { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp --- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -148,12 +148,12 @@ std::unique_ptr result(new JobOperationValues); result->Reserve(source.size()); - + for (Json::Value::ArrayIndex i = 0; i < source.size(); i++) { result->Append(unserializer.UnserializeValue(source[i])); } - + return result.release(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h --- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,7 +37,7 @@ { private: std::vector values_; - + void Append(JobOperationValues& target, bool clear); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.cpp --- a/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -32,13 +32,13 @@ { return Type_Null; } - - IJobOperationValue* NullOperationValue::Clone() const + + IJobOperationValue* NullOperationValue::Clone() const { return new NullOperationValue; } - void NullOperationValue::Serialize(Json::Value& target) const + void NullOperationValue::Serialize(Json::Value& target) const { target = Json::objectValue; target["Type"] = "Null"; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h --- a/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h Wed Aug 19 14:11:33 2026 +0200 @@ -34,7 +34,7 @@ { public: virtual Type GetType() const ORTHANC_OVERRIDE; - + virtual IJobOperationValue* Clone() const ORTHANC_OVERRIDE; virtual void Serialize(Json::Value& target) const ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp --- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -42,7 +42,7 @@ static const char* TYPE = "Type"; static const char* WORK_INPUTS = "WorkInputs"; - + class SequenceOfOperationsJob::Operation : public boost::noncopyable { private: @@ -162,7 +162,7 @@ target[CURRENT] = static_cast(currentInput_); operation_->Serialize(target[OPERATION]); originalInputs_->Serialize(target[ORIGINAL_INPUTS]); - workInputs_->Serialize(target[WORK_INPUTS]); + workInputs_->Serialize(target[WORK_INPUTS]); Json::Value tmp = Json::arrayValue; for (std::list::const_iterator it = nextOperations_.begin(); @@ -227,7 +227,7 @@ void SequenceOfOperationsJob::GetDescription(std::string& description) { boost::mutex::scoped_lock lock(mutex_); - description = description_; + description = description_; } @@ -254,7 +254,7 @@ that_.trailingTimeout_ = boost::posix_time::milliseconds(timeout); } - + size_t SequenceOfOperationsJob::Lock::AddOperation(IJobOperation* operation) { if (IsDone()) @@ -293,7 +293,7 @@ that_.operations_[index]->AddOriginalInput(value); } } - + void SequenceOfOperationsJob::Lock::Connect(size_t input, size_t output) @@ -332,7 +332,7 @@ { LOG(INFO) << "Executing the trailing timeout in the sequence of operations"; operationAdded_.timed_wait(lock, trailingTimeout_); - + if (current_ == operations_.size()) // Could have changed during the "timed_wait()" { // No operation was added during the trailing timeout: The @@ -340,7 +340,7 @@ LOG(INFO) << "The sequence of operations is over"; done_ = true; - for (std::list::iterator it = observers_.begin(); + for (std::list::iterator it = observers_.begin(); it != observers_.end(); ++it) { (*it)->SignalDone(*this); @@ -374,7 +374,7 @@ void SequenceOfOperationsJob::Reset() { boost::mutex::scoped_lock lock(mutex_); - + current_ = 0; done_ = false; @@ -392,8 +392,8 @@ float SequenceOfOperationsJob::GetProgress() const { boost::mutex::scoped_lock lock(mutex_); - - return (static_cast(current_) / + + return (static_cast(current_) / static_cast(operations_.size() + 1)); } @@ -421,11 +421,11 @@ std::string jobType; GetJobType(jobType); value[TYPE] = jobType; - + value[DESCRIPTION] = description_; value[TRAILING_TIMEOUT] = static_cast(trailingTimeout_.total_milliseconds()); value[CURRENT] = static_cast(current_); - + Json::Value tmp = Json::arrayValue; for (size_t i = 0; i < operations_.size(); i++) { @@ -452,7 +452,7 @@ { std::string jobType; SequenceOfOperationsJob::GetJobType(jobType); - + if (SerializationToolbox::ReadString(serialized, TYPE) != jobType || !serialized.isMember(OPERATIONS) || serialized[OPERATIONS].type() != Json::arrayValue) @@ -497,6 +497,6 @@ operations_[i]->AddNextOperation(*operations_[next[j].asUInt()], true); } } - } + } } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h --- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -93,14 +93,14 @@ bool IsDone() const; void SetTrailingOperationTimeout(unsigned int timeout); - + size_t AddOperation(IJobOperation* operation); size_t GetOperationsCount() const; void AddInput(size_t index, const IJobOperationValue& value); - + void Connect(size_t input, size_t output); }; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.cpp --- a/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -37,8 +37,8 @@ { return Type_String; } - - IJobOperationValue* StringOperationValue::Clone() const + + IJobOperationValue* StringOperationValue::Clone() const { return new StringOperationValue(content_); } @@ -48,7 +48,7 @@ return content_; } - void StringOperationValue::Serialize(Json::Value& target) const + void StringOperationValue::Serialize(Json::Value& target) const { target = Json::objectValue; target["Type"] = "String"; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h --- a/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h Wed Aug 19 14:11:33 2026 +0200 @@ -41,7 +41,7 @@ explicit StringOperationValue(const std::string& content); virtual Type GetType() const ORTHANC_OVERRIDE; - + virtual IJobOperationValue* Clone() const ORTHANC_OVERRIDE; const std::string& GetContent() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp --- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -168,7 +168,7 @@ return *commands_[index]; } } - + JobStepResult SetOfCommandsJob::Step(const std::string& jobId) { @@ -184,7 +184,7 @@ position_ = 1; return JobStepResult::Success(); } - + if (position_ >= commands_.size()) { // Already done @@ -236,11 +236,11 @@ static const char* KEY_TYPE = "Type"; static const char* KEY_COMMANDS = "Commands"; static const char* KEY_USER_DATA = "UserData"; - + void SetOfCommandsJob::GetPublicContent(Json::Value& value) const { value[KEY_DESCRIPTION] = GetDescription(); - } + } bool SetOfCommandsJob::Serialize(Json::Value& target) const @@ -250,7 +250,7 @@ std::string type; GetJobType(type); target[KEY_TYPE] = type; - + target[KEY_PERMISSIVE] = permissive_; target[KEY_POSITION] = static_cast(position_); target[KEY_DESCRIPTION] = description_; @@ -262,7 +262,7 @@ for (size_t i = 0; i < commands_.size(); i++) { assert(commands_[i] != NULL); - + Json::Value command; commands_[i]->Serialize(command); tmp.append(command); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h --- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -53,10 +53,10 @@ virtual ~ICommandUnserializer() { } - + virtual ICommand* Unserialize(const Json::Value& source) const = 0; }; - + private: bool started_; std::vector commands_; @@ -90,19 +90,19 @@ void SetPermissive(bool permissive); virtual void Reset() ORTHANC_OVERRIDE; - + virtual void Start() ORTHANC_OVERRIDE; - + virtual float GetProgress() const ORTHANC_OVERRIDE; bool IsStarted() const; const ICommand& GetCommand(size_t index) const; - + virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE; - + virtual void GetPublicContent(Json::Value& value) const ORTHANC_OVERRIDE; - + virtual bool Serialize(Json::Value& target) const ORTHANC_OVERRIDE; virtual bool GetOutput(std::string& output, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.cpp --- a/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -51,7 +51,7 @@ { return instance_; } - + virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE { if (!that_.HandleInstance(instance_)) @@ -81,8 +81,8 @@ explicit TrailingStepCommand(SetOfInstancesJob& that) : that_(that) { - } - + } + virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE { return that_.HandleTrailingStep(); @@ -123,7 +123,7 @@ } } }; - + SetOfInstancesJob::SetOfInstancesJob() : hasTrailingStep_(false) @@ -147,8 +147,8 @@ AddCommand(new TrailingStepCommand(*this)); hasTrailingStep_ = true; } - - + + size_t SetOfInstancesJob::GetInstancesCount() const { if (hasTrailingStep_) @@ -162,7 +162,7 @@ } } - + const std::string& SetOfInstancesJob::GetInstance(size_t index) const { if (index >= GetInstancesCount()) @@ -215,7 +215,7 @@ if (includeParentResourcesField) { std::set keys; - for (std::map::const_iterator it = parentResources.begin(); it != parentResources.end(); ++it) + for (std::map::const_iterator it = parentResources.begin(); it != parentResources.end(); ++it) { keys.insert(it->first); } @@ -230,11 +230,11 @@ SetOfCommandsJob::GetPublicContent(target); target["InstancesCount"] = static_cast(GetInstancesCount()); target["FailedInstancesCount"] = static_cast(failedInstances_.size()); - + SerializeResources(target, parentResources_, true); } - bool SetOfInstancesJob::Serialize(Json::Value& target) const + bool SetOfInstancesJob::Serialize(Json::Value& target) const { if (SetOfCommandsJob::Serialize(target)) { @@ -248,7 +248,7 @@ return false; } } - + SetOfInstancesJob::SetOfInstancesJob(const Json::Value& source) : SetOfCommandsJob(new InstanceUnserializer(*this), source) @@ -263,7 +263,7 @@ { SerializationToolbox::ReadMapOfResourcesAndTypes(parentResources_, source, KEY_RESOURCES); } - + if (source.isMember(KEY_TRAILING_STEP)) { hasTrailingStep_ = SerializationToolbox::ReadBoolean(source, KEY_TRAILING_STEP); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h --- a/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -38,7 +38,7 @@ class InstanceCommand; class TrailingStepCommand; class InstanceUnserializer; - + bool hasTrailingStep_; std::set failedInstances_; std::map parentResources_; @@ -60,13 +60,13 @@ // Only used for reporting in the public content // https://groups.google.com/d/msg/orthanc-users/9GCV88GLEzw/6wAgP_PRAgAJ void AddParentResource(const std::string& resource, ResourceType level); - + void AddInstance(const std::string& instance); - void AddTrailingStep(); + void AddTrailingStep(); size_t GetInstancesCount() const; - + const std::string& GetInstance(size_t index) const; bool HasTrailingStep() const; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Logging.cpp --- a/OrthancFramework/Sources/Logging.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Logging.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -47,12 +47,12 @@ namespace Logging { static const uint32_t ALL_CATEGORIES_MASK = 0xffffffff; - + static uint32_t infoCategoriesMask_ = 0; static uint32_t traceCategoriesMask_ = 0; static std::string logTargetFolder_; // keep a track of the log folder in case of reset of the context static std::string logTargetFile_; // keep a track of the log file in case of reset of the context - + const char* EnumerationToString(LogLevel level) { switch (level) @@ -93,13 +93,13 @@ { return LogLevel_TRACE; } - else + else { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + void EnableInfoLevel(bool enabled) { if (enabled) @@ -114,13 +114,13 @@ } } - + bool IsInfoLevelEnabled() { return (infoCategoriesMask_ != 0); } - + void EnableTraceLevel(bool enabled) { if (enabled) @@ -141,7 +141,7 @@ return (traceCategoriesMask_ != 0); } - + void SetCategoryEnabled(LogLevel level, LogCategory category, bool enabled) @@ -149,7 +149,7 @@ // Invariant: If a bit is set for "trace", it must also be set // for "verbose" (in other words, trace level implies verbose level) assert((traceCategoriesMask_ & infoCategoriesMask_) == traceCategoriesMask_); - + if (level == LogLevel_INFO) { if (enabled) @@ -183,7 +183,7 @@ assert((traceCategoriesMask_ & infoCategoriesMask_) == traceCategoriesMask_); } - + bool IsCategoryEnabled(LogLevel level, LogCategory category) { @@ -269,7 +269,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + const char* GetCategoryName(LogCategory category) { @@ -277,16 +277,16 @@ { case LogCategory_GENERIC: return "generic"; - + case LogCategory_PLUGINS: return "plugins"; - + case LogCategory_HTTP: return "http"; - + case LogCategory_DICOM: return "dicom"; - + case LogCategory_SQLITE: return "sqlite"; @@ -354,7 +354,7 @@ /********************************************************* * Logger compatible with OR logger that sends its - * output to the emscripten html5 api (depending on the + * output to the emscripten html5 api (depending on the * definition of __EMSCRIPTEN__) *********************************************************/ @@ -499,7 +499,7 @@ * plugin, limited to the logging facilities, and that is binary * compatible with the definitions of "OrthancCPlugin.h" **/ - typedef enum + typedef enum { _OrthancPluginService_LogInfo = 1, _OrthancPluginService_LogWarning = 2, @@ -531,7 +531,7 @@ } _OrthancPluginLogMessage; } - + #include "Enumerations.h" #include "SystemToolbox.h" @@ -557,7 +557,7 @@ std::unique_ptr file_; public: - LoggingStreamsContext() : + LoggingStreamsContext() : error_(&std::cerr), warning_(&std::cerr), info_(&std::cerr) @@ -992,7 +992,7 @@ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); boost::filesystem::path root(SystemToolbox::PathFromUtf8(directory)); boost::filesystem::path exe(SystemToolbox::GetPathToExecutable()); - + if (!boost::filesystem::exists(root) || !boost::filesystem::is_directory(root)) { @@ -1049,7 +1049,7 @@ #if defined(__linux__) && !defined(NDEBUG) && !defined(__LSB_VERSION__) // set the thread name at "system" level too -> required to have the thread names visible in GDB ! pthread_setname_np(pthread_self(), name.substr(0, 15).c_str()); // thread names are limited to 15 in Linux -#endif +#endif } else { @@ -1097,7 +1097,7 @@ { throw OrthancException(ErrorCode_NotImplemented); // Not available for plugins } - } + } static void PushCurrentThreadContext(const std::string& context) @@ -1294,7 +1294,7 @@ prefix += "(" + std::string(GetCategoryName(category)) + ") "; } } - + void InitializePluginContext(void* pluginContext) { @@ -1461,7 +1461,7 @@ // We lock the global mutex. The mutex is locked until the // destructor is called: No change in the output can be done. pimpl_->lock_.lock(); - + if (loggingStreamsContext_.get() == NULL) { // Have you called Orthanc::Logging::InitializePluginContext()? @@ -1476,19 +1476,19 @@ case LogLevel_ERROR: stream_ = &loggingStreamsContext_->GetError(); break; - + case LogLevel_WARNING: stream_ = &loggingStreamsContext_->GetWarning(); break; - + case LogLevel_INFO: case LogLevel_TRACE: stream_ = &loggingStreamsContext_->GetInfo(); break; - + default: // Should not occur stream_ = &loggingStreamsContext_->GetError(); - break; + break; } if (stream_ == &nullStream_) @@ -1504,7 +1504,7 @@ (*stream_) << prefix; } catch (...) - { + { // Something is going really wrong, probably running out of // memory. Fallback to a degraded mode. stream_ = &loggingStreamsContext_->GetError(); @@ -1522,7 +1522,7 @@ if (pluginContext_ != NULL) { // We are logging through the Orthanc SDK - + std::string message = messageStream_.str(); if (pluginContext_ != NULL) @@ -1586,7 +1586,7 @@ assert(pimpl_ != NULL); delete pimpl_; } - + void Flush() { @@ -1597,7 +1597,7 @@ loggingStreamsContext_->Flush(); } } - + void SetErrorWarnInfoLoggingStreams(std::ostream& errorStream, std::ostream& warningStream, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Logging.h --- a/OrthancFramework/Sources/Logging.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Logging.h Wed Aug 19 14:11:33 2026 +0200 @@ -169,7 +169,7 @@ ORTHANC_PUBLIC bool IsCategoryEnabled(LogLevel level, LogCategory category); - + ORTHANC_PUBLIC bool LookupCategory(LogCategory& target, const std::string& category); @@ -209,12 +209,12 @@ struct ORTHANC_LOCAL NullStream : public std::ostream { - NullStream() : - std::ios(0), + NullStream() : + std::ios(0), std::ostream(0) { } - + template std::ostream& operator<< (const T& message) { @@ -312,7 +312,7 @@ } ~InternalLogger(); - + std::ostream& operator<< (const std::string& message) { return messageStream_ << message; @@ -355,7 +355,7 @@ int line); ~InternalLogger(); - + std::ostream& operator<< (const std::string& message) { return messageStream_ << message; @@ -377,7 +377,7 @@ * InitializePluginContext() was called. **/ ORTHANC_PUBLIC void SetErrorWarnInfoLoggingStreams(std::ostream& errorStream, - std::ostream& warningStream, + std::ostream& warningStream, std::ostream& infoStream); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Lua/LuaContext.cpp --- a/OrthancFramework/Sources/Lua/LuaContext.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Lua/LuaContext.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -33,7 +33,7 @@ #include #include -extern "C" +extern "C" { #include #include @@ -53,7 +53,7 @@ return true; } - + LuaContext& LuaContext::GetLuaContext(lua_State *state) { const void* value = GetGlobalVariable(state, "_LuaContext"); @@ -88,11 +88,11 @@ result.append(""); else result.append(s); - + lua_pop(state, 1); } - LOG(WARNING) << "Lua says: " << result; + LOG(WARNING) << "Lua says: " << result; that.log_.append(result); that.log_.append("\n"); @@ -229,14 +229,14 @@ return true; } #endif - + #if ORTHANC_ENABLE_CURL == 1 void LuaContext::SetHttpHeaders(int top) { std::map headers; GetDictionaryArgument(headers, lua_, top, false /* keep key case as provided by Lua script */); - + httpClient_.ClearHeaders(); // always reset headers in case they have been set in a previous request for (std::map::const_iterator @@ -334,7 +334,7 @@ return 1; } #endif - + #if ORTHANC_ENABLE_CURL == 1 int LuaContext::CallHttpPost(lua_State *state) @@ -440,7 +440,7 @@ Json::Value::Members members = value.getMemberNames(); - for (Json::Value::Members::const_iterator + for (Json::Value::Members::const_iterator it = members.begin(); it != members.end(); ++it) { // Push the index of the cell @@ -472,7 +472,7 @@ size_t size = 0; // Code adapted from: http://stackoverflow.com/a/6142700/881731 - + // Push another reference to the table on top of the stack (so we know // where it is, and this function can work for negative, positive and // pseudo indices @@ -505,7 +505,7 @@ { isArray = false; } - + // pop value + copy of key, leaving original key lua_pop(state, 2); // stack now contains: -1 => key; -2 => table @@ -546,7 +546,7 @@ double value = static_cast(lua_tonumber(state, top)); int truncated = static_cast(value); - if (std::abs(value - static_cast(truncated)) <= + if (std::abs(value - static_cast(truncated)) <= std::numeric_limits::epsilon()) { result = truncated; @@ -586,7 +586,7 @@ lua_register(lua_, "print", PrintToLog); lua_register(lua_, "ParseJson", ParseJson); lua_register(lua_, "DumpJson", DumpJson); - + #if ORTHANC_ENABLE_CURL == 1 lua_register(lua_, "HttpGet", CallHttpGet); lua_register(lua_, "HttpPost", CallHttpPost); @@ -624,7 +624,7 @@ int error = (luaL_loadbuffer(lua_, command.c_str(), command.size(), "line") || lua_pcall(lua_, 0, 0, 0)); - if (error) + if (error) { assert(lua_gettop(lua_) >= 1); @@ -675,7 +675,7 @@ lua_setglobal(lua_, name); } - + const void* LuaContext::GetGlobalVariable(lua_State* state, const char* name) { @@ -709,7 +709,7 @@ { Toolbox::ToLowerCase(key); } - + target[key] = headers[members[i]].asString(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Lua/LuaContext.h --- a/OrthancFramework/Sources/Lua/LuaContext.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Lua/LuaContext.h Wed Aug 19 14:11:33 2026 +0200 @@ -43,7 +43,7 @@ # include "../HttpClient.h" #endif -extern "C" +extern "C" { #include } @@ -91,7 +91,7 @@ bool keepStrings); void SetHttpHeaders(int top); - + public: LuaContext(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Lua/LuaFunctionCall.cpp --- a/OrthancFramework/Sources/Lua/LuaFunctionCall.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Lua/LuaFunctionCall.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -46,7 +46,7 @@ } LuaFunctionCall::LuaFunctionCall(LuaContext& context, - const char* functionName) : + const char* functionName) : context_(context), isExecuted_(false) { @@ -93,10 +93,10 @@ int nargs = lua_gettop(context_.lua_) - 1; int error = lua_pcall(context_.lua_, nargs, numOutputs, 0); - if (error) + if (error) { assert(lua_gettop(context_.lua_) >= 1); - + std::string description(lua_tostring(context_.lua_, -1)); lua_pop(context_.lua_, 1); /* pop error message from the stack */ @@ -114,7 +114,7 @@ bool LuaFunctionCall::ExecutePredicate() { ExecuteInternal(1); - + if (!lua_isboolean(context_.lua_, 1)) { throw OrthancException(ErrorCode_NotLuaPredicate); @@ -135,7 +135,7 @@ void LuaFunctionCall::ExecuteToString(std::string& result) { ExecuteInternal(1); - + int top = lua_gettop(context_.lua_); if (lua_isstring(context_.lua_, top)) { @@ -150,7 +150,7 @@ void LuaFunctionCall::ExecuteToInt(int& result) { ExecuteInternal(1); - + int top = lua_gettop(context_.lua_); if (lua_isnumber(context_.lua_, top)) { @@ -208,7 +208,7 @@ { Json::Value output; ExecuteToJson(output, true /* keep strings */); - + target.Clear(); if (output.type() == Json::arrayValue && @@ -223,9 +223,9 @@ throw OrthancException(ErrorCode_LuaBadOutput, "Lua: The script must return a table"); } - + Json::Value::Members members = output.getMemberNames(); - + for (size_t i = 0; i < members.size(); i++) { if (output[members[i]].type() != Json::stringValue) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MallocMemoryBuffer.cpp --- a/OrthancFramework/Sources/MallocMemoryBuffer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MallocMemoryBuffer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -63,7 +63,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + free_(buffer_); buffer_ = NULL; size_ = 0; @@ -71,7 +71,7 @@ } } - + void MallocMemoryBuffer::Assign(void* buffer, uint64_t size, FreeFunction freeFunction) @@ -101,7 +101,7 @@ } } - + void MallocMemoryBuffer::CopyToString(std::string& target) const { target.resize(size_); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MallocMemoryBuffer.h --- a/OrthancFramework/Sources/MallocMemoryBuffer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MallocMemoryBuffer.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ { public: typedef void (*FreeFunction) (void* buffer); - + private: void* buffer_; size_t size_; @@ -52,7 +52,7 @@ void Assign(void* buffer, uint64_t size, FreeFunction freeFunction); - + virtual void CopyToString(std::string& target) const ORTHANC_OVERRIDE; virtual void MoveToString(std::string& target) ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MetricsRegistry.cpp --- a/OrthancFramework/Sources/MetricsRegistry.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MetricsRegistry.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -125,7 +125,7 @@ case MetricsUpdatePolicy_Directly: SetValue(value, now); break; - + case MetricsUpdatePolicy_MaxOver10Seconds: case MetricsUpdatePolicy_MaxOver1Minute: if (IsLargerOverPeriod(value, GetPeriodDuration(policy), now)) @@ -165,7 +165,7 @@ case MetricsUpdatePolicy_Directly: // nothing to do break; - + case MetricsUpdatePolicy_MaxOver10Seconds: case MetricsUpdatePolicy_MinOver10Seconds: case MetricsUpdatePolicy_MaxOver1Minute: @@ -234,13 +234,13 @@ { private: MetricsUpdatePolicy policy_; - + public: explicit Item(MetricsUpdatePolicy policy) : policy_(policy) { } - + virtual ~Item() { } @@ -261,7 +261,7 @@ virtual bool HasValue() const = 0; virtual const boost::posix_time::ptime& GetTime() const = 0; - + virtual std::string FormatValue() const = 0; virtual void Refresh() = 0; @@ -269,7 +269,7 @@ virtual void SetInitialValue(int64_t value) = 0; }; - + class MetricsRegistry::FloatItem : public Item { private: @@ -280,7 +280,7 @@ Item(policy) { } - + virtual void UpdateFloat(float value) ORTHANC_OVERRIDE { value_.Update(value, GetPolicy()); @@ -310,7 +310,7 @@ { return value_.GetTime(); } - + virtual std::string FormatValue() const ORTHANC_OVERRIDE { return boost::lexical_cast(value_.GetValue()); @@ -327,7 +327,7 @@ } }; - + class MetricsRegistry::IntegerItem : public Item { private: @@ -338,7 +338,7 @@ Item(policy) { } - + virtual void UpdateFloat(float value) ORTHANC_OVERRIDE { value_.Update(Orthanc::Math::llround(value), GetPolicy()); @@ -368,7 +368,7 @@ { return value_.GetTime(); } - + virtual std::string FormatValue() const ORTHANC_OVERRIDE { return boost::lexical_cast(value_.GetValue()); @@ -434,7 +434,7 @@ if (found == content_.end()) { Item* item = NULL; - + switch (type) { case MetricsDataType_Float: @@ -476,7 +476,7 @@ GetItemInternal(name, policy, MetricsDataType_Float).UpdateFloat(value); } } - + void MetricsRegistry::SetIntegerValue(const std::string &name, int64_t value, @@ -577,7 +577,7 @@ it->second->Refresh(); std::string line = (it->first + " " + - it->second->FormatValue() + " " + + it->second->FormatValue() + " " + boost::lexical_cast(diff.total_milliseconds()) + "\n"); buffer.AddChunk(line); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MetricsRegistry.h --- a/OrthancFramework/Sources/MetricsRegistry.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MetricsRegistry.h Wed Aug 19 14:11:33 2026 +0200 @@ -47,13 +47,13 @@ MetricsUpdatePolicy_MinOver10Seconds, MetricsUpdatePolicy_MinOver1Minute }; - + enum MetricsDataType { MetricsDataType_Float, MetricsDataType_Integer }; - + class ORTHANC_PUBLIC MetricsRegistry : public boost::noncopyable { private: @@ -88,23 +88,23 @@ void SetFloatValue(const std::string& name, float value, MetricsUpdatePolicy policy /* only used if this is a new metrics */); - + void SetFloatValue(const std::string& name, float value) { SetFloatValue(name, value, MetricsUpdatePolicy_Directly); } - + void SetIntegerValue(const std::string& name, int64_t value, MetricsUpdatePolicy policy /* only used if this is a new metrics */); - + void SetIntegerValue(const std::string& name, int64_t value) { SetIntegerValue(name, value, MetricsUpdatePolicy_Directly); } - + void SetInitialValue(const std::string& name, int64_t value); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.cpp --- a/OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -60,7 +60,7 @@ queue_.push_back(message.release()); // take ownership only when pushed into the queue elementAvailable_.notify_one(); - + return true; } @@ -114,7 +114,7 @@ bool BlockingSharedMessageQueue::WaitEmpty(int32_t millisecondsTimeout) { boost::mutex::scoped_lock lock(mutex_); - + // Wait for the queue to become empty while (!queue_.empty()) { @@ -150,7 +150,7 @@ { std::unique_ptr message(queue_.front()); queue_.pop_front(); - + roomAvailable_.notify_one(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.h --- a/OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MultiThreading/BlockingSharedMessageQueue.h Wed Aug 19 14:11:33 2026 +0200 @@ -58,7 +58,7 @@ public: explicit BlockingSharedMessageQueue(unsigned int maxSize = 0); - + ~BlockingSharedMessageQueue(); // This transfers the ownership of the message only if it is diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.cpp --- a/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -45,7 +45,7 @@ boost::thread thread_; std::string threadName_; MetricsRegistry::SharedMetrics* availableWorkers_; - + static void WorkerThread(Worker* that) { Logging::ScopedCurrentThreadNameSetter setter(that->threadName_); @@ -55,7 +55,7 @@ try { std::unique_ptr obj(that->queue_.Dequeue(100)); - + if (obj.get() != NULL) { std::unique_ptr counter; @@ -65,9 +65,9 @@ } IRunnableBySteps& runnable = *dynamic_cast(obj.get()); - + bool wishToContinue = runnable.Step(); - + if (wishToContinue) { // The runnable wishes to continue, reinsert it at the beginning of the queue diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MultiThreading/SharedMessageQueue.cpp --- a/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -31,7 +31,7 @@ /** * FIFO (queue): - * + * * back front * +--+--+--+--+--+--+--+--+--+--+--+ * Enqueue -> | | | | | | | | | | | | @@ -43,7 +43,7 @@ * * * LIFO (stack): - * + * * back front * +--+--+--+--+--+--+--+--+--+--+--+ * | | | | | | | | | | | | <- Enqueue @@ -146,7 +146,7 @@ bool SharedMessageQueue::WaitEmpty(unsigned int millisecondsTimeout) { boost::mutex::scoped_lock lock(mutex_); - + // Wait for the queue to become empty while (!queue_.empty()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h --- a/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h Wed Aug 19 14:11:33 2026 +0200 @@ -46,7 +46,7 @@ public: explicit SharedMessageQueue(unsigned int maxSize = 0); - + ~SharedMessageQueue(); // This transfers the ownership of the message diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/OrthancException.cpp --- a/OrthancFramework/Sources/OrthancException.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/OrthancException.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -111,7 +111,7 @@ } - OrthancException::OrthancException(const OrthancException& other) : + OrthancException::OrthancException(const OrthancException& other) : errorCode_(other.errorCode_), httpStatus_(other.httpStatus_), logged_(other.logged_), @@ -123,7 +123,7 @@ } } - OrthancException::OrthancException(ErrorCode errorCode) : + OrthancException::OrthancException(ErrorCode errorCode) : errorCode_(errorCode), httpStatus_(ConvertErrorCodeToHttpStatus(errorCode)), logged_(false) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/OrthancException.h --- a/OrthancFramework/Sources/OrthancException.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/OrthancException.h Wed Aug 19 14:11:33 2026 +0200 @@ -88,7 +88,7 @@ { private: OrthancException(); // Forbidden - + OrthancException& operator= (const OrthancException&); // Forbidden ErrorCode errorCode_; @@ -97,7 +97,7 @@ // New in Orthanc 1.5.0 std::unique_ptr details_; - + // New in Orthanc 1.12.10 ErrorPayload payload_; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/OrthancFramework.cpp --- a/OrthancFramework/Sources/OrthancFramework.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/OrthancFramework.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -106,7 +106,7 @@ dcmDisableGethostbyaddr.set(OFTrue); #endif } - + void FinalizeFramework() { @@ -117,13 +117,13 @@ #if ORTHANC_ENABLE_CURL == 1 HttpClient::GlobalFinalize(); #endif - + Toolbox::FinalizeOpenSsl(); #if (ORTHANC_ENABLE_LOCALE == 1) && !defined(__EMSCRIPTEN__) Toolbox::FinalizeGlobalLocale(); #endif - + Logging::Finalize(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/OrthancFramework.h --- a/OrthancFramework/Sources/OrthancFramework.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/OrthancFramework.h Wed Aug 19 14:11:33 2026 +0200 @@ -76,7 +76,7 @@ { ORTHANC_PUBLIC void InitializeFramework(const std::string& locale, bool loadPrivateDictionary); - + ORTHANC_PUBLIC void FinalizeFramework(); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Pkcs11.cpp --- a/OrthancFramework/Sources/Pkcs11.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Pkcs11.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -58,9 +58,9 @@ { static const char* PKCS11_ENGINE_ID = "pkcs11"; static const char* PKCS11_ENGINE_NAME = "PKCS#11 for Orthanc"; - static const ENGINE_CMD_DEFN PKCS11_ENGINE_COMMANDS[] = + static const ENGINE_CMD_DEFN PKCS11_ENGINE_COMMANDS[] = { - { + { CMD_MODULE_PATH, "MODULE_PATH", "Specifies the path to the PKCS#11 module shared library", @@ -70,13 +70,13 @@ CMD_PIN, "PIN", "Specifies the pin code", - ENGINE_CMD_FLAG_STRING + ENGINE_CMD_FLAG_STRING }, { CMD_VERBOSE, "VERBOSE", "Print additional details", - ENGINE_CMD_FLAG_NO_INPUT + ENGINE_CMD_FLAG_NO_INPUT }, { CMD_LOAD_CERT_CTRL, @@ -86,8 +86,8 @@ }, { 0, - NULL, - NULL, + NULL, + NULL, 0 } }; @@ -128,10 +128,10 @@ } - static int EngineControl(ENGINE *engine, - int command, - long i, - void *p, + static int EngineControl(ENGINE *engine, + int command, + long i, + void *p, void (*f) ()) { if (context_ == NULL) @@ -145,9 +145,9 @@ } - static EVP_PKEY *EngineLoadPublicKey(ENGINE *engine, + static EVP_PKEY *EngineLoadPublicKey(ENGINE *engine, const char *s_key_id, - UI_METHOD *ui_method, + UI_METHOD *ui_method, void *callback_data) { if (context_ == NULL) @@ -161,9 +161,9 @@ } - static EVP_PKEY *EngineLoadPrivateKey(ENGINE *engine, + static EVP_PKEY *EngineLoadPrivateKey(ENGINE *engine, const char *s_key_id, - UI_METHOD *ui_method, + UI_METHOD *ui_method, void *callback_data) { if (context_ == NULL) @@ -284,12 +284,12 @@ } if (!pin.empty() && - !ENGINE_ctrl_cmd_string(engine, "PIN", pin.c_str(), 0)) + !ENGINE_ctrl_cmd_string(engine, "PIN", pin.c_str(), 0)) { throw OrthancException(ErrorCode_InternalError, "Cannot set the PIN code for PKCS#11"); } - + if (!ENGINE_init(engine)) { throw OrthancException(ErrorCode_InternalError, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/PrecompiledHeaders.h --- a/OrthancFramework/Sources/PrecompiledHeaders.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/PrecompiledHeaders.h Wed Aug 19 14:11:33 2026 +0200 @@ -52,7 +52,7 @@ #include "OrthancException.h" #if ORTHANC_ENABLE_DCMTK == 1 -// Headers from DCMTK used in Orthanc headers +// Headers from DCMTK used in Orthanc headers # include # include # include @@ -60,7 +60,7 @@ #endif #if ORTHANC_ENABLE_DCMTK_NETWORKING == 1 -// Headers from DCMTK used in Orthanc headers +// Headers from DCMTK used in Orthanc headers # include #endif diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApi.cpp --- a/OrthancFramework/Sources/RestApi/RestApi.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApi.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -90,7 +90,7 @@ { case HttpMethod_Get: { - RestApiGetCall call(output_, api_, origin_, remoteIp_, username_, + RestApiGetCall call(output_, api_, origin_, remoteIp_, username_, headers_, components, trailing, uri, getArguments_); resource.Handle(call); return true; @@ -98,7 +98,7 @@ case HttpMethod_Post: { - RestApiPostCall call(output_, api_, origin_, remoteIp_, username_, + RestApiPostCall call(output_, api_, origin_, remoteIp_, username_, headers_, components, trailing, uri, bodyData_, bodySize_); resource.Handle(call); return true; @@ -106,7 +106,7 @@ case HttpMethod_Delete: { - RestApiDeleteCall call(output_, api_, origin_, remoteIp_, username_, + RestApiDeleteCall call(output_, api_, origin_, remoteIp_, username_, headers_, components, trailing, uri); resource.Handle(call); return true; @@ -114,7 +114,7 @@ case HttpMethod_Put: { - RestApiPutCall call(output_, api_, origin_, remoteIp_, username_, + RestApiPutCall call(output_, api_, origin_, remoteIp_, username_, headers_, components, trailing, uri, bodyData_, bodySize_); resource.Handle(call); return true; @@ -142,7 +142,7 @@ virtual bool HandleCall(RestApiCall& call, const std::string& path, const std::set& uriArgumentsNames) = 0; - + public: explicit DocumentationVisitor(RestApi& restApi) : restApi_(restApi), @@ -150,7 +150,7 @@ totalPathsCount_(0) { } - + virtual bool Visit(const RestApiHierarchy::Resource& resource, const UriComponents& uri, bool hasTrailing, @@ -165,7 +165,7 @@ std::set uriArgumentsNames; HttpToolbox::Arguments uriArguments; - + for (HttpToolbox::Arguments::const_iterator it = components.begin(); it != components.end(); ++it) { @@ -183,7 +183,7 @@ if (resource.HasHandler(HttpMethod_Get)) { totalPathsCount_ ++; - + StringHttpOutput o1; HttpOutput o2(o1, false /* assume no keep-alive */, 0); RestApiOutput o3(o2, HttpMethod_Get); @@ -193,7 +193,7 @@ uri, HttpToolbox::Arguments() /* GET arguments */); bool ok = false; - + try { ok = (resource.Handle(call) && @@ -217,11 +217,11 @@ LOG(WARNING) << "Ignoring URI without API documentation: GET " << path; } } - + if (resource.HasHandler(HttpMethod_Post)) { totalPathsCount_ ++; - + StringHttpOutput o1; HttpOutput o2(o1, false /* assume no keep-alive */, 0); RestApiOutput o3(o2, HttpMethod_Post); @@ -231,7 +231,7 @@ uri, NULL /* body */, 0 /* body size */); bool ok = false; - + try { ok = (resource.Handle(call) && @@ -255,11 +255,11 @@ LOG(WARNING) << "Ignoring URI without API documentation: POST " << path; } } - + if (resource.HasHandler(HttpMethod_Delete)) { totalPathsCount_ ++; - + StringHttpOutput o1; HttpOutput o2(o1, false /* assume no keep-alive */, 0); RestApiOutput o3(o2, HttpMethod_Delete); @@ -268,7 +268,7 @@ uriArguments, UriComponents() /* trailing */, uri); bool ok = false; - + try { ok = (resource.Handle(call) && @@ -296,7 +296,7 @@ if (resource.HasHandler(HttpMethod_Put)) { totalPathsCount_ ++; - + StringHttpOutput o1; HttpOutput o2(o1, false /* assume no keep-alive */, 0); RestApiOutput o3(o2, HttpMethod_Put); @@ -306,7 +306,7 @@ NULL /* body */, 0 /* body size */); bool ok = false; - + try { ok = (resource.Handle(call) && @@ -330,7 +330,7 @@ LOG(WARNING) << "Ignoring URI without API documentation: PUT " << path; } } - + return true; } @@ -354,7 +354,7 @@ } float coverage = (100.0f * static_cast(GetSuccessPathsCount()) / static_cast(total)); - + LOG(WARNING) << "The documentation of the REST API contains " << GetSuccessPathsCount() << " paths over a total of " << GetTotalPathsCount() << " paths " << "(coverage: " << static_cast(Math::iround(coverage)) << "%)"; @@ -376,29 +376,29 @@ if (call.GetDocumentation().FormatOpenApi(v, uriArgumentsNames, path)) { std::string method; - + switch (call.GetMethod()) { case HttpMethod_Get: method = "get"; break; - + case HttpMethod_Post: method = "post"; break; - + case HttpMethod_Delete: method = "delete"; break; - + case HttpMethod_Put: method = "put"; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if ((paths_.isMember(path) && paths_[path].type() != Json::objectValue) || paths_[path].isMember(method)) @@ -407,22 +407,22 @@ } paths_[path][method] = v; - + return true; } else { return false; } - } - + } + public: explicit OpenApiVisitor(RestApi& restApi) : DocumentationVisitor(restApi), paths_(Json::objectValue) { } - + const Json::Value& GetPaths() const { return paths_; @@ -476,40 +476,40 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + hasGet_ = true; getTag_ = tag; getDeprecated_ = deprecated; break; - + case HttpMethod_Post: if (hasPost_) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + hasPost_ = true; postTag_ = tag; postDeprecated_ = deprecated; break; - + case HttpMethod_Delete: if (hasDelete_) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + hasDelete_ = true; deleteTag_ = tag; deleteDeprecated_ = deprecated; break; - + case HttpMethod_Put: if (hasPut_) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + hasPut_ = true; putTag_ = tag; putDeprecated_ = deprecated; @@ -618,7 +618,7 @@ std::string verb; std::string url; - + switch (method) { case HttpMethod_Get: @@ -628,7 +628,7 @@ url = openApiUrl + "#tag/" + FormatTag(getTag_) + "/paths/" + p + "/get"; } break; - + case HttpMethod_Post: if (hasPost_) { @@ -636,7 +636,7 @@ url = openApiUrl + "#tag/" + FormatTag(postTag_) + "/paths/" + p + "/post"; } break; - + case HttpMethod_Delete: if (hasDelete_) { @@ -644,14 +644,14 @@ url = openApiUrl + "#tag/" + FormatTag(deleteTag_) + "/paths/" + p + "/delete"; } break; - + case HttpMethod_Put: if (hasPut_) { verb = (putDeprecated_ ? "(put)" : "PUT"); url = openApiUrl + "#tag/" + FormatTag(putTag_) + "/paths/" + p + "/put"; } - break; + break; default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); @@ -697,10 +697,10 @@ { path.SetSummary(call.GetDocumentation().GetSummary(), call.GetMethod()); } - + return true; - } - + } + public: explicit ReStructuredTextCheatSheet(RestApi& restApi) : DocumentationVisitor(restApi) @@ -718,14 +718,14 @@ target += it->second.Format(openApiUrl, HttpMethod_Post, it->first) + ","; target += it->second.Format(openApiUrl, HttpMethod_Delete, it->first) + ","; target += it->second.Format(openApiUrl, HttpMethod_Put, it->first) + ","; - + if (it->second.HasDeprecated()) { target += "*(deprecated)* "; } - + target += it->second.GetSummary() + "\n"; - } + } } }; } @@ -825,7 +825,7 @@ HttpToolbox::Arguments compiled; HttpToolbox::CompileGetArguments(compiled, getArguments); - HttpHandlerVisitor visitor(*this, wrappedOutput, origin, remoteIp, username, + HttpHandlerVisitor visitor(*this, wrappedOutput, origin, remoteIp, username, method, headers, compiled, bodyData, bodySize); if (root_.LookupResource(uri, visitor)) @@ -843,7 +843,7 @@ } else { - LOG(INFO) << "REST method " << EnumerationToString(method) + LOG(INFO) << "REST method " << EnumerationToString(method) << " not allowed on: " << Toolbox::FlattenUri(uri); output.SendMethodNotAllowed(MethodsToString(methods)); @@ -875,9 +875,9 @@ { root_.Register(path, handler); } - + void RestApi::AutoListChildren(RestApiGetCall& call) - { + { call.GetDocumentation() .SetTag("Other") .SetSummary("List operations") @@ -898,7 +898,7 @@ for (std::set::const_iterator it = c.begin(); it != c.end(); ++it) { call.GetDocumentation().SetUriArgument(*it, RestApiCallDocumentation::Type_String, ""); - } + } } else { @@ -911,7 +911,7 @@ void RestApi::GenerateOpenApiDocumentation(Json::Value& target) { OpenApiVisitor visitor(*this); - + UriComponents root; std::set uriArgumentsNames; root_.ExploreAllResources(visitor, root, uriArgumentsNames); @@ -931,13 +931,13 @@ const std::string& openApiUrl) { ReStructuredTextCheatSheet visitor(*this); - + UriComponents root; std::set uriArgumentsNames; root_.ExploreAllResources(visitor, root, uriArgumentsNames); visitor.Format(target, openApiUrl); - + visitor.LogStatistics(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiCall.cpp --- a/OrthancFramework/Sources/RestApi/RestApiCall.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiCall.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -33,14 +33,14 @@ void RestApiCall::GetUriComponentsNames(std::set& components) const { components.clear(); - + for (HttpToolbox::Arguments::const_iterator it = uriComponents_.begin(); it != uriComponents_.end(); ++it) { components.insert(it->first); } } - + std::string RestApiCall::FlattenUri() const { @@ -61,7 +61,7 @@ { documentation_.reset(new RestApiCallDocumentation(method_)); } - + return *documentation_; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiCall.h --- a/OrthancFramework/Sources/RestApi/RestApiCall.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiCall.h Wed Aug 19 14:11:33 2026 +0200 @@ -84,12 +84,12 @@ { return context_; } - + const UriComponents& GetFullUri() const { return fullUri_; } - + const UriComponents& GetTrailingUri() const { return trailing_; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp --- a/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -53,7 +53,7 @@ { requestTypes_[mime] = description; } - + return *this; } @@ -67,13 +67,13 @@ method_ != HttpMethod_Put) { throw OrthancException(ErrorCode_BadParameterType, "Request body is only allowed on POST and PUT"); - } + } if (requestTypes_.find(MimeType_Json) == requestTypes_.end()) { requestTypes_[MimeType_Json] = ""; } - + if (requestFields_.find(name) != requestFields_.end()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "Field \"" + name + "\" of JSON request is already documented"); @@ -82,7 +82,7 @@ { requestFields_[name] = Parameter(type, description, required); return *this; - } + } } @@ -102,7 +102,7 @@ return *this; } - + RestApiCallDocumentation& RestApiCallDocumentation::SetUriArgument(const std::string& name, Type type, @@ -144,7 +144,7 @@ { throw OrthancException(ErrorCode_InternalError, "Cannot set a HTTP GET argument on HTTP method: " + std::string(EnumerationToString(method_))); - } + } else if (getArguments_.find(name) != getArguments_.end()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "GET argument \"" + name + "\" is already documented"); @@ -156,7 +156,7 @@ } } - + RestApiCallDocumentation& RestApiCallDocumentation::SetAnswerField(const std::string& name, Type type, const std::string& description) @@ -165,7 +165,7 @@ { answerTypes_[MimeType_Json] = ""; } - + if (answerFields_.find(name) != answerFields_.end()) { throw OrthancException(ErrorCode_ParameterOutOfRange, "Field \"" + name + "\" of JSON answer is already documented"); @@ -174,7 +174,7 @@ { answerFields_[name] = Parameter(type, description, false); return *this; - } + } } @@ -259,7 +259,7 @@ // We use the "{" symbol, as it the last in the 7bit ASCII // table, which places "..." at the end of the object in OpenAPI v["{...}"] = "..."; - + value = v; } @@ -270,7 +270,7 @@ } } - + void RestApiCallDocumentation::SetTruncatedJsonHttpGetSample(const std::string& url, size_t size) { @@ -314,7 +314,7 @@ target["type"] = "array"; target["items"]["type"] = "object"; return; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -333,7 +333,7 @@ else { target = Json::objectValue; - + if (!tag_.empty()) { target["tags"].append(tag_); @@ -376,8 +376,8 @@ Json::Value p = Json::objectValue; TypeToSchema(p, field->second.GetType()); p["description"] = field->second.GetDescription(); - schema["properties"][field->first] = p; - } + schema["properties"][field->first] = p; + } if (!it->second.empty() && answerFields_.size() > 0) @@ -405,7 +405,7 @@ Json::Value p = Json::objectValue; TypeToSchema(p, field->second.GetType()); p["description"] = field->second.GetDescription(); - schema["properties"][field->first] = p; + schema["properties"][field->first] = p; } if (!it->second.empty() && @@ -416,7 +416,7 @@ } } } - + for (AllowedTypes::const_iterator it = answerTypes_.begin(); it != answerTypes_.end(); ++it) { @@ -441,7 +441,7 @@ { target["responses"]["200"]["content"][EnumerationToString(MimeType_Json)]["schema"]["example"] = sampleJson_; } - + if (hasSampleText_) { target["responses"]["200"]["content"][EnumerationToString(MimeType_PlainText)]["example"] = sampleText_; @@ -454,7 +454,7 @@ for (Parameters::const_iterator it = answerHeaders_.begin(); it != answerHeaders_.end(); ++it) { Json::Value h = Json::objectValue; - h["description"] = it->second.GetDescription(); + h["description"] = it->second.GetDescription(); answerHeaders[it->first] = h; } @@ -462,7 +462,7 @@ } Json::Value parameters = Json::arrayValue; - + for (Parameters::const_iterator it = getArguments_.begin(); it != getArguments_.end(); ++it) { @@ -472,7 +472,7 @@ p["required"] = it->second.IsRequired(); TypeToSchema(p["schema"], it->second.GetType()); p["description"] = it->second.GetDescription(); - parameters.append(p); + parameters.append(p); } for (Parameters::const_iterator it = httpHeaders_.begin(); @@ -484,7 +484,7 @@ p["required"] = it->second.IsRequired(); TypeToSchema(p["schema"], it->second.GetType()); p["description"] = it->second.GetDescription(); - parameters.append(p); + parameters.append(p); } for (Parameters::const_iterator it = uriArguments_.begin(); @@ -494,14 +494,14 @@ { throw OrthancException(ErrorCode_InternalError, "Unexpected URI argument: " + it->first); } - + Json::Value p = Json::objectValue; p["name"] = it->first; p["in"] = "path"; p["required"] = it->second.IsRequired(); TypeToSchema(p["schema"], it->second.GetType()); p["description"] = it->second.GetDescription(); - parameters.append(p); + parameters.append(p); } for (std::set::const_iterator it = expectedUriArguments.begin(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h --- a/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h Wed Aug 19 14:11:33 2026 +0200 @@ -47,8 +47,8 @@ Type_JsonListOfStrings, Type_JsonListOfObjects, Type_JsonObject - }; - + }; + private: class Parameter { @@ -63,7 +63,7 @@ required_(false) { } - + Parameter(Type type, const std::string& description, bool required) : @@ -88,7 +88,7 @@ return required_; } }; - + typedef std::map Parameters; typedef std::map AllowedTypes; @@ -118,7 +118,7 @@ deprecated_(false) { } - + RestApiCallDocumentation& SetTag(const std::string& tag) { tag_ = tag; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiDeleteCall.h --- a/OrthancFramework/Sources/RestApi/RestApiDeleteCall.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiDeleteCall.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,7 +32,7 @@ { public: typedef void (*Handler) (RestApiDeleteCall& call); - + RestApiDeleteCall(RestApiOutput& output, RestApi& context, RequestOrigin origin, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiGetCall.cpp --- a/OrthancFramework/Sources/RestApi/RestApiGetCall.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiGetCall.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -34,7 +34,7 @@ { result.clear(); - for (HttpToolbox::Arguments::const_iterator + for (HttpToolbox::Arguments::const_iterator it = getArguments_.begin(); it != getArguments_.end(); ++it) { result[it->first] = it->second; @@ -43,14 +43,14 @@ return true; } - + bool RestApiGetCall::GetBooleanArgument(const std::string& name, bool defaultValue) const { HttpToolbox::Arguments::const_iterator found = getArguments_.find(name); bool value; - + if (found == getArguments_.end()) { return defaultValue; @@ -76,7 +76,7 @@ HttpToolbox::Arguments::const_iterator found = getArguments_.find(name); uint32_t value; - + if (found == getArguments_.end()) { return defaultValue; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiGetCall.h --- a/OrthancFramework/Sources/RestApi/RestApiGetCall.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiGetCall.h Wed Aug 19 14:11:33 2026 +0200 @@ -34,7 +34,7 @@ const HttpToolbox::Arguments& getArguments_; public: - typedef void (*Handler) (RestApiGetCall& call); + typedef void (*Handler) (RestApiGetCall& call); RestApiGetCall(RestApiOutput& output, RestApi& context, @@ -66,9 +66,9 @@ bool GetBooleanArgument(const std::string& name, bool defaultValue) const; - uint32_t GetUnsignedInteger32Argument(const std::string& name, + uint32_t GetUnsignedInteger32Argument(const std::string& name, uint32_t defaultValue) const; - + virtual bool ParseJsonRequest(Json::Value& result) const ORTHANC_OVERRIDE; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp --- a/OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -32,10 +32,10 @@ namespace Orthanc { - RestApiHierarchy::Resource::Resource() : - getHandler_(NULL), + RestApiHierarchy::Resource::Resource() : + getHandler_(NULL), postHandler_(NULL), - putHandler_(NULL), + putHandler_(NULL), deleteHandler_(NULL) { } @@ -259,7 +259,7 @@ if (child->second->LookupResource(subComponents, uri, visitor, level + 1)) { return true; - } + } } } @@ -327,7 +327,7 @@ } } - for (child = wildcardChildren_.begin(); + for (child = wildcardChildren_.begin(); child != wildcardChildren_.end(); ++child) { if (child->second->GetDirectory(result, uri, level + 1)) @@ -338,7 +338,7 @@ return false; } - + RestApiHierarchy::~RestApiHierarchy() { @@ -400,13 +400,13 @@ } target = s;*/ - + for (Children::const_iterator it = children_.begin(); it != children_.end(); ++it) { it->second->CreateSiteMap(target[it->first]); } - + for (Children::const_iterator it = wildcardChildren_.begin(); it != wildcardChildren_.end(); ++it) { @@ -425,7 +425,7 @@ { HttpToolbox::Arguments components; return LookupResource(components, uri, visitor, 0); - } + } @@ -503,7 +503,7 @@ { args[*it] = ""; } - + if (!handlers_.IsEmpty()) { visitor.Visit(handlers_, path, false, args, UriComponents()); @@ -513,7 +513,7 @@ { visitor.Visit(handlersWithTrailing_, path, true, args, UriComponents()); } - + for (Children::const_iterator it = children_.begin(); it != children_.end(); ++it) { @@ -522,7 +522,7 @@ c.push_back(it->first); it->second->ExploreAllResources(visitor, c, uriArguments); } - + for (Children::const_iterator it = wildcardChildren_.begin(); it != wildcardChildren_.end(); ++it) { @@ -533,7 +533,7 @@ std::set d = uriArguments; d.insert(it->first); - + assert(it->second != NULL); UriComponents c = path; c.push_back("{" + it->first + "}"); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiOutput.cpp --- a/OrthancFramework/Sources/RestApi/RestApiOutput.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiOutput.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -35,7 +35,7 @@ namespace Orthanc { RestApiOutput::RestApiOutput(HttpOutput& output, - HttpMethod method) : + HttpMethod method) : output_(output), method_(method), convertJsonToXml_(false) @@ -61,7 +61,7 @@ } } } - + void RestApiOutput::CheckStatus() { if (alreadySent_) @@ -108,7 +108,7 @@ { std::string s; Toolbox::WriteStyledJson(s, value); - output_.SetContentType(MIME_JSON_UTF8); + output_.SetContentType(MIME_JSON_UTF8); output_.Answer(s); } @@ -140,7 +140,7 @@ { throw OrthancException(ErrorCode_BadFileFormat, "The REST API tries and answers with an invalid JSON file"); - } + } } else { @@ -189,7 +189,7 @@ CheckStatus(); output_.SendStatus(status, message, messageSize); - alreadySent_ = true; + alreadySent_ = true; } void RestApiOutput::SignalError(HttpStatus status) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiPath.cpp --- a/OrthancFramework/Sources/RestApi/RestApiPath.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiPath.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -57,7 +57,7 @@ size_t s = uri_[i].size(); assert(s > 0); - if (uri_[i][0] == '{' && + if (uri_[i][0] == '{' && uri_[i][s - 1] == '}') { components_[i] = uri_[i].substr(1, s - 2); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiPostCall.h --- a/OrthancFramework/Sources/RestApi/RestApiPostCall.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiPostCall.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ public: typedef void (*Handler) (RestApiPostCall& call); - + RestApiPostCall(RestApiOutput& output, RestApi& context, RequestOrigin origin, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/RestApi/RestApiPutCall.h --- a/OrthancFramework/Sources/RestApi/RestApiPutCall.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/RestApi/RestApiPutCall.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ public: typedef void (*Handler) (RestApiPutCall& call); - + RestApiPutCall(RestApiOutput& output, RestApi& context, RequestOrigin origin, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/Connection.cpp --- a/OrthancFramework/Sources/SQLite/Connection.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Connection.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -84,13 +84,13 @@ void Connection::Open(const std::string& path) { - if (db_) + if (db_) { throw OrthancSQLiteException(ErrorCode_SQLiteAlreadyOpened); } int err = sqlite3_open(path.c_str(), &db_); - if (err != SQLITE_OK) + if (err != SQLITE_OK) { Close(); db_ = NULL; @@ -108,7 +108,7 @@ Open(":memory:"); } - void Connection::Close() + void Connection::Close() { ClearCache(); @@ -121,8 +121,8 @@ void Connection::ClearCache() { - for (CachedStatements::iterator - it = cachedStatements_.begin(); + for (CachedStatements::iterator + it = cachedStatements_.begin(); it != cachedStatements_.end(); ++it) { delete it->second; @@ -154,7 +154,7 @@ } - bool Connection::Execute(const char* sql) + bool Connection::Execute(const char* sql) { #if ORTHANC_SQLITE_STANDALONE != 1 CLOG(TRACE, SQLITE) << "SQLite::Connection::Execute " << sql; @@ -195,11 +195,11 @@ return true; } - bool Connection::DoesTableOrIndexExist(const char* name, + bool Connection::DoesTableOrIndexExist(const char* name, const char* type) const { // Our SQL is non-mutating, so this cast is OK. - Statement statement(const_cast(*this), + Statement statement(const_cast(*this), "SELECT name FROM sqlite_master WHERE type=? AND name=?"); statement.BindString(0, type); statement.BindString(1, name); @@ -242,12 +242,12 @@ return sqlite3_changes(db_); } - int Connection::GetErrorCode() const + int Connection::GetErrorCode() const { return sqlite3_errcode(db_); } - int Connection::GetLastErrno() const + int Connection::GetLastErrno() const { int err = 0; if (SQLITE_OK != sqlite3_file_control(db_, NULL, SQLITE_LAST_ERRNO, &err)) @@ -256,7 +256,7 @@ return err; } - const char* Connection::GetErrorMessage() const + const char* Connection::GetErrorMessage() const { return sqlite3_errmsg(db_); } @@ -290,7 +290,7 @@ } bool success = true; - if (!transactionNesting_) + if (!transactionNesting_) { needsRollback_ = false; @@ -321,21 +321,21 @@ DoRollback(); } - bool Connection::CommitTransaction() + bool Connection::CommitTransaction() { - if (!transactionNesting_) + if (!transactionNesting_) { throw OrthancSQLiteException(ErrorCode_SQLiteCommitWithoutTransaction); } transactionNesting_--; - if (transactionNesting_ > 0) + if (transactionNesting_ > 0) { // Mark any nested transactions as failing after we've already got one. return !needsRollback_; } - if (needsRollback_) + if (needsRollback_) { DoRollback(); return false; @@ -345,7 +345,7 @@ return commit.Run(); } - void Connection::DoRollback() + void Connection::DoRollback() { Statement rollback(*this, SQLITE_FROM_HERE, "ROLLBACK"); rollback.Run(); @@ -380,10 +380,10 @@ IScalarFunction* Connection::Register(IScalarFunction* func) { - int err = sqlite3_create_function_v2(db_, - func->GetName(), + int err = sqlite3_create_function_v2(db_, + func->GetName(), static_cast(func->GetCardinality()), - SQLITE_UTF8, + SQLITE_UTF8, func, ScalarFunctionCaller, NULL, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/Connection.h --- a/OrthancFramework/Sources/SQLite/Connection.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Connection.h Wed Aug 19 14:11:33 2026 +0200 @@ -98,7 +98,7 @@ StatementReference& GetCachedStatement(const StatementId& id, const char* sql); - bool DoesTableOrIndexExist(const char* name, + bool DoesTableOrIndexExist(const char* name, const char* type) const; void DoRollback(); @@ -134,7 +134,7 @@ // Returns true if the given index exists. bool DoesIndexExist(const char* index_name) const; - + // Returns true if a column with the given name exists in the given table. bool DoesColumnExist(const char* table_name, const char* column_name) const; @@ -164,7 +164,7 @@ // Diagnostics (for unit tests) ---------------------------------------------- int ExecuteAndReturnErrorCode(const char* sql); - + bool HasCachedStatement(const StatementId& id) const; int GetTransactionNesting() const; @@ -173,7 +173,7 @@ bool BeginTransaction(); void RollbackTransaction(); - bool CommitTransaction(); + bool CommitTransaction(); }; } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/FunctionContext.cpp --- a/OrthancFramework/Sources/SQLite/FunctionContext.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/FunctionContext.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -112,7 +112,7 @@ CheckIndex(index); return sqlite3_value_type(argv_[index]) == SQLITE_NULL; } - + void FunctionContext::SetNullResult() { sqlite3_result_null(context_); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/FunctionContext.h --- a/OrthancFramework/Sources/SQLite/FunctionContext.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/FunctionContext.h Wed Aug 19 14:11:33 2026 +0200 @@ -60,7 +60,7 @@ Internals::SQLiteValue** argv); ColumnType GetColumnType(unsigned int index) const; - + unsigned int GetParameterCount() const; int GetIntValue(unsigned int index) const; @@ -72,7 +72,7 @@ std::string GetStringValue(unsigned int index) const; bool IsNullValue(unsigned int index) const; - + void SetNullResult(); void SetIntResult(int value); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/SQLiteTypes.h --- a/OrthancFramework/Sources/SQLite/SQLiteTypes.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/SQLiteTypes.h Wed Aug 19 14:11:33 2026 +0200 @@ -53,7 +53,7 @@ * We create our own copy of this typedef to get around this API incompatibility. * https://github.com/mackyle/sqlite/commit/db1d90df06a78264775a14d22c3361eb5b42be17 **/ - + #if ORTHANC_SQLITE_VERSION < 3019000 struct Mem; #else diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/Statement.cpp --- a/OrthancFramework/Sources/SQLite/Statement.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Statement.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -95,7 +95,7 @@ return err; } - void Statement::CheckOk(int err, ErrorCode code) const + void Statement::CheckOk(int err, ErrorCode code) const { if (err == SQLITE_RANGE) { @@ -117,7 +117,7 @@ Statement::Statement(Connection& database, const StatementId& id, - const std::string& sql) : + const std::string& sql) : reference_(database.GetCachedStatement(id, sql.c_str())) { Reset(true); @@ -127,7 +127,7 @@ Statement::Statement(Connection& database, const StatementId& id, - const char* sql) : + const char* sql) : reference_(database.GetCachedStatement(id, sql)) { Reset(true); @@ -170,7 +170,7 @@ return CheckError(sqlite3_step(GetStatement()), ErrorCode_SQLiteCannotStep) == SQLITE_ROW; } - void Statement::Reset(bool clear_bound_vars) + void Statement::Reset(bool clear_bound_vars) { // We don't call CheckError() here because sqlite3_reset() returns // the last error that Step() caused thereby generating a second @@ -193,36 +193,36 @@ ErrorCode_BadParameterType); } - void Statement::BindBool(int col, bool val) + void Statement::BindBool(int col, bool val) { BindInt(col, val ? 1 : 0); } - void Statement::BindInt(int col, int val) + void Statement::BindInt(int col, int val) { CheckOk(sqlite3_bind_int(GetStatement(), col + 1, val), ErrorCode_BadParameterType); } - void Statement::BindInt64(int col, int64_t val) + void Statement::BindInt64(int col, int64_t val) { CheckOk(sqlite3_bind_int64(GetStatement(), col + 1, val), ErrorCode_BadParameterType); } - void Statement::BindDouble(int col, double val) + void Statement::BindDouble(int col, double val) { CheckOk(sqlite3_bind_double(GetStatement(), col + 1, val), ErrorCode_BadParameterType); } - void Statement::BindCString(int col, const char* val) + void Statement::BindCString(int col, const char* val) { CheckOk(sqlite3_bind_text(GetStatement(), col + 1, val, -1, SQLITE_TRANSIENT), ErrorCode_BadParameterType); } - void Statement::BindString(int col, const std::string& val) + void Statement::BindString(int col, const std::string& val) { CheckOk(sqlite3_bind_text(GetStatement(), col + 1, @@ -232,7 +232,7 @@ ErrorCode_BadParameterType); } - /*void Statement::BindString16(int col, const string16& value) + /*void Statement::BindString16(int col, const string16& value) { BindString(col, UTF16ToUTF8(value)); }*/ @@ -256,13 +256,13 @@ } - int Statement::ColumnCount() const + int Statement::ColumnCount() const { return sqlite3_column_count(GetStatement()); } - ColumnType Statement::GetColumnType(int col) const + ColumnType Statement::GetColumnType(int col) const { // Verify that our enum matches sqlite's values. assert(COLUMN_TYPE_INTEGER == SQLITE_INTEGER); @@ -274,7 +274,7 @@ return static_cast(sqlite3_column_type(GetStatement(), col)); } - ColumnType Statement::GetDeclaredColumnType(int col) const + ColumnType Statement::GetDeclaredColumnType(int col) const { std::string column_type(sqlite3_column_decltype(GetStatement(), col)); std::transform(column_type.begin(), column_type.end(), column_type.begin(), tolower); @@ -291,32 +291,32 @@ return COLUMN_TYPE_NULL; } - bool Statement::ColumnIsNull(int col) const + bool Statement::ColumnIsNull(int col) const { return sqlite3_column_type(GetStatement(), col) == SQLITE_NULL; } - bool Statement::ColumnBool(int col) const + bool Statement::ColumnBool(int col) const { return !!ColumnInt(col); } - int Statement::ColumnInt(int col) const + int Statement::ColumnInt(int col) const { return sqlite3_column_int(GetStatement(), col); } - int64_t Statement::ColumnInt64(int col) const + int64_t Statement::ColumnInt64(int col) const { return sqlite3_column_int64(GetStatement(), col); } - double Statement::ColumnDouble(int col) const + double Statement::ColumnDouble(int col) const { return sqlite3_column_double(GetStatement(), col); } - std::string Statement::ColumnString(int col) const + std::string Statement::ColumnString(int col) const { const char* str = reinterpret_cast( sqlite3_column_text(GetStatement(), col)); @@ -328,23 +328,23 @@ return result; } - /*string16 Statement::ColumnString16(int col) const + /*string16 Statement::ColumnString16(int col) const { std::string s = ColumnString(col); return !s.empty() ? UTF8ToUTF16(s) : string16(); }*/ - int Statement::ColumnByteLength(int col) const + int Statement::ColumnByteLength(int col) const { return sqlite3_column_bytes(GetStatement(), col); } - const void* Statement::ColumnBlob(int col) const + const void* Statement::ColumnBlob(int col) const { return sqlite3_column_blob(GetStatement(), col); } - bool Statement::ColumnBlobAsString(int col, std::string* blob) + bool Statement::ColumnBlobAsString(int col, std::string* blob) { const void* p = ColumnBlob(col); size_t len = ColumnByteLength(col); @@ -356,7 +356,7 @@ return true; } - /*bool Statement::ColumnBlobAsString16(int col, string16* val) const + /*bool Statement::ColumnBlobAsString16(int col, string16* val) const { const void* data = ColumnBlob(col); size_t len = ColumnByteLength(col) / sizeof(char16); @@ -367,7 +367,7 @@ return true; }*/ - /*bool Statement::ColumnBlobAsVector(int col, std::vector* val) const + /*bool Statement::ColumnBlobAsVector(int col, std::vector* val) const { val->clear(); @@ -382,7 +382,7 @@ /*bool Statement::ColumnBlobAsVector( int col, - std::vector* val) const + std::vector* val) const { return ColumnBlobAsVector(col, reinterpret_cast< std::vector* >(val)); }*/ diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/Statement.h --- a/OrthancFramework/Sources/SQLite/Statement.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Statement.h Wed Aug 19 14:11:33 2026 +0200 @@ -61,7 +61,7 @@ // Possible return values from ColumnType in a statement. These // should match the values in sqlite3.h. - enum ColumnType + enum ColumnType { COLUMN_TYPE_INTEGER = 1, COLUMN_TYPE_FLOAT = 2, @@ -82,10 +82,10 @@ private: StatementReference reference_; - int CheckError(int err, + int CheckError(int err, ErrorCode code) const; - void CheckOk(int err, + void CheckOk(int err, ErrorCode code) const; struct sqlite3_stmt* GetStatement() const diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/StatementReference.cpp --- a/OrthancFramework/Sources/SQLite/StatementReference.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/StatementReference.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -90,7 +90,7 @@ if (extended == SQLITE_IOERR_SHMSIZE /* 4874 */) { LOG(ERROR) << " This probably indicates that your filesystem is full"; - } + } #endif throw OrthancSQLiteException(ErrorCode_SQLitePrepareStatement); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SQLite/Transaction.cpp --- a/OrthancFramework/Sources/SQLite/Transaction.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Transaction.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -82,9 +82,9 @@ } } - void Transaction::Rollback() + void Transaction::Rollback() { - if (!isOpen_) + if (!isOpen_) { throw OrthancSQLiteException(ErrorCode_SQLiteRollbackWithoutTransaction); } @@ -94,9 +94,9 @@ connection_.RollbackTransaction(); } - void Transaction::Commit() + void Transaction::Commit() { - if (!isOpen_) + if (!isOpen_) { throw OrthancSQLiteException(ErrorCode_SQLiteRollbackWithoutTransaction); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SerializationToolbox.cpp --- a/OrthancFramework/Sources/SerializationToolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SerializationToolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -53,10 +53,10 @@ } #else return DicomTag::ParseHexadecimal(tag, name); -#endif +#endif } - + std::string SerializationToolbox::ReadString(const Json::Value& value, const std::string& field) { @@ -105,10 +105,10 @@ int64_t v64 = value[field].asInt64(); if (v64 > static_cast(std::numeric_limits::max())) { - throw OrthancException(ErrorCode_BadParameterType, "Value too large to fit in an integer in field '" + field + "'"); + throw OrthancException(ErrorCode_BadParameterType, "Value too large to fit in an integer in field '" + field + "'"); } return static_cast(v64); - } + } } @@ -144,11 +144,11 @@ if (v64 < 0) { - throw OrthancException(ErrorCode_BadParameterType, "Negative value found while expecting an unsigned int in field '" + field + "'"); + throw OrthancException(ErrorCode_BadParameterType, "Negative value found while expecting an unsigned int in field '" + field + "'"); } return static_cast(v64); - } + } } @@ -180,10 +180,10 @@ else { return value[field.c_str()].asBool(); - } + } } - + void SerializationToolbox::ReadArrayOfStrings(std::vector& target, const Json::Value& valueObject, const std::string& field) @@ -250,7 +250,7 @@ target.push_back(tmp[i]); } } - + void SerializationToolbox::ReadSetOfStrings(std::set& target, const Json::Value& valueObject, @@ -397,7 +397,7 @@ } target.clear(); - + for (Json::ArrayIndex i = 0; i < value[field].size(); ++i) { target[value[field][i]["ID"].asString()] = StringToResourceType(value[field][i]["Type"].asString().c_str()); @@ -407,7 +407,7 @@ void SerializationToolbox::WriteMapOfResourcesAndTypes(Json::Value& targetArray, const std::map& values) { - for (std::map::const_iterator it = values.begin(); it != values.end(); ++it) + for (std::map::const_iterator it = values.begin(); it != values.end(); ++it) { Json::Value resource; resource["ID"] = it->first; @@ -605,14 +605,14 @@ return false; } } - + bool SerializationToolbox::ParseInteger64(int64_t& target, const std::string& source) { return ParseValue(target, source); } - + bool SerializationToolbox::ParseUnsignedInteger32(uint32_t& target, const std::string& source) @@ -628,7 +628,7 @@ return false; } } - + bool SerializationToolbox::ParseUnsignedInteger64(uint64_t& target, const std::string& source) @@ -636,7 +636,7 @@ return ParseValue(target, source); } - + bool SerializationToolbox::ParseUnsignedInteger(unsigned int& target, const std::string& source) { @@ -649,7 +649,7 @@ { return ParseValue(target, source); } - + bool SerializationToolbox::ParseDouble(double& target, const std::string& source) @@ -674,7 +674,7 @@ return true; } } - + bool SerializationToolbox::ParseFirstInteger32(int32_t& target, const std::string& source) @@ -689,7 +689,7 @@ return false; } } - + bool SerializationToolbox::ParseFirstInteger64(int64_t& target, const std::string& source) @@ -704,7 +704,7 @@ return false; } } - + bool SerializationToolbox::ParseFirstUnsignedInteger32(uint32_t& target, const std::string& source) @@ -719,7 +719,7 @@ return false; } } - + bool SerializationToolbox::ParseFirstUnsignedInteger64(uint64_t& target, const std::string& source) @@ -734,7 +734,7 @@ return false; } } - + bool SerializationToolbox::ParseFirstFloat(float& target, const std::string& source) @@ -749,7 +749,7 @@ return false; } } - + bool SerializationToolbox::ParseFirstDouble(double& target, const std::string& source) @@ -764,7 +764,7 @@ return false; } } - + bool SerializationToolbox::ParseBoolean(bool& result, const std::string& value) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SharedLibrary.cpp --- a/OrthancFramework/Sources/SharedLibrary.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SharedLibrary.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -41,8 +41,8 @@ namespace Orthanc { - SharedLibrary::SharedLibrary(const boost::filesystem::path& path) : - path_(path), + SharedLibrary::SharedLibrary(const boost::filesystem::path& path) : + path_(path), handle_(NULL) { #if defined(_WIN32) @@ -70,7 +70,7 @@ } #elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) - + /** * "RTLD_LOCAL" is the default, and is only present to be * explicit. "RTLD_DEEPBIND" was added in Orthanc 1.6.0, in order @@ -80,7 +80,7 @@ * BUT this had no effect, and this results in a crash if loading * the Python 2.7 plugin => We disabled it again in Orthanc 1.6.1. **/ - + #if 0 // && defined(RTLD_DEEPBIND) // This is a GNU extension // Disabled in Orthanc 1.6.1 handle_ = ::dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); @@ -88,7 +88,7 @@ handle_ = ::dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); #endif - if (handle_ == NULL) + if (handle_ == NULL) { std::string explanation; const char *tmp = ::dlerror(); @@ -103,7 +103,7 @@ #else #error Support your platform here -#endif +#endif } SharedLibrary::~SharedLibrary() @@ -147,7 +147,7 @@ SharedLibrary::FunctionPointer SharedLibrary::GetFunction(const std::string& name) { SharedLibrary::FunctionPointer result = GetFunctionInternal(name); - + if (result == NULL) { throw OrthancException( diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/StringMemoryBuffer.cpp --- a/OrthancFramework/Sources/StringMemoryBuffer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/StringMemoryBuffer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -50,7 +50,7 @@ return result.release(); } - + IMemoryBuffer* StringMemoryBuffer::CreateFromCopy(const std::string& buffer) { std::unique_ptr result(new StringMemoryBuffer); @@ -59,8 +59,8 @@ } - IMemoryBuffer* StringMemoryBuffer::CreateFromCopy(const std::string& buffer, - size_t start /* inclusive */, + IMemoryBuffer* StringMemoryBuffer::CreateFromCopy(const std::string& buffer, + size_t start /* inclusive */, size_t end /* exclusive */) { std::unique_ptr result(new StringMemoryBuffer); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SystemToolbox.cpp --- a/OrthancFramework/Sources/SystemToolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SystemToolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -86,7 +86,7 @@ /*========================================================================= The section below comes from the Boost 1.68.0 project: https://github.com/boostorg/program_options/blob/boost-1.68.0/src/parsers.cpp - + Copyright Vladimir Prus 2002-2004. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt @@ -94,9 +94,9 @@ =========================================================================*/ // The 'environ' should be declared in some cases. E.g. Linux man page says: -// (This variable must be declared in the user program, but is declared in -// the header file unistd.h in case the header files came from libc4 or libc5, -// and in case they came from glibc and _GNU_SOURCE was defined.) +// (This variable must be declared in the user program, but is declared in +// the header file unistd.h in case the header files came from libc4 or libc5, +// and in case they came from glibc and _GNU_SOURCE was defined.) // To be safe, declare it here. // It appears that on Mac OS X the 'environ' variable is not @@ -111,7 +111,7 @@ { extern char ***_NSGetEnviron(void); } -# define environ (*_NSGetEnviron()) +# define environ (*_NSGetEnviron()) #else # if defined(__MWERKS__) # include @@ -163,7 +163,7 @@ signal(SIGTERM, SignalHandler); signal(SIGHUP, SignalHandler); #endif - + // Active loop that awakens every 100ms finish_ = false; barrierEvent_ = ServerBarrierEvent_Stop; @@ -227,7 +227,7 @@ { if (!IsRegularFile(path)) { - throw OrthancException(ErrorCode_RegularFileExpected, + throw OrthancException(ErrorCode_RegularFileExpected, "Not a regular file or file not found: " + PathToUtf8(path), log); } @@ -248,7 +248,7 @@ throw OrthancException(ErrorCode_InternalError, "Reading a file that is too large for a 32bit architecture"); } - + if (size != 0) { f.read(&content[0], size); @@ -258,12 +258,12 @@ } catch (boost::filesystem::filesystem_error&) { - throw OrthancException(ErrorCode_InexistentFile, + throw OrthancException(ErrorCode_InexistentFile, "File not found: " + PathToUtf8(path)); } catch (...) // To catch "std::system_error&" in C++11 { - throw OrthancException(ErrorCode_InexistentFile, + throw OrthancException(ErrorCode_InexistentFile, "File not found: " + PathToUtf8(path)); } } @@ -275,7 +275,7 @@ { if (!IsRegularFile(path)) { - throw OrthancException(ErrorCode_RegularFileExpected, + throw OrthancException(ErrorCode_RegularFileExpected, "Not a regular file or file not found: " + PathToUtf8(path)); } @@ -317,19 +317,19 @@ } catch (boost::filesystem::filesystem_error&) { - throw OrthancException(ErrorCode_InexistentFile, + throw OrthancException(ErrorCode_InexistentFile, "File not found: " + PathToUtf8(path)); } catch (...) // To catch "std::system_error&" in C++11 { - throw OrthancException(ErrorCode_InexistentFile, + throw OrthancException(ErrorCode_InexistentFile, "File not found: " + PathToUtf8(path)); } } - - void SystemToolbox::WriteFile(const void *content, - size_t size, + + void SystemToolbox::WriteFile(const void *content, + size_t size, const boost::filesystem::path& path, bool callFsync) { @@ -402,10 +402,10 @@ void SystemToolbox::WriteFile(const std::string& content, - const boost::filesystem::path& path) - { - WriteFile(content.size() > 0 ? content.c_str() : NULL, - content.size(), path, false /* don't automatically call fsync */); + const boost::filesystem::path& path) + { + WriteFile(content.size() > 0 ? content.c_str() : NULL, + content.size(), path, false /* don't automatically call fsync */); } @@ -419,7 +419,7 @@ } else { - throw OrthancException(ErrorCode_RegularFileExpected, + throw OrthancException(ErrorCode_RegularFileExpected, "Not a regular file or file not found: " + PathToUtf8(path)); } } @@ -439,7 +439,7 @@ } catch (...) // To catch "std::system_error&" in C++11 { - throw OrthancException(ErrorCode_InexistentFile, + throw OrthancException(ErrorCode_InexistentFile, "File not found: " + PathToUtf8(path)); } } @@ -467,7 +467,7 @@ context.Export(result); } - + void SystemToolbox::ComputeFileMD5(std::string& result, const boost::filesystem::path& path) @@ -494,7 +494,7 @@ else { std::string path1md5, path2md5; - + ComputeFileMD5(path1md5, path1); ComputeFileMD5(path2md5, path2); @@ -526,7 +526,7 @@ #if defined(_WIN32) static std::string GetPathToExecutableInternal() { - // Yes, this is ugly, but there is no simple way to get the + // Yes, this is ugly, but there is no simple way to get the // required buffer size, so we use a big constant std::vector buffer(32768); /*int bytes =*/ GetModuleFileNameA(NULL, &buffer[0], static_cast(buffer.size() - 1)); @@ -570,7 +570,7 @@ const int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; size_t len; - if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1) + if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1) { throw OrthancException(ErrorCode_PathToExecutable); } @@ -580,7 +580,7 @@ char** buffer = reinterpret_cast(&tmp[0]); - if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1) + if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1) { throw OrthancException(ErrorCode_PathToExecutable); } @@ -817,7 +817,7 @@ return boost::posix_time::to_iso_string(GetNow(utc)); } - + void SystemToolbox::GetNowDicom(std::string& date, std::string& time, bool utc) @@ -834,13 +834,13 @@ time.assign(s); } - + unsigned int SystemToolbox::GetHardwareConcurrency() { // Get the number of available hardware threads (e.g. number of // CPUs or cores or hyperthreading units) unsigned int threads = boost::thread::hardware_concurrency(); - + if (threads == 0) { return 1; @@ -872,7 +872,7 @@ return false; } } - + bool SystemToolbox::IsContentCompressible(const std::string& contentType) { if (contentType.empty()) @@ -1023,7 +1023,7 @@ void SystemToolbox::GetEnvironmentVariables(std::map& env) { env.clear(); - + for (char **p = environ; *p != NULL; p++) { std::string v(*p); @@ -1034,7 +1034,7 @@ std::string key = v.substr(0, pos); std::string value = v.substr(pos + 1); env[key] = value; - } + } } } @@ -1043,7 +1043,7 @@ const boost::filesystem::path& relativePath) { /** - The following lines should be equivalent to this one: + The following lines should be equivalent to this one: return (baseDirectory / relativePath); @@ -1063,7 +1063,7 @@ } - void SystemToolbox::ReadFileRange(std::string& content, + void SystemToolbox::ReadFileRange(std::string& content, const boost::filesystem::path& path, uint64_t start, // Inclusive uint64_t end, // Exclusive @@ -1073,10 +1073,10 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if (!IsRegularFile(path)) { - throw OrthancException(ErrorCode_RegularFileExpected, + throw OrthancException(ErrorCode_RegularFileExpected, "Not a regular file or file not found: " + PathToUtf8(path)); } @@ -1131,7 +1131,7 @@ void SystemToolbox::GetMacAddresses(std::set& target) { target.clear(); - + // 15Ko is the recommanded size to start with std::vector buffer(15 * 1024); @@ -1139,13 +1139,13 @@ { ULONG outBufLen = static_cast(buffer.size()); DWORD result = GetAdaptersAddresses - (AF_UNSPEC, 0, NULL, + (AF_UNSPEC, 0, NULL, reinterpret_cast(&buffer[0]), &outBufLen); if (result == NO_ERROR) { IP_ADAPTER_ADDRESSES* current = - reinterpret_cast(&buffer[0]); + reinterpret_cast(&buffer[0]); while (current != NULL) { @@ -1170,10 +1170,10 @@ current = current->Next; } - + return; - } - else if (result != ERROR_BUFFER_OVERFLOW || + } + else if (result != ERROR_BUFFER_OVERFLOW || iteration >= 3 || outBufLen == 0) { @@ -1270,7 +1270,7 @@ target.clear(); SocketRaii socket; - + if (socket.GetDescriptor() != 1) { NetworkInterfaces interfaces; @@ -1316,20 +1316,20 @@ } strcpy(ifr.ifr_name, interfaces.GetCurrentName()); // NOLINT(clang-analyzer-security.insecureAPI.strcpy) - + if (ioctl(socket.GetDescriptor(), SIOCGIFFLAGS, &ifr) == 0 && !(ifr.ifr_flags & IFF_LOOPBACK) && // ignore loopback interface ioctl(socket.GetDescriptor(), SIOCGIFHWADDR, &ifr) == 0) { const unsigned char* mac = reinterpret_cast(ifr.ifr_hwaddr.sa_data); - + char tmp[32]; sprintf(tmp, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); target.insert(tmp); } #endif - + interfaces.Next(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/SystemToolbox.h --- a/OrthancFramework/Sources/SystemToolbox.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/SystemToolbox.h Wed Aug 19 14:11:33 2026 +0200 @@ -61,7 +61,7 @@ static ServerBarrierEvent ServerBarrier(); static void ReadFile(std::string& content, - const boost::filesystem::path& path, + const boost::filesystem::path& path, bool log); static inline void ReadFile(std::string& content, @@ -94,7 +94,7 @@ const boost::filesystem::path& path); // Returns true if the two files have the same MD5 - static bool CompareFilesMD5(const boost::filesystem::path& path1, + static bool CompareFilesMD5(const boost::filesystem::path& path1, const boost::filesystem::path& path2); #endif diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/TemporaryFile.cpp --- a/OrthancFramework/Sources/TemporaryFile.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/TemporaryFile.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -73,7 +73,7 @@ } - TemporaryFile::TemporaryFile() : + TemporaryFile::TemporaryFile() : path_(CreateTemporaryPath("", NULL)) { } @@ -122,7 +122,7 @@ } catch (OrthancException& e) { - throw OrthancException(e.GetErrorCode(), + throw OrthancException(e.GetErrorCode(), "Can't read temporary file \"" + SystemToolbox::PathToUtf8(path_) + "\": Another process has corrupted the temporary directory"); } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Toolbox.cpp --- a/OrthancFramework/Sources/Toolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Toolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -75,7 +75,7 @@ #else # include #endif - + #include #include #include @@ -126,7 +126,7 @@ int64_t strtoll(const char *nptr, char **endptr, int base) { return _strtoi64(nptr, endptr, base); - } + } } #endif @@ -207,7 +207,7 @@ # endif #endif - + #if defined(__unix__) && ORTHANC_SANDBOXED != 1 @@ -220,7 +220,7 @@ { #if ORTHANC_ENABLE_MD5 == 1 # if BOOST_VERSION >= 106600 - + struct Toolbox::MD5Context::PImpl : public boost::noncopyable { boost::uuids::detail::md5 md5_; @@ -316,19 +316,19 @@ # if BOOST_ENDIAN_LITTLE_BYTE sprintf(&target[0], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - (digest[0] >> 0) & 0xFF, + (digest[0] >> 0) & 0xFF, (digest[0] >> 8) & 0xFF, (digest[0] >> 16) & 0xFF, (digest[0] >> 24) & 0xFF, - (digest[1] >> 0) & 0xFF, + (digest[1] >> 0) & 0xFF, (digest[1] >> 8) & 0xFF, (digest[1] >> 16) & 0xFF, (digest[1] >> 24) & 0xFF, - (digest[2] >> 0) & 0xFF, + (digest[2] >> 0) & 0xFF, (digest[2] >> 8) & 0xFF, (digest[2] >> 16) & 0xFF, (digest[2] >> 24) & 0xFF, - (digest[3] >> 0) & 0xFF, + (digest[3] >> 0) & 0xFF, (digest[3] >> 8) & 0xFF, (digest[3] >> 16) & 0xFF, (digest[3] >> 24) & 0xFF); @@ -480,7 +480,7 @@ lineEnd_ += 1; } } - + Toolbox::LinesIterator::LinesIterator(const std::string& content) : content_(content), @@ -489,7 +489,7 @@ FindEndOfLine(); } - + bool Toolbox::LinesIterator::GetLine(std::string& target) const { assert(lineStart_ <= content_.size() && @@ -507,7 +507,7 @@ } } - + void Toolbox::LinesIterator::Next() { lineStart_ = lineEnd_; @@ -518,7 +518,7 @@ content_[lineStart_] == '\n'); char second; - + if (content_[lineStart_] == '\r') { second = '\n'; @@ -527,7 +527,7 @@ { second = '\r'; } - + lineStart_ += 1; if (lineStart_ < content_.size() && @@ -540,7 +540,7 @@ } } - + void Toolbox::ToUpperCase(std::string& s) { std::transform(s.begin(), s.end(), s.begin(), toupper); @@ -646,7 +646,7 @@ assert(j == target.size()); } } - + bool Toolbox::IsChildUri(const UriComponents& baseUri, @@ -749,14 +749,14 @@ #if ORTHANC_ENABLE_BASE64 == 1 - void Toolbox::EncodeBase64(std::string& result, + void Toolbox::EncodeBase64(std::string& result, const std::string& data) { result.clear(); base64_encode(result, data); } - void Toolbox::DecodeBase64(std::string& result, + void Toolbox::DecodeBase64(std::string& result, const std::string& data) { for (size_t i = 0; i < data.length(); i++) @@ -848,7 +848,7 @@ case Encoding_Hebrew: return "ISO-8859-8"; - + case Encoding_Japanese: return "SHIFT-JIS"; @@ -899,17 +899,17 @@ // The "::skip" flag makes boost skip invalid UTF-8 // characters. This can occur in badly-encoded DICOM files. - + try { if (sourceEncoding == Encoding_Ascii) { return ConvertToAscii(source); } - else + else { std::string s; - + if (sourceEncoding == Encoding_Utf8) { // Already in UTF-8: No conversion is required, but we ensure @@ -950,7 +950,7 @@ else { return s; - } + } } } catch (std::runtime_error& e) @@ -961,7 +961,7 @@ } } #endif - + #if ORTHANC_ENABLE_LOCALE == 1 std::string Toolbox::ConvertFromUtf8(const std::string& source, @@ -981,7 +981,7 @@ // The "::skip" flag makes boost skip invalid UTF-8 // characters. This can occur in badly-encoded DICOM files. - + try { if (targetEncoding == Encoding_Utf8) @@ -1081,7 +1081,7 @@ { return IsAsciiString(s.c_str(), s.size()); } - + std::string Toolbox::ConvertToAscii(const std::string& source) { @@ -1262,8 +1262,8 @@ isspace(source[last - 1])) { last--; - } - + } + assert(first <= last); return source.substr(first, last - first); } @@ -1329,14 +1329,14 @@ buffer[2] = 0x02; buffer[3] = 0x03; - switch (bufferView) + switch (bufferView) { - case 0x00010203: + case 0x00010203: return Endianness_Big; - case 0x03020100: + case 0x03020100: return Endianness_Little; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } @@ -1376,7 +1376,7 @@ bool includeEmptyStrings) { size_t countSeparators = 0; - + for (size_t i = 0; i < value.size(); i++) { if (value[i] == separator) @@ -1384,7 +1384,7 @@ countSeparators++; } } - + result.clear(); result.reserve(countSeparators + 1); @@ -1535,7 +1535,7 @@ } break; } - + case Json::objectValue: { Json::Value::Members members = source.getMemberNames(); @@ -1544,7 +1544,7 @@ { pugi::xml_node node = target.append_child(); node.set_name(members[i].c_str()); - JsonToXmlInternal(node, source[members[i]], arrayElement); + JsonToXmlInternal(node, source[members[i]], arrayElement); } break; @@ -1583,7 +1583,7 @@ #endif - + bool Toolbox::IsInteger(const std::string& str) { std::string s = StripSpaces(str); @@ -1690,7 +1690,7 @@ return str.compare(0, prefix.size(), prefix) == 0; } } - + static bool IsUnreservedCharacter(char c) { @@ -1929,7 +1929,7 @@ return (globalLocale_.get() != NULL); } - + static void InitializeIcu() { #if (ORTHANC_STATIC_ICU == 1) && (ORTHANC_ENABLE_ICU == 1) @@ -1963,7 +1963,7 @@ if (reinterpret_cast(globalIcuData_.c_str()) % ALIGN == 0) { // Data is already properly aligned - udata_setCommonData(globalIcuData_.c_str(), &status); + udata_setCommonData(globalIcuData_.c_str(), &status); } else { @@ -1988,18 +1988,18 @@ { *q = *p; } - + globalIcuData_.swap(aligned); const uint8_t* data = reinterpret_cast(globalIcuData_.c_str()) + offset; - + if (reinterpret_cast(data) % ALIGN != 0) { throw OrthancException(ErrorCode_InternalError, "Cannot align on 16-bytes boundary"); } else { - udata_setCommonData(data, &status); + udata_setCommonData(data, &status); } } @@ -2033,14 +2033,14 @@ uloc_getDefault(); #endif } - + void Toolbox::InitializeGlobalLocale(const char* locale) { InitializeIcu(); #if defined(__unix__) && ORTHANC_SANDBOXED != 1 static const char* LOCALTIME = "/etc/localtime"; - + if (!boost::filesystem::exists(LOCALTIME)) { // Check out file @@ -2056,14 +2056,14 @@ #endif bool ok; - + if (locale == NULL) { // Make Orthanc use English, United States locale // Linux: use "en_US.UTF-8" // Windows: use "" // Wine: use NULL - + #if defined(__MINGW32__) // Visibly, there is no support of locales in MinGW yet // http://mingw.5.n7.nabble.com/How-to-use-std-locale-global-with-MinGW-correct-td33048.html @@ -2124,7 +2124,7 @@ } # endif #endif - + if (error) { throw OrthancException(ErrorCode_BadSequenceOfCalls, @@ -2151,7 +2151,7 @@ * (2) The function "boost::algorithm::to_upper_copy" does not * make use of the "std::locale::global()". We therefore create a * global variable "globalLocale_". - * + * * (3) The variant of "boost::algorithm::to_upper_copy()" that * uses std::string does not work properly. We need to apply it * one wide strings (std::wstring). This explains the two calls to @@ -2194,21 +2194,21 @@ { LOG(INFO) << "OpenSSL is disabled"; } - + void Toolbox::FinalizeOpenSsl() { - } + } #elif (ORTHANC_ENABLE_SSL == 1 && \ - OPENSSL_VERSION_NUMBER < 0x10100000L) + OPENSSL_VERSION_NUMBER < 0x10100000L) /** * OpenSSL < 1.1.0 **/ void Toolbox::InitializeOpenSsl() { LOG(INFO) << "OpenSSL version: " << OPENSSL_VERSION_TEXT; - + // https://wiki.openssl.org/index.php/Library_Initialization SSL_library_init(); SSL_load_error_strings(); @@ -2227,7 +2227,7 @@ #if !defined(OPENSSL_NO_ENGINE) ENGINE_cleanup(); #endif - + CONF_modules_unload(1); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); @@ -2235,9 +2235,9 @@ ERR_free_strings(); } - + #elif (ORTHANC_ENABLE_SSL == 1 && \ - OPENSSL_VERSION_NUMBER >= 0x10100000L) + OPENSSL_VERSION_NUMBER >= 0x10100000L) /** * OpenSSL >= 1.1.0. In this case, the initialization is * automatically done by the functions of OpenSSL. @@ -2255,7 +2255,7 @@ #else # error "Support your platform here" #endif - + std::string Toolbox::GenerateUuid() @@ -2297,7 +2297,7 @@ dictionary_(dictionary) { } - + template Out operator()(const boost::smatch& what, Out out) const @@ -2306,7 +2306,7 @@ { // Variable without a default value Dictionary::const_iterator found = dictionary_.find(what[1]); - + if (found != dictionary_.end()) { const std::string& value = found->second; @@ -2318,7 +2318,7 @@ // Variable with a default value std::string key; std::string defaultValue; - + if (!what[2].str().empty()) { key = what[2].str(); @@ -2340,7 +2340,7 @@ } Dictionary::const_iterator found = dictionary_.find(key); - + if (found == dictionary_.end()) { out = std::copy(defaultValue.begin(), defaultValue.end(), out); @@ -2351,13 +2351,13 @@ out = std::copy(value.begin(), value.end(), out); } } - + return out; } }; } - + std::string Toolbox::SubstituteVariables(const std::string& source, const std::map& dictionary) { @@ -2479,7 +2479,7 @@ { size_t j = i+1; - // advance reading cursor while we are in a sequence + // advance reading cursor while we are in a sequence while (TestCharRange(s, j, '\x20', '\x2f')) ++j; @@ -2495,7 +2495,7 @@ } } - + /** This function will strip all ISO/IEC 2022 control codes and escape @@ -2537,7 +2537,7 @@ i += Iso2022::GetEscapeSequenceLength(src, i); // if the index was NOT incremented, this means there was no message at - // this location: we then may copy the character at this index and + // this location: we then may copy the character at this index and // increment the index to point to the next read position if (j == i) { @@ -2557,7 +2557,7 @@ static const uint8_t MASK_IS_1_BYTE = 0x80; // printf '0x%x\n' "$((2#10000000))" static const uint8_t TEST_IS_1_BYTE = 0x00; - + static const uint8_t MASK_IS_2_BYTES = 0xe0; // printf '0x%x\n' "$((2#11100000))" static const uint8_t TEST_IS_2_BYTES = 0xc0; // printf '0x%x\n' "$((2#11000000))" @@ -2630,7 +2630,7 @@ * NB: Focus of the code below is *not* efficiency, but * readability! **/ - + for (size_t i = 0; i < hex.size(); i++) { const char c = hex[i]; @@ -2642,7 +2642,7 @@ "Not an hexadecimal number"); } } - + std::vector decimal; decimal.push_back(0); @@ -2655,7 +2655,7 @@ { uint8_t val = static_cast(decimal[j]) * 16 + hexDigit; // Maximum: 9 * 16 + 15 assert(val <= 159 /* == 9 * 16 + 15 */); - + decimal[j] = val % 10; hexDigit = val / 10; assert(hexDigit <= 15 /* == 159 / 10 */); @@ -2705,7 +2705,7 @@ * each of those characters lying in the range [0,16[. The large * number is thus in the [0,16^32[ = [0,256^16[ range. This number * has a maximum of 39 decimal digits, as can be seen in Python: - * + * * # python -c 'import math; print(math.log(16**32))/math.log(10))' * 38.531839445 * @@ -2803,10 +2803,10 @@ #else Json::CharReaderBuilder builder; builder.settings_["collectComments"] = collectComments; - + const std::unique_ptr reader(builder.newCharReader()); assert(reader.get() != NULL); - + JSONCPP_STRING err; if (reader->parse(reinterpret_cast(buffer), reinterpret_cast(buffer) + size, &target, &err)) @@ -2827,7 +2827,7 @@ { return ReadJson(target, source.empty() ? NULL : source.c_str(), source.size()); } - + bool Toolbox::ReadJson(Json::Value& target, const void* buffer, @@ -2835,14 +2835,14 @@ { return ReadJsonInternal(target, buffer, size, true); } - + bool Toolbox::ReadJsonWithoutComments(Json::Value& target, const std::string& source) { return ReadJsonWithoutComments(target, source.empty() ? NULL : source.c_str(), source.size()); } - + bool Toolbox::ReadJsonWithoutComments(Json::Value& target, const void* buffer, @@ -2850,7 +2850,7 @@ { return ReadJsonInternal(target, buffer, size, false); } - + void Toolbox::WriteFastJson(std::string& target, const Json::Value& source) @@ -2864,7 +2864,7 @@ target = Json::writeString(builder, source); #endif } - + void Toolbox::WriteStyledJson(std::string& target, const Json::Value& source) @@ -3183,7 +3183,7 @@ int i = 0; double size = static_cast(sizeInBytes)/1024.0; - while (size >= 1024.0 && i < suffixesCount - 1) + while (size >= 1024.0 && i < suffixesCount - 1) { size /= 1024.0; i++; @@ -3211,7 +3211,7 @@ int i = 0; double duration = static_cast(durationInNanoseconds); - while (duration >= 1000.0 && i < suffixesCount - 1) + while (duration >= 1000.0 && i < suffixesCount - 1) { duration /= 1000.0; i++; @@ -3225,7 +3225,7 @@ std::string Toolbox::GetHumanTransferSpeed(bool full, uint64_t sizeInBytes, uint64_t durationInNanoseconds) { - // in "full" mode, returns " 26.45MB in 2.25s = 94.04Mbps" + // in "full" mode, returns " 26.45MB in 2.25s = 94.04Mbps" // else, return "94.04Mbps" if (full) @@ -3251,7 +3251,7 @@ int i = 0; - while (throughputInBps >= 1000.0 && i < suffixesCount - 1) + while (throughputInBps >= 1000.0 && i < suffixesCount - 1) { throughputInBps /= 1000.0; i++; diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/Toolbox.h --- a/OrthancFramework/Sources/Toolbox.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/Toolbox.h Wed Aug 19 14:11:33 2026 +0200 @@ -111,15 +111,15 @@ size_t lineEnd_; void FindEndOfLine(); - + public: explicit LinesIterator(const std::string& content); - + bool GetLine(std::string& target) const; void Next(); }; - + static void ToUpperCase(std::string& s); // Inplace version static void ToLowerCase(std::string& s); // Inplace version @@ -132,11 +132,11 @@ static void SplitUriComponents(UriComponents& components, const std::string& uri); - + static void TruncateUri(UriComponents& target, const UriComponents& source, size_t fromLevel); - + static bool IsChildUri(const UriComponents& baseUri, const UriComponents& testedUri); @@ -144,7 +144,7 @@ size_t fromLevel = 0); static std::string JoinUri(const std::string& base, const std::string& uri); - + #if ORTHANC_ENABLE_MD5 == 1 static void ComputeMD5(std::string& result, const std::string& data); @@ -170,10 +170,10 @@ static bool IsSHA1(const std::string& s); #if ORTHANC_ENABLE_BASE64 == 1 - static void DecodeBase64(std::string& result, + static void DecodeBase64(std::string& result, const std::string& data); - static void EncodeBase64(std::string& result, + static void EncodeBase64(std::string& result, const std::string& data); static bool DecodeDataUriScheme(std::string& mime, diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/WebServiceParameters.cpp --- a/OrthancFramework/Sources/WebServiceParameters.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/WebServiceParameters.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -67,7 +67,7 @@ } - WebServiceParameters::WebServiceParameters() : + WebServiceParameters::WebServiceParameters() : pkcs11Enabled_(false), timeout_(0) { @@ -132,7 +132,7 @@ void WebServiceParameters::SetCredentials(const std::string& username, const std::string& password) { - if (username.empty() && + if (username.empty() && !password.empty()) { throw OrthancException(ErrorCode_BadFileFormat); @@ -223,7 +223,7 @@ timeout_ = 0; ClearClientCertificate(); - if (peer.size() != 1 && + if (peer.size() != 1 && peer.size() != 3) { throw OrthancException(ErrorCode_BadFileFormat); @@ -348,7 +348,7 @@ const Json::Value::Members members = peer.getMemberNames(); - for (Json::Value::Members::const_iterator it = members.begin(); + for (Json::Value::Members::const_iterator it = members.begin(); it != members.end(); ++it) { if (!IsReservedKey(*it)) @@ -377,7 +377,7 @@ if (peer.isMember(KEY_TIMEOUT)) { - timeout_ = SerializationToolbox::ReadUnsignedInteger(peer, KEY_TIMEOUT); + timeout_ = SerializationToolbox::ReadUnsignedInteger(peer, KEY_TIMEOUT); } else { @@ -496,7 +496,7 @@ return true; } } - + bool WebServiceParameters::GetBooleanUserProperty(const std::string& key, bool defaultValue) const @@ -614,7 +614,7 @@ "Cannot open certificate file: " + certificateFile_); } - if (!certificateKeyFile_.empty() && + if (!certificateKeyFile_.empty() && !SystemToolbox::IsRegularFile(certificateKeyFile_)) { throw OrthancException(ErrorCode_InexistentFile, @@ -644,14 +644,14 @@ { target[KEY_CERTIFICATE_FILE] = certificateFile_; target[KEY_CERTIFICATE_KEY_FILE] = Json::nullValue; - target[KEY_CERTIFICATE_KEY_PASSWORD] = Json::nullValue; + target[KEY_CERTIFICATE_KEY_PASSWORD] = Json::nullValue; } target[KEY_PKCS11] = pkcs11Enabled_; target[KEY_TIMEOUT] = timeout_; Json::Value headers = Json::arrayValue; - + for (Dictionary::const_iterator it = headers_.begin(); it != headers_.end(); ++it) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/Sources/WebServiceParameters.h --- a/OrthancFramework/Sources/WebServiceParameters.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/Sources/WebServiceParameters.h Wed Aug 19 14:11:33 2026 +0200 @@ -72,7 +72,7 @@ void SetCredentials(const std::string& username, const std::string& password); - + const std::string& GetUsername() const; const std::string& GetPassword() const; @@ -100,10 +100,10 @@ const Dictionary& GetHttpHeaders() const; - void ListHttpHeaders(std::set& target) const; + void ListHttpHeaders(std::set& target) const; bool LookupHttpHeader(std::string& value, - const std::string& key) const; + const std::string& key) const; void AddUserProperty(const std::string& key, const std::string& value); @@ -112,7 +112,7 @@ const Dictionary& GetUserProperties() const; - void ListUserProperties(std::set& target) const; + void ListUserProperties(std::set& target) const; bool LookupUserProperty(std::string& value, const std::string& key) const; @@ -139,6 +139,6 @@ uint32_t GetTimeout() const; - bool HasTimeout() const; + bool HasTimeout() const; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/DicomMapTests.cpp --- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -170,7 +170,7 @@ DicomMap::AddMainDicomTag(DICOM_TAG_BITS_ALLOCATED, ResourceType_Instance); instanceSignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Instance); - + ASSERT_NE(defaultInstanceSignature, instanceSignature); } @@ -212,12 +212,12 @@ ASSERT_EQ(DICOM_TAG_PATIENT_NAME, *s.begin()); std::unique_ptr mm(m.Clone()); - ASSERT_EQ("PatientName", mm->GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); + ASSERT_EQ("PatientName", mm->GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); m.SetValue(DICOM_TAG_PATIENT_ID, "Hello", false); ASSERT_THROW(mm->GetValue(DICOM_TAG_PATIENT_ID), OrthancException); mm->CopyTagIfExists(m, DICOM_TAG_PATIENT_ID); - ASSERT_EQ("Hello", mm->GetValue(DICOM_TAG_PATIENT_ID).GetContent()); + ASSERT_EQ("Hello", mm->GetValue(DICOM_TAG_PATIENT_ID).GetContent()); DicomValue v; ASSERT_TRUE(v.IsNull()); @@ -256,7 +256,7 @@ std::set moduleTags; DicomTag::AddTagsForModule(moduleTags, module); - + // The main dicom tags are a subset of the module for (std::set::const_iterator it = main.begin(); it != main.end(); ++it) { @@ -335,7 +335,7 @@ uint64_t l; unsigned int ui; std::string s; - + m.SetValue(DICOM_TAG_PATIENT_NAME, " ", false); // Empty value ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); @@ -343,7 +343,7 @@ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); - + m.SetValue(DICOM_TAG_PATIENT_NAME, "0", true); // Binary value ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); @@ -355,7 +355,7 @@ ASSERT_FALSE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true)); ASSERT_EQ("0", s); - + // 2**31-1 m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483647", false); @@ -391,8 +391,8 @@ ASSERT_EQ("42", s); ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true)); ASSERT_EQ("42", s); - - + + // 2**31 m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483648", false); ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); @@ -420,7 +420,7 @@ ASSERT_EQ(4294967295ll, j); ASSERT_EQ(4294967295u, k); ASSERT_EQ(4294967295ull, l); - + // 2**32 m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967296", false); ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); @@ -433,7 +433,7 @@ ASSERT_DOUBLE_EQ(4294967296.0, d); ASSERT_EQ(4294967296ll, j); ASSERT_EQ(4294967296ull, l); - + m.SetValue(DICOM_TAG_PATIENT_NAME, "-1", false); ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); @@ -458,7 +458,7 @@ ASSERT_DOUBLE_EQ(-2147483648.0, d); ASSERT_EQ(static_cast(-2147483648ll), i); ASSERT_EQ(-2147483648ll, j); - + // -2**31 - 1 m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483649", false); ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); @@ -468,7 +468,7 @@ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); ASSERT_FLOAT_EQ(-2147483649.0f, f); - ASSERT_DOUBLE_EQ(-2147483649.0, d); + ASSERT_DOUBLE_EQ(-2147483649.0, d); ASSERT_EQ(-2147483649ll, j); @@ -485,7 +485,7 @@ TEST(DicomMap, Serialize) { Json::Value s; - + { DicomMap m; m.SetValue(DICOM_TAG_PATIENT_NAME, "Hello", false); @@ -670,7 +670,7 @@ Json::Value parsedJson; bool ret = Toolbox::ReadJson(parsedJson, jsonFullString); - + m.FromDicomAsJson(parsedJson, false /* append */, true /* parseSequences*/); ASSERT_TRUE(ret); @@ -749,17 +749,17 @@ item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.719"; a.append(item); } - + { Json::Value item = Json::objectValue; item["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4"; // ReferencedSOPClassUID item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.726"; a.append(item); } - + v["ReferencedImageSequence"] = a; } - + { Json::Value a = Json::arrayValue; @@ -779,10 +779,10 @@ item["PurposeOfReferenceCodeSequence"] = b; } - + a.append(item); } - + v["RelatedSeriesSequence"] = a; } @@ -814,7 +814,7 @@ { const Json::Value& tag = visitor.GetResult() ["00200037"]; // ImageOrientationPatient const Json::Value& value = tag["Value"]; - + ASSERT_EQ(EnumerationToString(ValueRepresentation_DecimalString), tag["vr"].asString()); ASSERT_EQ(2u, tag.getMemberNames().size()); ASSERT_EQ(3u, value.size()); @@ -878,7 +878,7 @@ { const Json::Value& tag = visitor.GetResult() ["00200037"]; const Json::Value& value = tag["Value"]; - + ASSERT_EQ(EnumerationToString(ValueRepresentation_DecimalString), tag["vr"].asString()); ASSERT_EQ(2u, tag.getMemberNames().size()); ASSERT_EQ(4u, value.size()); @@ -892,7 +892,7 @@ std::string xml; visitor.FormatXml(xml); - + { DicomMap m; m.FromDicomWeb(visitor.GetResult()); @@ -937,7 +937,7 @@ TEST(DicomMap, MainTagNames) { ASSERT_EQ(3, ResourceType_Instance - ResourceType_Patient); - + for (int i = ResourceType_Patient; i <= ResourceType_Instance; i++) { ResourceType level = static_cast(i); @@ -1088,12 +1088,12 @@ * servers, and must not be altered by the "ExtraMainDicomTags" * configuration option that was introduced in Orthanc 1.11.0. **/ - + { DicomMap m; m.SetValue(DICOM_TAG_ENCAPSULATED_DOCUMENT, "nope", false); m.SetValue(DICOM_TAG_PATIENT_ID, "patient_id", false); - + DicomMap::SetupFindPatientTemplate(m); std::set tags; m.GetTags(tags); @@ -1107,12 +1107,12 @@ ASSERT_EQ("", m.GetStringValue(DICOM_TAG_PATIENT_NAME, "nope", false)); ASSERT_EQ("", m.GetStringValue(DICOM_TAG_PATIENT_SEX, "nope", false)); } - + { DicomMap m; m.SetValue(DICOM_TAG_ENCAPSULATED_DOCUMENT, "nope", false); m.SetValue(DICOM_TAG_PATIENT_ID, "patient_id", false); - + DicomMap::SetupFindStudyTemplate(m); std::set tags; m.GetTags(tags); @@ -1129,12 +1129,12 @@ ASSERT_EQ("", m.GetStringValue(DICOM_TAG_STUDY_ID, "nope", false)); ASSERT_EQ("", m.GetStringValue(DICOM_TAG_STUDY_TIME, "nope", false)); } - + { DicomMap m; m.SetValue(DICOM_TAG_ENCAPSULATED_DOCUMENT, "nope", false); m.SetValue(DICOM_TAG_PATIENT_ID, "patient_id", false); - + DicomMap::SetupFindSeriesTemplate(m); std::set tags; m.GetTags(tags); @@ -1156,12 +1156,12 @@ ASSERT_EQ("", m.GetStringValue(DICOM_TAG_SERIES_NUMBER, "nope", false)); ASSERT_EQ("", m.GetStringValue(DICOM_TAG_SERIES_TIME, "nope", false)); } - + { DicomMap m; m.SetValue(DICOM_TAG_ENCAPSULATED_DOCUMENT, "nope", false); m.SetValue(DICOM_TAG_PATIENT_ID, "patient_id", false); - + DicomMap::SetupFindInstanceTemplate(m); std::set tags; m.GetTags(tags); @@ -1949,7 +1949,7 @@ TEST(DicomMap, DISABLED_ParseDicomMetaInformation) { static const std::string PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/"; - + std::map f; f.insert(std::make_pair(PATH + "../ColorTestMalaterre.dcm", DicomTransferSyntax_LittleEndianImplicit)); // 1.2.840.10008.1.2 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.1.dcm", DicomTransferSyntax_LittleEndianExplicit)); @@ -1967,7 +1967,7 @@ for (std::map::const_iterator it = f.begin(); it != f.end(); ++it) { printf("\n== %s ==\n\n", it->first.c_str()); - + std::string dicom; SystemToolbox::ReadFile(dicom, it->first, false); @@ -1977,7 +1977,7 @@ std::string s; ASSERT_TRUE(d.LookupStringValue(s, DICOM_TAG_TRANSFER_SYNTAX_UID, false)); - + DicomTransferSyntax ts; ASSERT_TRUE(LookupTransferSyntax(ts, s)); ASSERT_EQ(ts, it->second); @@ -1992,18 +1992,18 @@ private: DicomMap map_; uint64_t pixelDataOffset_; - + public: V() : pixelDataOffset_(0) { } - + const DicomMap& GetDicomMap() const { return map_; } - + virtual void VisitMetaHeaderTag(const DicomTag& tag, const ValueRepresentation& vr, const std::string& value) ORTHANC_OVERRIDE @@ -2015,7 +2015,7 @@ { printf("TRANSFER SYNTAX: %s\n", GetTransferSyntaxUid(transferSyntax)); } - + virtual bool VisitDatasetTag(const DicomTag& tag, const ValueRepresentation& vr, const std::string& value, @@ -2040,7 +2040,7 @@ } map_.SetValue(tag, value, Toolbox::IsAsciiString(value)); - + return true; } @@ -2092,7 +2092,7 @@ SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.dcm", false); ASSERT_FALSE(DicomStreamReader::LookupPixelDataOffset(offset, vr, dicom)); } - + for (Sources::const_iterator it = sources.begin(); it != sources.end(); ++it) { std::string dicom; @@ -2105,7 +2105,7 @@ ASSERT_EQ(it->get<1>(), offset); ASSERT_EQ(it->get<2>(), vr); } - + { uint64_t offset; ValueRepresentation vr; @@ -2113,14 +2113,14 @@ ASSERT_EQ(it->get<1>(), offset); ASSERT_EQ(it->get<2>(), vr); } - + ParsedDicomFile a(dicom); Json::Value aa; a.DatasetToJson(aa, DicomToJsonFormat_Short, DicomToJsonFlags_Default, 0); std::stringstream stream; size_t pos = 0; - + DicomStreamReader r(stream); V visitor; @@ -2157,9 +2157,9 @@ //const std::string path = PATH + "1.2.840.10008.1.2.4.50.dcm"; //const std::string path = PATH + "1.2.840.10008.1.2.2.dcm"; const std::string path = "/home/jodogne/Subversion/orthanc-tests/Database/HierarchicalAnonymization/RTH/RT.dcm"; - + std::ifstream stream(path.c_str()); - + DicomStreamReader r(stream); V visitor; @@ -2177,7 +2177,7 @@ std::set errors; unsigned int success = 0; - + for (boost::filesystem::recursive_directory_iterator current(PATH), end; current != end ; ++current) { @@ -2194,10 +2194,10 @@ { std::ifstream stream(path.c_str()); - + DicomStreamReader r(stream); V visitor; - + try { r.Consume(visitor, DICOM_TAG_PIXEL_DATA); @@ -2217,11 +2217,11 @@ DicomMap m2; - + { std::string dicom; SystemToolbox::ReadFile(dicom, current->path()); - + ParsedDicomFile f(dicom); f.ExtractDicomSummary(m2, 256); } @@ -2239,7 +2239,7 @@ fprintf(stderr, "[%s]\n", path.c_str()); first = false; } - + std::cerr << "ERROR: " << it->Format() << std::endl; } else if (!m2.GetValue(*it).IsNull() && @@ -2248,7 +2248,7 @@ { const std::string& v1 = m1.GetValue(*it).GetContent(); const std::string& v2 = m2.GetValue(*it).GetContent(); - + if (v1 != v2 && (v1.size() != v2.size() + 1 || v1.substr(0, v2.size()) != v2)) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/FileStorageTests.cpp --- a/OrthancFramework/UnitTestsSources/FileStorageTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/FileStorageTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -66,7 +66,7 @@ std::string d; { std::unique_ptr buffer(s.ReadWhole(uid, FileContentType_Unknown)); - buffer->MoveToString(d); + buffer->MoveToString(d); } ASSERT_EQ(d.size(), data.size()); ASSERT_FALSE(memcmp(&d[0], &data[0], data.size())); @@ -90,7 +90,7 @@ std::string d; { std::unique_ptr buffer(s.ReadWhole(uid, FileContentType_Unknown)); - buffer->MoveToString(d); + buffer->MoveToString(d); } ASSERT_EQ(d.size(), data.size()); ASSERT_FALSE(memcmp(&d[0], &data[0], data.size())); @@ -177,7 +177,7 @@ std::set ss; s.ListAllFiles(ss); ASSERT_EQ(10u, ss.size()); - + unsigned int c = 0; for (std::list::const_iterator i = u.begin(); i != u.end(); ++i, c++) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/FrameworkTests.cpp --- a/OrthancFramework/UnitTestsSources/FrameworkTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/FrameworkTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -276,11 +276,11 @@ TEST(Uri, Child) { - UriComponents c1; Toolbox::SplitUriComponents(c1, "/hello/world"); - UriComponents c2; Toolbox::SplitUriComponents(c2, "/hello/hello"); - UriComponents c3; Toolbox::SplitUriComponents(c3, "/hello"); - UriComponents c4; Toolbox::SplitUriComponents(c4, "/world"); - UriComponents c5; Toolbox::SplitUriComponents(c5, "/"); + UriComponents c1; Toolbox::SplitUriComponents(c1, "/hello/world"); + UriComponents c2; Toolbox::SplitUriComponents(c2, "/hello/hello"); + UriComponents c3; Toolbox::SplitUriComponents(c3, "/hello"); + UriComponents c4; Toolbox::SplitUriComponents(c4, "/world"); + UriComponents c5; Toolbox::SplitUriComponents(c5, "/"); ASSERT_TRUE(Toolbox::IsChildUri(c1, c1)); ASSERT_FALSE(Toolbox::IsChildUri(c1, c2)); @@ -428,7 +428,7 @@ TEST(Toolbox, ComputeSHA1) { std::string s; - + Toolbox::ComputeSHA1(s, "The quick brown fox jumps over the lazy dog"); ASSERT_EQ("2fd4e1c6-7a2d28fc-ed849ee1-bb76e739-1b93eb12", s); Toolbox::ComputeSHA1(s, ""); @@ -460,10 +460,10 @@ Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ(" abd ", s); s = "\""; - Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ("", s); + Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ("", s); s = "\"\""; - Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ("", s); + Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ("", s); s = "\"_\""; Toolbox::RemoveSurroundingQuotes(s); ASSERT_EQ("_", s); @@ -480,7 +480,7 @@ Toolbox::ToUpperCase(ss, s); ASSERT_EQ("COU", ss); Toolbox::ToLowerCase(ss, s); - ASSERT_EQ("cou", ss); + ASSERT_EQ("cou", ss); s = "CoU"; Toolbox::ToUpperCase(s); @@ -510,7 +510,7 @@ { // This is a Latin-1 test string const unsigned char data[10] = { 0xe0, 0xe9, 0xea, 0xe7, 0x26, 0xc6, 0x61, 0x62, 0x63, 0x00 }; - + std::string s(reinterpret_cast(&data[0]), 10); ASSERT_EQ("&abc", Toolbox::ConvertToAscii(s)); ASSERT_FALSE(Toolbox::IsValidUtf8(s)); @@ -574,40 +574,40 @@ TEST(Toolbox, Utf8ToUnicode) { // https://en.wikipedia.org/wiki/UTF-8 - + ASSERT_EQ(1u, sizeof(char)); ASSERT_EQ(1u, sizeof(uint8_t)); - + { const uint8_t data[] = { 0x24 }; ASSERT_EQ(0x24, GetUnicode(data, 1, 1)); ASSERT_THROW(GetUnicode(data, 0, 1), OrthancException); } - + { const uint8_t data[] = { 0xc2, 0xa2 }; ASSERT_EQ(0xa2, GetUnicode(data, 2, 2)); ASSERT_THROW(GetUnicode(data, 1, 2), OrthancException); } - + { const uint8_t data[] = { 0xe0, 0xa4, 0xb9 }; ASSERT_EQ(0x0939, GetUnicode(data, 3, 3)); ASSERT_THROW(GetUnicode(data, 2, 3), OrthancException); } - + { const uint8_t data[] = { 0xe2, 0x82, 0xac }; ASSERT_EQ(0x20ac, GetUnicode(data, 3, 3)); ASSERT_THROW(GetUnicode(data, 2, 3), OrthancException); } - + { const uint8_t data[] = { 0xf0, 0x90, 0x8d, 0x88 }; ASSERT_EQ(0x010348, GetUnicode(data, 4, 4)); ASSERT_THROW(GetUnicode(data, 3, 4), OrthancException); } - + { const uint8_t data[] = { 0xe0 }; ASSERT_THROW(GetUnicode(data, 1, 1), OrthancException); @@ -625,8 +625,8 @@ s = "%21%23%24%26%27%28%29%2A%2B%2c%2f%3A%3b%3d%3f%40%5B%5D%90%ff"; Toolbox::UrlDecode(s); - std::string ss = "!#$&'()*+,/:;=?@[]"; - ss.push_back((char) 144); + std::string ss = "!#$&'()*+,/:;=?@[]"; + ss.push_back((char) 144); ss.push_back((char) 255); ASSERT_EQ(ss, s); @@ -745,16 +745,16 @@ TEST(Toolbox, Tokenize) { std::vector t; - - Toolbox::TokenizeString(t, "", ','); + + Toolbox::TokenizeString(t, "", ','); ASSERT_EQ(1u, t.size()); ASSERT_EQ("", t[0]); - - Toolbox::TokenizeString(t, "abc", ','); + + Toolbox::TokenizeString(t, "abc", ','); ASSERT_EQ(1u, t.size()); ASSERT_EQ("abc", t[0]); - - Toolbox::TokenizeString(t, "ab,cd,ef,", ','); + + Toolbox::TokenizeString(t, "ab,cd,ef,", ','); ASSERT_EQ(4u, t.size()); ASSERT_EQ("ab", t[0]); ASSERT_EQ("cd", t[1]); @@ -992,15 +992,15 @@ /** * Windows and OS X are assumed to always little-endian. **/ - + #if defined(_WIN32) || defined(__APPLE__) ASSERT_EQ(Endianness_Little, Toolbox::DetectEndianness()); - + /** * FreeBSD. **/ - + #elif defined(__FreeBSD__) || defined(__OpenBSD__) # if _BYTE_ORDER == _BIG_ENDIAN ASSERT_EQ(Endianness_Big, Toolbox::DetectEndianness()); @@ -1012,7 +1012,7 @@ /** * Linux. **/ - + #elif defined(__linux__) || defined(__FreeBSD_kernel__) #if !defined(__BYTE_ORDER) @@ -1025,11 +1025,11 @@ ASSERT_EQ(Endianness_Little, Toolbox::DetectEndianness()); # endif - + /** * WebAssembly is always little-endian. **/ - + #elif defined(__EMSCRIPTEN__) ASSERT_EQ(Endianness_Little, Toolbox::DetectEndianness()); #else @@ -1296,7 +1296,7 @@ // Unreserved characters must not be modified std::string t = "aAzZ09.-~_"; - Toolbox::UriEncode(s, t); + Toolbox::UriEncode(s, t); ASSERT_EQ(t, s); Toolbox::UriEncode(s, "!#$&'()*+,/:;=?@[]"); ASSERT_EQ("%21%23%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D", s); @@ -1304,7 +1304,7 @@ // Encode characters from UTF-8. This is the test string from the // file "../Resources/EncodingTests.py" - Toolbox::UriEncode(s, "\x54\x65\x73\x74\xc3\xa9\xc3\xa4\xc3\xb6\xc3\xb2\xd0\x94\xce\x98\xc4\x9d\xd7\x93\xd8\xb5\xc4\xb7\xd1\x9b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0"); + Toolbox::UriEncode(s, "\x54\x65\x73\x74\xc3\xa9\xc3\xa4\xc3\xb6\xc3\xb2\xd0\x94\xce\x98\xc4\x9d\xd7\x93\xd8\xb5\xc4\xb7\xd1\x9b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0"); ASSERT_EQ("Test%C3%A9%C3%A4%C3%B6%C3%B2%D0%94%CE%98%C4%9D%D7%93%D8%B5%C4%B7%D1%9B%E0%B9%9B%EF%BE%88%C4%B0", s); } @@ -1362,7 +1362,7 @@ ASSERT_TRUE(it.GetLine(s)); it.Next(); ASSERT_EQ("", s); ASSERT_FALSE(it.GetLine(s)); } - + { std::string content = "\n Hello \n\nWorld\n\n"; Toolbox::LinesIterator it(content); @@ -1429,7 +1429,7 @@ Toolbox::SubstituteVariables( "${WORLD} A ${WORLD2:-a} B ${WORLD:-b} C ${WORLD2:-\"'c'\"} D ${WORLD2:-'{\"a\":\"b\"}'} E ${WORLD2:-}", env)); - + SystemToolbox::GetEnvironmentVariables(env); ASSERT_TRUE(env.find("NOPE") == env.end()); @@ -1456,7 +1456,7 @@ std::vector t; Toolbox::TokenizeString(t, s, '\n'); - + for (size_t i = 0; i < t.size() - 1; i++) { std::vector v; @@ -1471,7 +1471,7 @@ MetricsRegistry m; m.SetEnabled(false); m.SetIntegerValue("hello.world", 42); - + std::string s; m.ExportPrometheusText(s); ASSERT_TRUE(s.empty()); @@ -1480,7 +1480,7 @@ { MetricsRegistry m; m.Register("hello.world", MetricsUpdatePolicy_Directly, MetricsDataType_Integer); - + std::string s; m.ExportPrometheusText(s); ASSERT_TRUE(s.empty()); @@ -1491,7 +1491,7 @@ m.SetIntegerValue("hello.world", -42); ASSERT_EQ(MetricsUpdatePolicy_Directly, m.GetUpdatePolicy("hello.world")); ASSERT_THROW(m.GetUpdatePolicy("nope"), OrthancException); - + std::string s; m.ExportPrometheusText(s); @@ -1515,13 +1515,13 @@ m.SetIntegerValue("hello.min", 20); m.SetIntegerValue("hello.min", -10); m.SetIntegerValue("hello.min", 5); - + m.Register("hello.directly", MetricsUpdatePolicy_Directly, MetricsDataType_Integer); m.SetIntegerValue("hello.directly", 10); m.SetIntegerValue("hello.directly", 20); m.SetIntegerValue("hello.directly", -10); m.SetIntegerValue("hello.directly", 5); - + ASSERT_EQ(MetricsUpdatePolicy_MaxOver10Seconds, m.GetUpdatePolicy("hello.max")); ASSERT_EQ(MetricsUpdatePolicy_MinOver10Seconds, m.GetUpdatePolicy("hello.min")); ASSERT_EQ(MetricsUpdatePolicy_Directly, m.GetUpdatePolicy("hello.directly")); @@ -1620,7 +1620,7 @@ { MetricsRegistry::SharedMetrics max10(mr, "shared_max10", MetricsUpdatePolicy_MaxOver10Seconds); - + { MetricsRegistry::ActiveCounter c1(max10); MetricsRegistry::ActiveCounter c2(max10); @@ -1683,9 +1683,9 @@ tmp.Read(s); ASSERT_TRUE(s.empty()); tmp.ReadRange(s, 0, 0, true); ASSERT_TRUE(s.empty()); tmp.ReadRange(s, 0, 10, false); ASSERT_TRUE(s.empty()); - + ASSERT_THROW(tmp.ReadRange(s, 0, 1, true), OrthancException); - + tmp.Write("Hello"); tmp.Read(s); ASSERT_EQ("Hello", s); tmp.ReadRange(s, 0, 5, true); ASSERT_EQ("Hello", s); @@ -1698,7 +1698,7 @@ tmp.ReadRange(s, 2, 50, false); ASSERT_EQ("llo", s); tmp.ReadRange(s, 2, 2, false); ASSERT_TRUE(s.empty()); tmp.ReadRange(s, 10, 50, false); ASSERT_TRUE(s.empty()); - + ASSERT_THROW(tmp.ReadRange(s, 5, 10, true), OrthancException); ASSERT_THROW(tmp.ReadRange(s, 10, 50, true), OrthancException); ASSERT_THROW(tmp.ReadRange(s, 50, 10, true), OrthancException); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp --- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -183,7 +183,7 @@ ASSERT_TRUE(Toolbox::IsUuid(s)); ASSERT_TRUE(o->GetTagValue(s, privateTag)); ASSERT_STREQ("private tag", s.c_str()); - + m.SetupAnonymization(DicomVersion_2008); m.Apply(o); ASSERT_FALSE(o->GetTagValue(s, privateTag)); @@ -244,7 +244,7 @@ ImageAccessor accessor; img.GetWriteableAccessor(accessor); - + uint16_t v = 0; for (unsigned int y = 0; y < img.GetHeight(); y++) { @@ -378,15 +378,15 @@ TEST(FromDcmtkBridge, ValueRepresentation) { - ASSERT_EQ(ValueRepresentation_PersonName, + ASSERT_EQ(ValueRepresentation_PersonName, FromDcmtkBridge::LookupValueRepresentation(DICOM_TAG_PATIENT_NAME)); - ASSERT_EQ(ValueRepresentation_Date, + ASSERT_EQ(ValueRepresentation_Date, FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x0020) /* StudyDate */)); - ASSERT_EQ(ValueRepresentation_Time, + ASSERT_EQ(ValueRepresentation_Time, FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x0030) /* StudyTime */)); - ASSERT_EQ(ValueRepresentation_DateTime, + ASSERT_EQ(ValueRepresentation_DateTime, FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x002a) /* AcquisitionDateTime */)); - ASSERT_EQ(ValueRepresentation_NotSupported, + ASSERT_EQ(ValueRepresentation_NotSupported, FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0001, 0x0001) /* some private tag */)); } @@ -420,14 +420,14 @@ {// invalid tag std::string source = "0010,0010;Patient-BirthDate;0020,0020"; std::set result; - + ASSERT_THROW(FromDcmtkBridge::ParseListOfTags(result, source), OrthancException); } {// duplicate tag only once std::string source = "0010,0010;PatientName"; std::set result; - + FromDcmtkBridge::ParseListOfTags(result, source); ASSERT_EQ(1u, result.size()); @@ -555,7 +555,7 @@ ASSERT_NE(0, c["ReferencedStudySequence"].compare(a)); // Because Data URI Scheme decoding was enabled } - a = "data:application/octet-stream;base64,VGF0YQ=="; // echo -n "Tata" | base64 + a = "data:application/octet-stream;base64,VGF0YQ=="; // echo -n "Tata" | base64 f.Replace(DICOM_TAG_SOP_INSTANCE_UID, a, false, DicomReplaceMode_InsertIfAbsent, ""); // (*) f.Replace(DICOM_TAG_SOP_CLASS_UID, a, true, DicomReplaceMode_InsertIfAbsent, ""); // (**) @@ -698,25 +698,25 @@ f.DatasetToJson(v, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); ASSERT_EQ(Json::objectValue, v.type()); ASSERT_EQ(5u, v.getMemberNames().size()); - ASSERT_FALSE(v.isMember("7fe0,0010")); + ASSERT_FALSE(v.isMember("7fe0,0010")); f.DatasetToJson(v, DicomToJsonFormat_Short, static_cast(DicomToJsonFlags_IncludePixelData | DicomToJsonFlags_ConvertBinaryToNull), 0); ASSERT_EQ(Json::objectValue, v.type()); ASSERT_EQ(6u, v.getMemberNames().size()); - ASSERT_TRUE(v.isMember("7fe0,0010")); - ASSERT_EQ(Json::nullValue, v["7fe0,0010"].type()); + ASSERT_TRUE(v.isMember("7fe0,0010")); + ASSERT_EQ(Json::nullValue, v["7fe0,0010"].type()); f.DatasetToJson(v, DicomToJsonFormat_Short, static_cast(DicomToJsonFlags_IncludePixelData | DicomToJsonFlags_ConvertBinaryToAscii), 0); ASSERT_EQ(Json::objectValue, v.type()); ASSERT_EQ(6u, v.getMemberNames().size()); - ASSERT_TRUE(v.isMember("7fe0,0010")); - ASSERT_EQ(Json::stringValue, v["7fe0,0010"].type()); + ASSERT_TRUE(v.isMember("7fe0,0010")); + ASSERT_EQ(Json::stringValue, v["7fe0,0010"].type()); ASSERT_EQ("BA", v["7fe0,0010"].asString().substr(0, 2)); f.DatasetToJson(v, DicomToJsonFormat_Short, DicomToJsonFlags_IncludePixelData, 0); ASSERT_EQ(Json::objectValue, v.type()); ASSERT_EQ(6u, v.getMemberNames().size()); - ASSERT_TRUE(v.isMember("7fe0,0010")); + ASSERT_TRUE(v.isMember("7fe0,0010")); ASSERT_EQ(Json::stringValue, v["7fe0,0010"].type()); std::string mime, content; ASSERT_TRUE(Toolbox::DecodeDataUriScheme(mime, content, v["7fe0,0010"].asString())); @@ -757,7 +757,7 @@ ASSERT_EQ(2u, v.size()); ASSERT_EQ("HELLO^", v["0010,0010"].asString()); ASSERT_EQ("WORLD^", v["7fe1,0010"].asString()); - } + } } @@ -812,7 +812,7 @@ v["7052-1000"] = "Some unknown tag"; // Even group => public, unknown tag v["7057-1000"] = "Some private tag"; // Odd group => private tag v["7059-1000"] = "Some private tag2"; // Odd group => private tag, with an odd length to test padding - + std::string s; Toolbox::EncodeDataUriScheme(s, "application/octet-stream", "Sebastien"); v["StudyDescription"] = s; @@ -829,9 +829,9 @@ } const DicomToJsonFlags toJsonFlags = static_cast(DicomToJsonFlags_IncludeBinary | - DicomToJsonFlags_IncludePixelData | - DicomToJsonFlags_IncludePrivateTags | - DicomToJsonFlags_IncludeUnknownTags | + DicomToJsonFlags_IncludePixelData | + DicomToJsonFlags_IncludePrivateTags | + DicomToJsonFlags_IncludeUnknownTags | DicomToJsonFlags_ConvertBinaryToAscii); @@ -911,12 +911,12 @@ image.GetRegion(r, 32, 32, 64, 192); Orthanc::ImageProcessing::Set(r, 0); - + image.GetRegion(r, 160, 32, 64, 192); - Orthanc::ImageProcessing::Set(r, 255); + Orthanc::ImageProcessing::Set(r, 255); std::string saved; - + { ParsedDicomFile f(true); f.ReplacePlainString(DICOM_TAG_SOP_CLASS_UID, "1.2.840.10008.5.1.4.1.1.7"); @@ -932,7 +932,7 @@ { Orthanc::ParsedDicomFile f(saved); - + std::unique_ptr decoded(f.DecodeFrame(0)); ASSERT_EQ(256u, decoded->GetWidth()); ASSERT_EQ(256u, decoded->GetHeight()); @@ -992,7 +992,7 @@ { Orthanc::ParsedDicomFile f(saved); - + std::unique_ptr decoded(f.DecodeFrame(0)); ASSERT_EQ(384u, decoded->GetWidth()); ASSERT_EQ(256u, decoded->GetHeight()); @@ -1023,15 +1023,15 @@ } Orthanc::ImageAccessor r; - + image.GetRegion(r, 32, 32, 64, 192); Orthanc::ImageProcessing::Set(r, 0); - + image.GetRegion(r, 160, 32, 64, 192); - Orthanc::ImageProcessing::Set(r, 65535); + Orthanc::ImageProcessing::Set(r, 65535); std::string saved; - + { ParsedDicomFile f(true); f.ReplacePlainString(DICOM_TAG_SOP_CLASS_UID, "1.2.840.10008.5.1.4.1.1.7"); @@ -1047,7 +1047,7 @@ { Orthanc::ParsedDicomFile f(saved); - + std::unique_ptr decoded(f.DecodeFrame(0)); ASSERT_EQ(256u, decoded->GetWidth()); ASSERT_EQ(256u, decoded->GetHeight()); @@ -1080,12 +1080,12 @@ Orthanc::ImageAccessor r; image.GetRegion(r, 32, 32, 64, 192); Orthanc::ImageProcessing::Set(r, -32768); - + image.GetRegion(r, 160, 32, 64, 192); - Orthanc::ImageProcessing::Set(r, 32767); + Orthanc::ImageProcessing::Set(r, 32767); std::string saved; - + { ParsedDicomFile f(true); f.ReplacePlainString(DICOM_TAG_SOP_CLASS_UID, "1.2.840.10008.5.1.4.1.1.7"); @@ -1101,7 +1101,7 @@ { Orthanc::ParsedDicomFile f(saved); - + std::unique_ptr decoded(f.DecodeFrame(0)); ASSERT_EQ(256u, decoded->GetWidth()); ASSERT_EQ(256u, decoded->GetHeight()); @@ -1177,14 +1177,14 @@ utf8 = testEncodingsEncoded[i]; break; } - } + } ASSERT_TRUE(utf8 != NULL); for (unsigned int i = 0; i < testEncodingsCount; i++) { // 1251 codepage is not supported by the core DICOM standard, ignore it - if (testEncodings[i] != Encoding_Windows1251) + if (testEncodings[i] != Encoding_Windows1251) { { // Sanity check to test the proper behavior of "EncodingTests.py" @@ -1214,7 +1214,7 @@ m.SetValue(DICOM_TAG_PATIENT_NAME, testEncodingsExpected[i], false); ParsedDicomFile dicom(m, testEncodings[i], false); - + const char* encoded = NULL; ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->findAndGetString(DCM_PatientName, encoded).good()); ASSERT_STREQ(testEncodingsEncoded[i], encoded); @@ -1237,7 +1237,7 @@ Json::Value v2; dicom.DatasetToJson(v2, DicomToJsonFormat_Human, DicomToJsonFlags_Default, 0); - + ASSERT_EQ(v2["PatientName"].asString(), v["PatientName"].asString()); ASSERT_EQ(v2["SpecificCharacterSet"].asString(), v["SpecificCharacterSet"].asString()); } @@ -1251,7 +1251,7 @@ for (unsigned int i = 0; i < testEncodingsCount; i++) { // 1251 codepage is not supported by the core DICOM standard, ignore it - if (testEncodings[i] != Encoding_Windows1251) + if (testEncodings[i] != Encoding_Windows1251) { DicomMap m; m.SetValue(DICOM_TAG_PATIENT_NAME, testEncodingsExpected[i], false); @@ -1276,11 +1276,11 @@ ASSERT_EQ(testEncodings[i], dicom.DetectEncoding(hasCodeExtensions)); ASSERT_FALSE(hasCodeExtensions); - + const char* c = NULL; ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->findAndGetString(DCM_PatientName, c).good()); EXPECT_STREQ(c, testEncodingsEncoded[i]); - + ASSERT_TRUE(dicom.GetTagValue(tag, DICOM_TAG_PATIENT_NAME)); // Decodes to UTF-8 EXPECT_EQ(tag, testEncodingsExpected[i]); @@ -1315,7 +1315,7 @@ ASSERT_EQ(Encoding_Latin3, d.DetectEncoding(hasCodeExtensions)); ASSERT_FALSE(hasCodeExtensions); } - + { // Valid encoding, "ISO_IR 13" is Japanese DicomMap m; @@ -1328,7 +1328,7 @@ ASSERT_EQ(Encoding_Japanese, d.DetectEncoding(hasCodeExtensions)); ASSERT_FALSE(hasCodeExtensions); } - + { // Invalid value for an encoding ("nope" is not in the DICOM standard) DicomMap m; @@ -1338,7 +1338,7 @@ ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false), OrthancException); } - + { // Invalid encoding, as provided as a binary string DicomMap m; @@ -1348,7 +1348,7 @@ ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false), OrthancException); } - + { // Encoding provided as an empty string, fallback to default encoding // In Orthanc <= 1.3.1, this test was throwing an exception @@ -1431,21 +1431,21 @@ // +----------------------------------+ static const uint8_t iso2022_cstr_oneByteControl[] = { - 0x0f, 0x41, - 0x0e, 0x42, - 0x8e, 0x1b, 0x4e, 0x43, + 0x0f, 0x41, + 0x0e, 0x42, + 0x8e, 0x1b, 0x4e, 0x43, 0x8f, 0x1b, 0x4f, 0x44, - 0x8e, 0x1b, 0x4a, 0x45, + 0x8e, 0x1b, 0x4a, 0x45, 0x8f, 0x1b, 0x4a, 0x46, 0x50, 0x51, 0x52, 0x00 }; - + static const uint8_t iso2022_cstr_oneByteControl_ref[] = { 0x41, 0x42, 0x43, 0x44, - 0x8e, 0x1b, 0x4a, 0x45, + 0x8e, 0x1b, 0x4a, 0x45, 0x8f, 0x1b, 0x4a, 0x46, 0x50, 0x51, 0x52, 0x00 }; @@ -1463,7 +1463,7 @@ 0x1b, 0x7d, 0x46, 0x1b, 0x7c, 0x47, 0x00 }; - + static const uint8_t iso2022_cstr_twoByteControl_ref[] = { 0x41, 0x42, @@ -1480,17 +1480,17 @@ static const uint8_t iso2022_cstr_escapeSequence[] = { 0x1b, 0x40, 0x41, // 1b and 40 should not be removed (invalid esc seq) - 0x1b, 0x50, 0x42, // ditto + 0x1b, 0x50, 0x42, // ditto 0x1b, 0x7f, 0x43, // ditto 0x1b, 0x21, 0x4a, 0x44, // this will match 0x1b, 0x20, 0x21, 0x2f, 0x40, 0x45, // this will match 0x1b, 0x20, 0x21, 0x2f, 0x2f, 0x40, 0x46, // this will match too 0x1b, 0x20, 0x21, 0x2f, 0x1f, 0x47, 0x48, 0x00 // this will NOT match! }; - + static const uint8_t iso2022_cstr_escapeSequence_ref[] = { 0x1b, 0x40, 0x41, // 1b and 40 should not be removed (invalid esc seq) - 0x1b, 0x50, 0x42, // ditto + 0x1b, 0x50, 0x42, // ditto 0x1b, 0x7f, 0x43, // ditto 0x44, // this will match 0x45, // this will match @@ -1498,7 +1498,7 @@ 0x1b, 0x20, 0x21, 0x2f, 0x1f, 0x47, 0x48, 0x00 // this will NOT match! }; - + // +----------------------------------+ // | a real-world japanese sample | // +----------------------------------+ @@ -1574,7 +1574,7 @@ std::string result; result.resize(tokens.size()); - + for (size_t i = 0; i < tokens.size(); i++) { std::vector components; @@ -1644,11 +1644,11 @@ Encoding encoding = dicom.DetectEncoding(hasCodeExtensions); ASSERT_EQ(Encoding_Korean, encoding); ASSERT_TRUE(hasCodeExtensions); - + std::string value; ASSERT_TRUE(dicom.GetTagValue(value, DICOM_TAG_PATIENT_NAME)); ASSERT_EQ(utf8, value); - + DicomWebJsonVisitor visitor; dicom.Apply(visitor); ASSERT_EQ(utf8.substr(0, 12), visitor.GetResult()["00100010"]["Value"][0]["Alphabetic"].asString()); @@ -1690,7 +1690,7 @@ node = SelectNode(doc, "//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Phonetic/GivenName"); ASSERT_EQ(utf8.substr(28), node.node().text().as_string()); #endif - + { DicomMap m; m.FromDicomWeb(visitor.GetResult()); @@ -1746,7 +1746,7 @@ std::string value; ASSERT_TRUE(dicom.GetTagValue(value, DICOM_TAG_PATIENT_NAME)); ASSERT_EQ(utf8, value); - + DicomWebJsonVisitor visitor; dicom.Apply(visitor); ASSERT_EQ(utf8.substr(0, 12), visitor.GetResult()["00100010"]["Value"][0]["Alphabetic"].asString()); @@ -1787,8 +1787,8 @@ node = SelectNode(doc, "//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Phonetic/GivenName"); ASSERT_EQ(utf8.substr(37), node.node().text().as_string()); -#endif - +#endif + { DicomMap m; m.FromDicomWeb(visitor.GetResult()); @@ -1923,7 +1923,7 @@ 0x5a, 0x68, 0x61, 0x6e, 0x67, 0x5e, 0x58, 0x69, 0x61, 0x6f, 0x44, 0x6f, 0x6e, 0x67, 0x3d, 0xe5, 0xbc, 0xa0, 0x5e, 0xe5, 0xb0, 0x8f, 0xe4, 0xb8, 0x9c, 0x3d }; - + ParsedDicomFile dicom(false); dicom.ReplacePlainString(DICOM_TAG_SPECIFIC_CHARACTER_SET, "\\ISO 2022 IR 58"); ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString @@ -2052,7 +2052,7 @@ dicom.ReplacePlainString(DicomTag(0x4342, 0x1234), "UN"); // Inexistent tag dicom.ReplacePlainString(DicomTag(0x0008, 0x0120), "UR"); dicom.ReplacePlainString(DicomTag(0x0008, 0x0301), "17"); // US - dicom.ReplacePlainString(DicomTag(0x0040, 0x0031), "UT"); + dicom.ReplacePlainString(DicomTag(0x0040, 0x0031), "UT"); #if DCMTK_VERSION_NUMBER >= 365 dicom.ReplacePlainString(DicomTag(0x7056, 0x1000), "17"); // OV @@ -2196,7 +2196,7 @@ std::string xml; visitor.FormatXml(xml); - + { DicomMap m; m.FromDicomWeb(visitor.GetResult()); @@ -2206,7 +2206,7 @@ #else ASSERT_EQ(31u, m.GetSize()); #endif - + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0002, 0x0002), false)); ASSERT_EQ("UI", s); ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0040, 0x0241), false)); ASSERT_EQ("AE", s); ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x1010), false)); ASSERT_EQ("AS", s); @@ -2255,7 +2255,7 @@ ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0119), true)); ASSERT_EQ("UC", s); ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0120), true)); ASSERT_EQ("UR", s); ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0301), true)); ASSERT_EQ("17", s); // US (but tag unknown to DCMTK 3.6.0) -#endif +#endif #if DCMTK_VERSION_NUMBER >= 365 ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x7056, 0x1000), true)); ASSERT_EQ("17", s); // OV @@ -2269,7 +2269,7 @@ TEST(DicomWebJson, Sequence) { ParsedDicomFile dicom(false); - + { std::unique_ptr sequence(new DcmSequenceOfItems(DCM_ReferencedSeriesSequence)); @@ -2291,7 +2291,7 @@ ASSERT_EQ(3u, visitor.GetResult() ["00081115"]["Value"].size()); std::set items; - + for (Json::Value::ArrayIndex i = 0; i < 3; i++) { ASSERT_EQ(1u, visitor.GetResult() ["00081115"]["Value"][i].size()); @@ -2319,7 +2319,7 @@ TEST(DicomWebJson, SequenceWithEmptyItem) { ParsedDicomFile dicom(false); - + { std::unique_ptr sequence(new DcmSequenceOfItems(DCM_OriginalAttributesSequence)); @@ -2375,7 +2375,7 @@ ASSERT_THROW(accessor.GetDicom(), OrthancException); ASSERT_THROW(accessor.GetFileSize(), OrthancException); } - + { ParsedDicomCache::Accessor accessor(cache, "a"); ASSERT_TRUE(accessor.IsValid()); @@ -2384,9 +2384,9 @@ ASSERT_EQ("patient1", s); ASSERT_EQ(20u, accessor.GetFileSize()); } - + tags.SetValue(DICOM_TAG_PATIENT_ID, "patient2", false); - cache.Acquire("b", new ParsedDicomFile(tags, Encoding_Latin1, true), 5); + cache.Acquire("b", new ParsedDicomFile(tags, Encoding_Latin1, true), 5); ASSERT_EQ(5u, cache.GetCurrentSize()); ASSERT_EQ(1u, cache.GetNumberOfItems()); @@ -2402,7 +2402,7 @@ ASSERT_EQ("patient2", s); ASSERT_EQ(5u, accessor.GetFileSize()); } - + cache.Acquire("d", new ParsedDicomFile(true), 5); ASSERT_EQ(10u, cache.GetCurrentSize()); ASSERT_EQ(2u, cache.GetNumberOfItems()); @@ -2497,7 +2497,7 @@ ASSERT_EQ(0u, path.GetPrefixIndex(0)); ASSERT_THROW(path.GetPrefixTag(1), OrthancException); ASSERT_EQ(DICOM_TAG_PATIENT_NAME, path.GetFinalTag()); - + path = DicomPath::Parse("(0008,1111)[1].(0008,1111)[2].(0010,0010)"); ASSERT_FALSE(path.HasUniversal()); ASSERT_EQ(2u, path.GetPrefixLength()); @@ -2509,7 +2509,7 @@ ASSERT_EQ(2u, path.GetPrefixIndex(1)); ASSERT_THROW(path.GetPrefixTag(2), OrthancException); ASSERT_EQ(DICOM_TAG_PATIENT_NAME, path.GetFinalTag()); - + path = DicomPath::Parse("(0008,1111)[*].PatientName"); ASSERT_TRUE(path.HasUniversal()); ASSERT_EQ(1u, path.GetPrefixLength()); @@ -2519,7 +2519,7 @@ ASSERT_THROW(path.GetPrefixTag(1), OrthancException); ASSERT_EQ(DICOM_TAG_PATIENT_NAME, path.GetFinalTag()); ASSERT_EQ("(0008,1111)[*].(0010,0010)", path.Format()); - + path = DicomPath::Parse("(0008,1111)[1].(0008,1111)[*].(0010,0010)"); ASSERT_TRUE(path.HasUniversal()); ASSERT_EQ(2u, path.GetPrefixLength()); @@ -2531,7 +2531,7 @@ ASSERT_THROW(path.GetPrefixIndex(1), OrthancException); ASSERT_THROW(path.GetPrefixTag(2), OrthancException); ASSERT_EQ(DICOM_TAG_PATIENT_NAME, path.GetFinalTag()); - + path = DicomPath::Parse("PatientID[1].PatientName"); ASSERT_FALSE(path.HasUniversal()); ASSERT_EQ(1u, path.GetPrefixLength()); @@ -2605,17 +2605,17 @@ item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.719"; a.append(item); } - + { Json::Value item = Json::objectValue; item["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4"; // ReferencedSOPClassUID item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.726"; a.append(item); } - + v["ReferencedImageSequence"] = a; } - + { Json::Value a = Json::arrayValue; @@ -2635,10 +2635,10 @@ item["PurposeOfReferenceCodeSequence"] = b; } - + a.append(item); } - + v["RelatedSeriesSequence"] = a; } @@ -2670,7 +2670,7 @@ ASSERT_TRUE(vv[REF_IM_SEQ][1].isMember(REF_SOP_CLASS)); ASSERT_TRUE(vv[REL_SERIES_SEQ][0][PURPOSE_CODE_SEQ][0].isMember(CODE_VALUE)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2685,7 +2685,7 @@ ASSERT_FALSE(vv[REF_IM_SEQ][0].isMember(REF_SOP_CLASS)); ASSERT_FALSE(vv[REF_IM_SEQ][1].isMember(REF_SOP_CLASS)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2700,7 +2700,7 @@ ASSERT_FALSE(vv[REF_IM_SEQ][0].isMember(REF_SOP_CLASS)); ASSERT_TRUE(vv[REF_IM_SEQ][1].isMember(REF_SOP_CLASS)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2715,7 +2715,7 @@ ASSERT_TRUE(vv[REF_IM_SEQ][0].isMember(REF_SOP_CLASS)); ASSERT_FALSE(vv[REF_IM_SEQ][1].isMember(REF_SOP_CLASS)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2729,7 +2729,7 @@ ASSERT_EQ("WORLD", vv[REL_SERIES_SEQ][0][PURPOSE_CODE_SEQ][0][SERIES_DESCRIPTION].asString()); ASSERT_FALSE(vv[REL_SERIES_SEQ][0][PURPOSE_CODE_SEQ][0].isMember(CODE_VALUE)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2737,11 +2737,11 @@ Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); - + ASSERT_EQ(1u, vv[REL_SERIES_SEQ][0].size()); ASSERT_FALSE(vv[REL_SERIES_SEQ][0].isMember(PURPOSE_CODE_SEQ)); } - + { std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); @@ -2749,7 +2749,7 @@ Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); - + ASSERT_FALSE(vv.isMember(REL_SERIES_SEQ)); } @@ -2767,7 +2767,7 @@ "Hello4", false, DicomReplaceMode_IgnoreIfAbsent, ""); dicom->ReplacePath(DicomPath::Parse("RelatedSeriesSequence[*].PurposeOfReferenceCodeSequence[*].CodeValue"), "Hello5", false, DicomReplaceMode_ThrowIfAbsent, ""); - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2787,7 +2787,7 @@ "Hello1", false, DicomReplaceMode_ThrowIfAbsent, ""); dicom->ReplacePath(DicomPath::Parse("RelatedSeriesSequence[0].PurposeOfReferenceCodeSequence[0].CodeValue"), "Hello2", false, DicomReplaceMode_ThrowIfAbsent, ""); - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2803,20 +2803,20 @@ dicom->ClearPath(DicomPath::Parse("RelatedSeriesSequence[0].PurposeOfReferenceCodeSequence[0].CodeValue"), true); dicom->ClearPath(DicomPath::Parse("ReferencedImageSequence[0].PatientID"), false); dicom->ClearPath(DicomPath::Parse("ReferencedImageSequence[0].PatientName"), true); - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); ASSERT_EQ(3u, vv[REF_IM_SEQ][0].size()); ASSERT_EQ(2u, vv[REF_IM_SEQ][1].size()); - + ASSERT_EQ("1.2.840.10008.5.1.4.1.1.4", vv[REF_IM_SEQ][0][REF_SOP_CLASS].asString()); ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.719", vv[REF_IM_SEQ][0][REF_SOP_INSTANCE].asString()); ASSERT_EQ("", vv[REF_IM_SEQ][0][PATIENT_ID].asString()); - + ASSERT_EQ("", vv[REF_IM_SEQ][1][REF_SOP_CLASS].asString()); ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.726", vv[REF_IM_SEQ][1][REF_SOP_INSTANCE].asString()); - + ASSERT_EQ("", vv[REL_SERIES_SEQ][0][PURPOSE_CODE_SEQ][0][CODE_VALUE].asString()); } @@ -2830,7 +2830,7 @@ modif.Replace(DicomPath::Parse("RelatedSeriesSequence[0].PurposeOfReferenceCodeSequence[0].CodeValue"), "Hello3", false); modif.Apply(dicom); } - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2852,7 +2852,7 @@ modif.Remove(DicomPath::Parse("RelatedSeriesSequence[0].PurposeOfReferenceCodeSequence")); modif.Apply(dicom); } - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2875,7 +2875,7 @@ modif.Apply(dicom2); } - // Same anonymization context and same input DICOM => hence, same output DICOM + // Same anonymization context and same input DICOM => hence, same output DICOM Json::Value vv1, vv2; dicom1->DatasetToJson(vv1, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); dicom2->DatasetToJson(vv2, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2902,7 +2902,7 @@ modif.Keep(DicomPath::Parse("RelatedSeriesSequence")); modif.Apply(dicom); } - + Json::Value vv; dicom->DatasetToJson(vv, DicomToJsonFormat_Short, DicomToJsonFlags_None, 0); @@ -2919,14 +2919,14 @@ ASSERT_EQ(2u, m.GetSize()); ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.719", m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false)); - + ASSERT_TRUE(dicom->LookupSequenceItem(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 1)); ASSERT_EQ(2u, m.GetSize()); ASSERT_EQ("1.2.840.113619.2.176.2025.1499492.7040.1171286241.726", m.GetStringValue(DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, "", false)); - + ASSERT_FALSE(dicom->LookupSequenceItem(m, DicomPath(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE), 2)); - + ASSERT_TRUE(dicom->LookupSequenceItem(m, DicomPath(DicomTag(0x0008, 0x1250), 0, DicomTag(0x0040, 0xa170)), 0)); ASSERT_EQ(2u, m.GetSize()); ASSERT_EQ("122403", m.GetStringValue(DicomTag(0x0008, 0x0100), "", false)); @@ -2943,7 +2943,7 @@ { private: uint32_t seen_; - + public: V() : seen_(0) { @@ -2953,14 +2953,14 @@ { return seen_; } - + virtual Action VisitNotSupported(const std::vector& parentTags, const std::vector& parentIndexes, const DicomTag& tag, ValueRepresentation vr) ORTHANC_OVERRIDE { seen_ |= (1 << 0); - + if (parentTags.size() == 0u && parentIndexes.size() == 0u && DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_PixelData) @@ -2970,7 +2970,7 @@ else { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } virtual Action VisitSequence(const std::vector& parentTags, @@ -2979,7 +2979,7 @@ size_t countItems) ORTHANC_OVERRIDE { seen_ |= (1 << 1); - + if (parentTags.size() == 0u && parentIndexes.size() == 0u && tag == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE && @@ -3008,7 +3008,7 @@ else { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } virtual Action VisitIntegers(const std::vector& parentTags, @@ -3018,7 +3018,7 @@ const std::vector& values) ORTHANC_OVERRIDE { seen_ |= (1 << 2); - + if (parentTags.size() == 0u && parentIndexes.size() == 0u && DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_TagAngleSecondAxis && @@ -3041,7 +3041,7 @@ const std::vector& values) ORTHANC_OVERRIDE { seen_ |= (1 << 3); - + if (parentTags.size() == 1u && parentIndexes.size() == 1u && parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE && @@ -3066,7 +3066,7 @@ const std::vector& values) ORTHANC_OVERRIDE { seen_ |= (1 << 4); - + if (parentTags.size() == 1u && parentIndexes.size() == 1u && parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE && @@ -3099,7 +3099,7 @@ size_t size) ORTHANC_OVERRIDE { seen_ |= (1 << 5); - + if (parentTags.size() == 1u && parentIndexes.size() == 1u && parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE && @@ -3151,7 +3151,7 @@ ASSERT_TRUE(s->putSint16Array(a, 2).good()); dicom->GetDcmtkObject().getDataset()->insert(s.release()); } - + DcmItem *parent = NULL; ASSERT_TRUE(dicom->GetDcmtkObject().getDataset()->findAndGetSequenceItem(DCM_ReferencedImageSequence, parent, 0).good()); @@ -3161,7 +3161,7 @@ ASSERT_TRUE(s->putFloat32Array(a, 3).good()); parent->insert(s.release()); } - + { const uint16_t a[] = { 0x0008, 0x0020, 0x0008, 0x0030 }; std::unique_ptr s(new DcmAttributeTag(DCM_DimensionIndexPointer)); // VisitAttributes() @@ -3283,21 +3283,21 @@ v["PerFrameFunctionalGroupsSequence"][1]["PixelValueTransformationSequence"][0]["RescaleIntercept"] = "13"; v["PerFrameFunctionalGroupsSequence"][1]["PixelValueTransformationSequence"][0]["RescaleSlope"] = "-14"; std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); - + dicom->GetDefaultWindowing(wc, ww, 0); dicom->GetRescale(ri, rs, 0); ASSERT_DOUBLE_EQ(614.0, wc); ASSERT_DOUBLE_EQ(1067.0, ww); ASSERT_DOUBLE_EQ(12.0, ri); ASSERT_DOUBLE_EQ(2.551648, rs); - + dicom->GetDefaultWindowing(wc, ww, 1); dicom->GetRescale(ri, rs, 1); ASSERT_DOUBLE_EQ(-61.0, wc); ASSERT_DOUBLE_EQ(-63.0, ww); ASSERT_DOUBLE_EQ(13.0, ri); ASSERT_DOUBLE_EQ(-14.0, rs); - + dicom->GetDefaultWindowing(wc, ww, 2); dicom->GetRescale(ri, rs, 2); ASSERT_DOUBLE_EQ(128.0, wc); @@ -3314,7 +3314,7 @@ v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleIntercept"] = "30"; v["PerFrameFunctionalGroupsSequence"][0]["PixelValueTransformationSequence"][0]["RescaleSlope"] = "40"; std::unique_ptr dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "")); - + dicom->GetRescale(ri, rs, 0); ASSERT_DOUBLE_EQ(10.0, ri); ASSERT_DOUBLE_EQ(20.0, rs); @@ -3471,7 +3471,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + for (Syntaxes::const_iterator it = compressedSyntaxes.begin(); it != compressedSyntaxes.end(); ++it) { // All the compressed transfer syntaxes must have "OB" pixel data @@ -3554,7 +3554,7 @@ ASSERT_EQ(ValueRepresentation_OtherByte, dicom.GuessPixelDataValueRepresentation(DicomTransferSyntax_LittleEndianExplicit)); ASSERT_EQ(ValueRepresentation_OtherByte, dicom.GuessPixelDataValueRepresentation(DicomTransferSyntax_BigEndianExplicit)); } - + { ParsedDicomFile dicom(true); ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertUint16(DCM_BitsAllocated, bitsAllocated).good()); @@ -3573,7 +3573,7 @@ } // Explicit little and big endian with > 8 bpp is OW - + ASSERT_EQ(ValueRepresentation_OtherWord, DicomImageInformation::GuessPixelDataValueRepresentation(DicomTransferSyntax_LittleEndianExplicit, 16)); ASSERT_EQ(ValueRepresentation_OtherWord, DicomImageInformation::GuessPixelDataValueRepresentation(DicomTransferSyntax_BigEndianExplicit, 16)); @@ -4118,9 +4118,9 @@ "/Subversion/orthanc-tests/Database/KarstenHilbertRF.dcm"); toto.reset(FromDcmtkBridge::LoadFromMemoryBuffer(source.c_str(), source.size())); } - + const std::string sourceUid = IDicomTranscoder::GetSopInstanceUid(*toto); - + DicomTransferSyntax sourceSyntax; ASSERT_TRUE(FromDcmtkBridge::LookupOrthancTransferSyntax(sourceSyntax, *toto)); @@ -4129,7 +4129,7 @@ for (int i = 0; i <= DicomTransferSyntax_XML; i++) { DicomTransferSyntax a = (DicomTransferSyntax) i; - + std::set s; s.insert(a); @@ -4145,12 +4145,12 @@ { DicomTransferSyntax targetSyntax; ASSERT_TRUE(FromDcmtkBridge::LookupOrthancTransferSyntax(targetSyntax, target.GetParsed())); - + ASSERT_EQ(targetSyntax, a); bool lossy = (a == DicomTransferSyntax_JPEGProcess1 || a == DicomTransferSyntax_JPEGProcess2_4 || a == DicomTransferSyntax_JPEGLSLossy); - + if (sourceUid == IDicomTranscoder::GetSopInstanceUid(target.GetParsed())) { ASSERT_FALSE(lossy); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/GithubCACertificates.h --- a/OrthancFramework/UnitTestsSources/GithubCACertificates.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/GithubCACertificates.h Wed Aug 19 14:11:33 2026 +0200 @@ -34,4 +34,4 @@ "yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K\n" \ "00u/I5sUKUErmgQfky3xxzlIPK1aEn8=\n" \ "-----END CERTIFICATE-----\n" \ -"\n" +"\n" diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp --- a/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -266,7 +266,7 @@ public: typedef T ImageTraits; - + ImageAccessor& GetImage() { return *image_; @@ -300,7 +300,7 @@ TYPED_TEST(TestImageTraits, SetZero) { ImageAccessor& image = this->GetImage(); - + memset(image.GetBuffer(), 128, static_cast(image.GetHeight()) * image.GetWidth()); switch (image.GetFormat()) @@ -337,7 +337,7 @@ TYPED_TEST(TestIntegerImageTraits, SetZeroFloat) { ImageAccessor& image = this->GetImage(); - + memset(image.GetBuffer(), 128, static_cast(image.GetHeight()) * image.GetWidth()); float c = 0.0f; @@ -685,7 +685,7 @@ { Image image(PixelFormat_Grayscale8, 1, 1, false); - SetGrayscale8Pixel(image, 0, 0, 100); + SetGrayscale8Pixel(image, 0, 0, 100); ImageProcessing::SeparableConvolution(image, k1, 2, k2, 0, true /* round */); ASSERT_TRUE(TestGrayscale8Pixel(image, 0, 0, 100)); ImageProcessing::SeparableConvolution(image, k1, 2, k1, 2, true /* round */); @@ -695,10 +695,10 @@ ImageProcessing::SeparableConvolution(image, k2, 0, k2, 0, true /* round */); ASSERT_TRUE(TestGrayscale8Pixel(image, 0, 0, 100)); } - + { Image image(PixelFormat_RGB24, 1, 1, false); - SetRGB24Pixel(image, 0, 0, 10, 20, 30); + SetRGB24Pixel(image, 0, 0, 10, 20, 30); ImageProcessing::SeparableConvolution(image, k1, 2, k2, 0, true /* round */); ASSERT_TRUE(TestRGB24Pixel(image, 0, 0, 10, 20, 30)); ImageProcessing::SeparableConvolution(image, k1, 2, k1, 2, true /* round */); @@ -709,7 +709,7 @@ ASSERT_TRUE(TestRGB24Pixel(image, 0, 0, 10, 20, 30)); } - { + { Image dirac(PixelFormat_Grayscale8, 9, 1, false); ImageProcessing::Set(dirac, 0); SetGrayscale8Pixel(dirac, 4, 0, 100); @@ -725,7 +725,7 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 5, 0, 20)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 6, 0, 20)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 7, 0, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); } { @@ -739,7 +739,7 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 5, 0, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 6, 0, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 7, 0, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); } { @@ -753,11 +753,11 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 5, 0, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 6, 0, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 7, 0, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 8, 0, 0)); } } - { + { Image dirac(PixelFormat_Grayscale8, 1, 9, false); ImageProcessing::Set(dirac, 0); SetGrayscale8Pixel(dirac, 0, 4, 100); @@ -773,7 +773,7 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 5, 20)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 6, 20)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 7, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); } { @@ -787,7 +787,7 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 5, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 6, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 7, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); } { @@ -801,7 +801,7 @@ ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 5, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 6, 0)); ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 7, 0)); - ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); + ASSERT_TRUE(TestGrayscale8Pixel(*image, 0, 8, 0)); } } @@ -821,7 +821,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 5, 0, 20, 24, 28)); ASSERT_TRUE(TestRGB24Pixel(*image, 6, 0, 20, 24, 28)); ASSERT_TRUE(TestRGB24Pixel(*image, 7, 0, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); } { @@ -835,7 +835,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 5, 0, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 6, 0, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 7, 0, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); } { @@ -849,7 +849,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 5, 0, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 6, 0, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 7, 0, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 8, 0, 0, 0, 0)); } } @@ -869,7 +869,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 0, 5, 20, 24, 28)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 6, 20, 24, 28)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 7, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); } { @@ -883,7 +883,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 0, 5, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 6, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 7, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); } { @@ -897,7 +897,7 @@ ASSERT_TRUE(TestRGB24Pixel(*image, 0, 5, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 6, 0, 0, 0)); ASSERT_TRUE(TestRGB24Pixel(*image, 0, 7, 0, 0, 0)); - ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); + ASSERT_TRUE(TestRGB24Pixel(*image, 0, 8, 0, 0, 0)); } } } @@ -1225,7 +1225,7 @@ TEST(ImageProcessing, ShiftFloatBuggy) { // This test failed in Orthanc 1.10.1 - + Image image(PixelFormat_Float32, 3, 1, false); ImageTraits::SetFloatPixel(image, -1.0f, 0, 0); ImageTraits::SetFloatPixel(image, 0.0f, 1, 0); @@ -1251,7 +1251,7 @@ va.push_back(0); va.push_back(-10); va.push_back(5); - + std::vector vb; vb.push_back(0); vb.push_back(-42); @@ -1259,7 +1259,7 @@ Image source(PixelFormat_Float32, 1, 1, false); ImageTraits::SetFloatPixel(source, 10, 0, 0); - + for (std::vector::const_iterator a = va.begin(); a != va.end(); ++a) { for (std::vector::const_iterator b = vb.begin(); b != vb.end(); ++b) @@ -1287,7 +1287,7 @@ private: std::vector y_, x1_, x2_; - public: + public: virtual void Fill(int y, int x1, int x2) ORTHANC_OVERRIDE @@ -1345,7 +1345,7 @@ if (allZeros) { return false; - } + } x1 = 0; while (p[x1] == 0) diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/ImageTests.cpp --- a/OrthancFramework/UnitTestsSources/ImageTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/ImageTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -167,7 +167,7 @@ accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale8, width, height, pitch, &image[0]); std::string f; - + #if ORTHANC_SANDBOXED == 1 Orthanc::IImageWriter::WriteToMemory(w, f, accessor); #else @@ -203,7 +203,7 @@ accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale16, width, height, pitch, &image[0]); std::string f; - + #if ORTHANC_SANDBOXED == 1 Orthanc::IImageWriter::WriteToMemory(w, f, accessor); #else @@ -421,7 +421,7 @@ Orthanc::IImageWriter::WriteToFile(w, "UnitTestsResults/Gray8Pattern.pam", accessor); Orthanc::SystemToolbox::ReadFile(f, Orthanc::SystemToolbox::PathFromUtf8("UnitTestsResults/Gray8Pattern.pam")); #endif - + std::string md5; Orthanc::Toolbox::ComputeMD5(md5, f); ASSERT_EQ("7873c408d26a9d11dd1c1de5e69cc0a3", md5); @@ -613,7 +613,7 @@ std::string s; Orthanc::IImageWriter::WriteToMemory(w, s, image8); Orthanc::IImageWriter::WriteToMemory(w, s, image16); // No problem here - } + } { // The following call leads to "Invalid read of size 1" in Orthanc <= 1.9.2 @@ -621,7 +621,7 @@ std::string s; Orthanc::IImageWriter::WriteToMemory(w, s, image16); Orthanc::IImageWriter::WriteToMemory(w, s, image8); // Problem here - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/JobsTests.cpp --- a/OrthancFramework/UnitTestsSources/JobsTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/JobsTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -83,7 +83,7 @@ virtual void Reset() ORTHANC_OVERRIDE { } - + virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE { if (fails_) @@ -139,7 +139,7 @@ { return false; } - + virtual void SetUserData(const Json::Value& userData) ORTHANC_OVERRIDE { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); @@ -160,7 +160,7 @@ { private: bool trailingStepDone_; - + protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE { @@ -192,7 +192,7 @@ trailingStepDone_(false) { } - + explicit DummyInstancesJob(const Json::Value& value) : SetOfInstancesJob(value) { @@ -210,7 +210,7 @@ { return trailingStepDone_; } - + virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE { } @@ -242,7 +242,7 @@ } }; - + class DynamicInteger : public IDynamicObject { private: @@ -250,7 +250,7 @@ std::set& target_; public: - DynamicInteger(int value, std::set& target) : + DynamicInteger(int value, std::set& target) : value_(value), target_(target) { target_.insert(value); @@ -305,7 +305,7 @@ { SharedMessageQueue q; q.Enqueue(new DynamicInteger(10, s)); - q.Enqueue(new DynamicInteger(20, s)); + q.Enqueue(new DynamicInteger(20, s)); ASSERT_EQ(2, s.size()); THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -326,10 +326,10 @@ std::unique_ptr i; BlockingSharedMessageQueue q; - + ASSERT_TRUE(q.Enqueue(o10, 0)); ASSERT_TRUE(q.Enqueue(o20, 1)); - q.Enqueue(new DynamicInteger(30, s)); + q.Enqueue(new DynamicInteger(30, s)); i.reset(dynamic_cast(q.Dequeue(1))); ASSERT_EQ(10, i->GetValue()); i.reset(dynamic_cast(q.Dequeue(0))); ASSERT_EQ(20, i->GetValue()); @@ -352,7 +352,7 @@ std::unique_ptr i; BlockingSharedMessageQueue q(2); - + q.Enqueue(o10.release()); ASSERT_TRUE(q.Enqueue(o20, 1)); ASSERT_FALSE(q.Enqueue(o30, 1)); @@ -371,7 +371,7 @@ TEST(MultiThreading, BlockingSharedMessageQueueBasicClear) { std::set s; // keeps a copy of all DynamicInteger objects - + std::unique_ptr o10(new DynamicInteger(10, s)); std::unique_ptr o20(new DynamicInteger(20, s)); std::unique_ptr o30(new DynamicInteger(30, s)); @@ -379,7 +379,7 @@ std::unique_ptr i; BlockingSharedMessageQueue q(2); - + ASSERT_TRUE(q.Enqueue(o10, 0)); ASSERT_TRUE(q.Enqueue(o20, 1)); ASSERT_EQ(2, q.GetSize()); @@ -459,7 +459,7 @@ registry.Submit(i1, new DummyJob(), 10); registry.Submit(i2, new DummyJob(), 30); registry.Submit(i3, new DummyJob(), 20); - registry.Submit(i4, new DummyJob(), 5); + registry.Submit(i4, new DummyJob(), 5); registry.SetMaxCompletedJobs(2); @@ -625,7 +625,7 @@ registry.Resubmit(id); ASSERT_TRUE(CheckState(registry, id, JobState_Retry)); - + registry.ScheduleRetries(); ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); @@ -750,19 +750,19 @@ ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_Success)); - + ASSERT_TRUE(registry.Cancel(id)); ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); - + ASSERT_TRUE(registry.Cancel(id)); ASSERT_TRUE(CheckState(registry, id, JobState_Failure)); ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); - + ASSERT_TRUE(registry.Resubmit(id)); ASSERT_TRUE(CheckState(registry, id, JobState_Pending)); ASSERT_TRUE(CheckErrorCode(registry, id, ErrorCode_CanceledJob)); - + { JobsRegistry::RunningJob job(registry, 0); ASSERT_TRUE(job.IsValid()); @@ -882,7 +882,7 @@ StringOperationValue b("World"); lock.AddInput(i, a); lock.AddInput(i, b); - + lock.Connect(i, j); lock.Connect(j, k); } @@ -917,7 +917,7 @@ const IJob& job) { Json::Value a = 42; - + if (!job.Serialize(a)) { return false; @@ -925,7 +925,7 @@ else { std::unique_ptr unserialized(unserializer.UnserializeJob(a)); - + Json::Value b = 43; if (unserialized->Serialize(b)) { @@ -943,7 +943,7 @@ const SetOfInstancesJob& job) { Json::Value a = 42; - + if (!job.Serialize(a)) { return false; @@ -952,10 +952,10 @@ { std::unique_ptr unserialized (dynamic_cast(unserializer.UnserializeJob(a))); - + Json::Value b = 43; if (unserialized->Serialize(b)) - { + { return (CheckSameJson(a, b) && job.HasTrailingStep() == unserialized->HasTrailingStep() && job.GetPosition() == unserialized->GetPosition() && @@ -975,9 +975,9 @@ { Json::Value a = 42; value.Serialize(a); - + std::unique_ptr unserialized(unserializer.UnserializeValue(a)); - + Json::Value b = 43; unserialized->Serialize(b); @@ -1058,7 +1058,7 @@ std::unique_ptr value; value.reset(unserializer.UnserializeValue(s)); - + ASSERT_EQ(IJobOperationValue::Type_Null, value->GetType()); { @@ -1078,11 +1078,11 @@ TEST(JobsSerialization, GenericJobs) -{ +{ Json::Value s; // This tests SetOfInstancesJob - + { DummyInstancesJob job; job.SetDescription("description"); @@ -1101,7 +1101,7 @@ DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); } - + ASSERT_TRUE(job.Serialize(s)); } @@ -1151,7 +1151,7 @@ GenericJobUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSerialization(unserializer, job)); } - + ASSERT_TRUE(job.Serialize(s)); } @@ -1166,7 +1166,7 @@ std::string tmp; dynamic_cast(*job).GetDescription(tmp); ASSERT_EQ("hello", tmp); - } + } } @@ -1179,11 +1179,11 @@ dicom2.GetTagValue(b, tag) && (a == b)); } - + TEST(JobsSerialization, DicomModification) -{ +{ Json::Value s; ParsedDicomFile source(true); @@ -1209,7 +1209,7 @@ { DicomModification modification(s); ASSERT_EQ(ResourceType_Series, modification.GetLevel()); - + std::unique_ptr second(source.Clone(true)); modification.Apply(second); @@ -1230,7 +1230,7 @@ TEST(JobsSerialization, DicomModification2) -{ +{ Json::Value s; { @@ -1256,7 +1256,7 @@ TEST(JobsSerialization, Registry) -{ +{ Json::Value s; { @@ -1282,7 +1282,7 @@ { { Json::Value s; - + DummyInstancesJob job; ASSERT_EQ(0u, job.GetCommandsCount()); ASSERT_EQ(0u, job.GetInstancesCount()); @@ -1296,11 +1296,11 @@ DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); } - + ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); ASSERT_EQ(1u, job.GetPosition()); ASSERT_FALSE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1311,7 +1311,7 @@ { Json::Value s; - + DummyInstancesJob job; job.AddInstance("hello"); job.AddInstance("world"); @@ -1327,11 +1327,11 @@ DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); } - + ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); ASSERT_EQ(1u, job.GetPosition()); ASSERT_FALSE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1340,7 +1340,7 @@ ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); ASSERT_EQ(2u, job.GetPosition()); ASSERT_FALSE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1351,7 +1351,7 @@ { Json::Value s; - + DummyInstancesJob job; ASSERT_EQ(0u, job.GetInstancesCount()); ASSERT_EQ(0u, job.GetCommandsCount()); @@ -1368,11 +1368,11 @@ DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); } - + ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); ASSERT_EQ(1u, job.GetPosition()); ASSERT_TRUE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1383,7 +1383,7 @@ { Json::Value s; - + DummyInstancesJob job; job.AddInstance("hello"); ASSERT_EQ(1u, job.GetInstancesCount()); @@ -1391,7 +1391,7 @@ job.AddTrailingStep(); ASSERT_EQ(1u, job.GetInstancesCount()); ASSERT_EQ(2u, job.GetCommandsCount()); - + job.Start(); ASSERT_EQ(2u, job.GetCommandsCount()); ASSERT_EQ(0u, job.GetPosition()); @@ -1402,11 +1402,11 @@ DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); } - + ASSERT_EQ(JobStepCode_Continue, job.Step("jobId").GetCode()); ASSERT_EQ(1u, job.GetPosition()); ASSERT_FALSE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1415,7 +1415,7 @@ ASSERT_EQ(JobStepCode_Success, job.Step("jobId").GetCode()); ASSERT_EQ(2u, job.GetPosition()); ASSERT_TRUE(job.IsTrailingStepDone()); - + { DummyUnserializer unserializer; ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); @@ -1503,7 +1503,7 @@ } s["Port"] = "46"; - + { RemoteModalityParameters modality(s); ASSERT_EQ(46u, modality.GetPortNumber()); @@ -1525,7 +1525,7 @@ ASSERT_EQ(8u, operations.size()); - for (std::set::const_iterator + for (std::set::const_iterator it = operations.begin(); it != operations.end(); ++it) { { @@ -1542,7 +1542,7 @@ ASSERT_FALSE(modality.IsRequestAllowed(*it)); - for (std::set::const_iterator + for (std::set::const_iterator it2 = operations.begin(); it2 != operations.end(); ++it2) { if (*it2 != *it) @@ -1581,7 +1581,7 @@ t["AET"] = "AET"; t["Host"] = "host"; t["Port"] = "104"; - + RemoteModalityParameters modality(t); ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); @@ -1608,7 +1608,7 @@ t["UseDicomTls"] = true; t["LocalAet"] = "world"; t["Timeout"] = 20; - + RemoteModalityParameters modality(t); ASSERT_TRUE(modality.IsAdvancedFormatNeeded()); ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); @@ -1631,7 +1631,7 @@ t["AET"] = "AET"; t["Host"] = "host"; t["Port"] = "104"; - + RemoteModalityParameters modality(t); ASSERT_FALSE(modality.IsAdvancedFormatNeeded()); ASSERT_EQ("AET", modality.GetApplicationEntityTitle()); @@ -1662,7 +1662,7 @@ ASSERT_TRUE(v.isMember("MaximumPduLength")); ASSERT_EQ(5u, v.getMemberNames().size()); - + DicomAssociationParameters b; b.UnserializeJob(v); ASSERT_EQ("ANY-SCP", b.GetRemoteModality().GetApplicationEntityTitle()); @@ -1685,7 +1685,7 @@ p.SetHost("hello.world.com"); p.SetDicomTlsEnabled(true); p.SetTimeout(42); - + DicomAssociationParameters a("HELLO", p); a.SetOwnCertificatePath("key", "crt"); a.SetTrustedCertificatesPath("trusted"); @@ -1700,7 +1700,7 @@ a.SerializeJob(v); ASSERT_EQ(8u, v.getMemberNames().size()); - + DicomAssociationParameters b = DicomAssociationParameters::UnserializeJob(v); ASSERT_EQ("WORLD", b.GetRemoteModality().GetApplicationEntityTitle()); @@ -1715,7 +1715,7 @@ ASSERT_TRUE(b.GetRemoteModality().HasTimeout()); ASSERT_EQ(42u, b.GetRemoteModality().GetTimeout()); ASSERT_FALSE(b.IsRemoteCertificateRequired()); - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/LoggingTests.cpp --- a/OrthancFramework/UnitTestsSources/LoggingTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/LoggingTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -100,7 +100,7 @@ LoggingMementoScope() { } - + ~LoggingMementoScope() { Orthanc::Logging::Reset(); @@ -220,7 +220,7 @@ TEST(Logging, Categories) { using namespace Orthanc::Logging; - + // Unit tests are running in "--verbose" mode (not "--trace") ASSERT_FALSE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); @@ -260,7 +260,7 @@ ASSERT_FALSE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_FALSE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); // At least one category is verbose - + SetCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC, true); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -268,7 +268,7 @@ ASSERT_FALSE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_FALSE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); - + SetCategoryEnabled(LogLevel_INFO, LogCategory_DICOM, false); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -276,7 +276,7 @@ ASSERT_FALSE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_FALSE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); // "GENERIC" is still verbose - + SetCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC, false); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -294,7 +294,7 @@ ASSERT_TRUE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_TRUE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); - + SetCategoryEnabled(LogLevel_TRACE, LogCategory_GENERIC, true); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -302,7 +302,7 @@ ASSERT_TRUE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_TRUE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); - + SetCategoryEnabled(LogLevel_INFO, LogCategory_DICOM, false); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -310,7 +310,7 @@ ASSERT_FALSE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_TRUE(IsTraceLevelEnabled()); // "GENERIC" is still at trace level ASSERT_TRUE(IsInfoLevelEnabled()); - + SetCategoryEnabled(LogLevel_TRACE, LogCategory_GENERIC, false); ASSERT_TRUE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -318,7 +318,7 @@ ASSERT_FALSE(IsCategoryEnabled(LogLevel_TRACE, LogCategory_DICOM)); ASSERT_FALSE(IsTraceLevelEnabled()); ASSERT_TRUE(IsInfoLevelEnabled()); - + SetCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC, false); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_GENERIC)); ASSERT_FALSE(IsCategoryEnabled(LogLevel_INFO, LogCategory_DICOM)); @@ -379,7 +379,7 @@ TEST(Logging, Enumerations) { using namespace Orthanc; - + Logging::LogCategory c; ASSERT_TRUE(Logging::LookupCategory(c, "generic")); ASSERT_EQ(Logging::LogCategory_GENERIC, c); ASSERT_TRUE(Logging::LookupCategory(c, "plugins")); ASSERT_EQ(Logging::LogCategory_PLUGINS, c); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/MemoryCacheTests.cpp --- a/OrthancFramework/UnitTestsSources/MemoryCacheTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/MemoryCacheTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -49,7 +49,7 @@ TEST(LRU, Basic) { Orthanc::LeastRecentlyUsedIndex r; - + r.Add("d"); r.Add("a"); r.Add("c"); @@ -81,7 +81,7 @@ TEST(LRU, Payload) { Orthanc::LeastRecentlyUsedIndex r; - + r.Add("a", 420); r.Add("b", 421); r.Add("c", 422); @@ -122,7 +122,7 @@ TEST(LRU, PayloadUpdate) { Orthanc::LeastRecentlyUsedIndex r; - + r.Add("a", 420); r.Add("b", 421); r.Add("d", 423); @@ -150,7 +150,7 @@ TEST(LRU, PayloadUpdateBis) { Orthanc::LeastRecentlyUsedIndex r; - + r.AddOrMakeMostRecent("a", 420); r.AddOrMakeMostRecent("b", 421); r.AddOrMakeMostRecent("d", 423); @@ -238,7 +238,7 @@ cache.Access("45"); // 45, 43, 42 -> exit cache.Access("42"); // 42, 45, 43 -> exit cache.Access("43"); // 43, 42, 45 -> exit - cache.Access("47"); // 45 is removed; 47, 43, 42 -> exit + cache.Access("47"); // 45 is removed; 47, 43, 42 -> exit cache.Access("44"); // 42 is removed; 44, 47, 43 -> exit cache.Access("42"); // 43 is removed; 42, 44, 47 -> exit // Closing the cache: 47, 44, 42 are successively removed @@ -281,7 +281,7 @@ for (int i = 1; i < 100; i++) { a.Add(new S("Item " + boost::lexical_cast(i))); - + // Continuously protect the two first items { Orthanc::SharedArchive::Accessor accessor(a, first); @@ -324,7 +324,7 @@ { Orthanc::MemoryStringCache c; ASSERT_NO_THROW(c.SetMaximumSize(0)); // changed in 1.12.10, setting the MaximumSize to zero is a way to disable a cache - + c.SetMaximumSize(3); std::string v; @@ -386,14 +386,14 @@ a.Add("hello2", "b"); std::string v; - ASSERT_TRUE(a.Fetch(v, "hello")); + ASSERT_TRUE(a.Fetch(v, "hello")); ASSERT_EQ("a", v); - ASSERT_TRUE(a.Fetch(v, "hello2")); + ASSERT_TRUE(a.Fetch(v, "hello2")); ASSERT_EQ("b", v); c.Invalidate("hello"); ASSERT_FALSE(a.Fetch(v, "hello")); - ASSERT_TRUE(a.Fetch(v, "hello2")); + ASSERT_TRUE(a.Fetch(v, "hello2")); ASSERT_EQ("b", v); } @@ -414,7 +414,7 @@ { LOG(INFO) << "Thread1 has fetch"; ThreadingScenarioHappyStep = 1; - + // wait for the other thread to fetch too while (ThreadingScenarioHappyStep < 2) { @@ -487,7 +487,7 @@ { LOG(INFO) << "Thread1 has fetch"; ThreadingScenarioFailureStep = 1; - + // wait for the other thread to fetch too while (ThreadingScenarioFailureStep < 2) { @@ -550,7 +550,7 @@ { LOG(INFO) << "Thread1 has fetch"; ThreadingScenarioInvalidateStep = 1; - + // wait for the other thread to fetch too while (ThreadingScenarioInvalidateStep < 2) { diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/RestApiTests.cpp --- a/OrthancFramework/UnitTestsSources/RestApiTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/RestApiTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -83,7 +83,7 @@ // disabled in curl const std::string URL = "http://httpbin.org/get"; - + Json::Value v; c.SetUrl(URL); @@ -100,7 +100,7 @@ /** The HTTPS CA certificates for Github were extracted as follows: - + (1) We retrieve the URI of the root CA of Github: # echo | openssl s_client -servername raw.githubusercontent.com -connect raw.githubusercontent.com:443 2>/dev/null | openssl x509 -text | grep "CA Issuers" @@ -168,7 +168,7 @@ { ASSERT_EQ(16u * 1024u, b.GetPendingBufferSize()); } - + ASSERT_EQ(0u, b.GetNumBytes()); b.AddChunk("hello", 5); @@ -297,7 +297,7 @@ static bool GetDirectory(Json::Value& target, - RestApiHierarchy& hierarchy, + RestApiHierarchy& hierarchy, const std::string& uri) { UriComponents p; @@ -324,7 +324,7 @@ } -static bool HandleGet(RestApiHierarchy& hierarchy, +static bool HandleGet(RestApiHierarchy& hierarchy, const std::string& uri) { UriComponents p; @@ -351,7 +351,7 @@ Json::Value d; ASSERT_FALSE(GetDirectory(d, root, "/hello")); - ASSERT_TRUE(GetDirectory(d, root, "/hello/a")); + ASSERT_TRUE(GetDirectory(d, root, "/hello/a")); ASSERT_EQ(1u, d.size()); ASSERT_EQ("test3", d[0].asString()); @@ -454,9 +454,9 @@ ASSERT_EQ("0.2", h.GetParameters() ["q"]); ASSERT_EQ("test", h.GetParameters() ["type"]); ASSERT_EQ("", h.GetParameters() ["hello"]); - + ASSERT_FALSE(d.Apply("application/*; q=0.2, application/pdf")); - + ASSERT_TRUE(d.Apply("*/*; hello=world, application/*; q=0.2, application/pdf")); ASSERT_EQ("audio", h.GetType()); ASSERT_EQ(1u, h.GetParameters().size()); @@ -468,7 +468,7 @@ // text/x-dvi entity, and if that does not exist, send the // text/plain entity."" const std::string T1 = "text/plain; q=0.5, text/html ; hello = \"world\" , text/x-dvi; q=0.8, text/x-c"; - + { HttpContentNegociation d; d.Register("text/plain", h); @@ -480,7 +480,7 @@ ASSERT_EQ(1u, h.GetParameters().size()); ASSERT_EQ("world", h.GetParameters() ["hello"]); } - + { HttpContentNegociation d; d.Register("text/plain", h); @@ -491,7 +491,7 @@ ASSERT_EQ("x-c", h.GetSubType()); ASSERT_EQ(0u, h.GetParameters().size()); } - + { HttpContentNegociation d; d.Register("text/plain", h); @@ -511,7 +511,7 @@ ASSERT_EQ("world", h.GetParameters() ["hello"]); } } - + { HttpContentNegociation d; d.Register("text/plain", h); @@ -522,7 +522,7 @@ ASSERT_EQ(1u, h.GetParameters().size()); ASSERT_EQ("0.8", h.GetParameters() ["q"]); } - + { HttpContentNegociation d; d.Register("text/plain", h); @@ -825,7 +825,7 @@ { ASSERT_FALSE(matcher.Apply(NULL, 0)); - + const std::string s = ""; ASSERT_FALSE(matcher.Apply(s)); } @@ -833,7 +833,7 @@ { const char* s = "abc---def"; ASSERT_TRUE(matcher.Apply(s, s + 9)); - + ASSERT_EQ('a', matcher.GetMatchBegin()[-3]); ASSERT_EQ('b', matcher.GetMatchBegin()[-2]); ASSERT_EQ('c', matcher.GetMatchBegin()[-1]); @@ -960,7 +960,7 @@ { MultipartStreamReader::HttpHeaders h; h["content-type"] = "world"; - ASSERT_TRUE(MultipartStreamReader::GetMainContentType(header, h)); + ASSERT_TRUE(MultipartStreamReader::GetMainContentType(header, h)); ASSERT_EQ(header, "world"); ASSERT_FALSE(MultipartStreamReader::ParseMultipartContentType(ct, st, b, header)); } @@ -968,7 +968,7 @@ { MultipartStreamReader::HttpHeaders h; h["content-type"] = "multipart/related; dummy=value; boundary=1234; hello=world"; - ASSERT_TRUE(MultipartStreamReader::GetMainContentType(header, h)); + ASSERT_TRUE(MultipartStreamReader::GetMainContentType(header, h)); ASSERT_EQ(header, h["content-type"]); ASSERT_TRUE(MultipartStreamReader::ParseMultipartContentType(ct, st, b, header)); ASSERT_EQ(ct, "multipart/related"); @@ -1003,7 +1003,7 @@ { std::string main; std::map args; - + ASSERT_FALSE(MultipartStreamReader::ParseHeaderArguments(main, args, "")); ASSERT_FALSE(MultipartStreamReader::ParseHeaderArguments(main, args, " ")); ASSERT_FALSE(MultipartStreamReader::ParseHeaderArguments(main, args, " ; ")); @@ -1066,14 +1066,14 @@ for (size_t i = 0; i < 10; i++) { std::string f = "hello " + boost::lexical_cast(i); - + stream += "\r\n--" + boundary + "\r\n"; if (i % 2 == 0) stream += "Content-Length: " + boost::lexical_cast(f.size()) + "\r\n"; stream += "Content-Type: toto " + boost::lexical_cast(i) + "\r\n\r\n"; stream += f; } - + stream += "\r\n--" + boundary + "--"; stream += "GARBAGE"; } @@ -1150,7 +1150,7 @@ TEST(WebServiceParameters, Url) { WebServiceParameters w; - + ASSERT_THROW(w.SetUrl("ssh://coucou"), OrthancException); w.SetUrl("http://coucou"); w.SetUrl("https://coucou"); @@ -1166,7 +1166,7 @@ TEST(ChunkedBuffer, DISABLED_Large) { const size_t LARGE = static_cast(60) * 1024 * 1024; - + ChunkedBuffer b; for (size_t i = 0; i < LARGE; i++) { @@ -1177,7 +1177,7 @@ b.Flatten(s); ASSERT_EQ(LARGE, s.size()); ASSERT_EQ(0u, b.GetNumBytes()); - + for (size_t i = 0; i < LARGE; i++) { ASSERT_EQ(static_cast('0' + (i % 10)), s[i]); @@ -1191,7 +1191,7 @@ TEST(ChunkedBuffer, Pending) { ChunkedBuffer b; - + for (size_t pendingSize = 0; pendingSize < 16; pendingSize++) { b.SetPendingBufferSize(pendingSize); @@ -1199,7 +1199,7 @@ unsigned int pos = 0; unsigned int iteration = 0; - + while (pos < 1024) { size_t chunkSize = (iteration % 17); @@ -1213,7 +1213,7 @@ } b.AddChunk(chunk); - + iteration ++; } @@ -1221,11 +1221,11 @@ b.Flatten(s); ASSERT_EQ(0u, b.GetNumBytes()); ASSERT_EQ(pos, s.size()); - + for (size_t i = 0; i < s.size(); i++) { ASSERT_EQ(static_cast('0' + (i % 10)), s[i]); - } + } } } @@ -1242,7 +1242,7 @@ size_t size_; size_t chunkSize_; size_t pos_; - + public: TotoBody(size_t size, size_t chunkSize) : @@ -1251,7 +1251,7 @@ pos_(0) { } - + virtual bool ReadNextChunk(std::string& chunk) ORTHANC_OVERRIDE { if (pos_ == size_) @@ -1275,7 +1275,7 @@ { chunk.erase(i, chunk.size()); } - + return true; } }; @@ -1310,7 +1310,7 @@ printf("received %d\n", static_cast(bodySize)); const uint8_t* b = reinterpret_cast(bodyData); - + for (size_t i = 0; i < bodySize; i++) { if (b[i] != ('0' + i % 7)) @@ -1318,7 +1318,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + output.Answer("ok"); return true; } @@ -1337,19 +1337,19 @@ server.SetPortNumber(5000); server.Register(handler); server.Start(); - + WebServiceParameters w; w.SetUrl("http://localhost:5000"); // This is slow in Orthanc <= 1.5.8 (issue 156) TotoBody body(static_cast(600) * 1024 * 1024, static_cast(6) * 1024 * 1024 - 17); - + HttpClient c(w, "toto"); c.SetMethod(HttpMethod_Post); c.AddHeader("Expect", ""); c.AddHeader("Transfer-Encoding", "chunked"); c.SetBody(body); - + std::string s; ASSERT_TRUE(c.Apply(s)); ASSERT_EQ("ok", s); @@ -1365,19 +1365,19 @@ server.SetPortNumber(5000); server.Register(handler); server.Start(); - + WebServiceParameters w; w.SetUrl("http://localhost:5000"); - // This crashes Orthanc 1.6.0 to 1.7.2 - TotoBody body(static_cast(32) * 1024, static_cast(1)); - + // This crashes Orthanc 1.6.0 to 1.7.2 + TotoBody body(static_cast(32) * 1024, static_cast(1)); + HttpClient c(w, "toto"); c.SetMethod(HttpMethod_Post); c.AddHeader("Expect", ""); c.AddHeader("Transfer-Encoding", "chunked"); c.SetBody(body); - + std::string s; ASSERT_TRUE(c.Apply(s)); ASSERT_EQ("ok", s); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/SQLiteChromiumTests.cpp --- a/OrthancFramework/UnitTestsSources/SQLiteChromiumTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/SQLiteChromiumTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ namespace { - class SQLConnectionTest : public testing::Test + class SQLConnectionTest : public testing::Test { public: SQLConnectionTest() @@ -69,9 +69,9 @@ db_.Close(); } - Connection& db() - { - return db_; + Connection& db() + { + return db_; } private: @@ -81,7 +81,7 @@ -TEST_F(SQLConnectionTest, Execute) +TEST_F(SQLConnectionTest, Execute) { // Valid statement should return true. ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); @@ -276,7 +276,7 @@ } // Returns the number of rows in table "foo". - int CountFoo() + int CountFoo() { Statement count(db(), "SELECT count(*) FROM foo"); count.Step(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/SQLiteTests.cpp --- a/OrthancFramework/UnitTestsSources/SQLiteTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/SQLiteTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -113,7 +113,7 @@ { SQLite::Connection c; c.OpenInMemory(); - + SQLite::Statement s(c, "SELECT * from sqlite_master"); s.Run(); @@ -250,7 +250,7 @@ c.Execute("CREATE TABLE a(id INTEGER PRIMARY KEY);"); c.Execute("INSERT INTO a VALUES(NULL)"); - + { SQLite::Transaction t(c); t.Begin(); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/SharedLibraryUnitTests.cpp --- a/OrthancFramework/UnitTestsSources/SharedLibraryUnitTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/SharedLibraryUnitTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -40,16 +40,16 @@ int main(int argc, char **argv) { Orthanc::InitializeFramework("", true); - + Orthanc::Logging::SetCurrentThreadName("MAIN"); Orthanc::Logging::EnableInfoLevel(true); Orthanc::Toolbox::DetectEndianness(); Orthanc::SystemToolbox::MakeDirectory(Orthanc::SystemToolbox::PathFromUtf8("UnitTestsResults")); - + ::testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); Orthanc::FinalizeFramework(); - + return result; } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/StreamTests.cpp --- a/OrthancFramework/UnitTestsSources/StreamTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/StreamTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -48,7 +48,7 @@ TEST(Gzip, Basic) { std::string s = "Hello world"; - + std::string compressed; GzipCompressor c; ASSERT_FALSE(c.HasPrefixWithUncompressedSize()); @@ -64,7 +64,7 @@ TEST(Gzip, Empty) { std::string s; - + std::string compressed; GzipCompressor c; ASSERT_FALSE(c.HasPrefixWithUncompressedSize()); @@ -80,7 +80,7 @@ TEST(Gzip, BasicWithPrefix) { std::string s = "Hello world"; - + std::string compressed; GzipCompressor c; c.SetPrefixWithUncompressedSize(true); @@ -97,7 +97,7 @@ TEST(Gzip, EmptyWithPrefix) { std::string s; - + std::string compressed; GzipCompressor c; c.SetPrefixWithUncompressedSize(true); @@ -114,7 +114,7 @@ { std::string s = Toolbox::GenerateUuid(); s = s + s + s + s; - + std::string compressed; ZlibCompressor c; ASSERT_TRUE(c.HasPrefixWithUncompressedSize()); @@ -131,7 +131,7 @@ { std::string s = Toolbox::GenerateUuid(); s = s + s + s + s; - + std::string compressed, compressed2; ZlibCompressor c; c.SetCompressionLevel(9); @@ -148,7 +148,7 @@ { std::string s = Toolbox::GenerateUuid(); s = s + s + s + s; - + std::string compressed; ZlibCompressor c; IBufferCompressor::Compress(compressed, c, s); @@ -164,7 +164,7 @@ TEST(Zlib, Empty) { std::string s = ""; - + std::string compressed, compressed2; ZlibCompressor c; IBufferCompressor::Compress(compressed, c, s); @@ -284,10 +284,10 @@ sender.SetBuffer(t); HttpStreamTranscoder transcode(sender, CompressionType_None); - + std::string u; ASSERT_TRUE(ReadAllStream(u, transcode)); - + ASSERT_EQ(t, u); } @@ -299,10 +299,10 @@ sender.SetBuffer(t); HttpStreamTranscoder transcode(sender, CompressionType_ZlibWithSize); - + std::string u; ASSERT_TRUE(ReadAllStream(u, transcode, false, false)); - + ASSERT_EQ(s, u); } @@ -314,10 +314,10 @@ sender.SetBuffer(t); HttpStreamTranscoder transcode(sender, CompressionType_ZlibWithSize); - + std::string u; ASSERT_TRUE(ReadAllStream(u, transcode, false, true)); - + ASSERT_EQ(t.size() - sizeof(uint64_t), u.size()); ASSERT_EQ(t.substr(sizeof(uint64_t)), u); } @@ -330,7 +330,7 @@ HttpStreamTranscoder transcode(sender, CompressionType_ZlibWithSize); std::string u; ASSERT_TRUE(ReadAllStream(u, transcode, false, true)); - + ASSERT_EQ(0u, u.size()); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/ToolboxTests.cpp --- a/OrthancFramework/UnitTestsSources/ToolboxTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/ToolboxTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -77,7 +77,7 @@ std::string c; Toolbox::WriteFastJson(c, b); ASSERT_EQ(Toolbox::StripSpaces(c), "{\"hello\":\"world\"}"); - + Toolbox::WriteStyledJson(c, b); ASSERT_EQ(Toolbox::StripSpaces(c), "{\n \"hello\" : \"world\"\n}"); } @@ -250,7 +250,7 @@ std::set missings; needles.insert(5); - + ASSERT_FALSE(Toolbox::IsSetInSet(needles, haystack)); ASSERT_EQ(1u, Toolbox::GetMissingsFromSet(missings, needles, haystack)); ASSERT_TRUE(missings.count(5) == 1); diff -r bb9046c96483 -r 4ba287b00973 OrthancFramework/UnitTestsSources/ZipTests.cpp --- a/OrthancFramework/UnitTestsSources/ZipTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/ZipTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -191,7 +191,7 @@ TO CHECK THE CONTENT OF THE "hello2.zip" FILE: - # unzip -v hello2.zip + # unzip -v hello2.zip => There must be 6 files. The first 3 files must have a negative compression ratio. @@ -203,7 +203,7 @@ TEST(ZipReader, Basic) { TemporaryFile f; - + { ZipWriter w; ASSERT_EQ(0u, w.GetArchiveSize()); @@ -258,16 +258,16 @@ memory.clear(); uint64_t archiveSize; - + { ZipWriter w; ASSERT_EQ(0u, w.GetArchiveSize()); - + w.SetMemoryOutput(memory, (i == 0) /* ZIP64? */); w.Open(); ASSERT_EQ(0u, w.GetArchiveSize()); - + w.OpenFile("world/hello"); w.Write(large); w.OpenFile("world/hello2"); @@ -279,7 +279,7 @@ ASSERT_TRUE(memory.empty()); - uint64_t s1 = w.GetArchiveSize(); + uint64_t s1 = w.GetArchiveSize(); ASSERT_NE(0u, s1); w.Close(); @@ -290,7 +290,7 @@ } ASSERT_EQ(archiveSize, memory.size()); - + std::unique_ptr reader(ZipReader::CreateFromMemory(memory)); ASSERT_EQ(4u, reader->GetFilesCount()); @@ -302,7 +302,7 @@ ASSERT_EQ(large.size(), content.size()); ASSERT_TRUE(memcmp(large.c_str(), content.c_str(), large.size()) == 0); } - + { std::string filename, content; ASSERT_TRUE(reader->ReadNextFile(filename, content)); @@ -317,7 +317,7 @@ ASSERT_EQ("world/hello3", filename); ASSERT_EQ("Hello world", content); } - + { std::string filename, content; ASSERT_TRUE(reader->ReadNextFile(filename, content)); @@ -325,7 +325,7 @@ ASSERT_EQ(large.size(), content.size()); ASSERT_TRUE(memcmp(large.c_str(), content.c_str(), large.size()) == 0); } - + { std::string filename, content; ASSERT_FALSE(reader->ReadNextFile(filename, content)); @@ -338,7 +338,7 @@ { // The namespace is necessary because of FRIEND_TEST // http://code.google.com/p/googletest/wiki/AdvancedGuide#Private_Class_Members - + TEST(ZipWriter, BufferWithSeek) { ZipWriter::BufferWithSeek buffer; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/IPluginServiceProvider.h --- a/OrthancServer/Plugins/Engine/IPluginServiceProvider.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/IPluginServiceProvider.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -82,7 +82,7 @@ that_.CheckSuccess(code); } - + static FileInfo Convert(const OrthancPluginAttachment& attachment) { return FileInfo(attachment.uuid, @@ -121,7 +121,7 @@ if (type_ == _OrthancPluginDatabaseAnswerType_Int64) { - for (std::list::const_iterator + for (std::list::const_iterator it = answerInt64_.begin(); it != answerInt64_.end(); ++it) { target.push_back(*it); @@ -142,7 +142,7 @@ if (type_ == _OrthancPluginDatabaseAnswerType_String) { - for (std::list::const_iterator + for (std::list::const_iterator it = answerStrings_.begin(); it != answerStrings_.end(); ++it) { target.push_back(*it); @@ -161,7 +161,7 @@ answerStrings_.size() == 1) { target = answerStrings_.front(); - return true; + return true; } else { @@ -180,7 +180,7 @@ answerInt64_.size() == 1) { target = answerInt64_.front(); - return true; + return true; } else { @@ -195,19 +195,19 @@ { case _OrthancPluginDatabaseAnswerType_DeletedAttachment: { - const OrthancPluginAttachment& attachment = + const OrthancPluginAttachment& attachment = *reinterpret_cast(answer.valueGeneric); listener_.SignalAttachmentDeleted(Convert(attachment)); break; } - + case _OrthancPluginDatabaseAnswerType_RemainingAncestor: { ResourceType type = Plugins::Convert(static_cast(answer.valueInt32)); listener_.SignalRemainingAncestor(type, answer.valueString); break; } - + case _OrthancPluginDatabaseAnswerType_DeletedResource: { ResourceType type = Plugins::Convert(static_cast(answer.valueInt32)); @@ -234,7 +234,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + that_.activeTransaction_ = this; ResetAnswers(); @@ -242,7 +242,7 @@ virtual ~Transaction() ORTHANC_OVERRIDE { - assert(that_.activeTransaction_ != NULL); + assert(that_.activeTransaction_ != NULL); that_.activeTransaction_ = NULL; } @@ -350,7 +350,7 @@ { answerMatchingInstances_->clear(); } - + break; case _OrthancPluginDatabaseAnswerType_Metadata: @@ -393,7 +393,7 @@ case _OrthancPluginDatabaseAnswerType_Attachment: { - const OrthancPluginAttachment& attachment = + const OrthancPluginAttachment& attachment = *reinterpret_cast(answer.valueGeneric); answerAttachments_.push_back(Convert(attachment)); @@ -450,7 +450,7 @@ static_cast(change.changeType), Plugins::Convert(change.resourceType), change.publicId, - change.date)); + change.date)); } break; @@ -469,7 +469,7 @@ } else { - const OrthancPluginExportedResource& exported = + const OrthancPluginExportedResource& exported = *reinterpret_cast(answer.valueGeneric); assert(answerExportedResources_ != NULL); answerExportedResources_->push_back @@ -489,7 +489,7 @@ case _OrthancPluginDatabaseAnswerType_MatchingResource: { - const OrthancPluginMatchingResource& match = + const OrthancPluginMatchingResource& match = *reinterpret_cast(answer.valueGeneric); if (match.resourceId == NULL) @@ -509,7 +509,7 @@ answerMatchingInstances_->push_back(match.someInstanceId); } - + break; } @@ -537,7 +537,7 @@ boost::lexical_cast(answer.type)); } } - + // From the "ILookupResources" interface virtual void LookupIdentifier(std::list& result, @@ -563,7 +563,7 @@ ForwardAnswers(result); } - + virtual void ApplyLookupResources(std::list& resourcesId, std::list* instancesId, const DatabaseDicomTagConstraints& lookup, @@ -576,7 +576,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // "HasLabelsSupport()" has returned "false" } - + if (that_.extensions_.lookupResources == NULL) { // Fallback to compatibility mode @@ -599,7 +599,7 @@ ResetAnswers(); answerMatchingResources_ = &resourcesId; answerMatchingInstances_ = instancesId; - + CheckSuccess(that_.extensions_.lookupResources(that_.GetContext(), that_.payload_, lookup.GetSize(), (lookup.IsEmpty() ? NULL : &constraints[0]), Plugins::Convert(queryLevel), @@ -630,7 +630,7 @@ study.c_str(), series.c_str(), instance.c_str())); instanceId = output.instanceId; - + if (output.isNewInstance) { result.isNewPatient_ = output.isNewPatient; @@ -647,7 +647,7 @@ } } } - + virtual void AddAttachment(int64_t id, const FileInfo& attachment, @@ -767,7 +767,7 @@ if (type_ == _OrthancPluginDatabaseAnswerType_Int32) { - for (std::list::const_iterator + for (std::list::const_iterator it = answerInt32_.begin(); it != answerInt32_.end(); ++it) { MetadataType type = static_cast(*it); @@ -787,7 +787,7 @@ answerMetadata_ = ⌖ target.clear(); - + CheckSuccess(that_.extensions_.getAllMetadata(that_.GetContext(), that_.payload_, id)); if (type_ != _OrthancPluginDatabaseAnswerType_None && @@ -834,7 +834,7 @@ std::list tmp; GetAllPublicIds(tmp, resourceType); - + if (tmp.size() <= static_cast(since)) { // Not enough results => empty answer @@ -946,7 +946,7 @@ } } - + virtual void GetLastExportedResource(std::list& target /*out*/) ORTHANC_OVERRIDE { answerDoneIgnored_ = false; @@ -1008,14 +1008,14 @@ return size; } - + virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE { uint64_t size; CheckSuccess(that_.backend_.getTotalUncompressedSize(&size, that_.payload_)); return size; } - + virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE { @@ -1027,7 +1027,7 @@ { assert(GetTotalCompressedSize() == that_.currentDiskSize_); return that_.currentDiskSize_ > threshold; - } + } } @@ -1056,7 +1056,7 @@ if (type_ == _OrthancPluginDatabaseAnswerType_Int32) { - for (std::list::const_iterator + for (std::list::const_iterator it = answerInt32_.begin(); it != answerInt32_.end(); ++it) { target.insert(static_cast(*it)); @@ -1098,7 +1098,7 @@ CheckSuccess(that_.backend_.logExportedResource(that_.payload_, &tmp)); } - + virtual bool LookupAttachment(FileInfo& attachment, int64_t& revision, int64_t id, @@ -1108,7 +1108,7 @@ CheckSuccess(that_.backend_.lookupAttachment (that_.GetContext(), that_.payload_, id, static_cast(contentType))); - + revision = 0; // Dummy value, as revisions were added in Orthanc 1.9.2 if (type_ == _OrthancPluginDatabaseAnswerType_None) @@ -1119,7 +1119,7 @@ answerAttachments_.size() == 1) { attachment = answerAttachments_.front(); - return true; + return true; } else { @@ -1134,7 +1134,7 @@ { // "shared" is unused, as database plugins using Orthanc SDK <= // 1.9.1 are not compatible with multiple readers/writers - + ResetAnswers(); CheckSuccess(that_.backend_.lookupGlobalProperty @@ -1211,7 +1211,7 @@ { id = answerResources_.front().first; type = answerResources_.front().second; - return true; + return true; } else { @@ -1235,7 +1235,7 @@ uint8_t isExisting; OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient; - + ResetAnswers(); CheckSuccess(that_.extensions_.lookupResourceAndParent (that_.GetContext(), &isExisting, &id, &pluginType, that_.payload_, publicId.c_str())); @@ -1302,7 +1302,7 @@ { // "shared" is unused, as database plugins using Orthanc SDK <= // 1.9.1 are not compatible with multiple readers/writers - + CheckSuccess(that_.backend_.setGlobalProperty (that_.payload_, static_cast(property), value.c_str())); } @@ -1347,7 +1347,7 @@ } - virtual void SetProtectedPatient(int64_t internalId, + virtual void SetProtectedPatient(int64_t internalId, bool isProtected) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.setProtectedPatient(that_.payload_, internalId, isProtected)); @@ -1402,7 +1402,7 @@ assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && metadata.size() == content.GetListMetadata().size()); - + CheckSuccess(that_.extensions_.setResourcesContent( that_.payload_, identifierTags.size(), @@ -1444,7 +1444,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // Not supported } - + virtual void ListAllLabels(std::set& target) ORTHANC_OVERRIDE { @@ -1502,14 +1502,14 @@ } virtual bool ReserveQueueValue(std::string& value, - uint64_t& valueId, + uint64_t& valueId, const std::string& queueId, QueueOrigin origin, uint32_t releaseTimeout) ORTHANC_OVERRIDE { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // Not supported } - + virtual void AcknowledgeQueueValue(const std::string& queueId, uint64_t valueId) ORTHANC_OVERRIDE { @@ -1546,7 +1546,7 @@ const OrthancPluginDatabaseBackend& backend, const OrthancPluginDatabaseExtensions* extensions, size_t extensionsSize, - void *payload) : + void *payload) : library_(library), errorDictionary_(errorDictionary), backend_(backend), @@ -1556,7 +1556,7 @@ currentDiskSize_(0) { static const char* const MISSING = " Missing extension in database index plugin: "; - + memset(&extensions_, 0, sizeof(extensions_)); size_t size = sizeof(extensions_); @@ -1647,7 +1647,7 @@ } VoidDatabaseListener listener; - + { Transaction transaction(*this, listener); transaction.Begin(); @@ -1656,7 +1656,7 @@ fastGetTotalSize_ = (transaction.LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast, true /* unused in old databases */) && tmp == "1"); - + if (fastGetTotalSize_) { currentDiskSize_ = 0; // Unused @@ -1713,14 +1713,14 @@ IPluginStorageArea& storageArea) { VoidDatabaseListener listener; - + if (extensions_.upgradeDatabase != NULL) { Transaction transaction(*this, listener); transaction.Begin(); OrthancPluginErrorCode code = extensions_.upgradeDatabase( - payload_, targetVersion, + payload_, targetVersion, reinterpret_cast(&storageArea)); if (code == OrthancPluginErrorCode_Success) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabase.h --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -57,7 +57,7 @@ * transaction is running. **/ boost::recursive_mutex mutex_; - + SharedLibrary& library_; PluginsErrorDictionary& errorDictionary_; OrthancPluginDatabaseBackend backend_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -55,12 +55,12 @@ IDatabaseListener& listener_; OrthancPluginDatabaseTransaction* transaction_; - + void CheckSuccess(OrthancPluginErrorCode code) const { that_.CheckSuccess(code); } - + static FileInfo Convert(const OrthancPluginAttachment& attachment) { @@ -146,7 +146,7 @@ } } - + ExportedResource ReadAnswerExportedResource(uint32_t answerIndex) { OrthancPluginExportedResource exported; @@ -175,7 +175,7 @@ exported.sopInstanceUid); } } - + ServerIndexChange ReadAnswerChange(uint32_t answerIndex) { @@ -224,7 +224,7 @@ case OrthancPluginDatabaseEventType_DeletedAttachment: listener_.SignalAttachmentDeleted(Convert(event.content.attachment)); break; - + case OrthancPluginDatabaseEventType_DeletedResource: if (isDeletingAttachment) { @@ -234,9 +234,9 @@ else { listener_.SignalResourceDeleted(Plugins::Convert(event.content.resource.level), event.content.resource.publicId); - } + } break; - + case OrthancPluginDatabaseEventType_RemainingAncestor: if (isDeletingAttachment) { @@ -270,7 +270,7 @@ } } - + virtual ~Transaction() { OrthancPluginErrorCode code = that_.backend_.destructTransaction(transaction_); @@ -280,13 +280,13 @@ that_.errorDictionary_.LogError(code, true); } } - + virtual void Rollback() ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.rollback(transaction_)); CheckNoEvent(); } - + virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE { @@ -294,7 +294,7 @@ CheckNoEvent(); } - + virtual void AddAttachment(int64_t id, const FileInfo& attachment, int64_t revision) ORTHANC_OVERRIDE @@ -319,14 +319,14 @@ CheckNoEvent(); } - + virtual void ClearExportedResources() ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.clearExportedResources(transaction_)); CheckNoEvent(); } - + virtual void DeleteAttachment(int64_t id, FileContentType attachment) ORTHANC_OVERRIDE { @@ -334,7 +334,7 @@ ProcessEvents(true); } - + virtual void DeleteMetadata(int64_t id, MetadataType type) ORTHANC_OVERRIDE { @@ -342,14 +342,14 @@ CheckNoEvent(); } - + virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.deleteResource(transaction_, id)); ProcessEvents(false); } - + virtual void GetAllMetadata(std::map& target, int64_t id) ORTHANC_OVERRIDE { @@ -358,7 +358,7 @@ uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + target.clear(); for (uint32_t i = 0; i < count; i++) { @@ -377,7 +377,7 @@ } } - + virtual void GetAllPublicIds(std::list& target, ResourceType resourceType) ORTHANC_OVERRIDE { @@ -387,7 +387,7 @@ ReadStringAnswers(target); } - + virtual void GetAllPublicIdsCompatibility(std::list& target, ResourceType resourceType, int64_t since, @@ -401,7 +401,7 @@ ReadStringAnswers(target); } - + virtual void GetChanges(std::list& target /*out*/, bool& done /*out*/, int64_t since, @@ -412,10 +412,10 @@ CheckNoEvent(); done = (tmpDone != 0); - + uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + target.clear(); for (uint32_t i = 0; i < count; i++) { @@ -423,7 +423,7 @@ } } - + virtual void GetChildrenInternalId(std::list& target, int64_t id) ORTHANC_OVERRIDE { @@ -432,7 +432,7 @@ uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + target.clear(); for (uint32_t i = 0; i < count; i++) { @@ -442,7 +442,7 @@ } } - + virtual void GetChildrenPublicId(std::list& target, int64_t id) ORTHANC_OVERRIDE { @@ -452,7 +452,7 @@ ReadStringAnswers(target); } - + virtual void GetExportedResources(std::list& target /*out*/, bool& done /*out*/, int64_t since, @@ -463,10 +463,10 @@ CheckNoEvent(); done = (tmpDone != 0); - + uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + target.clear(); for (uint32_t i = 0; i < count; i++) { @@ -514,7 +514,7 @@ } } - + virtual void GetMainDicomTags(DicomMap& target, int64_t id) ORTHANC_OVERRIDE { @@ -542,7 +542,7 @@ } } - + virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getPublicId(transaction_, resourceId)); @@ -559,7 +559,7 @@ } } - + virtual uint64_t GetResourcesCount(ResourceType resourceType) ORTHANC_OVERRIDE { uint64_t value; @@ -568,7 +568,7 @@ return value; } - + virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE { OrthancPluginResourceType type; @@ -577,7 +577,7 @@ return Plugins::Convert(type); } - + virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE { uint64_t s; @@ -586,7 +586,7 @@ return s; } - + virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE { uint64_t s; @@ -595,7 +595,7 @@ return s; } - + virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE { uint8_t b; @@ -604,7 +604,7 @@ return (b != 0); } - + virtual void ListAvailableAttachments(std::set& target, int64_t id) ORTHANC_OVERRIDE { @@ -613,7 +613,7 @@ uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + target.clear(); for (uint32_t i = 0; i < count; i++) { @@ -623,7 +623,7 @@ } } - + virtual void LogChange(ChangeType changeType, ResourceType resourceType, int64_t internalId, @@ -636,7 +636,7 @@ CheckNoEvent(); } - + virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.logExportedResource(transaction_, Plugins::Convert(resource.GetResourceType()), @@ -650,7 +650,7 @@ CheckNoEvent(); } - + virtual bool LookupAttachment(FileInfo& attachment, int64_t& revision, int64_t id, @@ -684,13 +684,13 @@ bool shared) ORTHANC_OVERRIDE { const char* id = (shared ? "" : that_.serverIdentifier_.c_str()); - + CheckSuccess(that_.backend_.lookupGlobalProperty(transaction_, id, static_cast(property))); CheckNoEvent(); - return ReadSingleStringAnswer(target); + return ReadSingleStringAnswer(target); } - + virtual bool LookupMetadata(std::string& target, int64_t& revision, int64_t id, @@ -698,10 +698,10 @@ { CheckSuccess(that_.backend_.lookupMetadata(transaction_, &revision, id, static_cast(type))); CheckNoEvent(); - return ReadSingleStringAnswer(target); + return ReadSingleStringAnswer(target); } - + virtual bool LookupParent(int64_t& parentId, int64_t resourceId) ORTHANC_OVERRIDE { @@ -711,7 +711,7 @@ return (existing != 0); } - + virtual bool LookupResource(int64_t& id, ResourceType& type, const std::string& publicId) ORTHANC_OVERRIDE @@ -732,44 +732,44 @@ } } - + virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE { - uint8_t available; + uint8_t available; CheckSuccess(that_.backend_.selectPatientToRecycle(transaction_, &available, &internalId)); CheckNoEvent(); return (available != 0); } - + virtual bool SelectPatientToRecycle(int64_t& internalId, int64_t patientIdToAvoid) ORTHANC_OVERRIDE { - uint8_t available; + uint8_t available; CheckSuccess(that_.backend_.selectPatientToRecycle2(transaction_, &available, &internalId, patientIdToAvoid)); CheckNoEvent(); return (available != 0); } - + virtual void SetGlobalProperty(GlobalProperty property, bool shared, const std::string& value) ORTHANC_OVERRIDE { const char* id = (shared ? "" : that_.serverIdentifier_.c_str()); - + CheckSuccess(that_.backend_.setGlobalProperty(transaction_, id, static_cast(property), value.c_str())); CheckNoEvent(); } - + virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.clearMainDicomTags(transaction_, id)); CheckNoEvent(); } - + virtual void SetMetadata(int64_t id, MetadataType type, const std::string& value, @@ -779,8 +779,8 @@ CheckNoEvent(); } - - virtual void SetProtectedPatient(int64_t internalId, + + virtual void SetProtectedPatient(int64_t internalId, bool isProtected) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.setProtectedPatient(transaction_, internalId, (isProtected ? 1 : 0))); @@ -796,7 +796,7 @@ return (tmp != 0); } - + virtual void ApplyLookupResources(std::list& resourcesId, std::list* instancesId, // Can be NULL if not needed const DatabaseDicomTagConstraints& lookup, @@ -809,7 +809,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // "HasLabelsSupport()" has returned "false" } - + std::vector constraints; std::vector< std::vector > constraintsValues; @@ -829,14 +829,14 @@ uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); - + resourcesId.clear(); if (instancesId != NULL) { instancesId->clear(); } - + for (uint32_t i = 0; i < count; i++) { OrthancPluginMatchingResource resource; @@ -846,7 +846,7 @@ { throw OrthancException(ErrorCode_DatabasePlugin); } - + resourcesId.push_back(resource.resourceId); if (instancesId != NULL) @@ -863,7 +863,7 @@ } } - + virtual bool CreateInstance(CreateInstanceResult& result, /* out */ int64_t& instanceId, /* out */ const std::string& patient, @@ -879,7 +879,7 @@ CheckNoEvent(); instanceId = output.instanceId; - + if (output.isNewInstance) { result.isNewPatient_ = output.isNewPatient; @@ -897,7 +897,7 @@ } - + virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE { std::vector identifierTags; @@ -939,7 +939,7 @@ assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && metadata.size() == content.GetListMetadata().size()); - + CheckSuccess(that_.backend_.setResourcesContent(transaction_, identifierTags.size(), (identifierTags.empty() ? NULL : &identifierTags[0]), @@ -950,7 +950,7 @@ CheckNoEvent(); } - + virtual void GetChildrenMetadata(std::list& target, int64_t resourceId, MetadataType metadata) ORTHANC_OVERRIDE @@ -960,7 +960,7 @@ ReadStringAnswers(target); } - + virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE { int64_t tmp; @@ -969,7 +969,7 @@ return tmp; } - + virtual bool LookupResourceAndParent(int64_t& id, ResourceType& type, std::string& parentPublicId, @@ -983,7 +983,7 @@ if (isExisting) { type = Plugins::Convert(tmpType); - + uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -1020,14 +1020,14 @@ else { parentPublicId.assign(value); - } + } } break; default: throw OrthancException(ErrorCode_DatabasePlugin); } - + return true; } else @@ -1056,7 +1056,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // Not supported } - + virtual void ListAllLabels(std::set& target) ORTHANC_OVERRIDE { @@ -1114,14 +1114,14 @@ } virtual bool ReserveQueueValue(std::string& value, - uint64_t& valueId, + uint64_t& valueId, const std::string& queueId, QueueOrigin origin, uint32_t releaseTimeout) ORTHANC_OVERRIDE { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); // Not supported } - + virtual void AcknowledgeQueueValue(const std::string& queueId, uint64_t valueId) ORTHANC_OVERRIDE { @@ -1142,7 +1142,7 @@ } }; - + void OrthancPluginDatabaseV3::CheckSuccess(OrthancPluginErrorCode code) const { if (code != OrthancPluginErrorCode_Success) @@ -1167,7 +1167,7 @@ { CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties " << "of the custom database: \"" << serverIdentifier << "\""; - + if (backendSize >= sizeof(backend_)) { memcpy(&backend_, backend, sizeof(backend_)); @@ -1190,7 +1190,7 @@ CHECK_FUNCTION_EXISTS(backend_, readAnswerMatchingResource); CHECK_FUNCTION_EXISTS(backend_, readAnswerMetadata); CHECK_FUNCTION_EXISTS(backend_, readAnswerString); - + CHECK_FUNCTION_EXISTS(backend_, readEventsCount); CHECK_FUNCTION_EXISTS(backend_, readEvent); @@ -1205,7 +1205,7 @@ CHECK_FUNCTION_EXISTS(backend_, rollback); CHECK_FUNCTION_EXISTS(backend_, commit); - + CHECK_FUNCTION_EXISTS(backend_, addAttachment); CHECK_FUNCTION_EXISTS(backend_, clearChanges); CHECK_FUNCTION_EXISTS(backend_, clearExportedResources); @@ -1252,7 +1252,7 @@ CHECK_FUNCTION_EXISTS(backend_, setResourcesContent); } - + OrthancPluginDatabaseV3::~OrthancPluginDatabaseV3() { if (database_ != NULL) @@ -1266,7 +1266,7 @@ } } - + void OrthancPluginDatabaseV3::Open() { CheckSuccess(backend_.open(database_)); @@ -1282,7 +1282,7 @@ { CheckSuccess(backend_.close(database_)); } - + IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV3::StartTransaction(TransactionType type, IDatabaseListener& listener) @@ -1300,7 +1300,7 @@ } } - + unsigned int OrthancPluginDatabaseV3::GetDatabaseVersion() { uint32_t version = 0; @@ -1308,12 +1308,12 @@ return version; } - + void OrthancPluginDatabaseV3::Upgrade(unsigned int targetVersion, IPluginStorageArea& storageArea) { VoidDatabaseListener listener; - + if (backend_.upgradeDatabase != NULL) { Transaction transaction(*this, listener, OrthancPluginDatabaseTransactionType_ReadWrite); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -77,7 +77,7 @@ } } - + static DatabasePluginMessages::ResourceType Convert(ResourceType type) { switch (type) @@ -99,7 +99,7 @@ } } - + static void Convert(FileInfo& info, const DatabasePluginMessages::FileInfo& source) { @@ -400,7 +400,7 @@ throw OrthancException(ErrorCode_DatabasePlugin, "Cannot unserialize protobuf originating from the database plugin"); } } - + static void ExecuteDatabase(DatabasePluginMessages::DatabaseResponse& response, const OrthancPluginDatabaseV4& database, @@ -414,11 +414,11 @@ DatabasePluginMessages::Response fullResponse; Execute(fullResponse, database, fullRequest); - + response.CopyFrom(fullResponse.database_response()); } - + class OrthancPluginDatabaseV4::Transaction : public IDatabaseWrapper::ITransaction, public IDatabaseWrapper::ICompatibilityTransaction @@ -427,7 +427,7 @@ OrthancPluginDatabaseV4& database_; IDatabaseListener& listener_; void* transaction_; - + void ExecuteTransaction(DatabasePluginMessages::TransactionResponse& response, DatabasePluginMessages::TransactionOperation operation, const DatabasePluginMessages::TransactionRequest& request) @@ -440,27 +440,27 @@ DatabasePluginMessages::Response fullResponse; Execute(fullResponse, database_, fullRequest); - + response.CopyFrom(fullResponse.transaction_response()); } - - + + void ExecuteTransaction(DatabasePluginMessages::TransactionResponse& response, DatabasePluginMessages::TransactionOperation operation) { DatabasePluginMessages::TransactionRequest request; // Ignored ExecuteTransaction(response, operation, request); } - - + + void ExecuteTransaction(DatabasePluginMessages::TransactionOperation operation, const DatabasePluginMessages::TransactionRequest& request) { DatabasePluginMessages::TransactionResponse response; // Ignored ExecuteTransaction(response, operation, request); } - - + + void ExecuteTransaction(DatabasePluginMessages::TransactionOperation operation) { DatabasePluginMessages::TransactionResponse response; // Ignored @@ -494,7 +494,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + public: Transaction(OrthancPluginDatabaseV4& database, @@ -531,7 +531,7 @@ } } - + virtual ~Transaction() ORTHANC_OVERRIDE { try @@ -553,13 +553,13 @@ { return transaction_; } - + virtual void Rollback() ORTHANC_OVERRIDE { ExecuteTransaction(DatabasePluginMessages::OPERATION_ROLLBACK); } - + virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE { @@ -569,7 +569,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_COMMIT, request); } - + virtual void AddAttachment(int64_t id, const FileInfo& attachment, int64_t revision) ORTHANC_OVERRIDE @@ -582,7 +582,7 @@ request.mutable_add_attachment()->mutable_attachment()->set_uncompressed_hash(attachment.GetUncompressedMD5()); request.mutable_add_attachment()->mutable_attachment()->set_compression_type(attachment.GetCompressionType()); request.mutable_add_attachment()->mutable_attachment()->set_compressed_size(attachment.GetCompressedSize()); - request.mutable_add_attachment()->mutable_attachment()->set_compressed_hash(attachment.GetCompressedMD5()); + request.mutable_add_attachment()->mutable_attachment()->set_compressed_hash(attachment.GetCompressedMD5()); request.mutable_add_attachment()->mutable_attachment()->set_custom_data(attachment.GetCustomData()); // New in 1.12.8 request.mutable_add_attachment()->set_revision(revision); @@ -595,7 +595,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_CHANGES); } - + virtual void ClearExportedResources() ORTHANC_OVERRIDE { ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_EXPORTED_RESOURCES); @@ -617,7 +617,7 @@ listener_.SignalAttachmentDeleted(info); } - + virtual void DeleteMetadata(int64_t id, MetadataType type) ORTHANC_OVERRIDE { @@ -628,7 +628,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_DELETE_METADATA, request); } - + virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -657,7 +657,7 @@ } } - + virtual void GetAllMetadata(std::map& target, int64_t id) ORTHANC_OVERRIDE { @@ -671,7 +671,7 @@ for (int i = 0; i < response.get_all_metadata().metadata().size(); i++) { MetadataType key = static_cast(response.get_all_metadata().metadata(i).type()); - + if (target.find(key) == target.end()) { target[key] = response.get_all_metadata().metadata(i).value(); @@ -683,7 +683,7 @@ } } - + virtual void GetAllPublicIds(std::list& target, ResourceType resourceType) ORTHANC_OVERRIDE { @@ -700,7 +700,7 @@ } } - + virtual void GetAllPublicIdsCompatibility(std::list& target, ResourceType resourceType, int64_t since, @@ -721,7 +721,7 @@ } } - + virtual void GetChanges(std::list& target /*out*/, bool& done /*out*/, int64_t since, @@ -735,7 +735,7 @@ ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_CHANGES, request); done = response.get_changes().done(); - + target.clear(); for (int i = 0; i < response.get_changes().changes().size(); i++) { @@ -762,7 +762,7 @@ { request.mutable_get_changes_extended()->add_change_type(*it); } - + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_CHANGES_EXTENDED, request); done = response.get_changes_extended().done(); @@ -774,7 +774,7 @@ } } - + virtual void GetChildrenInternalId(std::list& target, int64_t id) ORTHANC_OVERRIDE { @@ -791,7 +791,7 @@ } } - + virtual void GetChildrenPublicId(std::list& target, int64_t id) ORTHANC_OVERRIDE { @@ -808,7 +808,7 @@ } } - + virtual void GetExportedResources(std::list& target /*out*/, bool& done /*out*/, int64_t since, @@ -822,7 +822,7 @@ ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_EXPORTED_RESOURCES, request); done = response.get_exported_resources().done(); - + target.clear(); for (int i = 0; i < response.get_exported_resources().resources().size(); i++) { @@ -830,7 +830,7 @@ } } - + virtual void GetLastChange(std::list& target /*out*/) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -843,7 +843,7 @@ } } - + virtual void GetLastExportedResource(std::list& target /*out*/) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -856,7 +856,7 @@ } } - + virtual void GetMainDicomTags(DicomMap& target, int64_t id) ORTHANC_OVERRIDE { @@ -883,7 +883,7 @@ } } - + virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -894,7 +894,7 @@ return response.get_public_id().id(); } - + virtual uint64_t GetResourcesCount(ResourceType resourceType) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -905,7 +905,7 @@ return response.get_resources_count().count(); } - + virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -916,7 +916,7 @@ return Convert(response.get_resource_type().type()); } - + virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -924,7 +924,7 @@ return response.get_total_compressed_size().size(); } - + virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -932,7 +932,7 @@ return response.get_total_uncompressed_size().size(); } - + virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -943,7 +943,7 @@ return response.is_protected_patient().protected_patient(); } - + virtual void ListAvailableAttachments(std::set& target, int64_t id) ORTHANC_OVERRIDE { @@ -969,7 +969,7 @@ } } - + virtual void LogChange(ChangeType changeType, ResourceType resourceType, int64_t internalId, @@ -985,11 +985,11 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_LOG_CHANGE, request); } - + virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE { // TODO: "seq" is ignored, could be simplified in "ExportedResource" - + DatabasePluginMessages::TransactionRequest request; request.mutable_log_exported_resource()->set_resource_type(Convert(resource.GetResourceType())); request.mutable_log_exported_resource()->set_public_id(resource.GetPublicId()); @@ -1003,7 +1003,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_LOG_EXPORTED_RESOURCE, request); } - + virtual bool LookupAttachment(FileInfo& attachment, int64_t& revision, int64_t id, @@ -1150,7 +1150,7 @@ } } - + virtual bool LookupParent(int64_t& parentId, int64_t resourceId) ORTHANC_OVERRIDE { @@ -1171,7 +1171,7 @@ } } - + virtual bool LookupResource(int64_t& id, ResourceType& type, const std::string& publicId) ORTHANC_OVERRIDE @@ -1194,7 +1194,7 @@ } } - + virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -1211,7 +1211,7 @@ } } - + virtual bool SelectPatientToRecycle(int64_t& internalId, int64_t patientIdToAvoid) ORTHANC_OVERRIDE { @@ -1232,7 +1232,7 @@ } } - + virtual void SetGlobalProperty(GlobalProperty property, bool shared, const std::string& value) ORTHANC_OVERRIDE @@ -1245,7 +1245,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_GLOBAL_PROPERTY, request); } - + virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -1254,7 +1254,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_MAIN_DICOM_TAGS, request); } - + virtual void SetMetadata(int64_t id, MetadataType type, const std::string& value, @@ -1269,8 +1269,8 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_METADATA, request); } - - virtual void SetProtectedPatient(int64_t internalId, + + virtual void SetProtectedPatient(int64_t internalId, bool isProtected) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -1313,7 +1313,7 @@ request.mutable_lookup_resources()->set_retrieve_instances_ids(instancesId != NULL); request.mutable_lookup_resources()->mutable_lookup()->Reserve(static_cast(lookup.GetSize())); - + for (size_t i = 0; i < lookup.GetSize(); i++) { Convert(*request.mutable_lookup_resources()->add_lookup(), lookup.GetConstraint(i)); @@ -1325,7 +1325,7 @@ } request.mutable_lookup_resources()->set_labels_constraint(Convert(labelsConstraint)); - + DatabasePluginMessages::TransactionResponse response; ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request); @@ -1333,7 +1333,7 @@ { resourcesId.push_back(response.lookup_resources().resources_ids(i)); } - + if (instancesId != NULL) { if (response.lookup_resources().resources_ids().size() != response.lookup_resources().instances_ids().size()) @@ -1350,7 +1350,7 @@ } } - + virtual bool CreateInstance(CreateInstanceResult& result, /* out */ int64_t& instanceId, /* out */ const std::string& patient, @@ -1359,7 +1359,7 @@ const std::string& instance) ORTHANC_OVERRIDE { // TODO: "CreateInstanceResult" => constructor and getters - + DatabasePluginMessages::TransactionRequest request; request.mutable_create_instance()->set_patient(patient); request.mutable_create_instance()->set_study(study); @@ -1387,7 +1387,7 @@ } } - + virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionRequest request; @@ -1402,7 +1402,7 @@ tag->set_element(it->GetTag().GetElement()); tag->set_value(it->GetValue()); } - + request.mutable_set_resources_content()->mutable_metadata()->Reserve(static_cast(content.GetListMetadata().size())); for (ResourcesContent::ListMetadata::const_iterator it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) { @@ -1415,7 +1415,7 @@ ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_RESOURCES_CONTENT, request); } - + virtual void GetChildrenMetadata(std::list& target, int64_t resourceId, MetadataType metadata) ORTHANC_OVERRIDE @@ -1433,7 +1433,7 @@ } } - + virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE { DatabasePluginMessages::TransactionResponse response; @@ -1441,7 +1441,7 @@ return response.get_last_change_index().result(); } - + virtual bool LookupResourceAndParent(int64_t& id, ResourceType& type, std::string& parentPublicId, @@ -1466,7 +1466,7 @@ throw OrthancException(ErrorCode_DatabasePlugin); } break; - + case ResourceType_Study: case ResourceType_Series: case ResourceType_Instance: @@ -1479,11 +1479,11 @@ parentPublicId = response.lookup_resource_and_parent().parent_public_id(); } break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + return true; } else @@ -1492,7 +1492,7 @@ } } - + virtual void AddLabel(int64_t resource, const std::string& label) ORTHANC_OVERRIDE { @@ -1537,7 +1537,7 @@ ListLabelsInternal(target, true, resource); } - + virtual void ListAllLabels(std::set& target) ORTHANC_OVERRIDE { ListLabelsInternal(target, false, -1); @@ -1580,7 +1580,7 @@ for (std::deque::const_iterator it = request.GetMetadataConstraint().begin(); it != request.GetMetadataConstraint().end(); ++it) { - Convert(*dbRequest.mutable_find()->add_metadata_constraints(), *(*it)); + Convert(*dbRequest.mutable_find()->add_metadata_constraints(), *(*it)); } for (std::set::const_iterator it = request.GetLabels().begin(); it != request.GetLabels().end(); ++it) @@ -1637,12 +1637,12 @@ for (std::deque::const_iterator it = request.GetMetadataConstraint().begin(); it != request.GetMetadataConstraint().end(); ++it) { - Convert(*dbRequest.mutable_find()->add_metadata_constraints(), *(*it)); + Convert(*dbRequest.mutable_find()->add_metadata_constraints(), *(*it)); } for (std::deque::const_iterator it = request.GetOrdering().begin(); it != request.GetOrdering().end(); ++it) { - Convert(*dbRequest.mutable_find()->add_ordering(), *(*it)); + Convert(*dbRequest.mutable_find()->add_ordering(), *(*it)); } if (request.HasLimits()) @@ -2058,7 +2058,7 @@ } virtual bool ReserveQueueValue(std::string& value, - uint64_t& valueId, + uint64_t& valueId, const std::string& queueId, QueueOrigin origin, uint32_t releaseTimeout) ORTHANC_OVERRIDE @@ -2103,7 +2103,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + virtual void AcknowledgeQueueValue(const std::string& queueId, uint64_t valueId) ORTHANC_OVERRIDE { @@ -2148,7 +2148,7 @@ } } - + OrthancPluginDatabaseV4::~OrthancPluginDatabaseV4() { definition_.finalize(definition_.backend); @@ -2179,14 +2179,14 @@ } } - + void OrthancPluginDatabaseV4::Open() { if (open_) { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - + { DatabasePluginMessages::DatabaseRequest request; AddIdentifierTags(*request.mutable_open(), ResourceType_Patient); @@ -2202,7 +2202,7 @@ DatabasePluginMessages::DatabaseRequest request; DatabasePluginMessages::DatabaseResponse response; ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_GET_SYSTEM_INFORMATION, request); - + const ::Orthanc::DatabasePluginMessages::GetSystemInformation_Response& systemInfo = response.get_system_information(); databaseVersion_ = systemInfo.database_version(); dbCapabilities_.SetFlushToDisk(systemInfo.supports_flush_to_disk()); @@ -2236,7 +2236,7 @@ ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_CLOSE, request); } } - + void OrthancPluginDatabaseV4::FlushToDisk() @@ -2253,7 +2253,7 @@ ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_FLUSH_TO_DISK, request); } } - + IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV4::StartTransaction(TransactionType type, IDatabaseListener& listener) @@ -2268,7 +2268,7 @@ } } - + unsigned int OrthancPluginDatabaseV4::GetDatabaseVersion() { if (!open_) @@ -2281,7 +2281,7 @@ } } - + void OrthancPluginDatabaseV4::Upgrade(unsigned int targetVersion, IPluginStorageArea& storageArea) { @@ -2300,7 +2300,7 @@ request.mutable_upgrade()->set_target_version(targetVersion); request.mutable_upgrade()->set_storage_area(reinterpret_cast(&storageArea)); request.mutable_upgrade()->set_transaction(reinterpret_cast(transaction.GetTransactionObject())); - + DatabasePluginMessages::DatabaseResponse response; ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_UPGRADE, request); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -69,7 +69,7 @@ { return serverIdentifier_; } - + virtual void Open() ORTHANC_OVERRIDE; virtual void Close() ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPlugins.cpp --- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -168,7 +168,7 @@ void Setup(ParsedDicomFile* parsed) { parsed_.reset(parsed); - + if (parsed_.get() == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -230,7 +230,7 @@ items_[i] = path[i].c_str(); } } - + uint32_t GetSize() const { return static_cast(items_.size()); @@ -256,7 +256,7 @@ return MimeType_Binary; } } - + static OrthancPluginErrorCode AddFile( OrthancPluginWebDavCollection* collection, const char* displayName, @@ -283,7 +283,7 @@ { f->SetMimeType(ParseMimeType(mimeType)); } - + reinterpret_cast(collection)->AddResource(f.release()); return OrthancPluginErrorCode_Success; } @@ -296,7 +296,7 @@ return OrthancPluginErrorCode_InternalError; } } - + static OrthancPluginErrorCode AddFolder( OrthancPluginWebDavCollection* collection, const char* displayName, @@ -350,7 +350,7 @@ { return isSent_; } - + static OrthancPluginErrorCode RetrieveFile( OrthancPluginWebDavCollection* collection, const void* data, @@ -359,7 +359,7 @@ const char* creationTime) { ContentTarget& target = *reinterpret_cast(collection); - + if (target.isSent_) { return OrthancPluginErrorCode_BadSequenceOfCalls; @@ -375,7 +375,7 @@ { target.mime_ = ParseMimeType(mimeType); } - + target.content_.assign(reinterpret_cast(data), size); target.modificationTime_ = boost::posix_time::from_iso_string(creationTime); return OrthancPluginErrorCode_Success; @@ -442,7 +442,7 @@ PathHelper helper(path); uint8_t isExisting; - OrthancPluginErrorCode code = listFolder_(&isExisting, reinterpret_cast(&collection), + OrthancPluginErrorCode code = listFolder_(&isExisting, reinterpret_cast(&collection), AddFile, AddFolder, helper.GetSize(), helper.GetItems(), payload_); if (code == OrthancPluginErrorCode_Success) @@ -458,16 +458,16 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, + boost::posix_time::ptime& modificationTime, const std::vector& path) { PathHelper helper(path); - + ContentTarget target(path.back(), mime, content, modificationTime); OrthancPluginErrorCode code = retrieveFile_( reinterpret_cast(&target), ContentTarget::RetrieveFile, helper.GetSize(), helper.GetItems(), payload_); - + if (code == OrthancPluginErrorCode_Success) { return target.IsSent(); @@ -515,7 +515,7 @@ errorDictionary_.LogError(code, true); throw OrthancException(static_cast(code)); } - } + } virtual bool DeleteItem(const std::vector& path) { @@ -543,7 +543,7 @@ { } }; - + static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer* target, const void* data, @@ -588,12 +588,12 @@ { Json::Value json = Json::objectValue; - for (HttpClient::HttpHeaders::const_iterator + for (HttpClient::HttpHeaders::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) { json[it->first] = it->second; } - + target.Assign(json.toStyledString()); } @@ -665,7 +665,7 @@ } virtual void Create(const std::string& uuid, - const void* content, + const void* content, size_t size, FileContentType type) ORTHANC_OVERRIDE { @@ -699,7 +699,7 @@ private: OrthancPluginStorageRead read_; OrthancPluginFree free_; - + public: PluginStorageAreaV1(const _OrthancPluginRegisterStorageArea& callbacks, PluginsErrorDictionary& errorDictionary) : @@ -821,7 +821,7 @@ } } } - + virtual bool HasEfficientReadRange() const ORTHANC_OVERRIDE { return (readRange_ != NULL); @@ -958,7 +958,7 @@ Version2, Version3 }; - + SharedLibrary& sharedLibrary_; Version version_; _OrthancPluginRegisterStorageArea callbacks1_; @@ -970,7 +970,7 @@ { LOG(WARNING) << "Performance warning: The storage area plugin doesn't implement reading of file ranges"; } - + public: StorageAreaFactory(SharedLibrary& sharedLibrary, const _OrthancPluginRegisterStorageArea& callbacks, @@ -1050,7 +1050,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + public: OrthancPeers() { @@ -1061,7 +1061,7 @@ names_.reserve(peers.size()); parameters_.reserve(peers.size()); - + for (std::set::const_iterator it = peers.begin(); it != peers.end(); ++it) { @@ -1113,17 +1113,17 @@ case OrthancPluginDicomWebBinaryMode_Ignore: that.currentMode_ = DicomWebJsonVisitor::BinaryMode_Ignore; break; - + case OrthancPluginDicomWebBinaryMode_InlineBinary: that.currentMode_ = DicomWebJsonVisitor::BinaryMode_InlineBinary; break; - + case OrthancPluginDicomWebBinaryMode_BulkDataUri: if (bulkDataUri == NULL) { throw OrthancException(ErrorCode_NullPointer); - } - + } + that.currentBulkDataUri_ = bulkDataUri; that.currentMode_ = DicomWebJsonVisitor::BinaryMode_BulkDataUri; break; @@ -1136,7 +1136,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + public: explicit DicomWebBinaryFormatter(OrthancPluginDicomWebBinaryCallback callback) : oldCallback_(callback), @@ -1145,7 +1145,7 @@ currentMode_(DicomWebJsonVisitor::BinaryMode_Ignore) { } - + DicomWebBinaryFormatter(OrthancPluginDicomWebBinaryCallback2 callback, void* payload) : oldCallback_(NULL), @@ -1154,7 +1154,7 @@ currentMode_(DicomWebJsonVisitor::BinaryMode_Ignore) { } - + virtual DicomWebJsonVisitor::BinaryMode Format(std::string& bulkDataUri, const std::vector& parentTags, const std::vector& parentIndexes, @@ -1208,9 +1208,9 @@ tag.GetElement(), Plugins::Convert(vr), newPayload_); - } - - bulkDataUri = currentBulkDataUri_; + } + + bulkDataUri = currentBulkDataUri_; return currentMode_; } } @@ -1238,11 +1238,11 @@ *target = CopyString(s); } - + void Apply(char** target, bool isJson, const void* dicom, - size_t dicomSize) + size_t dicomSize) { ParsedDicomFile parsed(dicom, dicomSize); Apply(target, isJson, parsed); @@ -1259,7 +1259,7 @@ size_t contextRefCount_; ServerContext* context_; - + public: class PluginHttpOutput : public boost::noncopyable { @@ -1399,7 +1399,7 @@ // Start an actual stream for chunked transfer as soon as // there are more than 2 elements in the multipart stream output_.StartMultipart(multipartSubType_, multipartContentType_); - output_.SendMultipartItem(multipartFirstPart_.c_str(), multipartFirstPart_.size(), + output_.SendMultipartItem(multipartFirstPart_.c_str(), multipartFirstPart_.size(), multipartFirstHeaders_); multipartFirstPart_.clear(); // Release memory @@ -1477,7 +1477,7 @@ } }; - + class RestCallback : public boost::noncopyable { private: @@ -1489,8 +1489,8 @@ const std::string& flatUri, const OrthancPluginHttpRequest& request) { - return callback_(reinterpret_cast(&output), - flatUri.c_str(), + return callback_(reinterpret_cast(&output), + flatUri.c_str(), &request); } @@ -1636,7 +1636,7 @@ } } }; - + std::unique_ptr<_OrthancPluginRegisterStorageCommitmentScpCallback> parameters_; std::unique_ptr<_OrthancPluginRegisterStorageCommitmentScpCallback2> parameters2_; @@ -1659,12 +1659,12 @@ const DicomConnectionInfo& connection) ORTHANC_OVERRIDE { const size_t n = sopClassUids.size(); - + if (sopInstanceUids.size() != n) { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + std::vector a, b; a.resize(n); b.resize(n); @@ -1699,7 +1699,7 @@ if (error != OrthancPluginErrorCode_Success) { - throw OrthancException(static_cast(error)); + throw OrthancException(static_cast(error)); } else if (handler == NULL) { @@ -1734,7 +1734,7 @@ size_t& refCount_; public: - explicit ServerContextReference(PImpl& that) : + explicit ServerContextReference(PImpl& that) : context_(that.context_), mutex_(that.contextMutex_), cond_(that.contextCond_), @@ -1847,9 +1847,9 @@ unsigned int maxDatabaseRetries_; // New in Orthanc 1.9.2 bool hasStorageAreaCustomData_; // New in Orthanc 1.12.8 - explicit PImpl(const std::string& databaseServerIdentifier) : + explicit PImpl(const std::string& databaseServerIdentifier) : contextRefCount_(0), - context_(NULL), + context_(NULL), findCallback_(NULL), findCallback2_(NULL), worklistCallback_(NULL), @@ -1864,7 +1864,7 @@ }; - + class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler { private: @@ -1913,13 +1913,13 @@ Json::Value target; call.ExecuteToJson(target, true); - + filtered_.reset(ParsedDicomFile::CreateFromJson(target, DicomFromJsonFlags_None, "" /* no private creator */)); currentQuery_ = filtered_.get(); } } - + matcher_.reset(new HierarchicalMatcher(*currentQuery_)); { @@ -2003,7 +2003,7 @@ } }; - + class OrthancPlugins::FindHandler : public IFindRequestHandler { private: @@ -2029,14 +2029,14 @@ DicomMap tmp; tmp.Assign(input); - for (std::list::const_iterator it = sequencesToReturn.begin(); + for (std::list::const_iterator it = sequencesToReturn.begin(); it != sequencesToReturn.end(); ++it) { if (!input.HasTag(*it)) { tmp.SetValue(*it, "", false); } - } + } { boost::mutex::scoped_lock lock(that_.pimpl_->findCallbackMutex_); @@ -2115,7 +2115,7 @@ } } }; - + class OrthancPlugins::MoveHandler : public IMoveRequestHandler @@ -2205,7 +2205,7 @@ return std::string(); } } - + public: @@ -2345,7 +2345,7 @@ size_t size = params_.requestChunkSize(params_.request); chunk.resize(size); - + if (size != 0) { const void* data = params_.requestChunkData(params_.request); @@ -2353,7 +2353,7 @@ } OrthancPluginErrorCode error = params_.requestNext(params_.request); - + if (error != OrthancPluginErrorCode_Success) { errorDictionary_.LogError(error, true); @@ -2386,19 +2386,19 @@ const std::string& value) ORTHANC_OVERRIDE { OrthancPluginErrorCode error = params_.answerAddHeader(params_.answer, key.c_str(), value.c_str()); - + if (error != OrthancPluginErrorCode_Success) { errorDictionary_.LogError(error, true); throw OrthancException(static_cast(error)); } } - + virtual void AddChunk(const void* data, size_t size) ORTHANC_OVERRIDE { OrthancPluginErrorCode error = params_.answerAddChunk(params_.answer, data, size); - + if (error != OrthancPluginErrorCode_Success) { errorDictionary_.LogError(error, true); @@ -2467,7 +2467,7 @@ pimpl_->manager_.RegisterServiceProvider(*this); } - + void OrthancPlugins::SetServerContext(ServerContext& context) { pimpl_->SetServerContext(&context); @@ -2479,23 +2479,23 @@ pimpl_->SetServerContext(NULL); } - + OrthancPlugins::~OrthancPlugins() { - for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); + for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); it != pimpl_->restCallbacks_.end(); ++it) { delete *it; } - for (PImpl::ChunkedRestCallbacks::iterator it = pimpl_->chunkedRestCallbacks_.begin(); + for (PImpl::ChunkedRestCallbacks::iterator it = pimpl_->chunkedRestCallbacks_.begin(); it != pimpl_->chunkedRestCallbacks_.end(); ++it) { delete *it; } for (PImpl::StorageCommitmentScpCallbacks::iterator - it = pimpl_->storageCommitmentScpCallbacks_.begin(); + it = pimpl_->storageCommitmentScpCallbacks_.begin(); it != pimpl_->storageCommitmentScpCallbacks_.end(); ++it) { delete *it; @@ -2522,7 +2522,7 @@ values.resize(arguments.size()); size_t pos = 0; - for (HttpToolbox::Arguments::const_iterator + for (HttpToolbox::Arguments::const_iterator it = arguments.begin(); it != arguments.end(); ++it) { keys[pos] = it->first.c_str(); @@ -2562,7 +2562,7 @@ std::string flatUri_; std::vector groups_; std::vector cgroups_; - + public: explicit RestCallbackMatcher(const UriComponents& uri) : flatUri_(Toolbox::FlattenUri(uri)) @@ -2667,7 +2667,7 @@ converted_.body = NULL; converted_.bodySize = 0; converted_.headersCount = headers.size(); - + if (headers.size() > 0) { converted_.headersKeys = &headersKeys_[0]; @@ -2720,7 +2720,7 @@ { s+= ","; } - + s += "POST"; } @@ -2730,7 +2730,7 @@ { s+= ","; } - + s += "DELETE"; } @@ -2740,7 +2740,7 @@ { s+= ","; } - + s += "PUT"; } @@ -2761,7 +2761,7 @@ // Loop over the callbacks registered by the plugins boost::shared_lock lock(pimpl_->restCallbackRegistrationMutex_); - for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); + for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); it != pimpl_->chunkedRestCallbacks_.end(); ++it) { if (matcher.IsMatch((*it)->GetRegularExpression())) @@ -2804,16 +2804,16 @@ { HttpRequestConverter converter(matcher, method, headers, authenticationPayload); converter.SetGetArguments(getArguments); - + PImpl::PluginHttpOutput pluginOutput(output); - + OrthancPluginErrorCode error = handler( - reinterpret_cast(&pluginOutput), + reinterpret_cast(&pluginOutput), matcher.GetFlatUri().c_str(), &converter.GetRequest()); - + pluginOutput.Close(error, GetErrorDictionary()); } - + return true; } } @@ -2837,7 +2837,7 @@ // Loop over the callbacks registered by the plugins boost::shared_lock lock(pimpl_->restCallbackRegistrationMutex_); - for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin(); + for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin(); it != pimpl_->restCallbacks_.end(); ++it) { if (matcher.IsMatch((*it)->GetRegularExpression())) @@ -2876,11 +2876,11 @@ const Json::Value& simplifiedTags) { DicomInstanceFromCallback wrapped(instance); - + boost::recursive_mutex::scoped_lock lock(pimpl_->storedCallbackMutex_); for (PImpl::OnStoredCallbacks::const_iterator - callback = pimpl_->onStoredCallbacks_.begin(); + callback = pimpl_->onStoredCallbacks_.begin(); callback != pimpl_->onStoredCallbacks_.end(); ++callback) { OrthancPluginErrorCode error = (*callback) ( @@ -2900,9 +2900,9 @@ const Json::Value& simplified) { DicomInstanceFromCallback wrapped(instance); - + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); - + for (PImpl::IncomingDicomInstanceFilters::const_iterator filter = pimpl_->incomingDicomInstanceFilters_.begin(); filter != pimpl_->incomingDicomInstanceFilters_.end(); ++filter) @@ -2930,9 +2930,9 @@ const Json::Value& simplified) { DicomInstanceFromCallback wrapped(instance); - + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); - + for (PImpl::IncomingCStoreInstanceFilters::const_iterator filter = pimpl_->incomingCStoreInstanceFilters_.begin(); filter != pimpl_->incomingCStoreInstanceFilters_.end(); ++filter) @@ -2992,8 +2992,8 @@ { boost::recursive_mutex::scoped_lock lock(pimpl_->changeCallbackMutex_); - for (std::list::const_iterator - callback = pimpl_->onChangeCallbacks_.begin(); + for (std::list::const_iterator + callback = pimpl_->onChangeCallbacks_.begin(); callback != pimpl_->onChangeCallbacks_.end(); ++callback) { OrthancPluginErrorCode error = (*callback) (changeType, resourceType, resource); @@ -3039,12 +3039,12 @@ void OrthancPlugins::RegisterRestCallback(const void* parameters, bool mutualExclusion) { - const _OrthancPluginRestCallback& p = + const _OrthancPluginRestCallback& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback " << (mutualExclusion ? "with" : "without") - << " mutual exclusion on: " + << " mutual exclusion on: " << p.pathRegularExpression; { @@ -3056,10 +3056,10 @@ void OrthancPlugins::RegisterChunkedRestCallback(const void* parameters) { - const _OrthancPluginChunkedRestCallback& p = + const _OrthancPluginChunkedRestCallback& p = *reinterpret_cast(parameters); - CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback for chunked streams on: " + CLOG(INFO, PLUGINS) << "Plugin has registered a REST callback for chunked streams on: " << p.pathRegularExpression; { @@ -3071,7 +3071,7 @@ void OrthancPlugins::RegisterOnStoredInstanceCallback(const void* parameters) { - const _OrthancPluginOnStoredInstanceCallback& p = + const _OrthancPluginOnStoredInstanceCallback& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin has registered an OnStoredInstance callback"; @@ -3083,7 +3083,7 @@ { boost::recursive_mutex::scoped_lock lock(pimpl_->changeCallbackMutex_); - const _OrthancPluginOnChangeCallback& p = + const _OrthancPluginOnChangeCallback& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin has registered an OnChange callback"; @@ -3093,7 +3093,7 @@ void OrthancPlugins::RegisterWorklistCallback(const void* parameters) { - const _OrthancPluginWorklistCallback& p = + const _OrthancPluginWorklistCallback& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->worklistCallbackMutex_); @@ -3114,7 +3114,7 @@ void OrthancPlugins::RegisterWorklistCallback2(const void* parameters) { - const _OrthancPluginWorklistCallback2& p = + const _OrthancPluginWorklistCallback2& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->worklistCallbackMutex_); @@ -3135,7 +3135,7 @@ void OrthancPlugins::RegisterFindCallback(const void* parameters) { - const _OrthancPluginFindCallback& p = + const _OrthancPluginFindCallback& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); @@ -3156,7 +3156,7 @@ void OrthancPlugins::RegisterFindCallback2(const void* parameters) { - const _OrthancPluginFindCallback2& p = + const _OrthancPluginFindCallback2& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); @@ -3179,7 +3179,7 @@ { // invokeServiceMutex_ is assumed to be locked - const _OrthancPluginMoveCallback& p = + const _OrthancPluginMoveCallback& p = *reinterpret_cast(parameters); if (pimpl_->moveCallbacks_.get() != NULL || @@ -3200,7 +3200,7 @@ { // invokeServiceMutex_ is assumed to be locked - const _OrthancPluginMoveCallback2& p = + const _OrthancPluginMoveCallback2& p = *reinterpret_cast(parameters); if (pimpl_->moveCallbacks_.get() != NULL || @@ -3219,50 +3219,50 @@ void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) { - const _OrthancPluginDecodeImageCallback& p = + const _OrthancPluginDecodeImageCallback& p = *reinterpret_cast(parameters); boost::unique_lock lock(pimpl_->decoderTranscoderMutex_); pimpl_->decodeImageCallbacks_.push_back(p.callback); - CLOG(INFO, PLUGINS) << "Plugin has registered a callback to decode DICOM images (" + CLOG(INFO, PLUGINS) << "Plugin has registered a callback to decode DICOM images (" << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)"; } void OrthancPlugins::RegisterTranscoderCallback(const void* parameters) { - const _OrthancPluginTranscoderCallback& p = + const _OrthancPluginTranscoderCallback& p = *reinterpret_cast(parameters); boost::unique_lock lock(pimpl_->decoderTranscoderMutex_); pimpl_->transcoderCallbacks_.push_back(p.callback); - CLOG(INFO, PLUGINS) << "Plugin has registered a callback to transcode DICOM images (" + CLOG(INFO, PLUGINS) << "Plugin has registered a callback to transcode DICOM images (" << pimpl_->transcoderCallbacks_.size() << " transcoder(s) now active)"; } void OrthancPlugins::RegisterJobsUnserializer(const void* parameters) { - const _OrthancPluginJobsUnserializer& p = + const _OrthancPluginJobsUnserializer& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->jobsUnserializersMutex_); pimpl_->jobsUnserializers_.push_back(p.unserializer); - CLOG(INFO, PLUGINS) << "Plugin has registered a callback to unserialize jobs (" + CLOG(INFO, PLUGINS) << "Plugin has registered a callback to unserialize jobs (" << pimpl_->jobsUnserializers_.size() << " unserializer(s) now active)"; } void OrthancPlugins::RegisterIncomingHttpRequestFilter(const void* parameters) { - const _OrthancPluginIncomingHttpRequestFilter& p = + const _OrthancPluginIncomingHttpRequestFilter& p = *reinterpret_cast(parameters); boost::unique_lock lock(pimpl_->incomingHttpRequestFilterMutex_); - + CLOG(INFO, PLUGINS) << "Plugin has registered a callback to filter incoming HTTP requests"; pimpl_->incomingHttpRequestFilters_.push_back(p.callback); } @@ -3270,11 +3270,11 @@ void OrthancPlugins::RegisterIncomingHttpRequestFilter2(const void* parameters) { - const _OrthancPluginIncomingHttpRequestFilter2& p = + const _OrthancPluginIncomingHttpRequestFilter2& p = *reinterpret_cast(parameters); boost::unique_lock lock(pimpl_->incomingHttpRequestFilterMutex_); - + CLOG(INFO, PLUGINS) << "Plugin has registered a callback to filter incoming HTTP requests"; pimpl_->incomingHttpRequestFilters2_.push_back(p.callback); } @@ -3282,7 +3282,7 @@ void OrthancPlugins::RegisterIncomingDicomInstanceFilter(const void* parameters) { - const _OrthancPluginIncomingDicomInstanceFilter& p = + const _OrthancPluginIncomingDicomInstanceFilter& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin has registered a callback to filter incoming DICOM instances"; @@ -3292,7 +3292,7 @@ void OrthancPlugins::RegisterIncomingCStoreInstanceFilter(const void* parameters) { - const _OrthancPluginIncomingCStoreInstanceFilter& p = + const _OrthancPluginIncomingCStoreInstanceFilter& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin has registered a callback to filter incoming C-Store DICOM instances"; @@ -3301,7 +3301,7 @@ void OrthancPlugins::RegisterReceivedInstanceCallback(const void* parameters) { - const _OrthancPluginReceivedInstanceCallback& p = + const _OrthancPluginReceivedInstanceCallback& p = *reinterpret_cast(parameters); if (pimpl_->receivedInstanceCallback_ != NULL) @@ -3318,7 +3318,7 @@ void OrthancPlugins::RegisterRefreshMetricsCallback(const void* parameters) { - const _OrthancPluginRegisterRefreshMetricsCallback& p = + const _OrthancPluginRegisterRefreshMetricsCallback& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->refreshMetricsMutex_); @@ -3330,7 +3330,7 @@ void OrthancPlugins::RegisterStorageCommitmentScpCallback(const void* parameters) { - const _OrthancPluginRegisterStorageCommitmentScpCallback& p = + const _OrthancPluginRegisterStorageCommitmentScpCallback& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->storageCommitmentScpMutex_); @@ -3342,7 +3342,7 @@ void OrthancPlugins::RegisterStorageCommitmentScpCallback2(const void* parameters) { - const _OrthancPluginRegisterStorageCommitmentScpCallback2& p = + const _OrthancPluginRegisterStorageCommitmentScpCallback2& p = *reinterpret_cast(parameters); boost::mutex::scoped_lock lock(pimpl_->storageCommitmentScpMutex_); @@ -3374,7 +3374,7 @@ void OrthancPlugins::RegisterAuditLogHandler(const void* parameters) { - const _OrthancPluginAuditLogHandler& p = + const _OrthancPluginAuditLogHandler& p = *reinterpret_cast(parameters); boost::unique_lock lock(pimpl_->auditLogHandlersMutex_); @@ -3386,7 +3386,7 @@ void OrthancPlugins::AnswerBuffer(const void* parameters) { - const _OrthancPluginAnswerBuffer& p = + const _OrthancPluginAnswerBuffer& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3397,7 +3397,7 @@ void OrthancPlugins::Redirect(const void* parameters) { - const _OrthancPluginOutputPlusArgument& p = + const _OrthancPluginOutputPlusArgument& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3407,7 +3407,7 @@ void OrthancPlugins::SendHttpStatusCode(const void* parameters) { - const _OrthancPluginSendHttpStatusCode& p = + const _OrthancPluginSendHttpStatusCode& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3417,7 +3417,7 @@ void OrthancPlugins::SendHttpStatus(const void* parameters) { - const _OrthancPluginSendHttpStatus& p = + const _OrthancPluginSendHttpStatus& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3436,7 +3436,7 @@ void OrthancPlugins::SendUnauthorized(const void* parameters) { - const _OrthancPluginOutputPlusArgument& p = + const _OrthancPluginOutputPlusArgument& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3446,7 +3446,7 @@ void OrthancPlugins::SendMethodNotAllowed(const void* parameters) { - const _OrthancPluginOutputPlusArgument& p = + const _OrthancPluginOutputPlusArgument& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3456,7 +3456,7 @@ void OrthancPlugins::SetCookie(const void* parameters) { - const _OrthancPluginSetHttpHeader& p = + const _OrthancPluginSetHttpHeader& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3466,7 +3466,7 @@ void OrthancPlugins::SetHttpHeader(const void* parameters) { - const _OrthancPluginSetHttpHeader& p = + const _OrthancPluginSetHttpHeader& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3476,7 +3476,7 @@ void OrthancPlugins::SetHttpErrorDetails(const void* parameters) { - const _OrthancPluginSetHttpErrorDetails& p = + const _OrthancPluginSetHttpErrorDetails& p = *reinterpret_cast(parameters); PImpl::PluginHttpOutput* output = @@ -3488,7 +3488,7 @@ void OrthancPlugins::CompressAndAnswerPngImage(const void* parameters) { // Bridge for backward compatibility with Orthanc <= 0.9.3 - const _OrthancPluginCompressAndAnswerPngImage& p = + const _OrthancPluginCompressAndAnswerPngImage& p = *reinterpret_cast(parameters); _OrthancPluginCompressAndAnswerImage p2; @@ -3507,7 +3507,7 @@ void OrthancPlugins::CompressAndAnswerImage(const void* parameters) { - const _OrthancPluginCompressAndAnswerImage& p = + const _OrthancPluginCompressAndAnswerImage& p = *reinterpret_cast(parameters); HttpOutput& translatedOutput = reinterpret_cast(p.output)->GetOutput(); @@ -3546,7 +3546,7 @@ void OrthancPlugins::GetDicomForInstance(const void* parameters) { - const _OrthancPluginGetDicomForInstance& p = + const _OrthancPluginGetDicomForInstance& p = *reinterpret_cast(parameters); std::unique_ptr raw; @@ -3588,9 +3588,9 @@ void OrthancPlugins::RestApiGet(const void* parameters, bool afterPlugins) { - const _OrthancPluginRestApiGet& p = + const _OrthancPluginRestApiGet& p = *reinterpret_cast(parameters); - + CLOG(INFO, PLUGINS) << "Plugin making REST GET call on URI " << p.uri << (afterPlugins ? " (after plugins)" : " (built-in API)"); @@ -3612,9 +3612,9 @@ void OrthancPlugins::RestApiGet2(const void* parameters) { - const _OrthancPluginRestApiGet2& p = + const _OrthancPluginRestApiGet2& p = *reinterpret_cast(parameters); - + CLOG(INFO, PLUGINS) << "Plugin making REST GET call on URI " << p.uri << (p.afterPlugins ? " (after plugins)" : " (built-in API)"); @@ -3633,7 +3633,7 @@ PImpl::ServerContextReference lock(*pimpl_); handler = &lock.GetContext().GetHttpHandler().RestrictToOrthancRestApi(!p.afterPlugins); } - + std::string result; ThrowOnHttpError(IHttpHandler::SimpleGet(result, NULL, *handler, RequestOrigin_Plugins, p.uri, headers)); @@ -3641,11 +3641,11 @@ } - void OrthancPlugins::RestApiPostPut(bool isPost, + void OrthancPlugins::RestApiPostPut(bool isPost, const void* parameters, bool afterPlugins) { - const _OrthancPluginRestApiPostPut& p = + const _OrthancPluginRestApiPostPut& p = *reinterpret_cast(parameters); CLOG(INFO, PLUGINS) << "Plugin making REST " << EnumerationToString(isPost ? HttpMethod_Post : HttpMethod_Put) @@ -3657,12 +3657,12 @@ PImpl::ServerContextReference lock(*pimpl_); handler = &lock.GetContext().GetHttpHandler().RestrictToOrthancRestApi(!afterPlugins); } - + std::map httpHeaders; std::string result; - - ThrowOnHttpError((isPost ? + + ThrowOnHttpError((isPost ? IHttpHandler::SimplePost(result, NULL, *handler, RequestOrigin_Plugins, p.uri, p.body, p.bodySize, httpHeaders) : IHttpHandler::SimplePut(result, NULL, *handler, RequestOrigin_Plugins, p.uri, @@ -3684,7 +3684,7 @@ PImpl::ServerContextReference lock(*pimpl_); handler = &lock.GetContext().GetHttpHandler().RestrictToOrthancRestApi(!afterPlugins); } - + std::map httpHeaders; std::string bodyIgnored; @@ -3695,7 +3695,7 @@ void OrthancPlugins::LookupResource(_OrthancPluginService service, const void* parameters) { - const _OrthancPluginRetrieveDynamicString& p = + const _OrthancPluginRetrieveDynamicString& p = *reinterpret_cast(parameters); /** @@ -3756,7 +3756,7 @@ LOG(WARNING) << "LookupResource(): Multiple resources match the query (instead of 0 or 1), which indicates " << "your DICOM database breaks the DICOM model of the real world"; } - + throw OrthancException(ErrorCode_UnknownResource); } } @@ -3787,7 +3787,7 @@ return; } - ServerIndex::MetadataMap::const_iterator it = + ServerIndex::MetadataMap::const_iterator it = instance.GetMetadata().find(std::make_pair(ResourceType_Instance, metadata)); if (checkExistence) @@ -3804,7 +3804,7 @@ else { if (it != instance.GetMetadata().end()) - { + { *params.resultString = it->second.c_str(); } else @@ -3819,7 +3819,7 @@ void OrthancPlugins::AccessDicomInstance(_OrthancPluginService service, const void* parameters) { - const _OrthancPluginAccessDicomInstance& p = + const _OrthancPluginAccessDicomInstance& p = *reinterpret_cast(parameters); if (p.instance == NULL) @@ -3858,7 +3858,7 @@ Json::Value dicomAsJson; std::set ignoreTagLength; instance.GetDicomAsJson(dicomAsJson, ignoreTagLength); - + std::string s; if (service == _OrthancPluginService_GetInstanceJson) { @@ -3890,7 +3890,7 @@ { *p.resultStringToFree = CopyString(""); } - + return; } @@ -3901,7 +3901,7 @@ case _OrthancPluginService_GetInstanceFramesCount: // New in Orthanc 1.7.0 *p.resultInt64 = instance.GetFramesCount(); return; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -3910,7 +3910,7 @@ void OrthancPlugins::BufferCompression(const void* parameters) { - const _OrthancPluginBufferCompression& p = + const _OrthancPluginBufferCompression& p = *reinterpret_cast(parameters); std::string result; @@ -3981,7 +3981,7 @@ { throw OrthancException(ErrorCode_NullPointer); } - + if (image->IsReadOnly()) { std::unique_ptr copy(new Image(image->GetFormat(), image->GetWidth(), image->GetHeight(), false)); @@ -3999,7 +3999,7 @@ void OrthancPlugins::AccessDicomInstance2(_OrthancPluginService service, const void* parameters) { - const _OrthancPluginAccessDicomInstance2& p = + const _OrthancPluginAccessDicomInstance2& p = *reinterpret_cast(parameters); if (p.instance == NULL) @@ -4015,7 +4015,7 @@ case _OrthancPluginService_GetInstanceFramesCount: *p.targetUint32 = instance.GetFramesCount(); return; - + case _OrthancPluginService_GetInstanceRawFrame: { if (p.targetBuffer == NULL) @@ -4025,14 +4025,14 @@ p.targetBuffer->data = NULL; p.targetBuffer->size = 0; - + MimeType mime; std::string frame; instance.GetParsedDicomFile().GetRawFrame(frame, mime, p.frameIndex); CopyToMemoryBuffer(p.targetBuffer, frame); return; } - + case _OrthancPluginService_GetInstanceDecodedFrame: { if (p.targetImage == NULL) @@ -4045,11 +4045,11 @@ PImpl::ServerContextReference lock(*pimpl_); decoded.reset(lock.GetContext().GetTranscoder()->DecodeFrame(instance, p.frameIndex)); } - + *(p.targetImage) = ReturnImage(decoded); return; } - + case _OrthancPluginService_SerializeDicomInstance: { if (p.targetBuffer == NULL) @@ -4069,17 +4069,17 @@ { throw OrthancException(ErrorCode_NullPointer); } - + Json::Value json; - instance.DatasetToJson(json, Plugins::Convert(p.format), + instance.DatasetToJson(json, Plugins::Convert(p.format), static_cast(p.flags), p.maxStringLength); std::string s; Toolbox::WriteFastJson(s, json); - *p.targetStringToFree = CopyString(s); + *p.targetStringToFree = CopyString(s); return; } - + case _OrthancPluginService_GetInstanceDicomWebJson: case _OrthancPluginService_GetInstanceDicomWebXml: { @@ -4104,7 +4104,7 @@ void OrthancPlugins::AccessDicomConnection(_OrthancPluginService service, const void* parameters) { - const _OrthancPluginAccessDicomConnection& p = + const _OrthancPluginAccessDicomConnection& p = *reinterpret_cast(parameters); if (p.connection == NULL) @@ -4221,7 +4221,7 @@ client.SetTimeout(parameters.timeout); } - if (parameters.username != NULL && + if (parameters.username != NULL && parameters.password != NULL) { client.SetCredentials(parameters.username, parameters.password); @@ -4336,7 +4336,7 @@ HttpClient client; - { + { _OrthancPluginCallHttpClient2 converted; memset(&converted, 0, sizeof(converted)); @@ -4369,7 +4369,7 @@ void OrthancPlugins::CallHttpClient2(const void* parameters) { const _OrthancPluginCallHttpClient2& p = *reinterpret_cast(parameters); - + if (p.httpStatus == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -4382,7 +4382,7 @@ { client.SetExternalBody(p.body, p.bodySize); } - + SetupHttpClient(client, p); ExecuteHttpClientWithoutChunkedBody(*p.httpStatus, p.answerBody, p.answerHeaders, client); } @@ -4392,7 +4392,7 @@ { const _OrthancPluginChunkedHttpClient& p = *reinterpret_cast(parameters); - + if (p.httpStatus == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -4424,7 +4424,7 @@ SetupHttpClient(client, converted); } - + HttpClientChunkedRequest body(p, pimpl_->dictionary_); client.SetBody(body); @@ -4444,7 +4444,7 @@ void OrthancPlugins::CallRestApi(const void* parameters) { const _OrthancPluginCallRestApi& p = *reinterpret_cast(parameters); - + if (p.httpStatus == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -4491,7 +4491,7 @@ PImpl::ServerContextReference lock(*pimpl_); handler = &lock.GetContext().GetHttpHandler().RestrictToOrthancRestApi(!p.afterPlugins); } - + std::string answerBody; std::map answerHeaders; HttpStatus status; @@ -4717,14 +4717,14 @@ } Json::Value json; - dicom->DatasetToJson(json, Plugins::Convert(p.format), + dicom->DatasetToJson(json, Plugins::Convert(p.format), static_cast(p.flags), p.maxStringLength); std::string s; Toolbox::WriteFastJson(s, json); *p.result = CopyString(s); } - + void OrthancPlugins::ApplyCreateDicom(const _OrthancPluginCreateDicom& parameters, const char* privateCreatorC) @@ -4758,7 +4758,7 @@ // New in Orthanc 1.9.0 privateCreator.assign(privateCreatorC); } - + std::unique_ptr file (ParsedDicomFile::CreateFromJson(json, static_cast(parameters.flags), privateCreator)); @@ -4780,7 +4780,7 @@ { const _OrthancPluginComputeHash& p = *reinterpret_cast(parameters); - + std::string hash; switch (service) { @@ -4795,7 +4795,7 @@ default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + *p.result = CopyString(hash); } @@ -4806,12 +4806,12 @@ *reinterpret_cast(parameters); std::string privateCreator; - + if (p.privateCreator != NULL) { privateCreator = p.privateCreator; } - + DicomTag tag(p.group, p.element); *p.result = CopyString(FromDcmtkBridge::GetTagName(tag, privateCreator)); } @@ -4874,13 +4874,13 @@ // connection was closed by the HTTP client. const _OrthancPluginSendMultipartItem2& p = *reinterpret_cast(parameters); - + std::map headers; for (uint32_t i = 0; i < p.headersCount; i++) { headers[p.headersKeys[i]] = p.headersValues[i]; } - + reinterpret_cast(p.output)->SendMultipartItem(p.answer, p.answerSize, headers); } @@ -5134,7 +5134,7 @@ void OrthancPlugins::ApplyLoadDicomInstance(const _OrthancPluginLoadDicomInstance& params) { std::unique_ptr target; - + switch (params.mode) { case OrthancPluginLoadDicomInstanceMode_WholeDicom: @@ -5149,7 +5149,7 @@ target.reset(new DicomInstanceFromBuffer(raw->GetData(), raw->GetSize())); break; } - + case OrthancPluginLoadDicomInstanceMode_UntilPixelData: case OrthancPluginLoadDicomInstanceMode_EmptyPixelData: { @@ -5214,7 +5214,7 @@ target.reset(new DicomInstanceFromParsed(parsed.release())); break; } - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -5226,9 +5226,9 @@ else { *params.target = reinterpret_cast(target.release()); - } - } - + } + } + void OrthancPlugins::DatabaseAnswer(const void* parameters) { @@ -5469,7 +5469,7 @@ case _OrthancPluginService_SetGlobalProperty: { - const _OrthancPluginGlobalProperty& p = + const _OrthancPluginGlobalProperty& p = *reinterpret_cast(parameters); if (p.property < 1024) { @@ -5488,7 +5488,7 @@ case _OrthancPluginService_GetGlobalProperty: { - const _OrthancPluginGlobalProperty& p = + const _OrthancPluginGlobalProperty& p = *reinterpret_cast(parameters); std::string result; @@ -5775,7 +5775,7 @@ case _OrthancPluginService_GenerateUuid: { - *reinterpret_cast(parameters)->result = + *reinterpret_cast(parameters)->result = CopyString(Toolbox::GenerateUuid()); return true; } @@ -5836,7 +5836,7 @@ { delete reinterpret_cast(p.peers); } - + return true; } @@ -5900,7 +5900,7 @@ } else { - const WebServiceParameters::Dictionary& properties = + const WebServiceParameters::Dictionary& properties = reinterpret_cast(p.peers)->GetPeerParameters(p.peerIndex).GetUserProperties(); WebServiceParameters::Dictionary::const_iterator found = @@ -5962,7 +5962,7 @@ PImpl::ServerContextReference lock(*pimpl_); lock.GetContext().GetJobsEngine().GetRegistry().Submit (uuid, reinterpret_cast(p.job), p.priority); - + *p.resultId = CopyString(uuid); return true; @@ -6040,7 +6040,7 @@ new DicomInstanceFromBuffer(p.buffer, p.size)); return true; } - + case _OrthancPluginService_FreeDicomInstance: { const _OrthancPluginFreeDicomInstance& p = @@ -6049,7 +6049,7 @@ if (p.dicom != NULL) { IDicomInstance* obj = reinterpret_cast(p.dicom); - + if (obj->CanBeFreed()) { delete obj; @@ -6127,7 +6127,7 @@ return true; } - + case _OrthancPluginService_RegisterIncomingHttpRequestFilter: RegisterIncomingHttpRequestFilter(parameters); return true; @@ -6299,7 +6299,7 @@ // Services that must be run in mutual exclusion. Guideline: // Whenever "pimpl_" is directly accessed by the service, it // should be listed here. - + switch (service) { case _OrthancPluginService_RegisterRestCallback: @@ -6399,8 +6399,8 @@ if (service == _OrthancPluginService_RegisterStorageArea) { CLOG(INFO, PLUGINS) << "Plugin has registered a custom storage area (v1)"; - - const _OrthancPluginRegisterStorageArea& p = + + const _OrthancPluginRegisterStorageArea& p = *reinterpret_cast(parameters); pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); } @@ -6408,7 +6408,7 @@ { CLOG(INFO, PLUGINS) << "Plugin has registered a custom storage area (v2)"; - const _OrthancPluginRegisterStorageArea2& p = + const _OrthancPluginRegisterStorageArea2& p = *reinterpret_cast(parameters); pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); } @@ -6416,7 +6416,7 @@ { CLOG(INFO, PLUGINS) << "Plugin has registered a custom storage area (v3)"; - const _OrthancPluginRegisterStorageArea3& p = + const _OrthancPluginRegisterStorageArea3& p = *reinterpret_cast(parameters); pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); pimpl_->hasStorageAreaCustomData_ = true; @@ -6436,7 +6436,7 @@ case _OrthancPluginService_SetPluginProperty: { - const _OrthancPluginSetPluginProperty& p = + const _OrthancPluginSetPluginProperty& p = *reinterpret_cast(parameters); pimpl_->properties_[std::make_pair(p.plugin, p.property)] = p.value; return true; @@ -6454,7 +6454,7 @@ { const _OrthancPluginGlobalProperty& p = *reinterpret_cast(parameters); - + if (p.property + 1 > static_cast(pimpl_->arguments_.size())) { return false; @@ -6478,7 +6478,7 @@ pimpl_->databaseV3_.get() == NULL && pimpl_->databaseV4_.get() == NULL) { - pimpl_->database_.reset(new OrthancPluginDatabase(plugin, GetErrorDictionary(), + pimpl_->database_.reset(new OrthancPluginDatabase(plugin, GetErrorDictionary(), *p.backend, NULL, 0, p.payload)); } else @@ -6605,7 +6605,7 @@ } VoidDatabaseListener listener; - + { IPluginStorageArea& storage = *reinterpret_cast(p.storageArea); @@ -6620,7 +6620,7 @@ case _OrthancPluginService_GenerateRestApiAuthorizationToken: { - const _OrthancPluginRetrieveDynamicString& p = + const _OrthancPluginRetrieveDynamicString& p = *reinterpret_cast(parameters); const std::string token = Toolbox::GenerateUuid(); @@ -6696,7 +6696,7 @@ boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); return pimpl_->storageArea_.get() != NULL; } - + bool OrthancPlugins::HasDatabaseBackend() const { boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); @@ -6920,7 +6920,7 @@ return NULL; } - + bool OrthancPlugins::IsAllowed(HttpMethod method, const char* uri, const char* ip, @@ -6952,7 +6952,7 @@ { boost::shared_lock lock(pimpl_->incomingHttpRequestFilterMutex_); - + // Improved callback with support for GET arguments, since Orthanc 1.3.0 for (PImpl::IncomingHttpRequestFilters2::const_iterator filter = pimpl_->incomingHttpRequestFilters2_.begin(); @@ -7008,7 +7008,7 @@ boost::mutex::scoped_lock lock(pimpl_->jobsUnserializersMutex_); - for (PImpl::JobsUnserializers::iterator + for (PImpl::JobsUnserializers::iterator unserializer = pimpl_->jobsUnserializers_.begin(); unserializer != pimpl_->jobsUnserializers_.end(); ++unserializer) { @@ -7027,7 +7027,7 @@ { boost::mutex::scoped_lock lock(pimpl_->refreshMetricsMutex_); - for (PImpl::RefreshMetricsCallbacks::iterator + for (PImpl::RefreshMetricsCallbacks::iterator it = pimpl_->refreshMetricsCallbacks_.begin(); it != pimpl_->refreshMetricsCallbacks_.end(); ++it) { @@ -7073,8 +7073,8 @@ assert(reader_ != NULL); parameters_.addChunk(reader_, data, size); - } - + } + virtual void Execute(HttpOutput& output) ORTHANC_OVERRIDE { assert(reader_ != NULL); @@ -7110,7 +7110,7 @@ // Loop over the callbacks registered by the plugins boost::shared_lock lock(pimpl_->restCallbackRegistrationMutex_); - for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); + for (PImpl::ChunkedRestCallbacks::const_iterator it = pimpl_->chunkedRestCallbacks_.begin(); it != pimpl_->chunkedRestCallbacks_.end(); ++it) { if (matcher.IsMatch((*it)->GetRegularExpression())) @@ -7157,10 +7157,10 @@ converter.GetRequest().bodySize = 0; OrthancPluginServerChunkedRequestReader* reader = NULL; - + OrthancPluginErrorCode errorCode = handler( &reader, matcher.GetFlatUri().c_str(), &converter.GetRequest()); - + if (errorCode != OrthancPluginErrorCode_Success) { throw OrthancException(static_cast(errorCode)); @@ -7190,7 +7190,7 @@ boost::mutex::scoped_lock lock(pimpl_->storageCommitmentScpMutex_); for (PImpl::StorageCommitmentScpCallbacks::iterator - it = pimpl_->storageCommitmentScpCallbacks_.begin(); + it = pimpl_->storageCommitmentScpCallbacks_.begin(); it != pimpl_->storageCommitmentScpCallbacks_.end(); ++it) { assert(*it != NULL); @@ -7201,8 +7201,8 @@ { return handler; } - } - + } + return NULL; } @@ -7227,7 +7227,7 @@ { uids.push_back(GetTransferSyntaxUid(*it)); } - + for (PImpl::TranscoderCallbacks::const_iterator transcoder = pimpl_->transcoderCallbacks_.begin(); transcoder != pimpl_->transcoderCallbacks_.end(); ++transcoder) @@ -7253,7 +7253,7 @@ return (pimpl_->authorizationTokens_.find(token) != pimpl_->authorizationTokens_.end()); } - + unsigned int OrthancPlugins::GetMaxDatabaseRetries() const { boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); @@ -7273,7 +7273,7 @@ UriComponents components; Toolbox::SplitUriComponents(components, collection->GetUri()); target.Register(components, collection); - + pimpl_->webDavCollections_.pop_front(); } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/OrthancPlugins.h --- a/OrthancServer/Plugins/Engine/OrthancPlugins.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -67,9 +67,9 @@ class ServerContext; class OutgoingDicomInstance; - class OrthancPlugins : - public IHttpHandler, - public IPluginServiceProvider, + class OrthancPlugins : + public IHttpHandler, + public IPluginServiceProvider, public IServerListener, public IWorklistRequestHandlerFactory, public IFindRequestHandlerFactory, @@ -165,7 +165,7 @@ void RestApiGet2(const void* parameters); - void RestApiPostPut(bool isPost, + void RestApiPostPut(bool isPost, const void* parameters, bool afterPlugins); @@ -177,7 +177,7 @@ void AccessDicomInstance(_OrthancPluginService service, const void* parameters); - + void AccessDicomInstance2(_OrthancPluginService service, const void* parameters); @@ -215,7 +215,7 @@ void CallRestApi(const void* parameters); static void CallPeerApi(const void* parameters); - + static void GetFontInfo(const void* parameters); static void DrawText(const void* parameters); @@ -291,7 +291,7 @@ size_t size, const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; - + public: explicit OrthancPlugins(const std::string& databaseServerIdentifier); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp --- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h --- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginMemoryBuffer64.cpp --- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer64.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer64.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginMemoryBuffer64.h --- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer64.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer64.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsEnumerations.cpp --- a/OrthancServer/Plugins/Engine/PluginsEnumerations.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsEnumerations.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -512,7 +512,7 @@ case ValueRepresentation_Unknown: return OrthancPluginValueRepresentation_UN; // Unknown - case ValueRepresentation_OtherDouble: + case ValueRepresentation_OtherDouble: return OrthancPluginValueRepresentation_OD; case ValueRepresentation_OtherLong: @@ -545,13 +545,13 @@ { case JobStepCode_Success: return OrthancPluginJobStepStatus_Success; - + case JobStepCode_Failure: return OrthancPluginJobStepStatus_Failure; - + case JobStepCode_Continue: return OrthancPluginJobStepStatus_Continue; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -563,13 +563,13 @@ { case OrthancPluginJobStepStatus_Success: return JobStepCode_Success; - + case OrthancPluginJobStepStatus_Failure: return JobStepCode_Failure; - + case OrthancPluginJobStepStatus_Continue: return JobStepCode_Continue; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -582,7 +582,7 @@ { case OrthancPluginStorageCommitmentFailureReason_Success: return StorageCommitmentFailureReason_Success; - + case OrthancPluginStorageCommitmentFailureReason_ProcessingFailure: return StorageCommitmentFailureReason_ProcessingFailure; @@ -600,7 +600,7 @@ case OrthancPluginStorageCommitmentFailureReason_DuplicateTransactionUID: return StorageCommitmentFailureReason_DuplicateTransactionUID; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsEnumerations.h --- a/OrthancServer/Plugins/Engine/PluginsEnumerations.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsEnumerations.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsErrorDictionary.cpp --- a/OrthancServer/Plugins/Engine/PluginsErrorDictionary.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsErrorDictionary.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -39,7 +39,7 @@ namespace Orthanc { - PluginsErrorDictionary::PluginsErrorDictionary() : + PluginsErrorDictionary::PluginsErrorDictionary() : pos_(ErrorCode_START_PLUGINS) { } @@ -86,7 +86,7 @@ { boost::mutex::scoped_lock lock(mutex_); Errors::const_iterator error = errors_.find(static_cast(code)); - + if (error != errors_.end()) { LOG(ERROR) << "Error code " << error->second->pluginCode_ @@ -112,7 +112,7 @@ { boost::mutex::scoped_lock lock(mutex_); Errors::const_iterator error = errors_.find(static_cast(exception.GetErrorCode())); - + if (error != errors_.end()) { httpStatus = error->second->httpStatus_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsErrorDictionary.h --- a/OrthancServer/Plugins/Engine/PluginsErrorDictionary.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsErrorDictionary.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -48,7 +48,7 @@ HttpStatus httpStatus_; std::string message_; }; - + typedef std::map Errors; boost::mutex mutex_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsJob.cpp --- a/OrthancServer/Plugins/Engine/PluginsJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -44,7 +44,7 @@ { throw OrthancException(ErrorCode_NullPointer); } - + if (parameters_.target == NULL || parameters_.finalize == NULL || parameters_.type == NULL || @@ -59,13 +59,13 @@ { parameters_.finalize(parameters_.job); } - + throw OrthancException(ErrorCode_NullPointer); } type_.assign(parameters_.type); } - + PluginsJob::PluginsJob(const _OrthancPluginCreateJob2& parameters) : parameters_(parameters), deprecatedGetContent_(NULL), @@ -92,7 +92,7 @@ deprecatedGetContent_ = parameters.getContent; deprecatedGetSerialized_ = parameters.getSerialized; - + Setup(); } @@ -216,7 +216,7 @@ target.ToJsonObject(value); static const char* KEY_TYPE = "Type"; - + if (value.isMember(KEY_TYPE)) { throw OrthancException(ErrorCode_Plugin, @@ -247,7 +247,7 @@ static const char* KEY_TYPE = "Type"; - + if (value.isMember(KEY_TYPE)) { throw OrthancException(ErrorCode_Plugin, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsJob.h --- a/OrthancServer/Plugins/Engine/PluginsJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -52,7 +52,7 @@ virtual void Start() ORTHANC_OVERRIDE { } - + virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE; virtual void Reset() ORTHANC_OVERRIDE; @@ -65,7 +65,7 @@ { target = type_; } - + virtual void GetPublicContent(Json::Value& value) const ORTHANC_OVERRIDE; virtual bool Serialize(Json::Value& value) const ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsManager.cpp --- a/OrthancServer/Plugins/Engine/PluginsManager.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsManager.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -52,7 +52,7 @@ namespace Orthanc { PluginsManager::Plugin::Plugin(PluginsManager& pluginManager, - const boost::filesystem::path& path) : + const boost::filesystem::path& path) : library_(path), pluginManager_(pluginManager) { @@ -146,7 +146,7 @@ OrthancPluginErrorCode PluginsManager::InvokeService(OrthancPluginContext* context, - _OrthancPluginService service, + _OrthancPluginService service, const void* params) { switch (service) @@ -166,11 +166,11 @@ case _OrthancPluginService_LogMessage: { const _OrthancPluginLogMessage& m = *reinterpret_cast(params); - // We can convert directly from OrthancPluginLogLevel to LogLevel (and category) because the enum values must be identical + // We can convert directly from OrthancPluginLogLevel to LogLevel (and category) because the enum values must be identical // for Orthanc::Logging to work both in the core and in the plugins Orthanc::Logging::LogLevel level = static_cast(m.level); Orthanc::Logging::LogCategory category = static_cast(m.category); - + LOG_FROM_PLUGIN(level, category, m.plugin, m.file, m.line) << m.message; return OrthancPluginErrorCode_Success; } @@ -182,7 +182,7 @@ Plugin* that = reinterpret_cast(context->pluginsManager); for (std::list::iterator - it = that->GetPluginManager().serviceProviders_.begin(); + it = that->GetPluginManager().serviceProviders_.begin(); it != that->GetPluginManager().serviceProviders_.end(); ++it) { try @@ -240,7 +240,7 @@ library.HasFunction("OrthancPluginGetVersion")); } - + void PluginsManager::RegisterPlugin(const boost::filesystem::path& path) { if (!boost::filesystem::exists(path)) @@ -249,12 +249,12 @@ Toolbox::ToLowerCase(extension); if (extension == PLUGIN_EXTENSION) - { + { // if this is a plugin path, fail to start throw OrthancException(ErrorCode_SharedLibrary, "Inexistent path to plugin: " + SystemToolbox::PathToUtf8(path)); } else - { + { // it might be a directory -> just log a warning LOG(WARNING) << "Inexistent path to plugins: " << SystemToolbox::PathToUtf8(path); return; @@ -343,7 +343,7 @@ { result.clear(); - for (Plugins::const_iterator it = plugins_.begin(); + for (Plugins::const_iterator it = plugins_.begin(); it != plugins_.end(); ++it) { result.push_back(it->first); @@ -370,7 +370,7 @@ } } - + std::string PluginsManager::GetPluginName(SharedLibrary& library) { return CallGetName(library); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Engine/PluginsManager.h --- a/OrthancServer/Plugins/Engine/PluginsManager.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Engine/PluginsManager.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h --- a/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Wed Aug 19 14:11:33 2026 +0200 @@ -14,7 +14,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -178,7 +178,7 @@ uint16_t element; const char* value; } OrthancPluginResourcesContentTags; - + typedef struct /* New in Orthanc 1.5.2 */ { int64_t resource; @@ -424,45 +424,45 @@ void* payload, int64_t id, const OrthancPluginAttachment* attachment); - + OrthancPluginErrorCode (*attachChild) ( /* inputs */ void* payload, int64_t parent, int64_t child); - + OrthancPluginErrorCode (*clearChanges) ( /* inputs */ void* payload); - + OrthancPluginErrorCode (*clearExportedResources) ( /* inputs */ void* payload); OrthancPluginErrorCode (*createResource) ( /* outputs */ - int64_t* id, + int64_t* id, /* inputs */ void* payload, const char* publicId, - OrthancPluginResourceType resourceType); - + OrthancPluginResourceType resourceType); + OrthancPluginErrorCode (*deleteAttachment) ( /* inputs */ void* payload, int64_t id, int32_t contentType); - + OrthancPluginErrorCode (*deleteMetadata) ( /* inputs */ void* payload, int64_t id, int32_t metadataType); - + OrthancPluginErrorCode (*deleteResource) ( /* inputs */ void* payload, - int64_t id); + int64_t id); /* Output: Use OrthancPluginDatabaseAnswerString() */ OrthancPluginErrorCode (*getAllPublicIds) ( @@ -489,7 +489,7 @@ /* inputs */ void* payload, int64_t id); - + /* Output: Use OrthancPluginDatabaseAnswerString() */ OrthancPluginErrorCode (*getChildrenPublicId) ( /* outputs */ @@ -507,7 +507,7 @@ void* payload, int64_t since, uint32_t maxResult); - + /* Output: Use OrthancPluginDatabaseAnswerChange() */ OrthancPluginErrorCode (*getLastChange) ( /* outputs */ @@ -521,7 +521,7 @@ OrthancPluginDatabaseContext* context, /* inputs */ void* payload); - + /* Output: Use OrthancPluginDatabaseAnswerDicomTag() */ OrthancPluginErrorCode (*getMainDicomTags) ( /* outputs */ @@ -529,7 +529,7 @@ /* inputs */ void* payload, int64_t id); - + /* Output: Use OrthancPluginDatabaseAnswerString() */ OrthancPluginErrorCode (*getPublicId) ( /* outputs */ @@ -544,7 +544,7 @@ /* inputs */ void* payload, OrthancPluginResourceType resourceType); - + OrthancPluginErrorCode (*getResourceType) ( /* outputs */ OrthancPluginResourceType* resourceType, @@ -557,13 +557,13 @@ uint64_t* target, /* inputs */ void* payload); - + OrthancPluginErrorCode (*getTotalUncompressedSize) ( /* outputs */ uint64_t* target, /* inputs */ void* payload); - + OrthancPluginErrorCode (*isExistingResource) ( /* outputs */ int32_t* existing, @@ -585,7 +585,7 @@ /* inputs */ void* payload, int64_t id); - + /* Output: Use OrthancPluginDatabaseAnswerInt32() */ OrthancPluginErrorCode (*listAvailableAttachments) ( /* outputs */ @@ -598,12 +598,12 @@ /* inputs */ void* payload, const OrthancPluginChange* change); - + OrthancPluginErrorCode (*logExportedResource) ( /* inputs */ void* payload, const OrthancPluginExportedResource* exported); - + /* Output: Use OrthancPluginDatabaseAnswerAttachment() */ OrthancPluginErrorCode (*lookupAttachment) ( /* outputs */ @@ -621,7 +621,7 @@ void* payload, int32_t property); - /* Use "OrthancPluginDatabaseExtensions::lookupIdentifier3" + /* Use "OrthancPluginDatabaseExtensions::lookupIdentifier3" instead of this function as of Orthanc 0.9.5 (db v6), can be set to NULL. Output: Use OrthancPluginDatabaseAnswerInt64() */ OrthancPluginErrorCode (*lookupIdentifier) ( @@ -739,7 +739,7 @@ /** * Base extensions since Orthanc 1.0.0 **/ - + /* Output: Use OrthancPluginDatabaseAnswerString() */ OrthancPluginErrorCode (*getAllPublicIdsWithLimit) ( /* outputs */ @@ -761,7 +761,7 @@ void* payload, uint32_t targetVersion, OrthancPluginStorageArea* storageArea); - + OrthancPluginErrorCode (*clearMainDicomTags) ( /* inputs */ void* payload, @@ -789,7 +789,7 @@ /** * Extensions since Orthanc 1.4.0 **/ - + /* Output: Use OrthancPluginDatabaseAnswerInt64() */ OrthancPluginErrorCode (*lookupIdentifierRange) ( /* outputs */ @@ -802,11 +802,11 @@ const char* start, const char* end); - + /** * Extensions since Orthanc 1.5.2 **/ - + /* Ouput: Use OrthancPluginDatabaseAnswerMatchingResource */ OrthancPluginErrorCode (*lookupResources) ( /* outputs */ @@ -818,7 +818,7 @@ OrthancPluginResourceType queryLevel, uint32_t limit, uint8_t requestSomeInstance); - + OrthancPluginErrorCode (*createInstance) ( /* output */ OrthancPluginCreateInstanceResult* output, @@ -853,13 +853,13 @@ int64_t* target, /* inputs */ void* payload); - + OrthancPluginErrorCode (*tagMostRecentPatient) ( /* inputs */ void* payload, int64_t patientId); - - + + /** * Extensions since Orthanc 1.5.4 **/ @@ -871,8 +871,8 @@ /* inputs */ void* payload, int64_t resourceId); - - /* Ouput: Use OrthancPluginDatabaseAnswerString to send + + /* Ouput: Use OrthancPluginDatabaseAnswerString to send the public ID of the parent (if the resource is not a patient) */ OrthancPluginErrorCode (*lookupResourceAndParent) ( /* outputs */ @@ -880,7 +880,7 @@ uint8_t* isExisting, int64_t* id, OrthancPluginResourceType* type, - + /* inputs */ void* payload, const char* publicId); @@ -1018,18 +1018,18 @@ /* For "DeletedAttachment" */ OrthancPluginAttachment attachment; - + } content; - + } OrthancPluginDatabaseEvent; - + typedef struct { /** * Functions to read the answers inside a transaction **/ - + OrthancPluginErrorCode (*readAnswersCount) (OrthancPluginDatabaseTransaction* transaction, uint32_t* target /* out */); @@ -1062,7 +1062,7 @@ OrthancPluginErrorCode (*readAnswerMatchingResource) (OrthancPluginDatabaseTransaction* transaction, OrthancPluginMatchingResource* target /* out */, uint32_t index); - + OrthancPluginErrorCode (*readAnswerMetadata) (OrthancPluginDatabaseTransaction* transaction, int32_t* metadata /* out */, const char** value /* out */, @@ -1071,7 +1071,7 @@ OrthancPluginErrorCode (*readAnswerString) (OrthancPluginDatabaseTransaction* transaction, const char** target /* out */, uint32_t index); - + OrthancPluginErrorCode (*readEventsCount) (OrthancPluginDatabaseTransaction* transaction, uint32_t* target /* out */); @@ -1079,8 +1079,8 @@ OrthancPluginDatabaseEvent* event /* out */, uint32_t index); - - + + /** * Functions to access the global database object * (cf. "IDatabaseWrapper" class in Orthanc) @@ -1115,7 +1115,7 @@ **/ OrthancPluginErrorCode (*rollback) (OrthancPluginDatabaseTransaction* transaction); - + OrthancPluginErrorCode (*commit) (OrthancPluginDatabaseTransaction* transaction, int64_t fileSizeDelta); @@ -1126,9 +1126,9 @@ int64_t revision); OrthancPluginErrorCode (*clearChanges) (OrthancPluginDatabaseTransaction* transaction); - + OrthancPluginErrorCode (*clearExportedResources) (OrthancPluginDatabaseTransaction* transaction); - + OrthancPluginErrorCode (*clearMainDicomTags) (OrthancPluginDatabaseTransaction* transaction, int64_t resourceId); @@ -1142,7 +1142,7 @@ OrthancPluginErrorCode (*deleteAttachment) (OrthancPluginDatabaseTransaction* transaction, int64_t id, int32_t contentType); - + OrthancPluginErrorCode (*deleteMetadata) (OrthancPluginDatabaseTransaction* transaction, int64_t id, int32_t metadataType); @@ -1153,11 +1153,11 @@ /* Answers are read using "readAnswerMetadata()" */ OrthancPluginErrorCode (*getAllMetadata) (OrthancPluginDatabaseTransaction* transaction, int64_t id); - + /* Answers are read using "readAnswerString()" */ OrthancPluginErrorCode (*getAllPublicIds) (OrthancPluginDatabaseTransaction* transaction, OrthancPluginResourceType resourceType); - + /* Answers are read using "readAnswerString()" */ OrthancPluginErrorCode (*getAllPublicIdsWithLimit) (OrthancPluginDatabaseTransaction* transaction, OrthancPluginResourceType resourceType, @@ -1169,11 +1169,11 @@ uint8_t* targetDone /* out */, int64_t since, uint32_t maxResults); - + /* Answers are read using "readAnswerInt64()" */ OrthancPluginErrorCode (*getChildrenInternalId) (OrthancPluginDatabaseTransaction* transaction, int64_t id); - + /* Answers are read using "readAnswerString()" */ OrthancPluginErrorCode (*getChildrenMetadata) (OrthancPluginDatabaseTransaction* transaction, int64_t resourceId, @@ -1188,50 +1188,50 @@ uint8_t* targetDone /* out */, int64_t since, uint32_t maxResults); - + /* Answer is read using "readAnswerChange()" */ OrthancPluginErrorCode (*getLastChange) (OrthancPluginDatabaseTransaction* transaction); - + OrthancPluginErrorCode (*getLastChangeIndex) (OrthancPluginDatabaseTransaction* transaction, int64_t* target /* out */); - + /* Answer is read using "readAnswerExportedResource()" */ OrthancPluginErrorCode (*getLastExportedResource) (OrthancPluginDatabaseTransaction* transaction); - + /* Answers are read using "readAnswerDicomTag()" */ OrthancPluginErrorCode (*getMainDicomTags) (OrthancPluginDatabaseTransaction* transaction, int64_t id); - + /* Answer is read using "readAnswerString()" */ OrthancPluginErrorCode (*getPublicId) (OrthancPluginDatabaseTransaction* transaction, int64_t internalId); - + OrthancPluginErrorCode (*getResourcesCount) (OrthancPluginDatabaseTransaction* transaction, uint64_t* target /* out */, OrthancPluginResourceType resourceType); - + OrthancPluginErrorCode (*getResourceType) (OrthancPluginDatabaseTransaction* transaction, OrthancPluginResourceType* target /* out */, uint64_t resourceId); - + OrthancPluginErrorCode (*getTotalCompressedSize) (OrthancPluginDatabaseTransaction* transaction, uint64_t* target /* out */); - + OrthancPluginErrorCode (*getTotalUncompressedSize) (OrthancPluginDatabaseTransaction* transaction, uint64_t* target /* out */); - + OrthancPluginErrorCode (*isDiskSizeAbove) (OrthancPluginDatabaseTransaction* transaction, uint8_t* target /* out */, uint64_t threshold); - + OrthancPluginErrorCode (*isExistingResource) (OrthancPluginDatabaseTransaction* transaction, uint8_t* target /* out */, int64_t resourceId); - + OrthancPluginErrorCode (*isProtectedPatient) (OrthancPluginDatabaseTransaction* transaction, uint8_t* target /* out */, int64_t resourceId); - + /* Answers are read using "readAnswerInt32()" */ OrthancPluginErrorCode (*listAvailableAttachments) (OrthancPluginDatabaseTransaction* transaction, int64_t internalId); @@ -1262,24 +1262,24 @@ OrthancPluginErrorCode (*lookupGlobalProperty) (OrthancPluginDatabaseTransaction* transaction, const char* serverIdentifier, int32_t property); - + /* Answer is read using "readAnswerString()" */ OrthancPluginErrorCode (*lookupMetadata) (OrthancPluginDatabaseTransaction* transaction, int64_t* revision /* out */, int64_t id, int32_t metadata); - + OrthancPluginErrorCode (*lookupParent) (OrthancPluginDatabaseTransaction* transaction, uint8_t* isExisting /* out */, int64_t* parentId /* out */, int64_t id); - + OrthancPluginErrorCode (*lookupResource) (OrthancPluginDatabaseTransaction* transaction, uint8_t* isExisting /* out */, int64_t* id /* out */, OrthancPluginResourceType* type /* out */, const char* publicId); - + /* Answers are read using "readAnswerMatchingResource()" */ OrthancPluginErrorCode (*lookupResources) (OrthancPluginDatabaseTransaction* transaction, uint32_t constraintsCount, @@ -1298,7 +1298,7 @@ OrthancPluginErrorCode (*selectPatientToRecycle) (OrthancPluginDatabaseTransaction* transaction, uint8_t* patientAvailable /* out */, int64_t* patientId /* out */); - + OrthancPluginErrorCode (*selectPatientToRecycle2) (OrthancPluginDatabaseTransaction* transaction, uint8_t* patientAvailable /* out */, int64_t* patientId /* out */, @@ -1315,7 +1315,7 @@ int32_t metadata, const char* value, int64_t revision); - + OrthancPluginErrorCode (*setProtectedPatient) (OrthancPluginDatabaseTransaction* transaction, int64_t id, uint8_t isProtected); @@ -1327,7 +1327,7 @@ const OrthancPluginResourcesContentTags* mainDicomTags, uint32_t countMetadata, const OrthancPluginResourcesContentMetadata* metadata); - + } OrthancPluginDatabaseBackendV3; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h --- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Wed Aug 19 14:11:33 2026 +0200 @@ -5,13 +5,13 @@ * can be loaded into Orthanc to extend its functionality. Each * Orthanc plugin must expose 4 public functions with the following * signatures: - * + * * -# int32_t OrthancPluginInitialize(const OrthancPluginContext* context): * This function is invoked by Orthanc when it loads the plugin on startup. * The plugin must: * - Check its compatibility with the Orthanc version using * ::OrthancPluginCheckVersion(). - * - Store the context pointer so that it can use the plugin + * - Store the context pointer so that it can use the plugin * services of Orthanc. * - Register all its REST callbacks using ::OrthancPluginRegisterRestCallback(). * - Possibly register its callback for received DICOM instances using ::OrthancPluginRegisterOnStoredInstanceCallback(). @@ -44,7 +44,7 @@ * The name and the version of a plugin is only used to prevent it * from being loaded twice. Note that, in C++, it is mandatory to * declare these functions within an extern "C" section. - * + * * To ensure multi-threading safety, the various REST callbacks are * guaranteed to be executed in mutual exclusion since Orthanc * 0.8.5. If this feature is undesired (notably when developing @@ -98,7 +98,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -618,7 +618,7 @@ _OrthancPluginService_GetInstanceDicomWebJson = 4018, /* New in Orthanc 1.7.0 */ _OrthancPluginService_GetInstanceDicomWebXml = 4019, /* New in Orthanc 1.7.0 */ _OrthancPluginService_LoadDicomInstance = 4020, /* New in Orthanc 1.12.1 */ - + /* Services for plugins implementing a database back-end */ _OrthancPluginService_RegisterDatabaseBackend = 5000, /* New in Orthanc 0.8.6 */ _OrthancPluginService_DatabaseAnswer = 5001, @@ -1066,7 +1066,7 @@ **/ OrthancPluginMetricsType_Timer = 1 } OrthancPluginMetricsType; - + /** * The available modes to export a binary DICOM tag into a DICOMweb @@ -1382,7 +1382,7 @@ _OrthancPluginFindMatcher_t OrthancPluginFindMatcher; - + /** * @brief Opaque structure to the set of remote Orthanc Peers that are known to the local Orthanc server. * @ingroup Toolbox @@ -1409,7 +1409,7 @@ typedef struct ORTHANC_PLUGIN_SINCE_SDK("1.5.4") _OrthancPluginDicomWebNode_t OrthancPluginDicomWebNode; - + /** * @brief Opaque structure that represents the parameters of a DICOM connection. * @ingroup DicomConnection @@ -1480,7 +1480,7 @@ OrthancPluginDicomWebNode* node, OrthancPluginDicomWebBinaryMode mode, const char* bulkDataUri); - + /** @@ -1491,7 +1491,7 @@ * @param uuid The UUID of the file. * @param content The content of the file. * @param size The size of the file. - * @param type The content type corresponding to this file. + * @param type The content type corresponding to this file. * @return 0 if success, other value if error. * @ingroup Callbacks **/ @@ -1511,7 +1511,7 @@ * @param content The content of the file (output). * @param size The size of the file (output). * @param uuid The UUID of the file of interest. - * @param type The content type corresponding to this file. + * @param type The content type corresponding to this file. * @return 0 if success, other value if error. * @ingroup Callbacks * @@ -1538,7 +1538,7 @@ * @param target Memory buffer where to store the content of the file. It must be allocated by the * plugin using OrthancPluginCreateMemoryBuffer64(). The core of Orthanc will free it. * @param uuid The UUID of the file of interest. - * @param type The content type corresponding to this file. + * @param type The content type corresponding to this file. * @ingroup Callbacks **/ typedef OrthancPluginErrorCode (*OrthancPluginStorageReadWhole) ( @@ -1559,7 +1559,7 @@ * The memory buffer is allocated and freed by Orthanc. The length of the range * of interest corresponds to the size of this buffer. * @param uuid The UUID of the file of interest. - * @param type The content type corresponding to this file. + * @param type The content type corresponding to this file. * @param rangeStart Start position of the requested range in the file. * @return 0 if success, other value if error. * @ingroup Callbacks @@ -1578,7 +1578,7 @@ * Signature of a callback function that is triggered when Orthanc deletes a file from the storage area. * * @param uuid The UUID of the file to be removed. - * @param type The content type corresponding to this file. + * @param type The content type corresponding to this file. * @return 0 if success, other value if error. * @ingroup Callbacks **/ @@ -1851,7 +1851,7 @@ * @return The NULL value if the plugin cannot deal with this query, * or a pointer to the driver object that is responsible for * handling the successive move suboperations. - * + * * @note If targetAet equals sourceAet, this is actually a query/retrieve operation. * @ingroup DicomCallbacks **/ @@ -1867,7 +1867,7 @@ const char* targetAet, uint16_t originatorId); - + /** * @brief Callback to handle incoming C-Move SCP requests (v2). * @@ -1915,14 +1915,14 @@ /** * @brief Callback to read the size of a C-Move driver. - * + * * Signature of a callback function that returns the number of * C-Move suboperations that are to be achieved by the given C-Move * driver. This driver is the return value of a previous call to the * OrthancPluginMoveCallback() or OrthancPluginMoveCallback2() callback. * * @param moveDriver The C-Move driver of interest. - * @return The number of suboperations. + * @return The number of suboperations. * @ingroup DicomCallbacks **/ typedef uint32_t (*OrthancPluginGetMoveSize) (void* moveDriver); @@ -1930,7 +1930,7 @@ /** * @brief Callback to apply one C-Move suboperation. - * + * * Signature of a callback function that applies the next C-Move * suboperation that os to be achieved by the given C-Move * driver. This driver is the return value of a previous call to the @@ -1945,7 +1945,7 @@ /** * @brief Callback to free one C-Move driver. - * + * * Signature of a callback function that releases the resources * allocated by the given C-Move driver. This driver is the return * value of a previous call to the OrthancPluginMoveCallback() @@ -1959,33 +1959,33 @@ /** * @brief Callback to finalize one custom job. - * + * * Signature of a callback function that releases all the resources * allocated by the given job. This job is the argument provided to * OrthancPluginCreateJob(). * * @param job The job of interest. * @ingroup Toolbox - **/ + **/ typedef void (*OrthancPluginJobFinalize) (void* job); /** * @brief Callback to check the progress of one custom job. - * + * * Signature of a callback function that returns the progress of the * job. * * @param job The job of interest. * @return The progress, as a floating-point number ranging from 0 to 1. * @ingroup Toolbox - **/ + **/ typedef float (*OrthancPluginJobGetProgress) (void* job); - + /** * @brief Callback to retrieve the content of one custom job. - * + * * Signature of a callback function that returns human-readable * statistics about the job. This statistics must be formatted as a * JSON object. This information is notably displayed in the "Jobs" @@ -1995,7 +1995,7 @@ * @return The statistics, as a JSON object encoded as a string. * @ingroup Toolbox * @deprecated This signature should not be used anymore since Orthanc SDK 1.11.3. - **/ + **/ typedef const char* (*OrthancPluginJobGetContent) (void* job); @@ -2020,7 +2020,7 @@ /** * @brief Callback to serialize one custom job. - * + * * Signature of a callback function that returns a serialized * version of the job, formatted as a JSON object. This * serialization is stored in the Orthanc database, and is used to @@ -2033,7 +2033,7 @@ * @see OrthancPluginRegisterJobsUnserializer() * @ingroup Toolbox * @deprecated This signature should not be used anymore since Orthanc SDK 1.11.3. - **/ + **/ typedef const char* (*OrthancPluginJobGetSerialized) (void* job); @@ -2060,7 +2060,7 @@ /** * @brief Callback to execute one step of a custom job. - * + * * Signature of a callback function that executes one step in the * job. The jobs engine of Orthanc will make successive calls to * this method, as long as it returns @@ -2069,13 +2069,13 @@ * @param job The job of interest. * @return The status of execution. * @ingroup Toolbox - **/ + **/ typedef OrthancPluginJobStepStatus (*OrthancPluginJobStep) (void* job); /** * @brief Callback executed once one custom job leaves the "running" state. - * + * * Signature of a callback function that is invoked once a job * leaves the "running" state. This can happen if the previous call * to OrthancPluginJobStep has failed/succeeded, if the host Orthanc @@ -2083,24 +2083,24 @@ * paused/canceled. This callback allows the plugin to free * resources allocated for running this custom job (e.g. to stop * threads, or to remove temporary files). - * + * * Note that handling pauses might involves a specific treatment * (such a stopping threads, but keeping temporary files on the * disk). This "paused" situation can be checked by looking at the * "reason" parameter. * * @param job The job of interest. - * @param reason The reason for leaving the "running" state. + * @param reason The reason for leaving the "running" state. * @return 0 if success, or the error code if failure. * @ingroup Toolbox - **/ - typedef OrthancPluginErrorCode (*OrthancPluginJobStop) (void* job, + **/ + typedef OrthancPluginErrorCode (*OrthancPluginJobStop) (void* job, OrthancPluginJobStopReason reason); /** * @brief Callback executed once one stopped custom job is started again. - * + * * Signature of a callback function that is invoked once a job * leaves the "failure/canceled" state, to be started again. This * function will typically reset the progress to zero. Note that @@ -2110,13 +2110,13 @@ * @param job The job of interest. * @return 0 if success, or the error code if failure. * @ingroup Toolbox - **/ + **/ typedef OrthancPluginErrorCode (*OrthancPluginJobReset) (void* job); /** * @brief Callback executed to unserialize a custom job. - * + * * Signature of a callback function that unserializes a job that was * saved in the Orthanc database. * @@ -2126,15 +2126,15 @@ * if this unserializer cannot handle this job type. * @see OrthancPluginRegisterJobsUnserializer() * @ingroup Callbacks - **/ + **/ typedef OrthancPluginJob* (*OrthancPluginJobsUnserializer) (const char* jobType, const char* serialized); - + /** * @brief Callback executed to update the metrics of the plugin. - * + * * Signature of a callback function that is called by Orthanc * whenever a monitoring tool (such as Prometheus) asks the current * values of the metrics. This callback gives the plugin a chance to @@ -2142,29 +2142,29 @@ * OrthancPluginSetMetricsIntegerValue(). * This is typically useful for metrics that are expensive to * acquire. - * + * * @see OrthancPluginRegisterRefreshMetrics() * @ingroup Callbacks **/ typedef void (*OrthancPluginRefreshMetricsCallback) (); - + /** * @brief Callback executed to encode a binary tag in DICOMweb. - * + * * Signature of a callback function that is called by Orthanc * whenever a DICOM tag that contains a binary value must be written * to a JSON or XML node, while a DICOMweb document is being * generated. The value representation (VR) of the DICOM tag can be * OB, OD, OF, OL, OW, or UN. - * + * * @see OrthancPluginEncodeDicomWebJson() and OrthancPluginEncodeDicomWebXml() * @param node The node being generated, as provided by Orthanc. * @param setter The setter to be used to encode the content of the node. If * the setter is not called, the binary tag is not written to the output document. * @param levelDepth The depth of the node in the DICOM hierarchy of sequences. - * This parameter gives the number of elements in the "levelTagGroup", + * This parameter gives the number of elements in the "levelTagGroup", * "levelTagElement", and "levelIndex" arrays. * @param levelTagGroup The group of the parent DICOM tags in the hierarchy. * @param levelTagElement The element of the parent DICOM tags in the hierarchy. @@ -2189,19 +2189,19 @@ /** * @brief Callback executed to encode a binary tag in DICOMweb. - * + * * Signature of a callback function that is called by Orthanc * whenever a DICOM tag that contains a binary value must be written * to a JSON or XML node, while a DICOMweb document is being * generated. The value representation (VR) of the DICOM tag can be * OB, OD, OF, OL, OW, or UN. - * + * * @see OrthancPluginEncodeDicomWebJson() and OrthancPluginEncodeDicomWebXml() * @param node The node being generated, as provided by Orthanc. * @param setter The setter to be used to encode the content of the node. If * the setter is not called, the binary tag is not written to the output document. * @param levelDepth The depth of the node in the DICOM hierarchy of sequences. - * This parameter gives the number of elements in the "levelTagGroup", + * This parameter gives the number of elements in the "levelTagGroup", * "levelTagElement", and "levelIndex" arrays. * @param levelTagGroup The group of the parent DICOM tags in the hierarchy. * @param levelTagElement The element of the parent DICOM tags in the hierarchy. @@ -2240,7 +2240,7 @@ } OrthancPluginContext; - + /** * @brief An entry in the dictionary of DICOM tags. **/ @@ -2257,14 +2257,14 @@ /** * @brief Free a string. - * + * * Free a string that was allocated by the core system of Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param str The string to be freed. **/ ORTHANC_PLUGIN_INLINE void OrthancPluginFreeString( - OrthancPluginContext* context, + OrthancPluginContext* context, char* str) { if (str != NULL) @@ -2276,14 +2276,14 @@ /** * @brief Check that the version of the hosting Orthanc is above a given version. - * + * * This function checks whether the version of the Orthanc server * running this plugin, is above the given version. Contrarily to * OrthancPluginCheckVersion(), it is up to the developer of the * plugin to make sure that all the Orthanc SDK services called by * the plugin are actually implemented in the given version of * Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param expectedMajor Expected major version. * @param expectedMinor Expected minor version. @@ -2345,7 +2345,7 @@ } /* Parse the version of the Orthanc core */ - if ( + if ( #ifdef _MSC_VER sscanf_s #else @@ -2395,14 +2395,14 @@ /** * @brief Check the compatibility of the plugin wrt. the version of its hosting Orthanc. - * + * * This function checks whether the version of the Orthanc server * running this plugin, is above the version of the current Orthanc * SDK header. This guarantees that the plugin is compatible with * the hosting Orthanc (i.e. it will not call unavailable services). * The result of this function should always be checked in the * OrthancPluginInitialize() entry point of the plugin. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return 1 if and only if the versions are compatible. If the * result is 0, the initialization of the plugin should fail. @@ -2422,14 +2422,14 @@ /** * @brief Free a memory buffer. - * + * * Free a memory buffer that was allocated by the core system of Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param buffer The memory buffer to release. **/ ORTHANC_PLUGIN_INLINE void OrthancPluginFreeMemoryBuffer( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginMemoryBuffer* buffer) { context->Free(buffer->data); @@ -2438,15 +2438,15 @@ /** * @brief Free a memory buffer. - * + * * Free a memory buffer that was allocated by the core system of Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param buffer The memory buffer to release. **/ ORTHANC_PLUGIN_SINCE_SDK("1.9.0") ORTHANC_PLUGIN_INLINE void OrthancPluginFreeMemoryBuffer64( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginMemoryBuffer64* buffer) { context->Free(buffer->data); @@ -2457,7 +2457,7 @@ * @brief Log an error. * * Log an error message using the Orthanc logging system. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param message The message to be logged. **/ @@ -2473,7 +2473,7 @@ * @brief Log a warning. * * Log a warning message using the Orthanc logging system. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param message The message to be logged. **/ @@ -2489,7 +2489,7 @@ * @brief Log an information. * * Log an information message using the Orthanc logging system. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param message The message to be logged. **/ @@ -2519,7 +2519,7 @@ * Each REST callback is guaranteed to run in mutual exclusion. * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). - * @param pathRegularExpression Regular expression for the URI. May contain groups. + * @param pathRegularExpression Regular expression for the URI. May contain groups. * @param callback The callback function to handle the REST call. * @see OrthancPluginRegisterRestCallbackNoLock() * @@ -2557,7 +2557,7 @@ * each incoming HTTP request). Of course, if using this function, * it is up to the plugin to implement the required locking * mechanisms. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param pathRegularExpression Regular expression for the URI. May contain groups. * @param callback The callback function to handle the REST call. @@ -2602,7 +2602,7 @@ * other primitives of Orthanc, you should make these calls in a * separate thread, passing the pending events to be processed * through a message queue. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback function. * @ingroup Callbacks @@ -2631,7 +2631,7 @@ * @brief Answer to a REST request. * * This function answers to a REST request with the content of a memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param answer Pointer to the memory buffer containing the answer. @@ -2685,7 +2685,7 @@ * parameters of this function describe a memory buffer that * contains an uncompressed image. The image will be automatically compressed * as a PNG image by the core system of Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param format The memory layout of the uncompressed image. @@ -2727,10 +2727,10 @@ /** * @brief Retrieve a DICOM instance using its Orthanc identifier. - * + * * Retrieve a DICOM instance using its Orthanc identifier. The DICOM * file is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param instanceId The Orthanc identifier of the DICOM instance of interest. @@ -2758,10 +2758,10 @@ /** * @brief Make a GET call to the built-in Orthanc REST API. - * + * * Make a GET call to the built-in Orthanc REST API. The result to * the query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -2785,13 +2785,13 @@ /** * @brief Make a GET call to the REST API, as tainted by the plugins. - * + * * Make a GET call to the Orthanc REST API, after all the plugins * are applied. In other words, if some plugin overrides or adds the * called URI to the built-in Orthanc REST API, this call will * return the result provided by this plugin. The result to the * query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -2823,10 +2823,10 @@ /** * @brief Make a POST call to the built-in Orthanc REST API. - * + * * Make a POST call to the built-in Orthanc REST API. The result to * the query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -2855,13 +2855,13 @@ /** * @brief Make a POST call to the REST API, as tainted by the plugins. - * + * * Make a POST call to the Orthanc REST API, after all the plugins * are applied. In other words, if some plugin overrides or adds the * called URI to the built-in Orthanc REST API, this call will * return the result provided by this plugin. The result to the * query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -2891,9 +2891,9 @@ /** * @brief Make a DELETE call to the built-in Orthanc REST API. - * + * * Make a DELETE call to the built-in Orthanc REST API. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param uri The URI to delete in the built-in Orthanc API. * @return 0 if success, or the error code if failure. @@ -2911,12 +2911,12 @@ /** * @brief Make a DELETE call to the REST API, as tainted by the plugins. - * + * * Make a DELETE call to the Orthanc REST API, after all the plugins * are applied. In other words, if some plugin overrides or adds the * called URI to the built-in Orthanc REST API, this call will - * return the result provided by this plugin. - * + * return the result provided by this plugin. + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param uri The URI to delete in the built-in Orthanc API. * @return 0 if success, or the error code if failure. @@ -2935,10 +2935,10 @@ /** * @brief Make a PUT call to the built-in Orthanc REST API. - * + * * Make a PUT call to the built-in Orthanc REST API. The result to * the query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -2968,13 +2968,13 @@ /** * @brief Make a PUT call to the REST API, as tainted by the plugins. - * + * * Make a PUT call to the Orthanc REST API, after all the plugins * are applied. In other words, if some plugin overrides or adds the * called URI to the built-in Orthanc REST API, this call will * return the result provided by this plugin. The result to the * query is stored into a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -3013,7 +3013,7 @@ * * This function answers to a REST request by redirecting the user * to another URI using HTTP status 301. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param redirection Where to redirect. @@ -3044,10 +3044,10 @@ * Look for a patient stored in Orthanc, using its Patient ID tag (0x0010, 0x0020). * This function uses the database index to run as fast as possible (it does not loop * over all the stored patients). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param patientID The Patient ID of interest. - * @return The NULL value if the patient is non-existent, or a string containing the + * @return The NULL value if the patient is non-existent, or a string containing the * Orthanc ID of the patient. This string must be freed by OrthancPluginFreeString(). * @ingroup Orthanc **/ @@ -3079,10 +3079,10 @@ * Look for a study stored in Orthanc, using its Study Instance UID tag (0x0020, 0x000d). * This function uses the database index to run as fast as possible (it does not loop * over all the stored studies). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param studyUID The Study Instance UID of interest. - * @return The NULL value if the study is non-existent, or a string containing the + * @return The NULL value if the study is non-existent, or a string containing the * Orthanc ID of the study. This string must be freed by OrthancPluginFreeString(). * @ingroup Orthanc **/ @@ -3114,10 +3114,10 @@ * Look for a study stored in Orthanc, using its Accession Number tag (0x0008, 0x0050). * This function uses the database index to run as fast as possible (it does not loop * over all the stored studies). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param accessionNumber The Accession Number of interest. - * @return The NULL value if the study is non-existent, or a string containing the + * @return The NULL value if the study is non-existent, or a string containing the * Orthanc ID of the study. This string must be freed by OrthancPluginFreeString(). * @ingroup Orthanc **/ @@ -3149,10 +3149,10 @@ * Look for a series stored in Orthanc, using its Series Instance UID tag (0x0020, 0x000e). * This function uses the database index to run as fast as possible (it does not loop * over all the stored series). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param seriesUID The Series Instance UID of interest. - * @return The NULL value if the series is non-existent, or a string containing the + * @return The NULL value if the series is non-existent, or a string containing the * Orthanc ID of the series. This string must be freed by OrthancPluginFreeString(). * @ingroup Orthanc **/ @@ -3184,10 +3184,10 @@ * Look for an instance stored in Orthanc, using its SOP Instance UID tag (0x0008, 0x0018). * This function uses the database index to run as fast as possible (it does not loop * over all the stored instances). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param sopInstanceUID The SOP Instance UID of interest. - * @return The NULL value if the instance is non-existent, or a string containing the + * @return The NULL value if the instance is non-existent, or a string containing the * Orthanc ID of the instance. This string must be freed by OrthancPluginFreeString(). * @ingroup Orthanc **/ @@ -3229,7 +3229,7 @@ * - Redirections (status 301) must use ::OrthancPluginRedirect(). * - Unauthorized access (status 401) must use ::OrthancPluginSendUnauthorized(). * - Methods not allowed (status 405) must use ::OrthancPluginSendMethodNotAllowed(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param status The HTTP status code to be sent. @@ -3253,7 +3253,7 @@ * * This function answers to a REST request by signaling that it is * not authorized. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param realm The realm for the authorization process. @@ -3276,7 +3276,7 @@ * * This function answers to a REST request by signaling that the * queried URI does not support this method. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param allowedMethods The allowed methods for this URI (e.g. "GET,POST" after a PUT or a POST request). @@ -3305,7 +3305,7 @@ * @brief Set a cookie. * * This function sets a cookie in the HTTP client. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param cookie The cookie to be set. @@ -3330,7 +3330,7 @@ * @brief Set some HTTP header. * * This function sets a HTTP header in the HTTP answer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param key The HTTP header to be set. @@ -3367,7 +3367,7 @@ * * This function returns the Application Entity Title (AET) of the * DICOM modality from which a DICOM instance originates. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The AET if success, NULL if error. @@ -3400,7 +3400,7 @@ * @brief Get the size of a DICOM file. * * This function returns the number of bytes of the given DICOM instance. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The size of the file, -1 in case of error. @@ -3433,7 +3433,7 @@ * @brief Get the data of a DICOM file. * * This function returns a pointer to the content of the given DICOM instance. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The pointer to the DICOM data, NULL in case of error. @@ -3468,7 +3468,7 @@ * This function returns a pointer to a newly created string * containing a JSON file. This JSON file encodes the tag hierarchy * of the given DICOM instance. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The NULL value in case of error, or a string containing the JSON file. @@ -3506,7 +3506,7 @@ * of the given DICOM instance. In contrast with * ::OrthancPluginGetInstanceJson(), the returned JSON file is in * its simplified version. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The NULL value in case of error, or a string containing the JSON file. @@ -3545,7 +3545,7 @@ * ::OrthancPluginRegisterOnStoredInstanceCallback(), the only * possibly available metadata are "ReceptionDate", "RemoteAET" and * "IndexInSeries". - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @param metadata The metadata of interest. @@ -3583,13 +3583,13 @@ * This functions returns the value of some metadata that is associated with the DICOM instance of interest. * Before calling this function, the existence of the metadata must have been checked with * ::OrthancPluginHasInstanceMetadata(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @param metadata The metadata of interest. - * @return The metadata value if success, NULL if error. Please note that the - * returned string belongs to the instance object and must NOT be - * deallocated. Please make a copy of the string if you wish to access + * @return The metadata value if success, NULL if error. Please note that the + * returned string belongs to the instance object and must NOT be + * deallocated. Please make a copy of the string if you wish to access * it later. * @ingroup DicomInstance **/ @@ -3634,7 +3634,7 @@ * built-in way Orthanc stores its files on the filesystem. This * function must be called during the initialization of the plugin, * i.e. inside the OrthancPluginInitialize() public function. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param create The callback function to store a file on the custom storage area. * @param read The callback function to read a file from the custom storage area. @@ -3668,7 +3668,7 @@ * @brief Return the path to the Orthanc executable. * * This function returns the path to the Orthanc executable. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return NULL in the case of an error, or a newly allocated string * containing the path. This string must be freed by @@ -3698,7 +3698,7 @@ * @brief Return the directory containing the Orthanc. * * This function returns the path to the directory containing the Orthanc executable. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return NULL in the case of an error, or a newly allocated string * containing the path. This string must be freed by @@ -3732,7 +3732,7 @@ * path can refer to a folder that stores a set of configuration * files. This function is deprecated in favor of * OrthancPluginGetConfiguration(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return NULL in the case of an error, or a newly allocated string * containing the path. This string must be freed by @@ -3780,7 +3780,7 @@ * other primitives of Orthanc, you should make these calls in a * separate thread, passing the pending events to be processed * through a message queue. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback function. * @ingroup Callbacks @@ -3812,14 +3812,14 @@ * declares the entry path where to find this interface. This * information is notably used in the "Plugins" page of Orthanc * Explorer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param uri The root URI for this plugin. * * @deprecated This function should not be used anymore because the * result of the call to "OrthancPluginGetName()" depends on the * system. Use "OrthancPluginSetRootUri2()" instead. - **/ + **/ ORTHANC_PLUGIN_DEPRECATED ORTHANC_PLUGIN_INLINE void OrthancPluginSetRootUri( OrthancPluginContext* context, const char* uri) @@ -3865,14 +3865,14 @@ * * Set a description for this plugin. It is displayed in the * "Plugins" page of Orthanc Explorer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param description The description. * * @deprecated This function should not be used anymore because the * result of the call to "OrthancPluginGetName()" depends on the * system. Use "OrthancPluginSetDescription2()" instead. - **/ + **/ ORTHANC_PLUGIN_DEPRECATED ORTHANC_PLUGIN_INLINE void OrthancPluginSetDescription( OrthancPluginContext* context, const char* description) @@ -3916,14 +3916,14 @@ * * Add JavaScript code to customize the default behavior of Orthanc * Explorer. This can for instance be used to add new buttons. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param javascript The custom JavaScript code. * * @deprecated This function should not be used anymore because the * result of the call to "OrthancPluginGetName()" depends on the * system. Use "OrthancPluginExtendOrthancExplorer2()" instead. - **/ + **/ ORTHANC_PLUGIN_DEPRECATED ORTHANC_PLUGIN_INLINE void OrthancPluginExtendOrthancExplorer( OrthancPluginContext* context, const char* javascript) @@ -3975,7 +3975,7 @@ * * Get the value of a global property that is stored in the Orthanc database. Global * properties whose index is below 1024 are reserved by Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param property The global property of interest. * @param defaultValue The value to return, if the global property is unset. @@ -4015,7 +4015,7 @@ * save their internal parameters. Plugins are only allowed to set * properties whose index are above or equal to 1024 (properties * below 1024 are read-only and reserved by Orthanc). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param property The global property of interest. * @param value The value to be set in the global property. @@ -4049,7 +4049,7 @@ * @brief Get the number of command-line arguments. * * Retrieve the number of command-line arguments that were used to launch Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return The number of arguments. **/ @@ -4081,7 +4081,7 @@ * Get the value of one of the command-line arguments that were used * to launch Orthanc. The number of available arguments can be * retrieved by OrthancPluginGetCommandLineArgumentsCount(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param argument The index of the argument. * @return The value of the argument, or NULL in the case of an error. This @@ -4114,7 +4114,7 @@ * @brief Get the expected version of the database schema. * * Retrieve the expected version of the database schema. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return The version. * @ingroup Callbacks @@ -4146,7 +4146,7 @@ * * This function returns the content of the configuration that is * used by Orthanc, formatted as a JSON string. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return NULL in the case of an error, or a newly allocated string * containing the configuration. This string must be freed by @@ -4184,7 +4184,7 @@ * @brief Start an HTTP multipart answer. * * Initiates a HTTP multipart answer, as the result of a REST request. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param subType The sub-type of the multipart answer ("mixed" or "related"). @@ -4212,7 +4212,7 @@ * * This function sends an item as a part of some HTTP multipart * answer that was initiated by OrthancPluginStartMultipartAnswer(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param answer Pointer to the memory buffer containing the item. @@ -4253,13 +4253,13 @@ * * This function compresses or decompresses a buffer, using the * version of the zlib library that is used by the Orthanc core. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param source The source buffer. * @param size The size in bytes of the source buffer. * @param compression The compression algorithm. - * @param uncompress If set to "0", the buffer must be compressed. + * @param uncompress If set to "0", the buffer must be compressed. * If set to "1", the buffer must be uncompressed. * @return 0 if success, or the error code if failure. * @ingroup Images @@ -4292,10 +4292,10 @@ /** * @brief Read a file. - * + * * Read the content of a file on the filesystem, and returns it into * a newly allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param path The path of the file to be read. @@ -4323,9 +4323,9 @@ /** * @brief Write a file. - * + * * Write the content of a memory buffer to the filesystem. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param path The path of the file to be written. * @param data The content of the memory buffer. @@ -4357,7 +4357,7 @@ * @brief Get the description of a given error code. * * This function returns the description of a given error code. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param error The error code of interest. * @return The error description. This is a statically-allocated @@ -4401,13 +4401,13 @@ * code (such as "400 - Bad Request"), together with a body * describing the error. The body will only be returned if the * configuration option "HttpDescribeErrors" of Orthanc is set to "true". - * + * * Note that: * - Successful requests (status 200) must use ::OrthancPluginAnswerBuffer(). * - Redirections (status 301) must use ::OrthancPluginRedirect(). * - Unauthorized access (status 401) must use ::OrthancPluginSendUnauthorized(). * - Methods not allowed (status 405) must use ::OrthancPluginSendMethodNotAllowed(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param status The HTTP status code to be sent. @@ -4457,7 +4457,7 @@ const OrthancPluginImage* image) { OrthancPluginPixelFormat target; - + _OrthancPluginGetImageInfo params; memset(¶ms, 0, sizeof(params)); params.image = image; @@ -4490,7 +4490,7 @@ const OrthancPluginImage* image) { uint32_t width; - + _OrthancPluginGetImageInfo params; memset(¶ms, 0, sizeof(params)); params.image = image; @@ -4523,7 +4523,7 @@ const OrthancPluginImage* image) { uint32_t height; - + _OrthancPluginGetImageInfo params; memset(¶ms, 0, sizeof(params)); params.image = image; @@ -4558,7 +4558,7 @@ const OrthancPluginImage* image) { uint32_t pitch; - + _OrthancPluginGetImageInfo params; memset(¶ms, 0, sizeof(params)); params.image = image; @@ -4673,7 +4673,7 @@ * @ingroup Images **/ ORTHANC_PLUGIN_INLINE void OrthancPluginFreeImage( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginImage* image) { _OrthancPluginFreeImage params; @@ -4795,7 +4795,7 @@ * parameters of this function describe a memory buffer that * contains an uncompressed image. The image will be automatically compressed * as a JPEG image by the core system of Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param format The memory layout of the uncompressed image. @@ -4848,12 +4848,12 @@ /** * @brief Issue a HTTP GET call. - * + * * Make a HTTP GET call to the given URL. The result to the query is * stored into a newly allocated memory buffer. Favor * OrthancPluginRestApiGet() if calling the built-in REST API of the * Orthanc instance that hosts this plugin. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param url The URL of interest. @@ -4884,12 +4884,12 @@ /** * @brief Issue a HTTP POST call. - * + * * Make a HTTP POST call to the given URL. The result to the query * is stored into a newly allocated memory buffer. Favor * OrthancPluginRestApiPost() if calling the built-in REST API of * the Orthanc instance that hosts this plugin. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param url The URL of interest. @@ -4926,12 +4926,12 @@ /** * @brief Issue a HTTP PUT call. - * + * * Make a HTTP PUT call to the given URL. The result to the query is * stored into a newly allocated memory buffer. Favor * OrthancPluginRestApiPut() if calling the built-in REST API of the * Orthanc instance that hosts this plugin. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param url The URL of interest. @@ -4968,11 +4968,11 @@ /** * @brief Issue a HTTP DELETE call. - * + * * Make a HTTP DELETE call to the given URL. Favor * OrthancPluginRestApiDelete() if calling the built-in REST API of * the Orthanc instance that hosts this plugin. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param url The URL of interest. * @param username The username (can be NULL if no password protection). @@ -5344,7 +5344,7 @@ uint16_t httpStatus; const char* message; } _OrthancPluginRegisterErrorCode; - + /** * @brief Declare a custom error code for this plugin. * @@ -5396,7 +5396,7 @@ uint32_t minMultiplicity; uint32_t maxMultiplicity; } _OrthancPluginRegisterDictionaryTag; - + /** * @brief Register a new tag into the DICOM dictionary. * @@ -5448,7 +5448,7 @@ uint32_t maxMultiplicity; const char* privateCreator; } _OrthancPluginRegisterPrivateDictionaryTag; - + /** * @brief Register a new private tag into the DICOM dictionary. * @@ -5563,7 +5563,7 @@ const void* buffer, uint32_t size, OrthancPluginDicomToJsonFormat format, - OrthancPluginDicomToJsonFlags flags, + OrthancPluginDicomToJsonFlags flags, uint32_t maxStringLength) { char* result; @@ -5611,7 +5611,7 @@ OrthancPluginContext* context, const char* instanceId, OrthancPluginDicomToJsonFormat format, - OrthancPluginDicomToJsonFlags flags, + OrthancPluginDicomToJsonFlags flags, uint32_t maxStringLength) { char* result; @@ -5648,11 +5648,11 @@ /** * @brief Make a GET call to the Orthanc REST API, with custom HTTP headers. - * + * * Make a GET call to the Orthanc REST API with extended * parameters. The result to the query is stored into a newly * allocated memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param uri The URI in the built-in Orthanc API. @@ -5874,7 +5874,7 @@ * @brief Get the origin of a DICOM file. * * This function returns the origin of a DICOM instance that has been received by Orthanc. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The origin of the instance. @@ -5981,7 +5981,7 @@ return context->InvokeService(context, _OrthancPluginService_RegisterDecodeImageCallback, ¶ms); } - + typedef struct @@ -6137,7 +6137,7 @@ * @brief Compute an MD5 hash. * * This functions computes the MD5 cryptographic hash of the given memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param buffer The source memory buffer. * @param size The size in bytes of the source buffer. @@ -6173,7 +6173,7 @@ * @brief Compute a SHA-1 hash. * * This functions computes the SHA-1 cryptographic hash of the given memory buffer. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param buffer The source memory buffer. * @param size The size in bytes of the source buffer. @@ -6220,7 +6220,7 @@ * tag. The tag can be specified using its human-readable name * (e.g. "PatientName") or a set of two hexadecimal numbers * (e.g. "0010-0020"). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target Where to store the information about the tag. * @param name The name of the DICOM tag. @@ -6257,7 +6257,7 @@ * answer that was initiated by OrthancPluginStartMultipartAnswer(). In addition to * OrthancPluginSendMultipartItem(), this function will set HTTP header associated * with the item. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param answer Pointer to the memory buffer containing the item. @@ -6286,7 +6286,7 @@ params.answerSize = answerSize; params.headersCount = headersCount; params.headersKeys = headersKeys; - params.headersValues = headersValues; + params.headersValues = headersValues; return context->InvokeService(context, _OrthancPluginService_SendMultipartItem2, ¶ms); } @@ -6319,7 +6319,7 @@ return context->InvokeService(context, _OrthancPluginService_RegisterIncomingHttpRequestFilter, ¶ms); } - + typedef struct @@ -6347,19 +6347,19 @@ /** * @brief Issue a HTTP call with full flexibility. - * + * * Make a HTTP call to the given URL. The result to the query is * stored into a newly allocated memory buffer. The HTTP request * will be done accordingly to the global configuration of Orthanc * (in particular, the options "HttpProxy", "HttpTimeout", * "HttpsVerifyPeers", "HttpsCACertificates", and "Pkcs11" will be * taken into account). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param answerBody The target memory buffer (out argument). * It must be freed with OrthancPluginFreeMemoryBuffer(). * The value of this argument is ignored if the HTTP method is DELETE. - * @param answerHeaders The target memory buffer for the HTTP headers in the answers (out argument). + * @param answerHeaders The target memory buffer for the HTTP headers in the answers (out argument). * The answer headers are formatted as a JSON object (associative array). * The buffer must be freed with OrthancPluginFreeMemoryBuffer(). * This argument can be set to NULL if the plugin has no interest in the HTTP headers. @@ -6378,7 +6378,7 @@ * (can be NULL if no client certificate or if not using HTTPS). * @param certificateKeyFile Path to the key of the client certificate for HTTPS, in PEM format * (can be NULL if no client certificate or if not using HTTPS). - * @param certificateKeyPassword Password to unlock the key of the client certificate + * @param certificateKeyPassword Password to unlock the key of the client certificate * (can be NULL if no client certificate or if not using HTTPS). * @param pkcs11 Enable PKCS#11 client authentication for hardware security modules and smart cards. * @return 0 if success, or the error code if failure. @@ -6435,7 +6435,7 @@ * @brief Generate an UUID. * * Generate a random GUID/UUID (globally unique identifier). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return NULL in the case of an error, or a newly allocated string * containing the UUID. This string must be freed by OrthancPluginFreeString(). @@ -6709,7 +6709,7 @@ return result; } } - + @@ -6815,7 +6815,7 @@ **/ ORTHANC_PLUGIN_SINCE_SDK("1.2.0") ORTHANC_PLUGIN_INLINE void OrthancPluginFreeFindMatcher( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginFindMatcher* matcher) { _OrthancPluginFreeFindMatcher params; @@ -6956,7 +6956,7 @@ **/ ORTHANC_PLUGIN_SINCE_SDK("1.4.2") ORTHANC_PLUGIN_INLINE void OrthancPluginFreePeers( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginPeers* peers) { _OrthancPluginFreePeers params; @@ -6982,7 +6982,7 @@ * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param peers The data structure describing the Orthanc peers. - * @result The number of peers. + * @result The number of peers. * @ingroup Toolbox **/ ORTHANC_PLUGIN_SINCE_SDK("1.4.2") @@ -7171,7 +7171,7 @@ /** * @brief Call the REST API of an Orthanc peer. - * + * * Make a REST call to the given URI in the REST API of a remote * Orthanc peer. The result to the query is stored into a newly * allocated memory buffer. The HTTP request will be done according @@ -7179,12 +7179,12 @@ * * This function is thread-safe: Several threads sharing the same * OrthancPluginPeers object can simultaneously call this function. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param answerBody The target memory buffer (out argument). * It must be freed with OrthancPluginFreeMemoryBuffer(). * The value of this argument is ignored if the HTTP method is DELETE. - * @param answerHeaders The target memory buffer for the HTTP headers in the answers (out argument). + * @param answerHeaders The target memory buffer for the HTTP headers in the answers (out argument). * The answer headers are formatted as a JSON object (associative array). * The buffer must be freed with OrthancPluginFreeMemoryBuffer(). * This argument can be set to NULL if the plugin has no interest in the HTTP headers. @@ -7265,13 +7265,13 @@ * * This function creates a custom job to be run by the jobs engine * of Orthanc. - * + * * Orthanc starts one dedicated thread per custom job that is * running. It is guaranteed that all the callbacks will only be * called from this single dedicated thread, in mutual exclusion: As * a consequence, it is *not* mandatory to protect the various * callbacks by mutexes. - * + * * The custom job can nonetheless launch its own processing threads * on the first call to the "step()" callback, and stop them once * the "stop()" callback is called. @@ -7279,7 +7279,7 @@ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param job The job to be executed. * @param finalize The finalization callback. - * @param type The type of the job, provided to the job unserializer. + * @param type The type of the job, provided to the job unserializer. * See OrthancPluginRegisterJobsUnserializer(). * @param getProgress The progress callback. * @param getContent The content callback. @@ -7353,13 +7353,13 @@ * * This function creates a custom job to be run by the jobs engine * of Orthanc. - * + * * Orthanc starts one dedicated thread per custom job that is * running. It is guaranteed that all the callbacks will only be * called from this single dedicated thread, in mutual exclusion: As * a consequence, it is *not* mandatory to protect the various * callbacks by mutexes. - * + * * The custom job can nonetheless launch its own processing threads * on the first call to the "step()" callback, and stop them once * the "stop()" callback is called. @@ -7367,7 +7367,7 @@ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param job The job to be executed. * @param finalize The finalization callback. - * @param type The type of the job, provided to the job unserializer. + * @param type The type of the job, provided to the job unserializer. * See OrthancPluginRegisterJobsUnserializer(). * @param getProgress The progress callback. * @param getContent The content callback. @@ -7437,7 +7437,7 @@ **/ ORTHANC_PLUGIN_SINCE_SDK("1.4.2") ORTHANC_PLUGIN_INLINE void OrthancPluginFreeJob( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginJob* job) { _OrthancPluginFreeJob params; @@ -7447,7 +7447,7 @@ } - + typedef struct { char** resultId; @@ -7494,7 +7494,7 @@ return resultId; } } - + typedef struct @@ -7544,7 +7544,7 @@ * different from "OrthancPluginErrorCode_Success", and if the * "HttpDescribeErrors" configuration option of Orthanc is set to * "true". - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param details The details of the error message. @@ -7577,7 +7577,7 @@ * @brief Detect the MIME type of a file. * * This function returns the MIME type of a file by inspecting its extension. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param path Path to the file. * @return The MIME type. This is a statically-allocated @@ -7622,7 +7622,7 @@ * monitor the behavior of the plugin through tools such as * Prometheus. The values of all the metrics are stored within the * Orthanc context. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param name The name of the metrics to be set. * @param value The value of the metrics. @@ -7708,7 +7708,7 @@ OrthancPluginDicomWebBinaryCallback callback) { char* target = NULL; - + _OrthancPluginEncodeDicomWeb params; params.target = ⌖ params.dicom = dicom; @@ -7751,7 +7751,7 @@ OrthancPluginDicomWebBinaryCallback callback) { char* target = NULL; - + _OrthancPluginEncodeDicomWeb params; params.target = ⌖ params.dicom = dicom; @@ -7768,7 +7768,7 @@ return target; } } - + typedef struct @@ -7805,7 +7805,7 @@ void* payload) { char* target = NULL; - + _OrthancPluginEncodeDicomWeb2 params; params.target = ⌖ params.dicom = dicom; @@ -7850,7 +7850,7 @@ void* payload) { char* target = NULL; - + _OrthancPluginEncodeDicomWeb2 params; params.target = ⌖ params.dicom = dicom; @@ -7868,7 +7868,7 @@ return target; } } - + /** @@ -7911,10 +7911,10 @@ void* answer, const void* data, uint32_t size); - - - /** - * @brief Callback to know whether the request body is entirely read during a chunked transfer + + + /** + * @brief Callback to know whether the request body is entirely read during a chunked transfer * * Signature of a callback function that is called by Orthanc acting * as a HTTP client during a chunked HTTP transfer, while reading @@ -7931,7 +7931,7 @@ /** - * @brief Callback to advance in the request body during a chunked transfer + * @brief Callback to advance in the request body during a chunked transfer * * Signature of a callback function that is called by Orthanc acting * as a HTTP client during a chunked HTTP transfer, while reading @@ -7948,7 +7948,7 @@ /** - * @brief Callback to read the current chunk of the request body during a chunked transfer + * @brief Callback to read the current chunk of the request body during a chunked transfer * * Signature of a callback function that is called by Orthanc acting * as a HTTP client during a chunked HTTP transfer, while reading @@ -7964,7 +7964,7 @@ /** - * @brief Callback to read the size of the current request chunk during a chunked transfer + * @brief Callback to read the size of the current request chunk during a chunked transfer * * Signature of a callback function that is called by Orthanc acting * as a HTTP client during a chunked HTTP transfer, while reading @@ -7978,7 +7978,7 @@ **/ typedef uint32_t (*OrthancPluginChunkedClientRequestGetChunkSize) (void* request); - + typedef struct { void* answer; @@ -8004,15 +8004,15 @@ uint8_t pkcs11; } _OrthancPluginChunkedHttpClient; - + /** * @brief Issue a HTTP call, using chunked HTTP transfers. - * + * * Make a HTTP call to the given URL using chunked HTTP * transfers. The request body is provided as an iterator over data * chunks. The answer is provided as a sequence of function calls * with the individual HTTP headers and answer chunks. - * + * * Contrarily to OrthancPluginHttpClient() that entirely stores the * request body and the answer body in memory buffers, this function * uses chunked HTTP transfers. This results in a lower memory @@ -8024,7 +8024,7 @@ * configuration of Orthanc (in particular, the options "HttpProxy", * "HttpTimeout", "HttpsVerifyPeers", "HttpsCACertificates", and * "Pkcs11" will be taken into account). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param answer The user payload for the answer body. It will be provided to the callbacks for the answer. * @param answerAddChunk Callback function to report a data chunk from the answer body. @@ -8048,7 +8048,7 @@ * (can be NULL if no client certificate or if not using HTTPS). * @param certificateKeyFile Path to the key of the client certificate for HTTPS, in PEM format * (can be NULL if no client certificate or if not using HTTPS). - * @param certificateKeyPassword Password to unlock the key of the client certificate + * @param certificateKeyPassword Password to unlock the key of the client certificate * (can be NULL if no client certificate or if not using HTTPS). * @param pkcs11 Enable PKCS#11 client authentication for hardware security modules and smart cards. * @return 0 if success, or the error code if failure. @@ -8130,7 +8130,7 @@ * callback is only invoked if the HTTP method is POST or PUT. The * callback must create an user-specific "reader" object that will * be fed with the body of the incoming body. - * + * * @see OrthancPluginRegisterChunkedRestCallback() * @param reader Memory location that must be filled with the newly-created reader. * @param uri The URI that is accessed. @@ -8142,14 +8142,14 @@ const char* uri, const OrthancPluginHttpRequest* request); - + /** * @brief Callback invoked whenever a new data chunk is available during a chunked transfer. * * Signature of a callback function that is called by Orthanc acting * as a HTTP server that supports chunked HTTP transfers. This callback * is invoked as soon as a new data chunk is available for the request body. - * + * * @see OrthancPluginRegisterChunkedRestCallback() * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. * @param data The content of the data chunk. @@ -8160,7 +8160,7 @@ OrthancPluginServerChunkedRequestReader* reader, const void* data, uint32_t size); - + /** * @brief Callback invoked whenever the request body is entirely received. @@ -8170,7 +8170,7 @@ * callback is invoked as soon as the full body of the HTTP request * is available. The plugin can then send its answer thanks to the * provided "output" object. - * + * * @see OrthancPluginRegisterChunkedRestCallback() * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. * @param output The HTTP connection to the client application. @@ -8179,7 +8179,7 @@ typedef OrthancPluginErrorCode (*OrthancPluginServerChunkedRequestReaderExecute) ( OrthancPluginServerChunkedRequestReader* reader, OrthancPluginRestOutput* output); - + /** * @brief Callback invoked to release the resources associated with an incoming HTTP chunked transfer. @@ -8190,13 +8190,13 @@ * given reader. Note that this function might be invoked even if * the entire body was not read, to deal with client error or * disconnection. - * + * * @see OrthancPluginRegisterChunkedRestCallback() * @param reader The user payload, as created by the OrthancPluginServerChunkedRequestReaderFactory() callback. **/ typedef void (*OrthancPluginServerChunkedRequestReaderFinalize) ( OrthancPluginServerChunkedRequestReader* reader); - + typedef struct { const char* pathRegularExpression; @@ -8223,7 +8223,7 @@ * plugin to implement the required locking mechanisms. * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). - * @param pathRegularExpression Regular expression for the URI. May contain groups. + * @param pathRegularExpression Regular expression for the URI. May contain groups. * @param getHandler The callback function to handle REST calls using the GET HTTP method. * @param postHandler The callback function to handle REST calls using the POST HTTP method. * @param deleteHandler The callback function to handle REST calls using the DELETE HTTP method. @@ -8332,7 +8332,7 @@ * queried about the status of these DICOM instances. * * @param handler Output variable where the factory puts the handler object it created. - * @param jobId ID of the Orthanc job that is responsible for handling + * @param jobId ID of the Orthanc job that is responsible for handling * the storage commitment request. This job will successively look for the * status of all the individual queried DICOM instances. * @param transactionUid UID of the storage commitment transaction @@ -8398,7 +8398,7 @@ /** * @brief Callback to free one storage commitment SCP handler. - * + * * Signature of a callback function that releases the resources * allocated by the factory of the storage commitment SCP. The * handler is the return value of a previous call to the @@ -8421,7 +8421,7 @@ * OrthancPluginStorageCommitmentFactory() callback. After each call * to this method, the progress of the associated Orthanc job is * updated. - * + * * @param target Output variable where to put the status for the queried instance. * @param handler The handler object associated with this storage commitment request. * @param sopClassUid The SOP class UID (0008,0016) of interest. @@ -8433,8 +8433,8 @@ void* handler, const char* sopClassUid, const char* sopInstanceUid); - - + + typedef struct { OrthancPluginStorageCommitmentFactory factory; @@ -8468,7 +8468,7 @@ params.lookup = lookup; return context->InvokeService(context, _OrthancPluginService_RegisterStorageCommitmentScpCallback, ¶ms); } - + /** @@ -8491,7 +8491,7 @@ * other primitives of Orthanc, you should make these calls in a * separate thread, passing the pending events to be processed * through a message queue. - * + * * @param instance The received DICOM instance. * @return 0 to discard the instance, 1 to store the instance, -1 if error. * @ingroup Callbacks @@ -8530,7 +8530,7 @@ /** - * @brief Callback to filter incoming DICOM instances received by + * @brief Callback to filter incoming DICOM instances received by * Orthanc through C-STORE. * * Signature of a callback function that is triggered whenever @@ -8553,7 +8553,7 @@ * separate thread, passing the pending events to be processed * through a message queue. * - * @param dimseStatus If the DICOM instance is discarded, + * @param dimseStatus If the DICOM instance is discarded, * DIMSE status to be sent by the C-STORE SCP of Orthanc * @param instance The received DICOM instance. * @return 0 to discard the instance, 1 to store the instance, -1 if error. @@ -8646,7 +8646,7 @@ * This function registers a custom callback to keep/discard/modify * incoming DICOM instances received by Orthanc from any source * (C-STORE or REST API). - * + * * @warning Contrarily to * OrthancPluginRegisterIncomingCStoreInstanceFilter() and * OrthancPluginRegisterIncomingDicomInstanceFilter() that can be @@ -8811,7 +8811,7 @@ **/ ORTHANC_PLUGIN_SINCE_SDK("1.7.0") ORTHANC_PLUGIN_INLINE void OrthancPluginFreeDicomInstance( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginDicomInstance* dicom) { _OrthancPluginFreeDicomInstance params; @@ -8841,7 +8841,7 @@ * * This function returns the number of frames that are part of a * DICOM image managed by the Orthanc core. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @return The number of frames (will be zero in the case of an error). @@ -8880,7 +8880,7 @@ * it gives access to the embedded files (such as JPEG, JPEG-LS or * JPEG2k). The Orthanc core transparently reassembles the fragments * to extract the raw frame. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param instance The instance of interest. @@ -8910,7 +8910,7 @@ * * This function decodes one frame of a DICOM image that is managed * by the Orthanc core. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param instance The instance of interest. * @param frameIndex The index of the frame of interest. @@ -8941,7 +8941,7 @@ } } - + /** * @brief Parse and transcode a DICOM instance. * @@ -8989,7 +8989,7 @@ * This function returns a memory buffer containing the * serialization of a DICOM instance that is managed by the Orthanc * core. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param instance The instance of interest. @@ -9009,7 +9009,7 @@ return context->InvokeService(context, _OrthancPluginService_SerializeDicomInstance, ¶ms); } - + /** * @brief Format a DICOM memory buffer as a JSON string. @@ -9034,7 +9034,7 @@ OrthancPluginContext* context, const OrthancPluginDicomInstance* instance, OrthancPluginDicomToJsonFormat format, - OrthancPluginDicomToJsonFlags flags, + OrthancPluginDicomToJsonFlags flags, uint32_t maxStringLength) { char* result = NULL; @@ -9081,7 +9081,7 @@ void* payload) { char* target = NULL; - + _OrthancPluginAccessDicomInstance2 params; params.targetStringToFree = ⌖ params.instance = instance; @@ -9098,7 +9098,7 @@ return target; } } - + /** * @brief Convert a DICOM instance to DICOMweb XML. @@ -9122,7 +9122,7 @@ void* payload) { char* target = NULL; - + _OrthancPluginAccessDicomInstance2 params; params.targetStringToFree = ⌖ params.instance = instance; @@ -9149,12 +9149,12 @@ * @param buffer Memory buffer containing the source DICOM instance. * @param size Size of the source memory buffer. * @param allowedSyntaxes A C array of possible transfer syntaxes UIDs for the - * result of the transcoding. The plugin must choose by itself the + * result of the transcoding. The plugin must choose by itself the * transfer syntax that will be used for the resulting DICOM image. * @param countSyntaxes The number of transfer syntaxes that are contained * in the "allowedSyntaxes" array. * @param allowNewSopInstanceUid Whether the transcoding plugin can select - * a transfer syntax that will change the SOP instance UID (or, in other + * a transfer syntax that will change the SOP instance UID (or, in other * terms, whether the plugin can transcode using lossy compression). * @return 0 if success (i.e. image successfully transcoded and stored into * "transcoded"), or the error code if failure. @@ -9197,7 +9197,7 @@ return context->InvokeService(context, _OrthancPluginService_RegisterTranscoderCallback, ¶ms); } - + typedef struct @@ -9212,7 +9212,7 @@ * This function creates a memory buffer that is managed by the * Orthanc core. The main use case of this function is for plugins * that act as DICOM transcoders. - * + * * Your plugin should never call "free()" on the resulting memory * buffer, as the C library that is used by the plugin is in general * not the same as the one used by the Orthanc core. @@ -9235,7 +9235,7 @@ return context->InvokeService(context, _OrthancPluginService_CreateMemoryBuffer, ¶ms); } - + /** * @brief Generate a token to grant full access to the REST API of Orthanc. @@ -9256,7 +9256,7 @@ * the "multiprocessing" package can be used to bypass the Global * Interpreter Lock (GIL) and thus to improve performance and * concurrency. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @return The authorization token, or NULL value in the case of an error. * This string must be freed by OrthancPluginFreeString(). @@ -9298,7 +9298,7 @@ * This function creates a 64-bit memory buffer that is managed by * the Orthanc core. The main use case of this function is for * plugins that read files from the storage area. - * + * * Your plugin should never call "free()" on the resulting memory * buffer, as the C library that is used by the plugin is in general * not the same as the one used by the Orthanc core. @@ -9321,7 +9321,7 @@ return context->InvokeService(context, _OrthancPluginService_CreateMemoryBuffer64, ¶ms); } - + typedef struct { @@ -9338,7 +9338,7 @@ * built-in way Orthanc stores its files on the filesystem. This * function must be called during the initialization of the plugin, * i.e. inside the OrthancPluginInitialize() public function. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param create The callback function to store a file on the custom storage area. * @param readWhole The callback function to read a whole file from the custom storage area. @@ -9437,17 +9437,17 @@ /** * @brief Call the REST API of Orthanc with full flexibility. - * + * * Make a call to the given URI in the REST API of Orthanc. The * result to the query is stored into a newly allocated memory * buffer. This function is always granted full access to the REST * API (no credentials, nor security token is needed). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param answerBody The target memory buffer (out argument). * It must be freed with OrthancPluginFreeMemoryBuffer(). * The value of this argument is ignored if the HTTP method is DELETE. - * @param answerHeaders The target memory buffer for the HTTP headers in the answer (out argument). + * @param answerHeaders The target memory buffer for the HTTP headers in the answer (out argument). * The answer headers are formatted as a JSON object (associative array). * The buffer must be freed with OrthancPluginFreeMemoryBuffer(). * This argument can be set to NULL if the plugin has no interest in the answer HTTP headers. @@ -9537,7 +9537,7 @@ const char* mimeType, const char* dateTime); - + /** * @brief Declare a subfolder while returning the content of a folder. * @@ -9585,7 +9585,7 @@ const char* mimeType, const char* dateTime); - + /** * @brief Callback for testing the existence of a folder. * @@ -9605,7 +9605,7 @@ const char* const* pathItems, void* payload); - + /** * @brief Callback for listing the content of a folder. * @@ -9633,7 +9633,7 @@ const char* const* pathItems, void* payload); - + /** * @brief Callback for retrieving the content of a file. * @@ -9657,7 +9657,7 @@ const char* const* pathItems, void* payload); - + /** * @brief Callback to store a file. * @@ -9681,7 +9681,7 @@ uint64_t size, void* payload); - + /** * @brief Callback to create a folder. * @@ -9701,7 +9701,7 @@ const char* const* pathItems, void* payload); - + /** * @brief Callback to remove a file or a folder. * @@ -9721,7 +9721,7 @@ const char* const* pathItems, void* payload); - + typedef struct { const char* uri; @@ -9741,7 +9741,7 @@ * REST API of Orthanc. This function must be called during the * initialization of the plugin, i.e. inside the * OrthancPluginInitialize() public function. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param uri URI where to map the WebDAV collection (must start with a `/` character). * @param isExistingFolder Callback method to test for the existence of a folder. @@ -9965,7 +9965,7 @@ * This function sets the value of an integer metrics to monitor the * behavior of the plugin through tools such as Prometheus. The * values of all the metrics are stored within the Orthanc context. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param name The name of the metrics to be set. * @param value The value of the metrics. @@ -10072,7 +10072,7 @@ * @brief Start an HTTP stream answer. * * Initiates an HTTP stream answer, as the result of a REST request. - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param contentType The MIME type of the items in the stream answer. @@ -10098,7 +10098,7 @@ * * This function sends a chunk as part of an HTTP stream * answer that was initiated by OrthancPluginStartStreamAnswer(). - * + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param output The HTTP connection to the client application. * @param answer Pointer to the memory buffer containing the item. diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/AdoptDicomInstance/Plugin.cpp --- a/OrthancServer/Plugins/Samples/AdoptDicomInstance/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/AdoptDicomInstance/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp --- a/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -49,8 +49,8 @@ const char* instanceId) { char buffer[1024]; - sprintf(buffer, "Just received a DICOM instance of size %d and ID %s from origin %d (AET %s)", - (int) OrthancPluginGetInstanceSize(context_, instance), instanceId, + sprintf(buffer, "Just received a DICOM instance of size %d and ID %s from origin %d (AET %s)", + (int) OrthancPluginGetInstanceSize(context_, instance), instanceId, OrthancPluginGetInstanceOrigin(context_, instance), OrthancPluginGetInstanceRemoteAet(context_, instance)); OrthancPluginLogInfo(context_, buffer); @@ -63,7 +63,7 @@ // Write the uncompressed DICOM content to some temporary file std::string uncompressed = "uncompressed-" + std::string(instanceId) + ".dcm"; - OrthancPluginErrorCode error = OrthancPluginWriteFile(context_, uncompressed.c_str(), + OrthancPluginErrorCode error = OrthancPluginWriteFile(context_, uncompressed.c_str(), OrthancPluginGetInstanceData(context_, instance), OrthancPluginGetInstanceSize(context_, instance)); if (error) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -418,7 +418,7 @@ { headersKeys_.push_back(it->first.c_str()); headersValues_.push_back(it->second.c_str()); - } + } } const char* const* GetKeys() @@ -446,7 +446,7 @@ PluginHttpHeaders headers(httpHeaders); return CheckHttp(OrthancPluginRestApiGet2( - GetGlobalContext(), &buffer_, uri.c_str(), + GetGlobalContext(), &buffer_, uri.c_str(), headers.GetSize(), headers.GetKeys(), headers.GetValues(), applyPlugins)); @@ -458,7 +458,7 @@ bool applyPlugins) { Clear(); - + // Cast for compatibility with Orthanc SDK <= 1.5.6 const char* b = reinterpret_cast(body); @@ -485,7 +485,7 @@ PluginHttpHeaders headers(httpHeaders); - return CheckHttp(OrthancPluginCallRestApi(GetGlobalContext(), + return CheckHttp(OrthancPluginCallRestApi(GetGlobalContext(), &buffer_, *answerHeaders, &httpStatus, @@ -541,10 +541,10 @@ #else Json::CharReaderBuilder builder; builder.settings_["collectComments"] = collectComments; - + const std::unique_ptr reader(builder.newCharReader()); assert(reader.get() != NULL); - + JSONCPP_STRING err; if (reader->parse(reinterpret_cast(buffer), reinterpret_cast(buffer) + size, &target, &err)) @@ -565,7 +565,7 @@ { return ReadJson(target, source.empty() ? NULL : source.c_str(), source.size()); } - + bool ReadJson(Json::Value& target, const void* buffer, @@ -573,14 +573,14 @@ { return ReadJsonInternal(target, buffer, size, true); } - + bool ReadJsonWithoutComments(Json::Value& target, const std::string& source) { return ReadJsonWithoutComments(target, source.empty() ? NULL : source.c_str(), source.size()); } - + bool ReadJsonWithoutComments(Json::Value& target, const void* buffer, @@ -602,7 +602,7 @@ target = Json::writeString(builder, source); #endif } - + void WriteStyledJson(std::string& target, const Json::Value& source) @@ -869,7 +869,7 @@ ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); } } - + OrthancConfiguration::OrthancConfiguration() { @@ -989,7 +989,7 @@ ORTHANC_PLUGINS_LOG_ERROR("The configuration option \"" + GetPath(key) + "\" is too large to fit in an integer"); - ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); + ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); } target = static_cast(configuration_[key].asUInt()); @@ -1577,7 +1577,7 @@ { std::string bodyString; WriteStyledJson(bodyString, value); - CheckAnswerSizeIsLessThan4GB(bodyString); + CheckAnswerSizeIsLessThan4GB(bodyString); OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); } @@ -1605,7 +1605,7 @@ output, "content-type", mimeType); - + OrthancPluginSendHttpStatus(GetGlobalContext(), output, httpError, @@ -2196,7 +2196,7 @@ size_t index, const std::string& uri, const std::string& body, - const HttpHeaders& headers, + const HttpHeaders& headers, unsigned int timeout) const { MemoryBuffer buffer; @@ -2218,7 +2218,7 @@ size_t index, const std::string& uri, const std::string& body, - const HttpHeaders& headers, + const HttpHeaders& headers, unsigned int timeout) const { MemoryBuffer buffer; @@ -2329,7 +2329,7 @@ { target.Swap(answer); DecodeHttpHeaders(answerHeaders, answerHeadersBuffer); - + return (status == 200); } else @@ -2472,7 +2472,7 @@ { memcpy(target->data, source.c_str(), source.size()); } - + return OrthancPluginErrorCode_Success; } } @@ -2515,7 +2515,7 @@ { assert(job != NULL); OrthancJob& that = *reinterpret_cast(job); - + if (that.hasSerialized_) { if (CopyStringToMemoryBuffer(target, that.serialized_) == OrthancPluginErrorCode_Success) @@ -2821,7 +2821,7 @@ static const char* KEY_PRIORITY = "Priority"; boost::movelib::unique_ptr protection(job); - + if (body.type() != Json::objectValue) { #if HAS_ORTHANC_EXCEPTION == 1 @@ -2834,7 +2834,7 @@ } bool synchronous = true; - + if (body.isMember(KEY_SYNCHRONOUS)) { if (body[KEY_SYNCHRONOUS].type() != Json::booleanValue) @@ -2893,7 +2893,7 @@ priority = !body[KEY_PRIORITY].asInt(); } } - + Json::Value result; if (synchronous) @@ -2929,7 +2929,7 @@ { start_ = boost::posix_time::microsec_clock::universal_time(); } - + MetricsTimer::~MetricsTimer() { const boost::posix_time::ptime stop = boost::posix_time::microsec_clock::universal_time(); @@ -2965,18 +2965,18 @@ body_(body), done_(false) { - } + } static uint8_t IsDone(void* body) { return GetObject(body).done_; } - + static const void* GetChunkData(void* body) { return GetObject(body).chunk_.c_str(); } - + static uint32_t GetChunkSize(void* body) { return static_cast(GetObject(body).chunk_.size()); @@ -2985,7 +2985,7 @@ static OrthancPluginErrorCode Next(void* body) { RequestBodyWrapper& that = GetObject(body); - + if (that.done_) { return OrthancPluginErrorCode_BadSequenceOfCalls; @@ -3006,7 +3006,7 @@ return OrthancPluginErrorCode_Plugin; } } - } + } }; @@ -3078,7 +3078,7 @@ } } - + void HttpClient::SetCredentials(const std::string& username, const std::string& password) { @@ -3086,7 +3086,7 @@ password_ = password; } - + void HttpClient::ClearCredentials() { username_.clear(); @@ -3103,7 +3103,7 @@ certificateKeyPassword_ = keyPassword; } - + void HttpClient::ClearCertificate() { certificateFile_.clear(); @@ -3118,21 +3118,21 @@ chunkedBody_ = NULL; } - + void HttpClient::SwapBody(std::string& body) { fullBody_.swap(body); chunkedBody_ = NULL; } - + void HttpClient::SetBody(const std::string& body) { fullBody_ = body; chunkedBody_ = NULL; } - + void HttpClient::SetBody(IRequestBody& body) { fullBody_.clear(); @@ -3361,7 +3361,7 @@ } RequestBodyWrapper request(body); - + OrthancPluginErrorCode error = OrthancPluginChunkedHttpClient( GetGlobalContext(), &answer, @@ -3391,7 +3391,7 @@ ORTHANC_PLUGINS_THROW_ERROR_CODE(error); } } -#endif +#endif void HttpClient::ExecuteWithoutStream(uint16_t& httpStatus, HttpHeaders& answerHeaders, @@ -3456,7 +3456,7 @@ return; } #endif - + // Compatibility mode for Orthanc SDK <= 1.5.6 or if chunked // transfers are disabled. This results in higher memory usage // (all chunks from the answer body are sent at once) @@ -3465,10 +3465,10 @@ std::string answerBody; Execute(answerHeaders, answerBody); - for (HttpHeaders::const_iterator it = answerHeaders.begin(); + for (HttpHeaders::const_iterator it = answerHeaders.begin(); it != answerHeaders.end(); ++it) { - answer.AddHeader(it->first, it->second); + answer.AddHeader(it->first, it->second); } if (!answerBody.empty()) @@ -3491,7 +3491,7 @@ return; } #endif - + // Compatibility mode for Orthanc SDK <= 1.5.6 or if chunked // transfers are disabled. This results in higher memory usage // (all chunks from the request body are sent at once) @@ -3499,7 +3499,7 @@ if (chunkedBody_ != NULL) { ChunkedBuffer buffer; - + std::string chunk; while (chunkedBody_->ReadNextChunk(chunk)) { @@ -3523,7 +3523,7 @@ { std::string body; Execute(answerHeaders, body); - + if (!ReadJson(answerBody, body)) { ORTHANC_PLUGINS_LOG_ERROR("Cannot convert HTTP answer body to JSON"); @@ -3556,7 +3556,7 @@ const OrthancPluginHttpRequest* request) { } - + IChunkedRequestReader *NullChunkedRestCallback(const char* url, const OrthancPluginHttpRequest* request) { @@ -3595,7 +3595,7 @@ } } - + OrthancPluginErrorCode ChunkedRequestReaderExecute( OrthancPluginServerChunkedRequestReader* reader, OrthancPluginRestOutput* output) @@ -3624,7 +3624,7 @@ } } - + void ChunkedRequestReaderFinalize( OrthancPluginServerChunkedRequestReader* reader) { @@ -3635,7 +3635,7 @@ } #else - + OrthancPluginErrorCode ChunkedRestCompatibility(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request, @@ -3659,7 +3659,7 @@ { allowed += ","; } - + allowed += "POST"; } @@ -3669,7 +3669,7 @@ { allowed += ","; } - + allowed += "DELETE"; } @@ -3679,10 +3679,10 @@ { allowed += ","; } - + allowed += "PUT"; } - + switch (request->method) { case OrthancPluginHttpMethod_Get: @@ -3795,7 +3795,7 @@ { assert(target != NULL && rawHandler != NULL); - + try { IStorageCommitmentScpHandler& handler = *reinterpret_cast(rawHandler); @@ -3823,7 +3823,7 @@ #endif -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) DicomInstance::DicomInstance(const OrthancPluginDicomInstance* instance) : toFree_(false), instance_(instance) @@ -3864,7 +3864,7 @@ #endif } - + std::string DicomInstance::GetRemoteAet() const { const char* s = OrthancPluginGetInstanceRemoteAet(GetGlobalContext(), instance_); @@ -3885,7 +3885,7 @@ s.Assign(OrthancPluginGetInstanceJson(GetGlobalContext(), instance_)); s.ToJson(target); } - + void DicomInstance::GetSimplifiedJson(Json::Value& target) const { @@ -3907,7 +3907,7 @@ } #endif - + #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) bool DicomInstance::HasPixelData() const { @@ -3924,7 +3924,7 @@ #endif -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) void DicomInstance::GetRawFrame(std::string& target, unsigned int frameIndex) const { @@ -3944,7 +3944,7 @@ #endif -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) OrthancImage* DicomInstance::GetDecodedFrame(unsigned int frameIndex) const { OrthancPluginImage* image = OrthancPluginGetInstanceDecodedFrame( @@ -3959,7 +3959,7 @@ return new OrthancImage(image); } } -#endif +#endif #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) @@ -3979,7 +3979,7 @@ } } #endif - + #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) DicomInstance* DicomInstance::Transcode(const void* buffer, @@ -4038,8 +4038,8 @@ return result; } #endif - - + + #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 static OrthancPluginErrorCode WebDavIsExistingFolder(uint8_t* isExisting, uint32_t pathSize, @@ -4064,7 +4064,7 @@ } #endif - + #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 static OrthancPluginErrorCode WebDavListFolder(uint8_t* isExisting, OrthancPluginWebDavCollection* collection, @@ -4075,12 +4075,12 @@ void* payload) { IWebDavCollection& that = *reinterpret_cast(payload); - + try { std::list files; std::list subfolders; - + if (!that.ListFolder(files, subfolders, WebDavConvertPath(pathSize, pathItems))) { *isExisting = 0; @@ -4088,33 +4088,33 @@ else { *isExisting = 1; - + for (std::list::const_iterator it = files.begin(); it != files.end(); ++it) { OrthancPluginErrorCode code = addFile( collection, it->GetName().c_str(), it->GetContentSize(), it->GetMimeType().c_str(), it->GetDateTime().c_str()); - + if (code != OrthancPluginErrorCode_Success) { return code; } } - + for (std::list::const_iterator it = subfolders.begin(); it != subfolders.end(); ++it) { OrthancPluginErrorCode code = addFolder( collection, it->GetName().c_str(), it->GetDateTime().c_str()); - + if (code != OrthancPluginErrorCode_Success) { return code; } } } - + return OrthancPluginErrorCode_Success; } catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) @@ -4126,7 +4126,7 @@ return OrthancPluginErrorCode_Plugin; } } -#endif +#endif #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 @@ -4141,7 +4141,7 @@ try { std::string content, mime, dateTime; - + if (that.GetFile(content, mime, dateTime, WebDavConvertPath(pathSize, pathItems))) { return retrieveFile(collection, content.empty() ? NULL : content.c_str(), @@ -4161,7 +4161,7 @@ { return OrthancPluginErrorCode_InternalError; } - } + } #endif @@ -4181,7 +4181,7 @@ { ORTHANC_PLUGINS_THROW_EXCEPTION(NotEnoughMemory); } - + *isReadOnly = (that.StoreFile(WebDavConvertPath(pathSize, pathItems), data, static_cast(size)) ? 1 : 0); return OrthancPluginErrorCode_Success; @@ -4197,7 +4197,7 @@ } #endif - + #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 static OrthancPluginErrorCode WebDavCreateFolderCallback(uint8_t* isReadOnly, /* out */ uint32_t pathSize, @@ -4221,8 +4221,8 @@ } } #endif - - + + #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 static OrthancPluginErrorCode WebDavDeleteItemCallback(uint8_t* isReadOnly, /* out */ uint32_t pathSize, @@ -4247,7 +4247,7 @@ } #endif - + #if HAS_ORTHANC_PLUGINS_WEBDAV == 1 void IWebDavCollection::Register(const std::string& uri, IWebDavCollection& collection) @@ -4270,7 +4270,7 @@ for (uint32_t i = 0; i < request->getCount; ++i) { result[request->getKeys[i]] = request->getValues[i]; - } + } } void GetHttpHeaders(HttpHeaders& result, const OrthancPluginHttpRequest* request) @@ -4280,7 +4280,7 @@ for (uint32_t i = 0; i < request->headersCount; ++i) { result[request->headersKeys[i]] = request->headersValues[i]; - } + } } void SerializeGetArguments(std::string& output, const OrthancPluginHttpRequest* request) @@ -4474,7 +4474,7 @@ mimeType = h->second.c_str(); } } - + AnswerString(answerBody_, mimeType, output); } else diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -40,7 +40,7 @@ /** * The definition of ORTHANC_PLUGINS_VERSION_IS_ABOVE below is for * backward compatibility with Orthanc SDK <= 1.3.0. - * + * * $ hg diff -r Orthanc-1.3.0:Orthanc-1.3.1 ../../../Plugins/Include/orthanc/OrthancCPlugin.h * **/ @@ -203,7 +203,7 @@ OrthancPluginContext* GetGlobalContext(); - + class OrthancImage; @@ -393,7 +393,7 @@ void ToString(std::string& target) const; void ToJson(Json::Value& target) const; - + void ToJsonWithoutComments(Json::Value& target) const; }; @@ -407,7 +407,7 @@ std::string GetPath(const std::string& key) const; void LoadConfiguration(); - + public: OrthancConfiguration(); // loads the full Orthanc configuration @@ -427,7 +427,7 @@ bool LookupStringValue(std::string& target, const std::string& key) const; - + bool LookupIntegerValue(int& target, const std::string& key) const; @@ -510,7 +510,7 @@ unsigned int GetHeight() const; unsigned int GetPitch() const; - + void* GetBuffer() const; const OrthancPluginImage* GetObject() const @@ -527,7 +527,7 @@ void AnswerJpegImage(OrthancPluginRestOutput* output, uint8_t quality) const; - + void* GetWriteableBuffer(); OrthancPluginImage* Release(); @@ -573,13 +573,13 @@ bool ReadJson(Json::Value& target, const std::string& source); - + bool ReadJson(Json::Value& target, const void* buffer, size_t size); bool ReadJsonWithoutComments(Json::Value& target, - const std::string& source); + const std::string& source); bool ReadJsonWithoutComments(Json::Value& target, const void* buffer, @@ -731,7 +731,7 @@ void ReportMinimalOrthancVersion(unsigned int major, unsigned int minor, unsigned int revision); - + bool CheckMinimalOrthancVersion(unsigned int major, unsigned int minor, unsigned int revision); @@ -780,7 +780,7 @@ } } - + template void RegisterRestCallback(const std::string& uri, bool isThreadSafe) @@ -906,7 +906,7 @@ const std::string& body, const HttpHeaders& headers, unsigned int timeout) const; - + bool DoPost(Json::Value& target, HttpHeaders& answerHeaders, size_t index, @@ -989,10 +989,10 @@ void UpdateSerialized(const Json::Value& serialized); void UpdateProgress(float progress); - + public: explicit OrthancJob(const std::string& jobType); - + virtual ~OrthancJob() { } @@ -1000,7 +1000,7 @@ virtual OrthancPluginJobStepStatus Step() = 0; virtual void Stop(OrthancPluginJobStopReason reason) = 0; - + virtual void Reset() = 0; static OrthancPluginJob* Create(OrthancJob* job /* takes ownership */); @@ -1115,7 +1115,7 @@ HttpHeaders& answerHeaders, // out std::string& answerBody, // out const std::string& body) const; - + public: HttpClient(); @@ -1230,7 +1230,7 @@ void NullRestCallback(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request); - + IChunkedRequestReader *NullChunkedRestCallback(const char* url, const OrthancPluginHttpRequest* request); @@ -1286,7 +1286,7 @@ void ChunkedRequestReaderFinalize( OrthancPluginServerChunkedRequestReader* reader); -#else +#else OrthancPluginErrorCode ChunkedRestCompatibility(OrthancPluginRestOutput* output, const char* url, @@ -1339,13 +1339,13 @@ Internals::ChunkedRequestReaderFinalize); #else OrthancPluginRegisterRestCallbackNoLock( - GetGlobalContext(), uri.c_str(), + GetGlobalContext(), uri.c_str(), Internals::ChunkedRestCompatibility); #endif } }; - + #if HAS_ORTHANC_PLUGINS_STORAGE_COMMITMENT_SCP == 1 class IStorageCommitmentScpHandler : public boost::noncopyable @@ -1354,10 +1354,10 @@ virtual ~IStorageCommitmentScpHandler() { } - + virtual OrthancPluginStorageCommitmentFailureReason Lookup(const std::string& sopClassUid, const std::string& sopInstanceUid) = 0; - + static OrthancPluginErrorCode Lookup(OrthancPluginStorageCommitmentFailureReason* target, void* rawHandler, const char* sopClassUid, @@ -1373,14 +1373,14 @@ private: bool toFree_; -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) const OrthancPluginDicomInstance* instance_; #else OrthancPluginDicomInstance* instance_; #endif - + public: -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 6, 1) explicit DicomInstance(const OrthancPluginDicomInstance* instance); #else explicit DicomInstance(OrthancPluginDicomInstance* instance); @@ -1515,7 +1515,7 @@ return dateTime_; } }; - + class FolderInfo { private: @@ -1540,7 +1540,7 @@ return dateTime_; } }; - + virtual ~IWebDavCollection() { } @@ -1550,7 +1550,7 @@ virtual bool ListFolder(std::list& files, std::list& subfolders, const std::vector& path) = 0; - + virtual bool GetFile(std::string& content /* out */, std::string& mime /* out */, std::string& dateTime /* out */, @@ -1597,7 +1597,7 @@ public: RestApiClient(); - + // used to forward a call from the plugin to the core RestApiClient(const char* url, const OrthancPluginHttpRequest* request); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Common/OrthancPluginException.h --- a/OrthancServer/Plugins/Samples/Common/OrthancPluginException.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginException.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -78,7 +78,7 @@ # define ORTHANC_PLUGINS_THROW_EXCEPTION(code) \ throw ORTHANC_PLUGINS_EXCEPTION_CLASS(ORTHANC_PLUGINS_GET_ERROR_CODE(code)); -#endif +#endif #define ORTHANC_PLUGINS_CHECK_ERROR(code) \ diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Common/OrthancPlugins.cmake --- a/OrthancServer/Plugins/Samples/Common/OrthancPlugins.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPlugins.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -9,7 +9,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Common/OrthancPluginsExports.cmake --- a/OrthancServer/Plugins/Samples/Common/OrthancPluginsExports.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginsExports.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -9,7 +9,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake --- a/OrthancServer/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -9,7 +9,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ConnectivityChecks/OrthancFrameworkDependencies.cpp --- a/OrthancServer/Plugins/Samples/ConnectivityChecks/OrthancFrameworkDependencies.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/OrthancFrameworkDependencies.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ConnectivityChecks/Plugin.cpp --- a/OrthancServer/Plugins/Samples/ConnectivityChecks/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -73,7 +73,7 @@ ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) { context_ = c; - + /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(c) == 0) { @@ -92,7 +92,7 @@ OrthancPluginSetRootUri2(context_, ORTHANC_PLUGIN_NAME, ROOT_URI "/app/index.html"); OrthancPluginRegisterRestCallback(context_, ROOT_URI "/libs/(.*)", ServeStaticResource); OrthancPluginRegisterRestCallback(context_, ROOT_URI "/app/(.*)", ServeStaticResource); - + return 0; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/CppSkeleton/Plugin.cpp --- a/OrthancServer/Plugins/Samples/CppSkeleton/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/CppSkeleton/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/CppSkeleton/Resources/SyncOrthancFolder.py --- a/OrthancServer/Plugins/Samples/CppSkeleton/Resources/SyncOrthancFolder.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/CppSkeleton/Resources/SyncOrthancFolder.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/CustomImageDecoder/Plugin.cpp --- a/OrthancServer/Plugins/Samples/CustomImageDecoder/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/CustomImageDecoder/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.cpp --- a/OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -73,7 +73,7 @@ } } } - + void LargeDeleteJob::ScheduleResource(Orthanc::ResourceType level, const std::string& id) @@ -85,11 +85,11 @@ case Orthanc::ResourceType_Patient: ScheduleChildrenResources(instances_, "/patients/" + id + "/instances"); break; - + case Orthanc::ResourceType_Study: ScheduleChildrenResources(instances_, "/studies/" + id + "/instances"); break; - + case Orthanc::ResourceType_Series: ScheduleChildrenResources(instances_, "/series/" + id + "/instances"); break; @@ -112,11 +112,11 @@ case Orthanc::ResourceType_Patient: ScheduleChildrenResources(series_, "/patients/" + id + "/series"); break; - + case Orthanc::ResourceType_Study: ScheduleChildrenResources(series_, "/studies/" + id + "/series"); break; - + case Orthanc::ResourceType_Series: series_.push_back(id); break; @@ -135,21 +135,21 @@ void LargeDeleteJob::DeleteResource(Orthanc::ResourceType level, const std::string& id) { - std::string uri; + std::string uri; switch (level) { case Orthanc::ResourceType_Patient: uri = "/patients/" + id; break; - + case Orthanc::ResourceType_Study: uri = "/studies/" + id; break; - + case Orthanc::ResourceType_Series: uri = "/series/" + id; break; - + case Orthanc::ResourceType_Instance: uri = "/instances/" + id; break; @@ -161,7 +161,7 @@ OrthancPlugins::RestApiDelete(uri, false); } - + LargeDeleteJob::LargeDeleteJob(const std::vector& resources, const std::vector& levels) : OrthancJob("LargeDelete"), @@ -178,7 +178,7 @@ } } - + OrthancPluginJobStepStatus LargeDeleteJob::Step() { if (posResources_ == 0) @@ -192,17 +192,17 @@ // LOG(WARNING) << "LargeDeleteJob has started"; } } - + if (posResources_ < resources_.size()) { // First step: Discovering all the instances of the resources ScheduleResource(levels_[posResources_], resources_[posResources_]); - + posResources_ += 1; UpdateDeleteProgress(); return OrthancPluginJobStepStatus_Continue; - } + } else if (posInstances_ < instances_.size()) { // Second step: Deleting the instances one by one @@ -248,7 +248,7 @@ UpdateProgress(1); return OrthancPluginJobStepStatus_Success; - } + } } @@ -266,7 +266,7 @@ const OrthancPluginHttpRequest* request) { static const char* KEY_RESOURCES = "Resources"; - + if (request->method != OrthancPluginHttpMethod_Post) { OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "POST"); @@ -319,7 +319,7 @@ resources.push_back(arr[i][1].asString()); } } - + OrthancPlugins::OrthancJob::SubmitFromRestApiPost( output, body, new LargeDeleteJob(resources, levels)); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.h --- a/OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/LargeDeleteJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -44,13 +44,13 @@ void ScheduleChildrenResources(std::vector& target, const std::string& uri); - + void ScheduleResource(Orthanc::ResourceType level, const std::string& id); void DeleteResource(Orthanc::ResourceType level, const std::string& id); - + public: LargeDeleteJob(const std::vector& resources, const std::vector& levels); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/OrthancFrameworkDependencies.cpp --- a/OrthancServer/Plugins/Samples/DelayedDeletion/OrthancFrameworkDependencies.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/OrthancFrameworkDependencies.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.cpp --- a/OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -42,25 +42,25 @@ if (!db_.DoesTableExist("Pending")) { db_.Execute("CREATE TABLE Pending(uuid TEXT, type INTEGER)"); - + // New in v 1.12.7+ // add an index on uuid to speed up the DELETE FROM Pending WHERE uuid=? // With this patch, we observed a 100 fold performance // improvement when the Pending table contains 1-2 millions files. db_.Execute("CREATE INDEX PendingIndex ON Pending(uuid)"); } - + t.Commit(); } } - + PendingDeletionsDatabase::PendingDeletionsDatabase(const std::string& path) { db_.Open(path); Setup(); } - + void PendingDeletionsDatabase::Enqueue(const std::string& uuid, Orthanc::FileContentType type) @@ -79,13 +79,13 @@ t.Commit(); } - + bool PendingDeletionsDatabase::Dequeue(std::string& uuid, Orthanc::FileContentType& type) { bool ok = false; - + boost::mutex::scoped_lock lock(mutex_); Orthanc::SQLite::Transaction t(db_); @@ -102,7 +102,7 @@ Orthanc::SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM Pending WHERE uuid=?"); s.BindString(0, uuid); s.Run(); - + ok = true; } } @@ -118,7 +118,7 @@ boost::mutex::scoped_lock lock(mutex_); unsigned int value = 0; - + Orthanc::SQLite::Transaction t(db_); t.Begin(); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.h --- a/OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/PendingDeletionsDatabase.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -35,13 +35,13 @@ Orthanc::SQLite::Connection db_; void Setup(); - + public: PendingDeletionsDatabase(const std::string& path); void Enqueue(const std::string& uuid, Orthanc::FileContentType type); - + bool Dequeue(std::string& uuid, Orthanc::FileContentType& type); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/DelayedDeletion/Plugin.cpp --- a/OrthancServer/Plugins/Samples/DelayedDeletion/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/DelayedDeletion/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -124,7 +124,7 @@ } memcpy(target->data, buffer->GetData(), buffer->GetSize()); - + return OrthancPluginErrorCode_Success; } catch (Orthanc::OrthancException& e) @@ -150,7 +150,7 @@ assert(buffer->GetSize() == target->size); memcpy(target->data, buffer->GetData(), buffer->GetSize()); - + return OrthancPluginErrorCode_Success; } catch (Orthanc::OrthancException& e) @@ -173,7 +173,7 @@ { LOG(INFO) << "DelayedDeletion - Scheduling delayed deletion of " << uuid; db_->Enqueue(uuid, Convert(type)); - + return OrthancPluginErrorCode_Success; } catch (Orthanc::OrthancException& e) @@ -198,16 +198,16 @@ Orthanc::FileContentType type = Orthanc::FileContentType_Dicom; // Dummy initialization bool hasDeleted = false; - + while (continue_ && db_->Dequeue(uuid, type)) { if (!hasDeleted) { - LOG(INFO) << "DelayedDeletion - Starting to process the pending deletions"; + LOG(INFO) << "DelayedDeletion - Starting to process the pending deletions"; } - + hasDeleted = true; - + try { LOG(INFO) << "DelayedDeletion - Asynchronous removal of file: " << uuid; @@ -227,7 +227,7 @@ if (hasDeleted) { LOG(INFO) << "DelayedDeletion - All the pending deletions have been completed"; - } + } boost::this_thread::sleep(boost::posix_time::milliseconds(GRANULARITY)); } @@ -242,7 +242,7 @@ { case OrthancPluginChangeType_OrthancStarted: assert(deletionThread_.get() == NULL); - + LOG(WARNING) << "DelayedDeletion - Starting the deletion thread"; continue_ = true; deletionThread_.reset(new boost::thread(DeletionWorker)); @@ -269,7 +269,7 @@ return OrthancPluginErrorCode_Success; } - + void GetPluginStatus(OrthancPluginRestOutput* output, const char* url, @@ -293,7 +293,7 @@ { OrthancPlugins::SetGlobalContext(context, ORTHANC_PLUGIN_NAME); Orthanc::Logging::InitializePluginContext(context, ORTHANC_PLUGIN_NAME); - + /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(context) == 0) @@ -324,7 +324,7 @@ if (delayedDeletionConfig.GetBooleanValue("Enable", true)) { databaseServerIdentifier_ = OrthancPluginGetDatabaseServerIdentifier(context); - throttleDelayMs_ = delayedDeletionConfig.GetUnsignedIntegerValue("ThrottleDelayMs", 0); // delay in ms + throttleDelayMs_ = delayedDeletionConfig.GetUnsignedIntegerValue("ThrottleDelayMs", 0); // delay in ms std::string pathStorage = orthancConfig.GetStringValue("StorageDirectory", "OrthancStorage"); @@ -336,7 +336,7 @@ std::string dbPath = delayedDeletionConfig.GetStringValue("Path", defaultDbPath.string()); LOG(WARNING) << "DelayedDeletion - Path to the SQLite database: " << dbPath; - + // This must run after the allocation of "storage_", to make sure // that the folder actually exists db_.reset(new PendingDeletionsDatabase(dbPath)); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp --- a/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -276,10 +276,10 @@ target["Version"] = statusVersion; target["LastProcessedChange"] = Json::Value::Int64(lastProcessedChange); target["LastChangeToProcess"] = Json::Value::Int64(lastChangeToProcess); - + if (lastTimeStarted == boost::date_time::not_a_date_time) { - target["LastTimeStarted"] = Json::Value::null; + target["LastTimeStarted"] = Json::Value::null; } else { @@ -338,7 +338,7 @@ pluginStatus_.lastProcessedChange = -1; pluginStatus_.lastChangeToProcess = -1; pluginStatus_.lastTimeStarted = boost::date_time::not_a_date_time; - + pluginStatus_.lastProcessedConfiguration.orthancVersion = "1.9.0"; // when we don't know, we assume some files were stored with Orthanc 1.9.0 (last version saving the dicom-as-json files) pluginStatus_.lastProcessedConfiguration.dicomWebVersion = "1.14"; // the first change that requires processing has been introduced between 1.14 & 1.15 @@ -346,7 +346,7 @@ pluginStatus_.lastProcessedConfiguration.patientsMainDicomTagsSignature = "0010,0010;0010,0020;0010,0030;0010,0040;0010,1000"; pluginStatus_.lastProcessedConfiguration.studiesMainDicomTagsSignature = "0008,0020;0008,0030;0008,0050;0008,0080;0008,0090;0008,1030;0020,000d;0020,0010;0032,1032;0032,1060"; pluginStatus_.lastProcessedConfiguration.seriesMainDicomTagsSignature = "0008,0021;0008,0031;0008,0060;0008,0070;0008,1010;0008,103e;0008,1070;0018,0010;0018,0015;0018,0024;0018,1030;0018,1090;0018,1400;0020,000e;0020,0011;0020,0037;0020,0105;0020,1002;0040,0254;0054,0081;0054,0101;0054,1000"; - pluginStatus_.lastProcessedConfiguration.instancesMainDicomTagsSignature = "0008,0012;0008,0013;0008,0018;0020,0012;0020,0013;0020,0032;0020,0037;0020,0100;0020,4000;0028,0008;0054,1330"; + pluginStatus_.lastProcessedConfiguration.instancesMainDicomTagsSignature = "0008,0012;0008,0013;0008,0018;0020,0012;0020,0013;0020,0032;0020,0037;0020,0100;0020,4000;0028,0008;0054,1330"; } } @@ -478,7 +478,7 @@ { ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: storage compression is now disabled -> will perform housekeeping"); } - + needsReingest = true; } else @@ -492,7 +492,7 @@ if (triggerOnIngestTranscodingChange_) { ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: ingest transcoding has changed -> will perform housekeeping"); - + needsReingest = true; } else @@ -552,7 +552,7 @@ try { - if (!limitToChange_.empty()) // if updating only maindicomtags for a single level + if (!limitToChange_.empty()) // if updating only maindicomtags for a single level { if (change["ChangeType"] == limitToChange_) { @@ -689,7 +689,7 @@ { ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: the Orthanc configuration has changed since last run, will reprocess the whole DB !"); } - + Json::Value changes; OrthancPlugins::RestApiGet(changes, "/changes?last", false); @@ -732,10 +732,10 @@ if (!completed) { boost::recursive_mutex::scoped_lock lock(pluginStatusMutex_); - + ORTHANC_PLUGINS_LOG_INFO("Housekeeper: processed changes " + boost::lexical_cast(pluginStatus_.lastProcessedChange) + " / " + boost::lexical_cast(pluginStatus_.lastChangeToProcess)); - + boost::this_thread::sleep(boost::posix_time::milliseconds(throttleDelay_ * 100)); // wait 1/10 of the delay between changes } @@ -751,7 +751,7 @@ boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } - } + } if (completed) { @@ -762,7 +762,7 @@ pluginStatus_.lastProcessedChange = -1; pluginStatus_.lastChangeToProcess = -1; - + SaveStatusInDb(); OrthancPluginLogWarning(OrthancPlugins::GetGlobalContext(), "Housekeeper: finished processing all changes"); @@ -844,7 +844,7 @@ /* { "Housekeeper": { - + // Enables/disables the plugin "Enable": false, @@ -859,8 +859,8 @@ // New in 1.12.9 // If "Force" is set to true, forces the "ReconstructFiles" - // option when reconstructing resources even if the plugin - // did not detect any changes in the configuration that + // option when reconstructing resources even if the plugin + // did not detect any changes in the configuration that // should trigger a Reconstruct. "ForceReconstructFiles": false, @@ -871,8 +871,8 @@ // Runs the plugin only at certain period of time. // If not specified, the plugin runs all the time - // Examples: - // to run between 0AM and 6AM everyday + every night + // Examples: + // to run between 0AM and 6AM everyday + every night // from 8PM to 12PM and 24h a day on the weekend: // "Schedule": { // "Monday": ["0-6", "20-24"], @@ -884,7 +884,7 @@ // "Sunday": ["0-24"] // }, - // configure events that can trigger a housekeeping processing + // configure events that can trigger a housekeeping processing "Triggers" : { "StorageCompressionChange": true, "MainDicomTagsChange": true, @@ -894,7 +894,7 @@ }, // When rebuilding MainDicomTags, limit to a single level of resource - // which can greatly improve performances e.g. if you have only updated + // which can greatly improve performances e.g. if you have only updated // the Study level ExtraMainDicomTags. // Allowed values: "Patient", "Study", "Series", "Instance", "All" "LimitMainDicomTagsReconstructLevel": "All" @@ -907,7 +907,7 @@ globalPropertyId_ = housekeeper.GetIntegerValue("GlobalPropertyId", 1025); force_ = housekeeper.GetBooleanValue("Force", false); forceReconstructFiles_ = housekeeper.GetBooleanValue("ForceReconstructFiles", false); - throttleDelay_ = housekeeper.GetUnsignedIntegerValue("ThrottleDelay", 5); + throttleDelay_ = housekeeper.GetUnsignedIntegerValue("ThrottleDelay", 5); if (housekeeper.GetJson().isMember("Triggers")) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ModalityWorklists/Plugin.cpp --- a/OrthancServer/Plugins/Samples/ModalityWorklists/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ModalityWorklists/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -132,7 +132,7 @@ // Encode the modified JSON as a DICOM instance, then convert it to a C-Find matcher OrthancPlugins::MemoryBuffer modified; modified.CreateDicom(json, OrthancPluginCreateDicomFlags_None); - + return new OrthancPlugins::FindMatcher(modified); } } @@ -159,7 +159,7 @@ { unsigned int parsedFilesCount = 0; unsigned int matchedWorklistCount = 0; - + for (fs::directory_iterator it(source); it != end; ++it) { fs::file_type type(it->status().type()); @@ -185,7 +185,7 @@ OrthancPluginWorklistMarkIncomplete(OrthancPlugins::GetGlobalContext(), answers); return OrthancPluginErrorCode_Success; } - + ORTHANC_PLUGINS_LOG_INFO("Worklist matched: " + it->path().string()); matchedWorklistCount++; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/DicomFilter.h --- a/OrthancServer/Plugins/Samples/MultitenantDicom/DicomFilter.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/DicomFilter.h Wed Aug 19 14:11:33 2026 +0200 @@ -73,6 +73,6 @@ virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp, const std::string& remoteAet, const std::string& calledAet) ORTHANC_OVERRIDE; - + virtual void GetAcceptedSopClasses(std::set& sopClasses, size_t maxCount) ORTHANC_OVERRIDE; }; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.cpp --- a/OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -63,7 +63,7 @@ { level = s; } - else + else { query[it->Format()] = s; } @@ -102,7 +102,7 @@ { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } - + Orthanc::DicomMap m; for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) @@ -119,9 +119,9 @@ response[i][KEY_PATIENT_MAIN_DICOM_TAGS][tag].type() == Json::stringValue) { m.SetValue(*it, response[i][KEY_PATIENT_MAIN_DICOM_TAGS][tag].asString(), false); - } + } } - + m.SetValue(Orthanc::DICOM_TAG_QUERY_RETRIEVE_LEVEL, level, false); m.SetValue(Orthanc::DICOM_TAG_RETRIEVE_AE_TITLE, retrieveAet_, false); answers.Add(m); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.h --- a/OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/FindRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -36,7 +36,7 @@ const std::string retrieveAet_; const std::set labels_; const LabelsConstraint constraint_; - + public: FindRequestHandler(const std::string& retrieveAet, const std::set& labels, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/MoveRequestHandler.h --- a/OrthancServer/Plugins/Samples/MultitenantDicom/MoveRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/MoveRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -47,7 +47,7 @@ void LookupIdentifiers(std::set& publicIds, Orthanc::ResourceType level, const Orthanc::DicomMap& input) const; - + public: MoveRequestHandler(const std::set& labels, LabelsConstraint constraint, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/MultitenantDicomServer.cpp --- a/OrthancServer/Plugins/Samples/MultitenantDicom/MultitenantDicomServer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/MultitenantDicomServer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -92,7 +92,7 @@ labelsStoreLevels_.insert(Orthanc::ResourceType_Series); labelsStoreLevels_.insert(Orthanc::ResourceType_Instance); } - + server_.reset(new Orthanc::DicomServer("MULTI-DCM-SERVER", "MULTI-DCM")); { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/OrthancFrameworkDependencies.cpp --- a/OrthancServer/Plugins/Samples/MultitenantDicom/OrthancFrameworkDependencies.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/OrthancFrameworkDependencies.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/Plugin.cpp --- a/OrthancServer/Plugins/Samples/MultitenantDicom/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -47,7 +47,7 @@ case OrthancPluginChangeType_OrthancStarted: { for (DicomServers::iterator it = dicomServers_.begin(); it != dicomServers_.end(); ++it) - { + { if (*it != NULL) { try @@ -63,11 +63,11 @@ break; } - + case OrthancPluginChangeType_OrthancStopped: { for (DicomServers::iterator it = dicomServers_.begin(); it != dicomServers_.end(); ++it) - { + { if (*it != NULL) { try @@ -80,10 +80,10 @@ } } } - + break; } - + default: break; } @@ -140,7 +140,7 @@ OrthancPluginSetDescription2(context, ORTHANC_PLUGIN_NAME, "Multitenant plugin for Orthanc."); OrthancPluginRegisterOnChangeCallback(context, OnChangeCallback); - + try { OrthancPlugins::OrthancConfiguration globalConfig; @@ -166,7 +166,7 @@ } } } - + return 0; } catch (Orthanc::OrthancException& e) @@ -180,7 +180,7 @@ ORTHANC_PLUGINS_API void OrthancPluginFinalize() { for (DicomServers::iterator it = dicomServers_.begin(); it != dicomServers_.end(); ++it) - { + { if (*it != NULL) { try diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.cpp --- a/OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -45,7 +45,7 @@ // column of undefined length as a primary key return false; } - + for (size_t i = 0; i < label.size(); i++) { if (!(label[i] == '_' || @@ -122,7 +122,7 @@ for (size_t i = 0; i < names.size(); i++) { parameters = Orthanc::RemoteModalityParameters(modalities[names[i]]); - + if (IsSameAETitle(isStrict, parameters.GetApplicationEntityTitle(), aet)) { name = names[i]; @@ -151,7 +151,7 @@ std::string s = Orthanc::SerializationToolbox::ReadString(serverConfig, KEY_LABELS_CONSTRAINT, KEY_ALL); targetConstraint = PluginToolbox::StringToLabelsConstraint(s); } - + void AddLabelsToFindRequest(Json::Value& request, const std::set& labels, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.h --- a/OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/MultitenantDicom/PluginToolbox.h Wed Aug 19 14:11:33 2026 +0200 @@ -32,9 +32,9 @@ namespace PluginToolbox { bool IsValidLabel(const std::string& label); - + Orthanc::ResourceType ParseQueryRetrieveLevel(const std::string& level); - + bool IsSameAETitle(bool isStrict, const std::string& aet1, const std::string& aet2); @@ -47,10 +47,10 @@ void ParseLabels(std::set& targetLabels, LabelsConstraint& targetConstraint, const Json::Value& serverConfig); - + void AddLabelsToFindRequest(Json::Value& request, const std::set& labels, LabelsConstraint constraint); - + LabelsConstraint StringToLabelsConstraint(const std::string& s); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp --- a/OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -27,7 +27,7 @@ #include "../Common/OrthancPluginCppWrapper.h" #include -#include +#include #include #include @@ -43,13 +43,13 @@ std::string institutionName = "My institution"; dicom.Replace(Orthanc::DICOM_TAG_INSTITUTION_NAME, institutionName, false, Orthanc::DicomReplaceMode_InsertIfAbsent, ""); - + std::string modifiedDicom; dicom.SaveToMemoryBuffer(modifiedDicom); - + OrthancPluginCreateMemoryBuffer64(OrthancPlugins::GetGlobalContext(), modifiedDicomBuffer, modifiedDicom.size()); memcpy(modifiedDicomBuffer->data, modifiedDicom.c_str(), modifiedDicom.size()); - + return OrthancPluginReceivedInstanceAction_Modify; } @@ -70,7 +70,7 @@ ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); return -1; } - + ORTHANC_PLUGINS_LOG_WARNING("Sanitizer plugin is initializing"); OrthancPlugins::SetDescription(ORTHANC_PLUGIN_NAME, "Sample plugin to sanitize incoming DICOM instances."); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ServeFolders/OrthancFrameworkDependencies.cpp --- a/OrthancServer/Plugins/Samples/ServeFolders/OrthancFrameworkDependencies.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ServeFolders/OrthancFrameworkDependencies.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/ServeFolders/Plugin.cpp --- a/OrthancServer/Plugins/Samples/ServeFolders/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/ServeFolders/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -147,7 +147,7 @@ const char* url, const OrthancPluginHttpRequest* request) { - namespace fs = boost::filesystem; + namespace fs = boost::filesystem; if (request->method != OrthancPluginHttpMethod_Get) { @@ -166,7 +166,7 @@ fs::is_directory(parent) && !fs::is_regular_file(Orthanc::SystemToolbox::PathFromUtf8(folder) / item)) { - // On-the-fly generation of an "index.html" + // On-the-fly generation of an "index.html" std::string s; s += "\n"; s += " \n"; @@ -254,7 +254,7 @@ // The URI is relative to INDEX_URI ("/app/plugin-serve-folders.html") s += "
  • first + "/index.html\">" + it->first + "
  • \n"; } - + s += "\n"; } @@ -275,12 +275,12 @@ Json::Value::Members members = folders.getMemberNames(); // Register the callback for each base URI - for (Json::Value::Members::const_iterator + for (Json::Value::Members::const_iterator it = members.begin(); it != members.end(); ++it) { if (folders[*it].type() != Json::stringValue) { - ORTHANC_PLUGINS_LOG_ERROR("The folder to be served \"" + *it + + ORTHANC_PLUGINS_LOG_ERROR("The folder to be served \"" + *it + "\" must be associated with a string value (its mapped URI)"); ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); } @@ -335,12 +335,12 @@ Json::Value::Members members = extensions.getMemberNames(); - for (Json::Value::Members::const_iterator + for (Json::Value::Members::const_iterator it = members.begin(); it != members.end(); ++it) { if (extensions[*it].type() != Json::stringValue) { - ORTHANC_PLUGINS_LOG_ERROR("The file extension \"" + *it + + ORTHANC_PLUGINS_LOG_ERROR("The file extension \"" + *it + "\" must be associated with a string value (its MIME type)"); ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); } @@ -367,7 +367,7 @@ ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: Associating file extension \"." + name + "\" with MIME type \"" + mime + "\""); } - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp --- a/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -163,7 +163,7 @@ else { return OrthancPluginErrorCode_StorageAreaPlugin; - } + } } static OrthancPluginErrorCode StorageReadRange(OrthancPluginMemoryBuffer64* target, @@ -196,7 +196,7 @@ else { return OrthancPluginErrorCode_StorageAreaPlugin; - } + } } #endif diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/StorageCommitmentScp/Plugin.cpp --- a/OrthancServer/Plugins/Samples/StorageCommitmentScp/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/StorageCommitmentScp/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -32,12 +32,12 @@ { private: int count_; - + public: StorageCommitmentSample() : count_(0) { } - + virtual OrthancPluginStorageCommitmentFailureReason Lookup(const std::string& sopClassUid, const std::string& sopInstanceUid) { @@ -61,7 +61,7 @@ { /*std::string s; OrthancPlugins::RestApiPost(s, "/jobs/" + std::string(jobId) + "/pause", NULL, 0, false);*/ - + printf("[%s] [%s] [%s] [%s]\n", jobId, transactionUid, remoteAet, calledAet); for (uint32_t i = 0; i < countInstances; i++) @@ -95,7 +95,7 @@ c, StorageCommitmentScp, OrthancPlugins::IStorageCommitmentScpHandler::Destructor, OrthancPlugins::IStorageCommitmentScpHandler::Lookup); - + return 0; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/WebDavFilesystem/Plugin.cpp --- a/OrthancServer/Plugins/Samples/WebDavFilesystem/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/WebDavFilesystem/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -35,10 +35,10 @@ public: Resource() : - dateTime_(boost::posix_time::second_clock::universal_time()) + dateTime_(boost::posix_time::second_clock::universal_time()) { } - + virtual ~Resource() { } @@ -58,7 +58,7 @@ { private: std::string content_; - + public: File(const void* data, size_t size) : @@ -75,7 +75,7 @@ { return false; } - + virtual Resource* LookupPath(const std::vector& path) ORTHANC_OVERRIDE { if (path.empty()) @@ -126,14 +126,14 @@ return NULL; } else - { + { std::vector childPath(path.size() - 1); - + for (size_t i = 0; i < childPath.size(); i++) { childPath[i] = path[i + 1]; } - + return found->second->LookupPath(childPath); } } @@ -147,7 +147,7 @@ assert(it->second != NULL); const std::string dateTime = boost::posix_time::to_iso_string(it->second->GetDateTime()); - + if (it->second->IsFolder()) { subfolders.push_back(OrthancPlugins::IWebDavCollection::FolderInfo(it->first, dateTime)); @@ -224,7 +224,7 @@ else { std::vector p(path.size() - 1); - + for (size_t i = 0; i < p.size(); i++) { p[i] = path[i]; @@ -239,11 +239,11 @@ root_(new Folder) { } - + virtual bool IsExistingFolder(const std::vector& path) { boost::mutex::scoped_lock lock(mutex_); - + const Resource* resource = root_->LookupPath(path); return (resource != NULL && resource->IsFolder()); @@ -254,7 +254,7 @@ const std::vector& path) { boost::mutex::scoped_lock lock(mutex_); - + Resource* resource = root_->LookupPath(path); if (resource != NULL && resource->IsFolder()) @@ -267,14 +267,14 @@ return false; } } - + virtual bool GetFile(std::string& content /* out */, std::string& mime /* out */, std::string& dateTime /* out */, const std::vector& path) { boost::mutex::scoped_lock lock(mutex_); - + Resource* resource = root_->LookupPath(path); if (resource != NULL && !resource->IsFolder()) @@ -296,7 +296,7 @@ size_t size) { boost::mutex::scoped_lock lock(mutex_); - + Resource* parent = root_->LookupPath(GetParentPath(path)); if (parent != NULL && parent->IsFolder()) @@ -309,11 +309,11 @@ return false; } } - + virtual bool CreateFolder(const std::vector& path) { boost::mutex::scoped_lock lock(mutex_); - + Resource* parent = root_->LookupPath(GetParentPath(path)); if (parent != NULL && parent->IsFolder()) @@ -330,7 +330,7 @@ virtual bool DeleteItem(const std::vector& path) { boost::mutex::scoped_lock lock(mutex_); - + Resource* parent = root_->LookupPath(GetParentPath(path)); if (parent != NULL && parent->IsFolder()) @@ -341,7 +341,7 @@ else { return false; - } + } } }; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/WebSkeleton/Configuration.h --- a/OrthancServer/Plugins/Samples/WebSkeleton/Configuration.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/WebSkeleton/Configuration.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py --- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py Wed Aug 19 14:11:33 2026 +0200 @@ -71,7 +71,7 @@ if resourceName in resources: raise Exception("Twice the same resource: " + resourceName) - + if os.path.isdir(pathName): # The resource is a directory: Recursively explore its files content = {} @@ -143,7 +143,7 @@ if resources[name]['Type'] == 'File': if isFirst: isFirst = False - else: + else: header.write(',\n') header.write(' %s' % name) @@ -159,7 +159,7 @@ if resources[name]['Type'] == 'Directory': if isFirst: isFirst = False - else: + else: header.write(',\n') header.write(' %s' % name) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/WebSkeleton/Framework/Framework.cmake --- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Framework.cmake Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Framework.cmake Wed Aug 19 14:11:33 2026 +0200 @@ -9,7 +9,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,7 +33,7 @@ OUTPUT "${AUTOGENERATED_DIR}/EmbeddedResources.h" "${AUTOGENERATED_DIR}/EmbeddedResources.cpp" - COMMAND + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/Framework/EmbedResources.py" "${AUTOGENERATED_DIR}/EmbeddedResources" diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp --- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -116,7 +116,7 @@ } content.resize(size); - + if (fseek(fp, 0, SEEK_SET) == -1) { fclose(fp); @@ -226,7 +226,7 @@ ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) { context = c; - + /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(c) == 0) { @@ -251,7 +251,7 @@ #endif OrthancPluginRegisterRestCallback(context, "/", RedirectRoot); - + return 0; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/CodeModel/GenerateCodeModel.py --- a/OrthancServer/Resources/CodeModel/GenerateCodeModel.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/CodeModel/GenerateCodeModel.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Configuration.json --- a/OrthancServer/Resources/Configuration.json Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Configuration.json Wed Aug 19 14:11:33 2026 +0200 @@ -3,8 +3,8 @@ * General configuration of Orthanc * * As a general recommendation, you should always favor absolute - * paths when you need to provide a path to a file or a directory. - * This is not done in this configuration file since we don't know + * paths when you need to provide a path to a file or a directory. + * This is not done in this configuration file since we don't know * where Orthanc is going to be installed. **/ @@ -40,7 +40,7 @@ // if the instance was sent through C-STORE, a 507 HTTP status code // if using the REST API and a 0xA700 Failure reason when using // DICOMweb STOW-RS. - // Note: this value is taken into account only if you have set + // Note: this value is taken into account only if you have set // a MaximumStorageSize != 0 or a MaximumPatientCount != 0 // Allowed values: "Recycle", "Reject" // (new in Orthanc 1.11.2) @@ -184,7 +184,7 @@ "Mpeg4TransferSyntaxAccepted" : true, // New in Orthanc 1.6.0 "H265TransferSyntaxAccepted" : true, // New in Orthanc 1.9.0 **/ - + // Whether Orthanc accepts to act as C-STORE SCP for unknown storage // SOP classes (aka. "promiscuous mode") "UnknownSopClassAccepted" : false, @@ -245,11 +245,11 @@ // Path to a file containing the concatenation of the client SSL // certificate(s) that are trusted to verify the identity of remote - // HTTP clients. The individual certificate(s) or root CAs must be - // stored in the PEM format. This option is only meaningful - // if "SslVerifyPeers" is true. + // HTTP clients. The individual certificate(s) or root CAs must be + // stored in the PEM format. This option is only meaningful + // if "SslVerifyPeers" is true. "SslTrustedClientCertificates" : "trustedClientCertificates.pem", - + // Whether or not the password protection is enabled (using HTTP // basic access authentication). Starting with Orthanc 1.5.8, if // "AuthenticationEnabled" is not explicitly set, authentication is @@ -298,7 +298,7 @@ /** "DicomTlsTrustedCertificates" : "trusted.crt", **/ - + // Whether Orthanc rejects DICOM TLS connections to/from remote // modalities that do not provide a certificate. Setting this option // to "true" (resp. "false") corresponds to "--require-peer-cert" @@ -307,7 +307,7 @@ // Once you set this configuration to true, you must provide a list of // trusted certificates in DicomTlsTrustedCertificates. "DicomTlsRemoteCertificateRequired" : true, - + // Whether the Orthanc SCP allows incoming C-ECHO requests, even // from SCU modalities it does not know about (i.e. that are not // listed in the "DicomModalities" option above). Orthanc 1.3.0 @@ -328,7 +328,7 @@ // "DicomAlwaysAllowFindWorklist" for worklists. "DicomAlwaysAllowFind" : false, - // Whether the Orthanc SCP allows incoming C-FIND requests for worklists, + // Whether the Orthanc SCP allows incoming C-FIND requests for worklists, // even from SCU modalities it does not know about (i.e. that are not // listed in the "DicomModalities" option above). Setting this // option to "true" implies security risks. (new in Orthanc 1.10.0) @@ -367,7 +367,7 @@ * connect to an instance of the "storescp" open-source DICOM * store (shipped in the DCMTK distribution), as started by the * command line "storescp 2000". The first parameter is the - * AET of the remote modality (cannot be longer than 16 + * AET of the remote modality (cannot be longer than 16 * characters), the second one is the remote network address, * and the third one is the TCP port number corresponding * to the DICOM protocol on the remote modality (usually 104). @@ -378,7 +378,7 @@ * A fourth parameter is available to enable patches for * specific PACS manufacturers. The allowed values are currently: * - "Generic" (default value), - * - "GenericNoWildcardInDates" (to replace "*" by "" in date fields + * - "GenericNoWildcardInDates" (to replace "*" by "" in date fields * in outgoing C-FIND requests originating from Orthanc), * - "GenericNoUniversalWildcard" (to replace "*" by "" in all fields * in outgoing C-FIND SCU requests originating from Orthanc), @@ -412,9 +412,9 @@ * the global option "EnableTranscoding" is set to "true". * * By default, all "Allow*" options are true. - * "AllowStorageCommitment" is actually an alias for + * "AllowStorageCommitment" is actually an alias for * "AllowNAction" & "AllowEventReport". - * + * * The "UseDicomTls" option specifies whether DICOM TLS should be * used when opening a SCU connection from Orthanc to this remote * modality. By default, DICOM TLS is not enabled. @@ -480,7 +480,7 @@ // Number of threads that are used by the embedded DICOM server. // This defines the number of concurrent DICOM operations that can - // be run when Orthanc is acting as SCP. + // be run when Orthanc is acting as SCP. // Note: This is not limiting the number of concurrent connections // but the number of concurrent DICOM operations. // For instance, with a single thread, if a C-FIND request is received during @@ -607,7 +607,7 @@ // (such as PatientName). By default, the search is // case-insensitive, which does not follow the DICOM standard. "CaseSensitivePN" : false, - + // If set to "false", Orthanc will not load its default dictionary // of private tags. This might be necessary if you cannot import a // DICOM file encoded using the Implicit VR Endian transfer syntax, @@ -690,7 +690,7 @@ // corresponding to "Never" and true corresponding to "Always". // Boolean values are still accepted for backward compatibility. // "OverwriteInstances" : "Never", - "OverwriteInstances" : "Never", + "OverwriteInstances" : "Never", // Maximum number of ZIP/media archives that are maintained by // Orthanc, as a response to the asynchronous creation of archives. @@ -760,11 +760,11 @@ // Implicit, Little Endian Explicit or Big Endian Explicit (new in // Orthanc 1.8.2). "IngestTranscodingOfUncompressed" : true, - + // Whether ingest transcoding is applied to incoming DICOM instances // that have a compressed transfer syntax (new in Orthanc 1.8.2). "IngestTranscodingOfCompressed" : true, - + // The default compression level that is used when transcoding to one // of the lossy/JPEG transfer syntaxes (integer between 1 and 100). // This value is currently only used by the default built-in DCMTK @@ -816,7 +816,7 @@ // Extra Main Dicom tags that are stored in DB together with all default // Main Dicom tags that are already stored. - // see https://orthanc.uclouvain.be/book/faq/main-dicom-tags.html + // see https://orthanc.uclouvain.be/book/faq/main-dicom-tags.html // (new in Orthanc 1.11.0) // Sequences tags are not supported. /** @@ -840,7 +840,7 @@ */ // Configure Orthanc in read only mode. - // In this mode, many Orthanc features that requires a write access to the + // In this mode, many Orthanc features that requires a write access to the // Index DB or the disk storage won't be available at all. // (new in Orthanc 1.12.5) "ReadOnly" : false, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/DicomConformanceStatement.py --- a/OrthancServer/Resources/DicomConformanceStatement.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/DicomConformanceStatement.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Fonts/GenerateFont.py --- a/OrthancServer/Resources/Fonts/GenerateFont.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Fonts/GenerateFont.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/GenerateAnonymizationProfile.py --- a/OrthancServer/Resources/GenerateAnonymizationProfile.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/GenerateAnonymizationProfile.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -50,17 +50,17 @@ def FormatLine(command, name): indentation = 65 - + if len(command) > indentation: indentation = len(command) + 2 - + line = command + (' ' * (indentation - len(command))) + '// ' + name LINES.append(line) def FormatUnknown(rawTag, name, profile): FormatLine('// TODO: %s with rule %s' % (rawTag, profile), name) - + RAW_TAG_RE = re.compile(r'^\(\s*([0-9A-Fx]{4})\s*,\s*([0-9A-Fx]{4})\s*\)$') @@ -121,7 +121,7 @@ for line in sorted(LINES): print(line.encode('ascii', 'ignore').decode('ascii')) - + # D - replace with a non-zero length value that may be a dummy value and consistent with the VR # Z - replace with a zero length value, or a non-zero length value that may be a dummy value and consistent with the VR diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/PreventProtobufDirectoryLeaks.py --- a/OrthancServer/Resources/PreventProtobufDirectoryLeaks.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/PreventProtobufDirectoryLeaks.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py --- a/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -99,7 +99,7 @@ creds_str_bytes_b64 = b'Basic ' + base64.b64encode(creds_str_bytes) headers['authorization'] = creds_str_bytes_b64.decode('ascii') - resp, content = h.request(URL, 'POST', + resp, content = h.request(URL, 'POST', body = content, headers = headers) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py --- a/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -36,7 +36,7 @@ parser = argparse.ArgumentParser(description = 'Command-line tool to import files or archives into Orthanc.') -parser.add_argument('--url', +parser.add_argument('--url', default = 'http://localhost:8042', help = 'URL to the REST API of the Orthanc server') parser.add_argument('--username', @@ -99,7 +99,7 @@ if IsJson(dicom): COUNT_JSON += 1 return - + auth = HTTPBasicAuth(args.username, args.password) r = requests.post('%s/instances' % args.url, auth = auth, data = dicom) @@ -113,14 +113,14 @@ return else: raise - + info = r.json() COUNT_DICOM += 1 if (isinstance(info, dict) and not info['ParentStudy'] in IMPORTED_STUDIES): IMPORTED_STUDIES.add(info['ParentStudy']) - + r2 = requests.get('%s/instances/%s/tags?short' % (args.url, info['ID']), auth = auth) r2.raise_for_status() @@ -145,7 +145,7 @@ UploadBuffer(dicom) - + def UploadBzip2(path): with bz2.BZ2File(path, 'rb') as f: dicom = f.read() @@ -154,7 +154,7 @@ UploadBuffer(dicom) - + def UploadGzip(path): with gzip.open(path, 'rb') as f: dicom = f.read() @@ -163,7 +163,7 @@ UploadBuffer(dicom) - + def UploadTar(path, decoder): if args.verbose: print('Uncompressing tar archive: %s' % path) @@ -179,7 +179,7 @@ UploadBuffer(dicom) - + def UploadZip(path): if args.verbose: print('Uncompressing ZIP archive: %s' % path) @@ -197,11 +197,11 @@ def DecodeFile(path): extension = os.path.splitext(path) [1] - + if path.endswith('.tar.bz2'): UploadTar(path, 'r:bz2') elif path.endswith('.tar.gz'): - UploadTar(path, 'r:gz') + UploadTar(path, 'r:gz') elif extension == '.zip': UploadZip(path) elif extension == '.tar': @@ -212,7 +212,7 @@ UploadGzip(path) else: UploadFile(path) - + if args.clear: print('Removing the content of Orthanc') @@ -222,14 +222,14 @@ r.raise_for_status() print(' %d studies are being removed...' % len(r.json())) - + for study in r.json(): requests.delete('%s/studies/%s' % (args.url, study), auth = auth).raise_for_status() print('Orthanc is now empty') print('') - - + + for path in args.files: if os.path.isfile(path): DecodeFile(path) @@ -239,7 +239,7 @@ DecodeFile(os.path.join(root, name)) else: raise Exception('Missing file or directory: %s' % path) - + print('') @@ -247,7 +247,7 @@ print('SUCCESS:') else: print('WARNING:') - + print(' %d DICOM instances properly imported' % COUNT_DICOM) print(' %d DICOM studies properly imported' % len(IMPORTED_STUDIES)) print(' %d JSON files ignored' % COUNT_JSON) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/AnonymizeAllPatients.py --- a/OrthancServer/Resources/Samples/Python/AnonymizeAllPatients.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/AnonymizeAllPatients.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/ArchiveAllPatients.py --- a/OrthancServer/Resources/Samples/Python/ArchiveAllPatients.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/ArchiveAllPatients.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py --- a/OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/AutoClassify.py --- a/OrthancServer/Resources/Samples/Python/AutoClassify.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/AutoClassify.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -49,7 +49,7 @@ def FixPath(p): s = p.encode('ascii', errors = 'replace').decode('ascii') - + for c in "'\/:*?\"<>|!=": s = s.replace(c, '') @@ -76,19 +76,19 @@ c = '%s - %s' % (GetTag(series, 'Modality'), GetTag(series, 'SeriesDescription')) d = '%s.dcm' % GetTag(instance, 'SOPInstanceUID') - + p = os.path.join(args.target, FixPath(a), FixPath(b), FixPath(c)) f = os.path.join(p, FixPath(d)) # Copy the DICOM file to the target path print('Writing new DICOM file: %s' % f) - + try: os.makedirs(p) except: # Already existing directory, ignore the error pass - + dcm = RestToolbox.DoGet('%s/instances/%s/file' % (URL, instanceId)) with open(f, 'wb') as g: g.write(dcm) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/ChangesLoop.py --- a/OrthancServer/Resources/Samples/Python/ChangesLoop.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/ChangesLoop.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -53,7 +53,7 @@ def NewInstanceReceived(path): global URL patientName = RestToolbox.DoGet(URL + path + '/content/PatientName') - + # Remove the possible trailing characters due to DICOM padding patientName = patientName.strip() @@ -63,7 +63,7 @@ ## ## Main loop that listens to the changes API. -## +## current = 0 while True: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/ContinuousPatientAnonymization.py --- a/OrthancServer/Resources/Samples/Python/ContinuousPatientAnonymization.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/ContinuousPatientAnonymization.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -64,7 +64,7 @@ # Ignore anonymized patients if not 'AnonymizedFrom' in patient: print('Patient with ID "%s" is stabilized: anonymizing it...' % (patientID)) - + # The PatientID after anonymization is taken as the 8 first # characters from the MD5 hash of the original PatientID h = hashlib.md5(patientID.encode('ascii')) @@ -84,7 +84,7 @@ ## ## Main loop that listens to the changes API. -## +## current = 0 while True: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/DeleteAllStudies.py --- a/OrthancServer/Resources/Samples/Python/DeleteAllStudies.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/DeleteAllStudies.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/DicomizeImage.py --- a/OrthancServer/Resources/Samples/Python/DicomizeImage.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/DicomizeImage.py Wed Aug 19 14:11:33 2026 +0200 @@ -74,7 +74,7 @@ 'PatientID' : 'Test', 'PatientName' : 'Hello^World', 'PatientSex' : 'O', - + 'PatientBirthDate' : None, 'StudyID' : 'Test', 'ReferringPhysicianName' : None, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/DownloadAnonymized.py --- a/OrthancServer/Resources/Samples/Python/DownloadAnonymized.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/DownloadAnonymized.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py --- a/OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py Wed Aug 19 14:11:33 2026 +0200 @@ -12,7 +12,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -91,7 +91,7 @@ def Consumer(queue): TIMEOUT = 0.1 - + while True: instances = [] diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/ManualModification.py --- a/OrthancServer/Resources/Samples/Python/ManualModification.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/ManualModification.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -39,7 +39,7 @@ for instance in DoGet('%s/studies/%s/instances' % (URL, STUDY)): # Setup the parameters of the modification - replace = { + replace = { "PatientID" : "Hello", "PatientName" : "Modified", "StationName" : "TEST", diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/Replicate.py --- a/OrthancServer/Resources/Samples/Python/Replicate.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/Replicate.py Wed Aug 19 14:11:33 2026 +0200 @@ -11,7 +11,7 @@ # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -79,7 +79,7 @@ return content else: raise Exception('Unable to contact Orthanc at: ' + url) - + def DoPostDicom(url, body): global URL_REGEX @@ -94,7 +94,7 @@ if resp.status != 200: raise Exception('Unable to contact Orthanc at: ' + url) - + def _DecodeJson(s): if (sys.version_info >= (3, 0)): diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Python/RestToolbox.py --- a/OrthancServer/Resources/Samples/Python/RestToolbox.py Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Python/RestToolbox.py Wed Aug 19 14:11:33 2026 +0200 @@ -57,7 +57,7 @@ d = '?' + urlencode(data) return uri + d - + def DoGet(uri, data = {}, interpretAsJson = True): h = httplib2.Http() _SetupCredentials(h) @@ -93,7 +93,7 @@ else: body = json.dumps(data) headers = { 'content-type' : 'application/json' } - + resp, content = h.request( uri, method, body = body, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Samples/Tools/RecoverCompressedFile.cpp --- a/OrthancServer/Resources/Samples/Tools/RecoverCompressedFile.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Samples/Tools/RecoverCompressedFile.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -81,8 +81,8 @@ Orthanc::ZlibCompressor compressor; std::string uncompressed; - compressor.Uncompress(uncompressed, - content.empty() ? NULL : content.c_str(), + compressor.Uncompress(uncompressed, + content.empty() ? NULL : content.c_str(), content.size()); fprintf(stderr, "Writing the uncompressed data...\n"); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Resources/Testing/Issue32/Cpp/main.cpp --- a/OrthancServer/Resources/Testing/Issue32/Cpp/main.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Resources/Testing/Issue32/Cpp/main.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -17,7 +17,7 @@ //client.SetUrl("http://localhost:8042/"); //client.SetCredentials("orthanc", "orthanc"); client.SetRedirectionFollowed(false); - + while (!(*done)) { try @@ -79,7 +79,7 @@ delete threads[i]; } } - + Orthanc::HttpClient::GlobalFinalize(); printf("OK\n"); return 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/BaseCompatibilityTransaction.cpp --- a/OrthancServer/Sources/Database/BaseCompatibilityTransaction.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/BaseCompatibilityTransaction.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/BaseCompatibilityTransaction.h --- a/OrthancServer/Sources/Database/BaseCompatibilityTransaction.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/BaseCompatibilityTransaction.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/DatabaseLookup.cpp --- a/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -73,15 +73,15 @@ return *constraints_[i]; } } - + void Add(const DatabaseDicomTagConstraint& constraint) { constraints_.push_back(new DicomTagConstraint(constraint)); - } + } }; } - - + + static void ApplyIdentifierConstraint(SetOfResources& candidates, ILookupResources& compatibility, const DatabaseDicomTagConstraint& constraint, @@ -95,24 +95,24 @@ compatibility.LookupIdentifier(matches, level, constraint.GetTag(), IdentifierConstraintType_Equal, constraint.GetSingleValue()); break; - + case ConstraintType_SmallerOrEqual: compatibility.LookupIdentifier(matches, level, constraint.GetTag(), IdentifierConstraintType_SmallerOrEqual, constraint.GetSingleValue()); break; - + case ConstraintType_GreaterOrEqual: compatibility.LookupIdentifier(matches, level, constraint.GetTag(), IdentifierConstraintType_GreaterOrEqual, constraint.GetSingleValue()); break; - + case ConstraintType_Wildcard: compatibility.LookupIdentifier(matches, level, constraint.GetTag(), IdentifierConstraintType_Wildcard, constraint.GetSingleValue()); break; - + case ConstraintType_List: for (size_t i = 0; i < constraint.GetValuesCount(); i++) { @@ -123,7 +123,7 @@ } break; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -131,7 +131,7 @@ candidates.Intersect(matches); } - + static void ApplyIdentifierRange(SetOfResources& candidates, ILookupResources& compatibility, const DatabaseDicomTagConstraint& smaller, @@ -149,7 +149,7 @@ candidates.Intersect(matches); } - + static void ApplyLevel(SetOfResources& candidates, IDatabaseWrapper::ITransaction& transaction, ILookupResources& compatibility, @@ -165,7 +165,7 @@ Identifiers identifiers; SetOfConstraints mainTags; - + for (size_t i = 0; i < lookup.GetSize(); i++) { const DatabaseDicomTagConstraint& constraint = lookup.GetConstraint(i); @@ -183,9 +183,9 @@ } } - + // (2) Apply the constraints over the identifiers - + for (Identifiers::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it) { @@ -193,12 +193,12 @@ // present at this level const DatabaseDicomTagConstraint* smaller = NULL; const DatabaseDicomTagConstraint* greater = NULL; - + for (SetOfConstraints::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { assert(*it2 != NULL); - + if ((*it2)->GetConstraintType() == ConstraintType_SmallerOrEqual) { smaller = *it2; @@ -242,7 +242,7 @@ { MainTagsConstraints c; c.Reserve(mainTags.size()); - + for (SetOfConstraints::const_iterator it = mainTags.begin(); it != mainTags.end(); ++it) { @@ -255,7 +255,7 @@ candidates.Clear(); std::list filtered; - for (std::list::const_iterator candidate = source.begin(); + for (std::list::const_iterator candidate = source.begin(); candidate != source.end(); ++candidate) { DicomMap tags; @@ -271,7 +271,7 @@ break; } } - + if (match) { filtered.push_back(*candidate); @@ -293,18 +293,18 @@ std::list children; compatibility.GetChildrenInternalId(children, resource); - + if (children.empty()) { throw OrthancException(ErrorCode_Database); } - + resource = children.front(); } return compatibility.GetPublicId(resource); } - + void DatabaseLookup::ApplyLookupResources(std::list& resourcesId, std::list* instancesId, @@ -318,7 +318,7 @@ assert(ResourceType_Patient < ResourceType_Study && ResourceType_Study < ResourceType_Series && ResourceType_Series < ResourceType_Instance); - + ResourceType upperLevel = queryLevel; ResourceType lowerLevel = queryLevel; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/DatabaseLookup.h --- a/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/GenericFind.cpp --- a/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -501,7 +501,7 @@ { ResourceType childrenLevel = GetChildResourceType(currentLevel); - if (request.GetChildrenSpecification(childrenLevel).IsRetrieveIdentifiers() || + if (request.GetChildrenSpecification(childrenLevel).IsRetrieveIdentifiers() || request.GetChildrenSpecification(childrenLevel).IsRetrieveCount()) { for (std::list::const_iterator it = currentIds.begin(); it != currentIds.end(); ++it) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ICreateInstance.cpp --- a/OrthancServer/Sources/Database/Compatibility/ICreateInstance.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ICreateInstance.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -44,7 +44,7 @@ { ResourceType type; int64_t tmp; - + if (database.LookupResource(tmp, type, hashInstance)) { // The instance already exists @@ -62,7 +62,7 @@ result.patientId_ = -1; result.studyId_ = -1; result.seriesId_ = -1; - + // Detect up to which level the patient/study/series/instance // hierarchy must be created @@ -139,7 +139,7 @@ } database.TagMostRecentPatient(result.patientId_); - + // Sanity checks assert(result.patientId_ != -1); assert(result.studyId_ != -1); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ICreateInstance.h --- a/OrthancServer/Sources/Database/Compatibility/ICreateInstance.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ICreateInstance.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -43,7 +43,7 @@ int64_t child) = 0; virtual void TagMostRecentPatient(int64_t patientId) = 0; - + static bool Apply(ICreateInstance& database, IDatabaseWrapper::CreateInstanceResult& result, int64_t& instanceId, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.cpp --- a/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -38,11 +38,11 @@ // Loop over the instances of this series target.clear(); - + std::list children; database.GetChildrenInternalId(children, resourceId); - for (std::list::const_iterator + for (std::list::const_iterator it = children.begin(); it != children.end(); ++it) { std::string value; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.h --- a/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.cpp --- a/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.h --- a/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ILookupResources.cpp --- a/OrthancServer/Sources/Database/Compatibility/ILookupResources.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ILookupResources.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ILookupResources.h --- a/OrthancServer/Sources/Database/Compatibility/ILookupResources.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ILookupResources.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -35,21 +35,21 @@ * during the optimization of the database engine. **/ class ILookupResources : public boost::noncopyable - { + { public: virtual ~ILookupResources() { } - + virtual void GetAllInternalIds(std::list& target, ResourceType resourceType) = 0; - + virtual void LookupIdentifier(std::list& result, ResourceType level, const DicomTag& tag, IdentifierConstraintType type, const std::string& value) = 0; - + virtual void LookupIdentifierRange(std::list& result, ResourceType level, const DicomTag& tag, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/ISetResourcesContent.h --- a/OrthancServer/Sources/Database/Compatibility/ISetResourcesContent.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/ISetResourcesContent.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -35,7 +35,7 @@ virtual ~ISetResourcesContent() { } - + virtual void SetMainDicomTag(int64_t id, const DicomTag& tag, const std::string& value) = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/SetOfResources.cpp --- a/OrthancServer/Sources/Database/Compatibility/SetOfResources.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/SetOfResources.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -76,7 +76,7 @@ { std::unique_ptr children(new Resources); - for (Resources::const_iterator it = resources_->begin(); + for (Resources::const_iterator it = resources_->begin(); it != resources_->end(); ++it) { std::list tmp; @@ -119,7 +119,7 @@ void SetOfResources::Flatten(std::list& result) { result.clear(); - + if (resources_.get() == NULL) { // All the resources of this level are part of the filter @@ -127,7 +127,7 @@ } else { - for (Resources::const_iterator it = resources_->begin(); + for (Resources::const_iterator it = resources_->begin(); it != resources_->end(); ++it) { result.push_back(transaction_.GetPublicId(*it)); @@ -140,7 +140,7 @@ std::list& result) { result.clear(); - + if (resources_.get() == NULL) { // All the resources of this level are part of the filter @@ -148,7 +148,7 @@ } else { - for (Resources::const_iterator it = resources_->begin(); + for (Resources::const_iterator it = resources_->begin(); it != resources_->end(); ++it) { result.push_back(*it); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/Compatibility/SetOfResources.h --- a/OrthancServer/Sources/Database/Compatibility/SetOfResources.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/SetOfResources.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -42,10 +42,10 @@ IDatabaseWrapper::ITransaction& transaction_; ResourceType level_; std::unique_ptr resources_; - + public: SetOfResources(IDatabaseWrapper::ITransaction& transaction, - ResourceType level) : + ResourceType level) : transaction_(transaction), level_(level) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/FindRequest.cpp --- a/OrthancServer/Sources/Database/FindRequest.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -233,7 +233,7 @@ } - void FindRequest::AddOrdering(MetadataType metadataType, + void FindRequest::AddOrdering(MetadataType metadataType, OrderingCast cast, OrderingDirection direction) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/FindRequest.h --- a/OrthancServer/Sources/Database/FindRequest.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.h Wed Aug 19 14:11:33 2026 +0200 @@ -70,7 +70,7 @@ KeyType type_; DicomTag dicomTag_; MetadataType metadata_; - + // TODO-FIND: to execute the query, we actually need: // ResourceType level_; // DicomTagType dicomTagType_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/IDatabaseListener.h --- a/OrthancServer/Sources/Database/IDatabaseListener.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/IDatabaseListener.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/IDatabaseWrapper.h --- a/OrthancServer/Sources/Database/IDatabaseWrapper.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -117,7 +117,7 @@ { return hasAttachmentCustomDataSupport_; } - + void SetHasExtendedChanges(bool value) { hasExtendedChanges_ = value; @@ -278,7 +278,7 @@ virtual ResourceType GetResourceType(int64_t resourceId) = 0; virtual uint64_t GetTotalCompressedSize() = 0; - + virtual uint64_t GetTotalUncompressedSize() = 0; virtual bool IsProtectedPatient(int64_t internalId) = 0; @@ -293,7 +293,7 @@ const std::string& date) = 0; virtual void LogExportedResource(const ExportedResource& resource) = 0; - + virtual bool LookupAttachment(FileInfo& attachment, int64_t& revision, int64_t id, @@ -344,16 +344,16 @@ const std::string& value, int64_t revision) = 0; - virtual void SetProtectedPatient(int64_t internalId, + virtual void SetProtectedPatient(int64_t internalId, bool isProtected) = 0; /** * Primitives introduced in Orthanc 1.5.2 **/ - + virtual bool IsDiskSizeAbove(uint64_t threshold) = 0; - + // Returns "true" iff. the instance is new and has been inserted // into the database. If "false" is returned, the content of @@ -485,11 +485,11 @@ // New in Orthanc 1.12.10 virtual bool ReserveQueueValue(std::string& value /* out */, - uint64_t& valueId /* out */, + uint64_t& valueId /* out */, const std::string& queueId, QueueOrigin origin, uint32_t releaseTimeout) = 0; - + // New in Orthanc 1.12.10 virtual void AcknowledgeQueueValue(const std::string& queueId, uint64_t valueId) = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/MainDicomTagsRegistry.cpp --- a/OrthancServer/Sources/Database/MainDicomTagsRegistry.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/MainDicomTagsRegistry.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -129,7 +129,7 @@ } bool isEquivalentConstraint; - + // DicomIdentifiers are stored UPPERCASE -> as soon as a case senstive search happens, it is currently not possible to perform it in DB only if (type == DicomTagType_Identifier && source.GetConstraint(i).IsCaseSensitive()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/ResourcesContent.cpp --- a/OrthancServer/Sources/Database/ResourcesContent.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/ResourcesContent.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -69,7 +69,7 @@ { // The identifiers tags are a subset of the main DICOM tags assert(DicomMap::IsMainDicomTag(tags[i])); - + const DicomValue* value = map.TestAndGetValue(tags[i]); if (value != NULL && value->IsString()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/ResourcesContent.h --- a/OrthancServer/Sources/Database/ResourcesContent.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/ResourcesContent.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -36,7 +36,7 @@ { class ISetResourcesContent; } - + class ResourcesContent : public boost::noncopyable { public: @@ -116,7 +116,7 @@ typedef std::list ListTags; typedef std::list ListMetadata; - + private: bool isNewResource_; ListTags tags_; @@ -129,12 +129,12 @@ isNewResource_(isNewResource) { } - + void AddMainDicomTag(int64_t resourceId, const DicomTag& tag, const std::string& value) { - // avoid adding twice the same tag for the same resource e.g, when the same tag is registered at study and patient level + // avoid adding twice the same tag for the same resource e.g, when the same tag is registered at study and patient level // https://discourse.orthanc-server.org/t/jobs-api-the-dicommovescu-job-doesnt-seems-to-track-progress/3140/14 if (mainDicomTagsPerResource_.find(resourceId) == mainDicomTagsPerResource_.end()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -55,7 +55,7 @@ namespace Orthanc -{ +{ static std::string JoinRequestedMetadata(const FindRequest::ChildrenSpecification& childrenSpec) { std::set metadataTypes; @@ -72,14 +72,14 @@ static std::string JoinRequestedTags(const FindRequest::ChildrenSpecification& childrenSpec) { // note: SQLite does not seem to support (tagGroup, tagElement) in ((x, y), (z, w)) in complex subqueries. - // Therefore, since we expect the requested tag list to be short, we write it as + // Therefore, since we expect the requested tag list to be short, we write it as // ((tagGroup = x AND tagElement = y ) OR (tagGroup = z AND tagElement = w)) std::string sql = " ("; std::set tags; for (std::set::const_iterator it = childrenSpec.GetMainDicomTags().begin(); it != childrenSpec.GetMainDicomTags().end(); ++it) { - tags.insert("(tagGroup = " + boost::lexical_cast(it->GetGroup()) + tags.insert("(tagGroup = " + boost::lexical_cast(it->GetGroup()) + " AND tagElement = " + boost::lexical_cast(it->GetElement()) + ")"); } std::string joinedTags; @@ -114,7 +114,7 @@ values_.push_back(value); return "?"; } - + virtual std::string FormatResourceType(ResourceType level) ORTHANC_OVERRIDE { return boost::lexical_cast(level); @@ -143,7 +143,7 @@ sql += " OFFSET " + boost::lexical_cast(since); } - + return sql; } @@ -155,7 +155,7 @@ void Bind(SQLite::Statement& statement) const { int pos = 0; - + for (std::list::const_iterator it = values_.begin(); it != values_.end(); ++it, pos++) { @@ -164,7 +164,7 @@ } }; - + class SQLiteDatabaseWrapper::SignalRemainingAncestor : public SQLite::IScalarFunction { private: @@ -173,7 +173,7 @@ ResourceType remainingType_; public: - SignalRemainingAncestor() : + SignalRemainingAncestor() : hasRemainingAncestor_(false) { } @@ -241,9 +241,9 @@ { resourcesId.clear(); instancesId.clear(); - + std::unique_ptr statement; - + switch (level) { case ResourceType_Patient: @@ -256,7 +256,7 @@ "INNER JOIN Resources series ON studies.internalId=series.parentId " "INNER JOIN Resources instances ON series.internalId=instances.parentId " "GROUP BY patients.publicId")); - + break; } @@ -269,7 +269,7 @@ "INNER JOIN Resources series ON studies.internalId=series.parentId " "INNER JOIN Resources instances ON series.internalId=instances.parentId " "GROUP BY studies.publicId")); - + break; } @@ -281,7 +281,7 @@ "SELECT series.publicId, instances.publicID FROM Lookup AS series " "INNER JOIN Resources instances ON series.internalId=instances.parentId " "GROUP BY series.publicId")); - + break; } @@ -290,16 +290,16 @@ statement.reset( new SQLite::Statement( db_, SQLITE_FROM_HERE, "SELECT publicId, publicId FROM Lookup")); - + break; } - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } assert(statement.get() != NULL); - + while (statement->Step()) { resourcesId.push_back(statement->ColumnString(0)); @@ -310,7 +310,7 @@ void ClearTable(const std::string& tableName) { - db_.Execute("DELETE FROM " + tableName); + db_.Execute("DELETE FROM " + tableName); } @@ -336,7 +336,7 @@ } done = target.size() <= limit; // 'done' means "there are no more other changes of this type in that direction (depending on since/to)" - + // if we have retrieved more changes than requested -> cleanup if (target.size() > limit) { @@ -367,7 +367,7 @@ ResourceType resourceType = static_cast(s.ColumnInt(1)); std::string publicId = s.ColumnString(2); - ExportedResource resource(seq, + ExportedResource resource(seq, resourceType, publicId, s.ColumnString(3), // modality @@ -421,12 +421,12 @@ return listener_; } - + virtual void AddAttachment(int64_t id, const FileInfo& attachment, int64_t revision) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO AttachedFiles (id, fileType, uuid, compressedSize, uncompressedSize, compressionType, uncompressedMD5, compressedMD5, revision, customData) " "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); s.BindInt64(0, id); @@ -456,7 +456,7 @@ LookupFormatter::Apply(sql, formatter, lookup, queryLevel, labels, labelsConstraint, limit); sql = "CREATE TEMPORARY TABLE Lookup AS " + sql; // TODO-FIND: use a CTE (or is this method obsolete ?) - + { SQLite::Statement s(db_, SQLITE_FROM_HERE, "DROP TABLE IF EXISTS Lookup"); s.Run(); @@ -475,9 +475,9 @@ else { resourcesId.clear(); - + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT publicId FROM Lookup"); - + while (s.Step()) { resourcesId.push_back(s.ColumnString(0)); @@ -663,7 +663,7 @@ " NULL AS c11_big_int2 " " FROM OneInstance " " INNER JOIN Metadata ON Metadata.id = OneInstance.instanceInternalId "; - + sql += " UNION SELECT" " " TOSTRING(QUERY_ONE_INSTANCE_ATTACHMENTS) " AS c0_queryId, " " parentInternalId AS c1_internalId, " @@ -804,7 +804,7 @@ " NULL AS c11_big_int2 " "FROM Lookup " "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " - "INNER JOIN Metadata ON Metadata.id = currentLevel.parentId "; + "INNER JOIN Metadata ON Metadata.id = currentLevel.parentId "; } if (requestLevel > ResourceType_Study) @@ -873,7 +873,7 @@ " NULL AS c11_big_int2 " "FROM Lookup " " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " - " INNER JOIN MainDicomTags ON MainDicomTags.id = childLevel.internalId AND " + JoinRequestedTags(request.GetChildrenSpecification(static_cast(requestLevel + 1))); + " INNER JOIN MainDicomTags ON MainDicomTags.id = childLevel.internalId AND " + JoinRequestedTags(request.GetChildrenSpecification(static_cast(requestLevel + 1))); } // need MainDicomTags from grandchildren ? @@ -895,7 +895,7 @@ "FROM Lookup " " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " " INNER JOIN Resources grandChildLevel ON grandChildLevel.parentId = childLevel.internalId " - " INNER JOIN MainDicomTags ON MainDicomTags.id = grandChildLevel.internalId AND " + JoinRequestedTags(request.GetChildrenSpecification(static_cast(requestLevel + 2))); + " INNER JOIN MainDicomTags ON MainDicomTags.id = grandChildLevel.internalId AND " + JoinRequestedTags(request.GetChildrenSpecification(static_cast(requestLevel + 2))); } // need parent identifier ? @@ -1134,7 +1134,7 @@ case QUERY_MAIN_DICOM_TAGS: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddStringDicomTag(requestLevel, + res.AddStringDicomTag(requestLevel, static_cast(s.ColumnInt(C7_INT_1)), static_cast(s.ColumnInt(C8_INT_2)), s.ColumnString(C3_STRING_1)); @@ -1143,7 +1143,7 @@ case QUERY_PARENT_MAIN_DICOM_TAGS: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddStringDicomTag(static_cast(requestLevel - 1), + res.AddStringDicomTag(static_cast(requestLevel - 1), static_cast(s.ColumnInt(C7_INT_1)), static_cast(s.ColumnInt(C8_INT_2)), s.ColumnString(C3_STRING_1)); @@ -1152,7 +1152,7 @@ case QUERY_GRAND_PARENT_MAIN_DICOM_TAGS: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddStringDicomTag(static_cast(requestLevel - 2), + res.AddStringDicomTag(static_cast(requestLevel - 2), static_cast(s.ColumnInt(C7_INT_1)), static_cast(s.ColumnInt(C8_INT_2)), s.ColumnString(C3_STRING_1)); @@ -1161,7 +1161,7 @@ case QUERY_CHILDREN_MAIN_DICOM_TAGS: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddChildrenMainDicomTagValue(static_cast(requestLevel + 1), + res.AddChildrenMainDicomTagValue(static_cast(requestLevel + 1), DicomTag(static_cast(s.ColumnInt(C7_INT_1)), static_cast(s.ColumnInt(C8_INT_2))), s.ColumnString(C3_STRING_1)); }; break; @@ -1169,7 +1169,7 @@ case QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddChildrenMainDicomTagValue(static_cast(requestLevel + 2), + res.AddChildrenMainDicomTagValue(static_cast(requestLevel + 2), DicomTag(static_cast(s.ColumnInt(C7_INT_1)), static_cast(s.ColumnInt(C8_INT_2))), s.ColumnString(C3_STRING_1)); }; break; @@ -1177,7 +1177,7 @@ case QUERY_METADATA: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddMetadata(static_cast(requestLevel), + res.AddMetadata(static_cast(requestLevel), static_cast(s.ColumnInt(C7_INT_1)), s.ColumnString(C3_STRING_1), s.ColumnInt(C8_INT_2)); }; break; @@ -1185,7 +1185,7 @@ case QUERY_PARENT_METADATA: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddMetadata(static_cast(requestLevel - 1), + res.AddMetadata(static_cast(requestLevel - 1), static_cast(s.ColumnInt(C7_INT_1)), s.ColumnString(C3_STRING_1), s.ColumnInt(C8_INT_2)); }; break; @@ -1193,7 +1193,7 @@ case QUERY_GRAND_PARENT_METADATA: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddMetadata(static_cast(requestLevel - 2), + res.AddMetadata(static_cast(requestLevel - 2), static_cast(s.ColumnInt(C7_INT_1)), s.ColumnString(C3_STRING_1), s.ColumnInt(C8_INT_2)); }; break; @@ -1201,7 +1201,7 @@ case QUERY_CHILDREN_METADATA: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddChildrenMetadataValue(static_cast(requestLevel + 1), + res.AddChildrenMetadataValue(static_cast(requestLevel + 1), static_cast(s.ColumnInt(C7_INT_1)), s.ColumnString(C3_STRING_1)); }; break; @@ -1209,7 +1209,7 @@ case QUERY_GRAND_CHILDREN_METADATA: { FindResponse::Resource& res = response.GetResourceByInternalId(internalId); - res.AddChildrenMetadataValue(static_cast(requestLevel + 2), + res.AddChildrenMetadataValue(static_cast(requestLevel + 2), static_cast(s.ColumnInt(C7_INT_1)), s.ColumnString(C3_STRING_1)); }; break; @@ -1404,12 +1404,12 @@ void GetDeletedFileCustomData(std::string& customData, const std::string& uuid) { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT customData FROM DeletedFiles WHERE uuid=?"); s.BindString(0, uuid); - + if (s.Step()) - { + { if (s.ColumnIsNull(0) || !s.ColumnBlobAsString(0, &customData)) { @@ -1528,7 +1528,7 @@ sql = "SELECT * FROM Changes " + filtersString + " ORDER BY seq ASC LIMIT ?"; returnFirstResults = true; } - + SQLite::Statement s(db_, SQLITE_FROM_HERE_DYNAMIC(sql), sql); int paramCounter = 0; @@ -1558,7 +1558,7 @@ int64_t id) ORTHANC_OVERRIDE { SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.internalId FROM Resources AS a, Resources AS b " - "WHERE a.parentId = b.internalId AND b.internalId = ?"); + "WHERE a.parentId = b.internalId AND b.internalId = ?"); s.BindInt64(0, id); target.clear(); @@ -1574,7 +1574,7 @@ int64_t id) ORTHANC_OVERRIDE { SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.publicId FROM Resources AS a, Resources AS b " - "WHERE a.parentId = b.internalId AND b.internalId = ?"); + "WHERE a.parentId = b.internalId AND b.internalId = ?"); s.BindInt64(0, id); target.clear(); @@ -1591,7 +1591,7 @@ int64_t since, uint32_t limit) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM ExportedResources WHERE seq>? ORDER BY seq LIMIT ?"); s.BindInt64(0, since); s.BindInt(1, static_cast(limit) + 1); @@ -1609,7 +1609,7 @@ int64_t GetLastChangeIndex() ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT seq FROM sqlite_sequence WHERE name='Changes'"); if (s.Step()) @@ -1625,11 +1625,11 @@ } } - + virtual void GetLastExportedResource(std::list& target) ORTHANC_OVERRIDE { bool done; // Ignored - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1"); GetExportedResourcesInternal(target, done, s, 1); } @@ -1653,12 +1653,12 @@ virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT publicId FROM Resources WHERE internalId=?"); s.BindInt64(0, resourceId); - + if (s.Step()) - { + { return s.ColumnString(0); } else @@ -1670,10 +1670,10 @@ virtual uint64_t GetResourcesCount(ResourceType resourceType) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT COUNT(*) FROM Resources WHERE resourceType=?"); s.BindInt(0, resourceType); - + if (!s.Step()) { return 0; @@ -1689,16 +1689,16 @@ virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT resourceType FROM Resources WHERE internalId=?"); s.BindInt64(0, resourceId); - + if (s.Step()) { return static_cast(s.ColumnInt(0)); } else - { + { throw OrthancException(ErrorCode_UnknownResource); } } @@ -1722,7 +1722,7 @@ return static_cast(statement->ColumnInt64(0)); } - + virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE { std::unique_ptr statement; @@ -1762,7 +1762,7 @@ { target.clear(); - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT fileType FROM AttachedFiles WHERE id=?"); s.BindInt64(0, id); @@ -1790,7 +1790,7 @@ virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO ExportedResources (seq, resourceType, publicId, remoteModality, patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid, date) VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?)"); s.BindInt(0, resource.GetResourceType()); @@ -1801,7 +1801,7 @@ s.BindString(5, resource.GetSeriesInstanceUid()); s.BindString(6, resource.GetSopInstanceUid()); s.BindString(7, resource.GetDate()); - s.Run(); + s.Run(); } @@ -1810,7 +1810,7 @@ int64_t id, FileContentType contentType) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT uuid, uncompressedSize, compressionType, compressedSize, " "uncompressedMD5, compressedMD5, revision, customData FROM AttachedFiles WHERE id=? AND fileType=?"); s.BindInt64(0, id); @@ -1838,7 +1838,7 @@ virtual void GetAttachmentCustomData(std::string& customData, const std::string& attachmentUuid) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT customData FROM AttachedFiles WHERE uuid=?"); s.BindString(0, attachmentUuid); @@ -1863,7 +1863,7 @@ const void* customData, size_t customDataSize) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "UPDATE AttachedFiles SET customData=? WHERE uuid=?"); s.BindBlob(0, customData, customDataSize); s.BindString(1, attachmentUuid); @@ -1876,8 +1876,8 @@ { // The "shared" info is not used by the SQLite database, as it // can only be used by one Orthanc server. - - SQLite::Statement s(db_, SQLITE_FROM_HERE, + + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT value FROM GlobalProperties WHERE property=?"); s.BindInt(0, property); @@ -1898,7 +1898,7 @@ int64_t id, MetadataType type) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT value, revision FROM Metadata WHERE id=? AND type=?"); s.BindInt64(0, id); s.BindInt(1, type); @@ -1919,7 +1919,7 @@ virtual bool LookupParent(int64_t& parentId, int64_t resourceId) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT parentId FROM Resources WHERE internalId=?"); s.BindInt64(0, resourceId); @@ -1953,7 +1953,7 @@ ResourceType& type, const std::string& publicId) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT internalId, resourceType FROM Resources WHERE publicId=?"); s.BindString(0, publicId); @@ -1978,7 +1978,7 @@ { SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT patientId FROM PatientRecyclingOrder ORDER BY seq ASC LIMIT 1"); - + if (!s.Step()) { // No patient remaining or all the patients are protected @@ -1988,7 +1988,7 @@ { internalId = s.ColumnInt(0); return true; - } + } } @@ -2009,7 +2009,7 @@ { internalId = s.ColumnInt(0); return true; - } + } } @@ -2019,7 +2019,7 @@ { // The "shared" info is not used by the SQLite database, as it // can only be used by one Orthanc server. - + SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT OR REPLACE INTO GlobalProperties (property, value) VALUES(?, ?)"); s.BindInt(0, property); s.BindString(1, value); @@ -2041,7 +2041,7 @@ } - virtual void SetProtectedPatient(int64_t internalId, + virtual void SetProtectedPatient(int64_t internalId, bool isProtected) ORTHANC_OVERRIDE { if (isProtected) @@ -2108,7 +2108,7 @@ assert(db_.GetLastChangeCount() == 0 || db_.GetLastChangeCount() == 1); - + if (db_.GetLastChangeCount() == 0) { // The patient was protected, there was nothing to delete from the recycling order @@ -2164,7 +2164,7 @@ { target.clear(); - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT label FROM Labels WHERE id=?"); s.BindInt64(0, resource); @@ -2179,7 +2179,7 @@ { target.clear(); - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT DISTINCT label FROM Labels"); while (s.Step()) @@ -2213,7 +2213,7 @@ const std::string& storeId, const std::string& key) ORTHANC_OVERRIDE { - SQLite::Statement s(db_, SQLITE_FROM_HERE, + SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT value FROM KeyValueStores WHERE storeId=? AND key=?"); s.BindString(0, storeId); s.BindString(1, key); @@ -2233,7 +2233,7 @@ { return true; } - } + } } // New in Orthanc 1.12.8 @@ -2519,7 +2519,7 @@ } } }; - + class SQLiteDatabaseWrapper::SignalResourceDeleted : public SQLite::IScalarFunction { @@ -2553,7 +2553,7 @@ } }; - + class SQLiteDatabaseWrapper::ReadWriteTransaction : public SQLiteDatabaseWrapper::TransactionBase { private: @@ -2562,7 +2562,7 @@ int64_t initialDiskSize_; bool isNested_; - // Rationale for the isNested_ field: + // Rationale for the isNested_ field: // This was added while implementing the DelayedDeletion part of the advanced-storage plugin. // When Orthanc deletes an attachment, a SQLite transaction is created to delete the attachment from // the SQLite DB and, while the transaction is still active, the StorageRemove callback is called. @@ -2587,7 +2587,7 @@ { throw OrthancException(ErrorCode_InternalError, "Unable to create a nested RW transaction, the current transaction is not a RW transaction"); } - + isNested_ = true; } else @@ -2608,7 +2608,7 @@ { if (!isNested_) { - assert(that_.activeTransaction_ != NULL); + assert(that_.activeTransaction_ != NULL); that_.activeTransaction_ = NULL; } } @@ -2651,7 +2651,7 @@ private: SQLiteDatabaseWrapper& that_; bool isNested_; // see explanation on the ReadWriteTransaction - + public: ReadOnlyTransaction(SQLiteDatabaseWrapper& that, IDatabaseListener& listener, @@ -2666,7 +2666,7 @@ // THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } else - { + { that_.activeTransaction_ = this; } } @@ -2675,7 +2675,7 @@ { if (!isNested_) { - assert(that_.activeTransaction_ != NULL); + assert(that_.activeTransaction_ != NULL); that_.activeTransaction_ = NULL; } } @@ -2692,10 +2692,10 @@ } } }; - - - SQLiteDatabaseWrapper::SQLiteDatabaseWrapper(const std::string& path) : - activeTransaction_(NULL), + + + SQLiteDatabaseWrapper::SQLiteDatabaseWrapper(const std::string& path) : + activeTransaction_(NULL), signalRemainingAncestor_(NULL), version_(0) { @@ -2712,8 +2712,8 @@ } - SQLiteDatabaseWrapper::SQLiteDatabaseWrapper() : - activeTransaction_(NULL), + SQLiteDatabaseWrapper::SQLiteDatabaseWrapper() : + activeTransaction_(NULL), signalRemainingAncestor_(NULL), version_(0) { @@ -2766,11 +2766,11 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls); // Cannot open twice } - + signalRemainingAncestor_ = dynamic_cast(db_.Register(new SignalRemainingAncestor)); db_.Register(new SignalFileDeleted(*this)); db_.Register(new SignalResourceDeleted(*this)); - + db_.Execute("PRAGMA ENCODING=\"UTF-8\";"); // Performance tuning of SQLite with PRAGMAs @@ -2781,12 +2781,12 @@ db_.Execute("PRAGMA WAL_AUTOCHECKPOINT=1000;"); //db_.Execute("PRAGMA TEMP_STORE=memory"); - // Make "LIKE" case-sensitive in SQLite + // Make "LIKE" case-sensitive in SQLite db_.Execute("PRAGMA case_sensitive_like = true;"); } VoidDatabaseListener listener; - + { std::unique_ptr transaction(StartTransaction(TransactionType_ReadOnly, listener)); @@ -2888,7 +2888,7 @@ db_.Close(); } - + static void ExecuteUpgradeScript(SQLite::Connection& db, ServerResources::FileResourceId script) { @@ -2896,7 +2896,7 @@ ServerResources::GetFileResource(upgrade, script); db.BeginTransaction(); db.Execute(upgrade); - db.CommitTransaction(); + db.CommitTransaction(); } @@ -2942,7 +2942,7 @@ // (as more tags got included). VoidDatabaseListener listener; - + { ReadWriteTransaction transaction(*this, listener, false /* GetTotalSizeIsFast necessitates the table "GlobalIntegers" */); transaction.Begin(); @@ -2962,7 +2962,7 @@ boost::lexical_cast(GlobalProperty_DatabaseSchemaVersion) + ";"); transaction.Commit(0); } - + version_ = 6; } @@ -3006,7 +3006,7 @@ } } - + void SQLiteDatabaseWrapper::FlushToDisk() { boost::recursive_mutex::scoped_lock lock(mutex_); @@ -3100,7 +3100,7 @@ int64_t id) { SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.publicId FROM Resources AS a, Resources AS b " - "WHERE a.internalId = b.parentId AND b.internalId = ?"); + "WHERE a.internalId = b.parentId AND b.internalId = ?"); s.BindInt64(0, id); if (s.Step()) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -117,18 +117,18 @@ { protected: SQLite::Connection& db_; - + public: UnitTestsTransaction(SQLite::Connection& db) : db_(db) { } - + void GetChildren(std::list& childrenPublicIds, int64_t id); int64_t GetTableRecordCount(const std::string& table); - + bool GetParentPublicId(std::string& target, int64_t id); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp --- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -53,7 +53,7 @@ * Some handy templates to reduce the verbosity in the definitions * of the internal classes. **/ - + template class TupleOperationsWrapper : public StatelessDatabaseOperations::IReadOnlyOperations @@ -61,7 +61,7 @@ protected: Operations& operations_; const Tuple& tuple_; - + public: TupleOperationsWrapper(Operations& operations, const Tuple& tuple) : @@ -69,7 +69,7 @@ tuple_(tuple) { } - + virtual void Apply(StatelessDatabaseOperations::ReadOnlyTransaction& transaction) ORTHANC_OVERRIDE { operations_.ApplyTuple(transaction, tuple_); @@ -82,7 +82,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT1() { } @@ -106,7 +106,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT2() { } @@ -132,7 +132,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT3() { } @@ -160,7 +160,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT4() { } @@ -190,7 +190,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT5() { } @@ -222,7 +222,7 @@ { public: typedef typename boost::tuple Tuple; - + virtual ~ReadOnlyOperationsT6() { } @@ -280,7 +280,7 @@ last = log.back().GetSeq(); } } - + target["Last"] = static_cast(last); if (!log.empty()) { @@ -326,7 +326,7 @@ { return SeriesStatus_Unknown; } - + if (!(index > 0 && index <= expectedNumberOfInstances)) { // Out-of-range instance index @@ -360,7 +360,7 @@ std::unique_ptr transaction_; std::unique_ptr context_; bool isCommitted_; - + public: Transaction(IDatabaseWrapper& db, ITransactionContextFactory& factory, @@ -372,8 +372,8 @@ if (context_.get() == NULL) { throw OrthancException(ErrorCode_NullPointer); - } - + } + transaction_.reset(db_.StartTransaction(type, *context_)); if (transaction_.get() == NULL) { @@ -424,7 +424,7 @@ return *context_; } }; - + void StatelessDatabaseOperations::ApplyInternal(IReadOnlyOperations* readOperations, IReadWriteOperations* writeOperations) @@ -439,9 +439,9 @@ if (factory_.get() == NULL) { - throw OrthancException(ErrorCode_BadSequenceOfCalls, "No transaction context was provided"); + throw OrthancException(ErrorCode_BadSequenceOfCalls, "No transaction context was provided"); } - + unsigned int attempt = 0; for (;;) @@ -455,7 +455,7 @@ * in this case. This was OK because of the presence of the * global mutex that was protecting the database. **/ - + Transaction transaction(db_, *factory_, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" { ReadOnlyTransaction t(transaction.GetDatabaseTransaction(), transaction.GetContext()); @@ -470,7 +470,7 @@ { throw OrthancException(ErrorCode_ReadOnly, "The DB is trying to execute a ReadWrite transaction while Orthanc has been started in ReadOnly mode."); } - + Transaction transaction(db_, *factory_, TransactionType_ReadWrite); { ReadWriteTransaction t(transaction.GetDatabaseTransaction(), transaction.GetContext()); @@ -478,7 +478,7 @@ } transaction.Commit(); } - + return; // Success } catch (OrthancException& e) @@ -496,7 +496,7 @@ // The "rand()" adds some jitter to de-synchronize writers boost::this_thread::sleep(boost::posix_time::milliseconds(100 * attempt + 5 * (rand() % 10))); - } + } } else { @@ -506,8 +506,8 @@ } } - - StatelessDatabaseOperations::StatelessDatabaseOperations(IDatabaseWrapper& db, bool readOnly) : + + StatelessDatabaseOperations::StatelessDatabaseOperations(IDatabaseWrapper& db, bool readOnly) : db_(db), mainDicomTagsRegistry_(new MainDicomTagsRegistry), maxRetries_(0), @@ -546,20 +546,20 @@ factory_.reset(factory); } } - + void StatelessDatabaseOperations::SetMaxDatabaseRetries(unsigned int maxRetries) { boost::unique_lock lock(mutex_); maxRetries_ = maxRetries; } - + void StatelessDatabaseOperations::Apply(IReadOnlyOperations& operations) { ApplyInternal(&operations, NULL); } - + void StatelessDatabaseOperations::Apply(IReadWriteOperations& operations) { @@ -641,7 +641,7 @@ FindResponse response; ExecuteFind(response, request); - + if (response.GetSize() == 0) { return false; @@ -680,9 +680,9 @@ void StatelessDatabaseOperations::GetGlobalStatistics(/* out */ uint64_t& diskSize, /* out */ uint64_t& uncompressedSize, - /* out */ uint64_t& countPatients, - /* out */ uint64_t& countStudies, - /* out */ uint64_t& countSeries, + /* out */ uint64_t& countPatients, + /* out */ uint64_t& countStudies, + /* out */ uint64_t& countSeries, /* out */ uint64_t& countInstances) { // Code introduced in Orthanc 1.12.3 that updates and gets all statistics. @@ -712,9 +712,9 @@ void GetValues(uint64_t& diskSize, uint64_t& uncompressedSize, - uint64_t& countPatients, - uint64_t& countStudies, - uint64_t& countSeries, + uint64_t& countPatients, + uint64_t& countStudies, + uint64_t& countSeries, uint64_t& countInstances) const { diskSize = static_cast(diskSize_); @@ -753,9 +753,9 @@ Apply(operations); operations.GetValues(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); - } + } else - { + { LegacyOperations operations; operations.Apply(*this, diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); @@ -764,7 +764,7 @@ void StatelessDatabaseOperations::GetChanges(Json::Value& target, - int64_t since, + int64_t since, unsigned int maxResults) { class Operations : public ReadOnlyOperationsT3 @@ -791,7 +791,7 @@ FormatLog(tuple.get<0>(), changes, "Changes", done, tuple.get<1>(), hasLast, last); } }; - + Operations operations; operations.Apply(*this, target, since, maxResults); } @@ -799,7 +799,7 @@ void StatelessDatabaseOperations::GetChangesExtended(Json::Value& target, int64_t since, - int64_t to, + int64_t to, unsigned int maxResults, const std::set& changeType) { @@ -824,7 +824,7 @@ FormatLog(tuple.get<0>(), changes, "Changes", done, tuple.get<1>(), hasLast, last); } }; - + Operations operations; operations.Apply(*this, target, since, to, maxResults, changeType); } @@ -855,7 +855,7 @@ FormatLog(tuple.get<0>(), changes, "Changes", true, 0, hasLast, last); } }; - + Operations operations; operations.Apply(*this, target); } @@ -879,7 +879,7 @@ FormatLog(tuple.get<0>(), exported, "Exports", done, tuple.get<1>(), false, -1); } }; - + Operations operations; operations.Apply(*this, target, since, maxResults); } @@ -900,7 +900,7 @@ FormatLog(tuple.get<0>(), exported, "Exports", true, 0, false, -1); } }; - + Operations operations; operations.Apply(*this, target); } @@ -1086,38 +1086,38 @@ } - void StatelessDatabaseOperations::GetResourceStatistics(/* out */ uint64_t& diskSize, - /* out */ uint64_t& uncompressedSize, - /* out */ unsigned int& countStudies, - /* out */ unsigned int& countSeries, - /* out */ unsigned int& countInstances, - /* out */ uint64_t& dicomDiskSize, + void StatelessDatabaseOperations::GetResourceStatistics(/* out */ uint64_t& diskSize, + /* out */ uint64_t& uncompressedSize, + /* out */ unsigned int& countStudies, + /* out */ unsigned int& countSeries, + /* out */ unsigned int& countInstances, + /* out */ uint64_t& dicomDiskSize, /* out */ uint64_t& dicomUncompressedSize, - ResourceType type, + ResourceType type, const std::string& publicId) { class Operations : public IReadOnlyOperations { private: - uint64_t& diskSize_; - uint64_t& uncompressedSize_; - unsigned int& countStudies_; - unsigned int& countSeries_; - unsigned int& countInstances_; - uint64_t& dicomDiskSize_; - uint64_t& dicomUncompressedSize_; + uint64_t& diskSize_; + uint64_t& uncompressedSize_; + unsigned int& countStudies_; + unsigned int& countSeries_; + unsigned int& countInstances_; + uint64_t& dicomDiskSize_; + uint64_t& dicomUncompressedSize_; const std::string& publicId_; ResourceType type_; IDatabaseWrapper::Capabilities dbCapabilities_; public: - explicit Operations(uint64_t& diskSize, - uint64_t& uncompressedSize, - unsigned int& countStudies, - unsigned int& countSeries, - unsigned int& countInstances, - uint64_t& dicomDiskSize, - uint64_t& dicomUncompressedSize, + explicit Operations(uint64_t& diskSize, + uint64_t& uncompressedSize, + unsigned int& countStudies, + unsigned int& countSeries, + unsigned int& countInstances, + uint64_t& dicomDiskSize, + uint64_t& dicomUncompressedSize, ResourceType type, const std::string& publicId, const IDatabaseWrapper::Capabilities& dbCapabilities) : @@ -1194,7 +1194,7 @@ dicomDiskSize_ += attachment.GetCompressedSize(); dicomUncompressedSize_ += attachment.GetUncompressedSize(); } - + diskSize_ += attachment.GetCompressedSize(); uncompressedSize_ += attachment.GetUncompressedSize(); } @@ -1223,7 +1223,7 @@ // Tag all the children of this resource as to be explored std::list tmp; transaction.GetChildrenInternalId(tmp, resource); - for (std::list::const_iterator + for (std::list::const_iterator it = tmp.begin(); it != tmp.end(); ++it) { toExplore.push(*it); @@ -1372,7 +1372,7 @@ operations.Apply(*this, found, value, property, shared); return found; } - + std::string StatelessDatabaseOperations::GetGlobalProperty(GlobalProperty property, bool shared, @@ -1588,7 +1588,7 @@ Json::Value& remainingAncestor_; const std::string& uuid_; ResourceType expectedType_; - + public: Operations(Json::Value& remainingAncestor, const std::string& uuid, @@ -1641,7 +1641,7 @@ content.AddMetadata(parentId, MetadataType_LastUpdate, now); } while (transaction.LookupParent(parentId, parentId)); - + transaction.SetResourcesContent(content); } } @@ -1676,7 +1676,7 @@ remoteModality_(remoteModality) { } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { int64_t id; @@ -1749,7 +1749,7 @@ } } - ExportedResource resource(-1, + ExportedResource resource(-1, type, publicId_, remoteModality_, @@ -1876,9 +1876,9 @@ expectedMD5 != oldMD5_) { throw OrthancException(ErrorCode_Revision); - } + } } - + newRevision_ = expectedRevision + 1; } else @@ -1889,7 +1889,7 @@ } transaction.SetMetadata(id, type_, value_, newRevision_); - + if (IsUserMetadata(type_)) { transaction.LogChange(id, ChangeType_UpdatedMetadata, resourceType, publicId_); @@ -1973,10 +1973,10 @@ throw OrthancException(ErrorCode_Revision); } } - + found_ = true; transaction.DeleteMetadata(id, type_); - + if (IsUserMetadata(type_)) { transaction.LogChange(id, ChangeType_UpdatedMetadata, resourceType, publicId_); @@ -2036,7 +2036,7 @@ if (transaction.LookupGlobalProperty(oldString, sequence_, shared_)) { uint64_t oldValue; - + try { oldValue = boost::lexical_cast(oldString); @@ -2083,7 +2083,7 @@ Apply(operations); } - + void StatelessDatabaseOperations::DeleteExportedResources() { class Operations : public IReadWriteOperations @@ -2110,7 +2110,7 @@ GlobalProperty property_; bool shared_; const std::string& value_; - + public: Operations(GlobalProperty property, bool shared, @@ -2120,7 +2120,7 @@ value_(value) { } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { transaction.SetGlobalProperty(property_, shared_, value_); @@ -2162,12 +2162,12 @@ found_(false) { } - + bool HasFound() const { return found_; } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { ResourceType resourceType; @@ -2188,10 +2188,10 @@ { throw OrthancException(ErrorCode_Revision); } - + found_ = true; transaction.DeleteAttachment(id, type_); - + if (IsUserContentType(type_)) { transaction.LogChange(id, ChangeType_UpdatedAttachment, resourceType, publicId_); @@ -2223,7 +2223,7 @@ ChangeType changeType_; const std::string& publicId_; ResourceType level_; - + public: Operations(int64_t internalId, ChangeType changeType, @@ -2235,7 +2235,7 @@ level_(level) { } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { int64_t id; @@ -2311,7 +2311,7 @@ { std::string oldValue; int64_t oldRevision; - + if (transaction.LookupMetadata(oldValue, oldRevision, instance, metadata)) { transaction.SetMetadata(instance, metadata, value, oldRevision + 1); @@ -2321,7 +2321,7 @@ transaction.SetMetadata(instance, metadata, value, 0); } } - + static void SetMainDicomSequenceMetadata(ReadWriteTransaction& transaction, int64_t instance, const DicomMap& dicomSummary, @@ -2338,7 +2338,7 @@ { transaction.DeleteMetadata(instance, MetadataType_MainDicomSequences); } - + } public: @@ -2350,12 +2350,12 @@ hasher_.reset(new DicomInstanceHasher(summary_)); hasTransferSyntax_ = dicom.LookupTransferSyntax(transferSyntax_); } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { int64_t patient = -1, study = -1, series = -1, instance = -1; - ResourceType type1, type2, type3, type4; + ResourceType type1, type2, type3, type4; if (!transaction.LookupResource(patient, type1, hasher_->HashPatient()) || !transaction.LookupResource(study, type2, hasher_->HashStudy()) || !transaction.LookupResource(series, type3, hasher_->HashSeries()) || @@ -2418,7 +2418,7 @@ ReplaceMetadata(transaction, study, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0 ReplaceMetadata(transaction, series, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0 ReplaceMetadata(transaction, instance, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 - + SetMainDicomSequenceMetadata(transaction, patient, summary_, ResourceType_Patient); SetMainDicomSequenceMetadata(transaction, study, summary_, ResourceType_Study); SetMainDicomSequenceMetadata(transaction, series, summary_, ResourceType_Series); @@ -2458,7 +2458,7 @@ " bytes in a storage area limited to " + boost::lexical_cast(maximumStorageSize)); } - + if (transaction_.IsDiskSizeAbove(maximumStorageSize - addedInstanceSize)) { return true; @@ -2466,7 +2466,7 @@ } return false; - } + } bool StatelessDatabaseOperations::ReadOnlyTransaction::HasReachedMaxPatientCount(unsigned int maximumPatientCount, const std::string& patientId) @@ -2479,7 +2479,7 @@ return false; } - + bool StatelessDatabaseOperations::ReadWriteTransaction::IsRecyclingNeeded(uint64_t maximumStorageSize, unsigned int maximumPatients, uint64_t addedInstanceSize, @@ -2495,7 +2495,7 @@ const std::string& newPatientId) { // TODO - Performance: Avoid calls to "IsRecyclingNeeded()" - + if (IsRecyclingNeeded(maximumStorageSize, maximumPatients, addedInstanceSize, newPatientId)) { // Check whether other DICOM instances from this patient are @@ -2527,12 +2527,12 @@ bool ok = (hasPatientToAvoid ? transaction_.SelectPatientToRecycle(patientToRecycle, patientToAvoid) : transaction_.SelectPatientToRecycle(patientToRecycle)); - + if (!ok) { throw OrthancException(ErrorCode_FullStorage, "Cannot recycle more patients"); } - + LOG(TRACE) << "Recycling one patient"; transaction_.DeleteResource(patientToRecycle); @@ -2555,7 +2555,7 @@ private: uint64_t maximumStorageSize_; unsigned int maximumPatientCount_; - + public: Operations(uint64_t maximumStorageSize, unsigned int maximumPatientCount) : @@ -2563,14 +2563,14 @@ maximumPatientCount_(maximumPatientCount) { } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { transaction.Recycle(maximumStorageSize_, maximumPatientCount_, 0, ""); } }; - if (maximumStorageMode == MaxStorageMode_Recycle + if (maximumStorageMode == MaxStorageMode_Recycle && (maximumStorageSize != 0 || maximumPatientCount != 0)) { Operations operations(maximumStorageSize, maximumPatientCount); @@ -2623,7 +2623,7 @@ std::string hashSeries_; std::string hashInstance_; - + static void SetInstanceMetadata(ResourcesContent& content, std::map& instanceMetadata, int64_t instance, @@ -2647,7 +2647,7 @@ content.AddMetadata(resource, MetadataType_MainDicomSequences, serialized); } } - + static bool ComputeExpectedNumberOfInstances(int64_t& target, const DicomMap& dicomSummary) { @@ -2655,7 +2655,7 @@ { const DicomValue* value; const DicomValue* value2; - + if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGES_IN_ACQUISITION)) != NULL && // NOLINT(bugprone-assignment-in-if-condition) !value->IsNull() && !value->IsBinary() && @@ -2736,7 +2736,7 @@ isReconstruct_(isReconstruct) { hasExpectedInstances_ = ComputeExpectedNumberOfInstances(expectedInstances_, dicomSummary); - + instanceMetadata_.clear(); DicomInstanceHasher hasher(dicomSummary); @@ -2750,12 +2750,12 @@ { return storeStatus_; } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { IDatabaseWrapper::CreateInstanceResult status; int64_t instanceId; - + bool isNewInstance = transaction.CreateInstance(status, instanceId, hashPatient_, hashStudy_, hashSeries_, hashInstance_); @@ -2780,7 +2780,7 @@ if (!transaction.CreateInstance(status, instanceId, hashPatient_, hashStudy_, hashSeries_, hashInstance_)) { - // Note that, sometime, it does not create a new instance, + // Note that, sometime, it does not create a new instance, // in very rare occasions in READ COMMITTED mode when multiple clients are pushing the same instance at the same time, // this thread will not create the instance because another thread has created it in the meantime. // At the end, there is always a thread that creates the instance and this is what we expect. @@ -2815,18 +2815,18 @@ { transaction.LogChange(status.seriesId_, ChangeType_NewSeries, ResourceType_Series, hashSeries_); } - + if (status.isNewStudy_) { transaction.LogChange(status.studyId_, ChangeType_NewStudy, ResourceType_Study, hashStudy_); } - + if (status.isNewPatient_) { transaction.LogChange(status.patientId_, ChangeType_NewPatient, ResourceType_Patient, hashPatient_); } - } - + } + // Ensure there is enough room in the storage for the new instance uint64_t instanceSize = 0; for (Attachments::const_iterator it = attachments_.begin(); @@ -2857,8 +2857,8 @@ transaction.Recycle(maximumStorageSize_, maximumPatientCount_, instanceSize, hashPatient_ /* don't consider the current patient for recycling */); } - } - + } + // Attach the files to the newly created instance for (Attachments::const_iterator it = attachments_.begin(); it != attachments_.end(); ++it) @@ -2875,7 +2875,7 @@ ResourcesContent content(true /* new resource, metadata can be set */); // Attach the user-specified metadata (in case of reconstruction, metadata_ contains all past metadata, including the system ones we want to keep) - for (MetadataMap::const_iterator + for (MetadataMap::const_iterator it = metadata_.begin(); it != metadata_.end(); ++it) { switch (it->first.first) @@ -2954,7 +2954,7 @@ MetadataType_Instance_ReceptionDate, now); SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_RemoteAet, origin_.GetRemoteAetC()); - SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_Instance_Origin, + SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_Instance_Origin, EnumerationToString(origin_.GetRequestOrigin())); std::string s; @@ -3008,7 +3008,7 @@ EnumerationToString(pixelDataVR_)); } } - + const DicomValue* value; if ((value = dicomSummary_.TestAndGetValue(DICOM_TAG_SOP_CLASS_UID)) != NULL && // NOLINT(bugprone-assignment-in-if-condition) !value->IsNull() && @@ -3022,7 +3022,7 @@ if ((value = dicomSummary_.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || // NOLINT(bugprone-assignment-in-if-condition) (value = dicomSummary_.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL) // NOLINT(bugprone-assignment-in-if-condition) { - if (!value->IsNull() && + if (!value->IsNull() && !value->IsBinary()) { SetInstanceMetadata(content, instanceMetadata_, instanceId, @@ -3030,7 +3030,7 @@ } } - + transaction.SetResourcesContent(content); @@ -3046,11 +3046,11 @@ transaction.LogChange(status.seriesId_, ChangeType_CompletedSeries, ResourceType_Series, hashSeries_); } } - + transaction.LogChange(status.seriesId_, ChangeType_NewChildInstance, ResourceType_Series, hashSeries_); transaction.LogChange(status.studyId_, ChangeType_NewChildInstance, ResourceType_Study, hashStudy_); transaction.LogChange(status.patientId_, ChangeType_NewChildInstance, ResourceType_Patient, hashPatient_); - + // Mark the parent resources of this instance as unstable transaction.GetTransactionContext().MarkAsUnstable(ResourceType_Series, status.seriesId_, hashSeries_); transaction.GetTransactionContext().MarkAsUnstable(ResourceType_Study, status.studyId_, hashStudy_); @@ -3134,7 +3134,7 @@ { return status_; } - + virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE { ResourceType resourceType; @@ -3243,7 +3243,7 @@ Operations operations; operations.Apply(*this, target); } - + void StatelessDatabaseOperations::AddLabels(const std::string& publicId, ResourceType level, @@ -3310,7 +3310,7 @@ }; ServerToolbox::CheckValidLabel(label); - + Operations operations(publicId, level, label, operation); Apply(operations); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/StatelessDatabaseOperations.h --- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -77,7 +77,7 @@ virtual void SignalChange(const ServerIndexChange& change) = 0; }; - + class ITransactionContextFactory : public boost::noncopyable { public: @@ -97,7 +97,7 @@ protected: IDatabaseWrapper::ITransaction& transaction_; - + public: explicit ReadOnlyTransaction(IDatabaseWrapper::ITransaction& transaction, ITransactionContext& context) : @@ -118,7 +118,7 @@ SeriesStatus GetSeriesStatus(int64_t id, int64_t expectedNumberOfInstances); - + /** * Read-only methods from "IDatabaseWrapper" **/ @@ -186,12 +186,12 @@ { return transaction_.GetPublicId(resourceId); } - + uint64_t GetResourcesCount(ResourceType resourceType) { return transaction_.GetResourcesCount(resourceType); } - + ResourceType GetResourceType(int64_t resourceId) { return transaction_.GetResourceType(resourceId); @@ -201,12 +201,12 @@ { return transaction_.GetTotalCompressedSize(); } - + uint64_t GetTotalUncompressedSize() { return transaction_.GetTotalUncompressedSize(); } - + bool IsProtectedPatient(int64_t internalId) { return transaction_.IsProtectedPatient(internalId); @@ -225,7 +225,7 @@ { return transaction_.LookupAttachment(attachment, revision, id, contentType); } - + void GetAttachmentCustomData(std::string& customData, const std::string& attachmentUuid) { @@ -252,7 +252,7 @@ { return transaction_.LookupParent(parentId, resourceId); } - + bool LookupResource(int64_t& id, ResourceType& type, const std::string& publicId) @@ -339,7 +339,7 @@ { transaction_.AddAttachment(id, attachment, revision); } - + void ClearChanges() { transaction_.ClearChanges(); @@ -370,7 +370,7 @@ { return transaction_.DeleteAttachment(id, attachment); } - + void DeleteMetadata(int64_t id, MetadataType type) { @@ -424,7 +424,7 @@ return transaction_.SetMetadata(id, type, value, revision); } - void SetProtectedPatient(int64_t internalId, + void SetProtectedPatient(int64_t internalId, bool isProtected) { transaction_.SetProtectedPatient(internalId, isProtected); @@ -530,7 +530,7 @@ virtual void Apply(ReadWriteTransaction& transaction) = 0; }; - + private: class Transaction; @@ -568,7 +568,7 @@ // Only used to handle "ErrorCode_DatabaseCannotSerialize" in the // case of collision between multiple writers void SetMaxDatabaseRetries(unsigned int maxRetries); - + // It is assumed that "GetDatabaseVersion()" can run out of a // database transaction unsigned int GetDatabaseVersion() @@ -585,7 +585,7 @@ void Apply(IReadOnlyOperations& operations); - + void Apply(IReadWriteOperations& operations); void GetAllMetadata(std::map& target, @@ -597,9 +597,9 @@ void GetGlobalStatistics(/* out */ uint64_t& diskSize, /* out */ uint64_t& uncompressedSize, - /* out */ uint64_t& countPatients, - /* out */ uint64_t& countStudies, - /* out */ uint64_t& countSeries, + /* out */ uint64_t& countPatients, + /* out */ uint64_t& countStudies, + /* out */ uint64_t& countSeries, /* out */ uint64_t& countInstances); void GetAttachmentCustomData(std::string& customData, @@ -683,13 +683,13 @@ bool LookupParent(std::string& target, const std::string& publicId); - void GetResourceStatistics(/* out */ uint64_t& diskSize, - /* out */ uint64_t& uncompressedSize, - /* out */ unsigned int& countStudies, - /* out */ unsigned int& countSeries, - /* out */ unsigned int& countInstances, - /* out */ uint64_t& dicomDiskSize, - /* out */ uint64_t& dicomUncompressedSize, + void GetResourceStatistics(/* out */ uint64_t& diskSize, + /* out */ uint64_t& uncompressedSize, + /* out */ unsigned int& countStudies, + /* out */ unsigned int& countSeries, + /* out */ unsigned int& countInstances, + /* out */ uint64_t& dicomDiskSize, + /* out */ uint64_t& dicomUncompressedSize, ResourceType type, const std::string& publicId); @@ -777,8 +777,8 @@ const std::string& publicId, ResourceType level); - void ReconstructInstance(const ParsedDicomFile& dicom, - bool limitToThisLevelDicomTags, + void ReconstructInstance(const ParsedDicomFile& dicom, + bool limitToThisLevelDicomTags, ResourceType limitToLevel_); StoreStatus Store(std::map& instanceMetadata, @@ -861,7 +861,7 @@ bool DequeueValue(std::string& value, const std::string& queueId, QueueOrigin origin); - + uint64_t GetQueueSize(const std::string& queueId); bool ReserveQueueValue(std::string& value, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/VoidDatabaseListener.cpp --- a/OrthancServer/Sources/Database/VoidDatabaseListener.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/VoidDatabaseListener.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,7 +33,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + void VoidDatabaseListener::SignalAttachmentDeleted(const FileInfo& info) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); @@ -43,5 +43,5 @@ const std::string& publicId) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Database/VoidDatabaseListener.h --- a/OrthancServer/Sources/Database/VoidDatabaseListener.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Database/VoidDatabaseListener.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -37,7 +37,7 @@ public: virtual void SignalRemainingAncestor(ResourceType parentType, const std::string& publicId) ORTHANC_OVERRIDE; - + virtual void SignalAttachmentDeleted(const FileInfo& info) ORTHANC_OVERRIDE; virtual void SignalResourceDeleted(ResourceType type, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceDestination.cpp --- a/OrthancServer/Sources/DicomInstanceDestination.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceDestination.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceDestination.h --- a/OrthancServer/Sources/DicomInstanceDestination.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceDestination.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceOrigin.cpp --- a/OrthancServer/Sources/DicomInstanceOrigin.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceOrigin.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -177,7 +177,7 @@ static const char* DICOM_REMOTE_AET = "RemoteAET"; static const char* DICOM_CALLED_AET = "CalledAET"; static const char* HTTP_USERNAME = "Username"; - + DicomInstanceOrigin::DicomInstanceOrigin(const Json::Value& serialized) { @@ -187,8 +187,8 @@ dicomCalledAet_ = SerializationToolbox::ReadString(serialized, DICOM_CALLED_AET); httpUsername_ = SerializationToolbox::ReadString(serialized, HTTP_USERNAME); } - - + + void DicomInstanceOrigin::Serialize(Json::Value& result) const { result = Json::objectValue; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceOrigin.h --- a/OrthancServer/Sources/DicomInstanceOrigin.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceOrigin.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -78,7 +78,7 @@ return origin_; } - const char* GetRemoteAetC() const; + const char* GetRemoteAetC() const; bool LookupRemoteAet(std::string& result) const; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceToStore.cpp --- a/OrthancServer/Sources/DicomInstanceToStore.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceToStore.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -75,7 +75,7 @@ } }; - + class DicomInstanceToStore::FromParsedDicomFile : public DicomInstanceToStore { private: @@ -116,7 +116,7 @@ assert(buffer_.get() != NULL); return buffer_->size(); - } + } }; @@ -132,7 +132,7 @@ if (buffer_.get() == NULL) { buffer_.reset(new std::string); - + std::string errorMessage; if (!FromDcmtkBridge::SaveToMemoryBuffer(*buffer_, dataset_, errorMessage)) { @@ -146,7 +146,7 @@ dataset_(dataset) { } - + virtual ParsedDicomFile& GetParsedDicomFile() const ORTHANC_OVERRIDE { if (parsed_.get() == NULL) @@ -193,7 +193,7 @@ OrthancConfiguration::DefaultDicomDatasetToJson(dicomAsJson, dataset_, ignoreTagLength); } - virtual void DatasetToJson(Json::Value& target, + virtual void DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength) const ORTHANC_OVERRIDE @@ -207,21 +207,21 @@ { return DicomFrameIndex::GetFramesCount(dataset_); } - + virtual ImageAccessor* DecodeFrame(unsigned int frame) const ORTHANC_OVERRIDE { return DicomImageDecoder::Decode(dataset_, frame); } }; - + DicomInstanceToStore* DicomInstanceToStore::CreateFromBuffer(const void* buffer, size_t size) { return new FromBuffer(buffer, size); } - + DicomInstanceToStore* DicomInstanceToStore::CreateFromBuffer(const std::string& buffer) { return new FromBuffer(buffer.empty() ? NULL : buffer.c_str(), buffer.size()); @@ -233,13 +233,13 @@ return new FromParsedDicomFile(dicom); } - + DicomInstanceToStore* DicomInstanceToStore::CreateFromDcmDataset(DcmDataset& dataset) { return new FromDcmDataset(dataset); } - + bool DicomInstanceToStore::LookupTransferSyntax(DicomTransferSyntax& result) const { DicomMap header; @@ -260,7 +260,7 @@ // the transfer syntax. Added in Orthanc 1.8.2. return GetParsedDicomFile().LookupTransferSyntax(result); } - + return false; } @@ -270,20 +270,20 @@ return GetParsedDicomFile().HasTag(DICOM_TAG_PIXEL_DATA); } - + void DicomInstanceToStore::GetSummary(DicomMap& summary) const { OrthancConfiguration::DefaultExtractDicomSummary(summary, GetParsedDicomFile()); } - + void DicomInstanceToStore::GetDicomAsJson(Json::Value& dicomAsJson, const std::set& ignoreTagLength) const { OrthancConfiguration::DefaultDicomDatasetToJson(dicomAsJson, GetParsedDicomFile(), ignoreTagLength); } - void DicomInstanceToStore::DatasetToJson(Json::Value& target, + void DicomInstanceToStore::DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength) const @@ -297,7 +297,7 @@ return GetParsedDicomFile().GetFramesCount(); } - + ImageAccessor* DicomInstanceToStore::DecodeFrame(unsigned int frame) const { return GetParsedDicomFile().DecodeFrame(frame); @@ -305,7 +305,7 @@ void DicomInstanceToStore::CopyMetadata(const DicomInstanceToStore::MetadataMap& metadata) { - for (MetadataMap::const_iterator it = metadata.begin(); + for (MetadataMap::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { AddMetadata(it->first.first, it->first.second, it->second); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/DicomInstanceToStore.h --- a/OrthancServer/Sources/DicomInstanceToStore.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/DicomInstanceToStore.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -84,12 +84,12 @@ { origin_ = origin; } - + const DicomInstanceOrigin& GetOrigin() const { return origin_; - } - + } + const MetadataMap& GetMetadata() const { return metadata_; @@ -125,13 +125,13 @@ virtual void GetDicomAsJson(Json::Value& dicomAsJson, const std::set& ignoreTagLength) const; - virtual void DatasetToJson(Json::Value& target, + virtual void DatasetToJson(Json::Value& target, DicomToJsonFormat format, DicomToJsonFlags flags, unsigned int maxStringLength) const; virtual unsigned int GetFramesCount() const; - + virtual ImageAccessor* DecodeFrame(unsigned int frame) const; }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/EmbeddedResourceHttpHandler.cpp --- a/OrthancServer/Sources/EmbeddedResourceHttpHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/EmbeddedResourceHttpHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -84,5 +84,5 @@ } return true; - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/EmbeddedResourceHttpHandler.h --- a/OrthancServer/Sources/EmbeddedResourceHttpHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/EmbeddedResourceHttpHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ExportedResource.cpp --- a/OrthancServer/Sources/ExportedResource.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ExportedResource.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ExportedResource.h --- a/OrthancServer/Sources/ExportedResource.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ExportedResource.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/IServerListener.h --- a/OrthancServer/Sources/IServerListener.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/IServerListener.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -43,7 +43,7 @@ virtual void SignalStoredInstance(const std::string& publicId, const DicomInstanceToStore& instance, const Json::Value& simplifiedTags) = 0; - + virtual void SignalChange(const ServerIndexChange& change) = 0; virtual void SignalJobEvent(const JobEvent& event) = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/JobEvent.h --- a/OrthancServer/Sources/JobEvent.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/JobEvent.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -54,7 +54,7 @@ { } - JobEvent(const JobEvent& other) + JobEvent(const JobEvent& other) : eventType_(other.eventType_), jobId_(other.jobId_) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/LuaScripting.cpp --- a/OrthancServer/Sources/LuaScripting.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/LuaScripting.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -134,7 +134,7 @@ const ServerIndexChange& change_; bool ok_; DicomMap tags_; - std::map metadata_; + std::map metadata_; public: explicit GetInfoOperations(const ServerIndexChange& change) : @@ -142,7 +142,7 @@ ok_(false) { } - + virtual void Apply(ServerIndex::ReadOnlyTransaction& transaction) ORTHANC_OVERRIDE { int64_t internalId; @@ -163,12 +163,12 @@ { Json::Value formattedMetadata = Json::objectValue; - for (std::map::const_iterator + for (std::map::const_iterator it = metadata_.begin(); it != metadata_.end(); ++it) { std::string key = EnumerationToString(it->first); formattedMetadata[key] = it->second; - } + } { LuaScripting::Lock lock(that); @@ -202,7 +202,7 @@ } } }; - + public: explicit StableResourceEvent(const ServerIndexChange& change) : @@ -241,7 +241,7 @@ return; } } - + GetInfoOperations operations(change_); that.context_.GetIndex().Apply(operations); operations.CallLua(that, name); @@ -263,7 +263,7 @@ virtual void Apply(LuaScripting& that) ORTHANC_OVERRIDE { std::string functionName; - + switch (event_.GetEventType()) { case JobEventType_Failure: @@ -313,7 +313,7 @@ virtual void Apply(LuaScripting& that) ORTHANC_OVERRIDE { std::string functionName; - + switch (level_) { case ResourceType_Patient: @@ -367,7 +367,7 @@ virtual void Apply(LuaScripting& that) ORTHANC_OVERRIDE { std::string functionName; - + switch (level_) { case ResourceType_Patient: @@ -424,7 +424,7 @@ // Check the types of the arguments int nArgs = lua_gettop(state); - if (nArgs < 1 || nArgs > 3 || + if (nArgs < 1 || nArgs > 3 || !lua_isstring(state, 1) || // URI (nArgs >= 2 && !lua_isboolean(state, 2))) // Restrict to built-in API? { @@ -442,7 +442,7 @@ try { std::string result; - if (IHttpHandler::SimpleGet(result, NULL, serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), + if (IHttpHandler::SimpleGet(result, NULL, serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), RequestOrigin_Lua, uri, headers) == HttpStatus_200_Ok) { lua_pushlstring(state, result.c_str(), result.size()); @@ -473,7 +473,7 @@ // Check the types of the arguments int nArgs = lua_gettop(state); - if (nArgs < 2 || nArgs > 4 || + if (nArgs < 2 || nArgs > 4 || !lua_isstring(state, 1) || // URI !lua_isstring(state, 2) || // Body (nArgs >= 3 && !lua_isboolean(state, 3))) // Restrict to built-in API? @@ -490,16 +490,16 @@ std::map headers; LuaContext::GetDictionaryArgument(headers, state, 4, true /* HTTP header key to lower case */); - + try { std::string result; if (isPost ? IHttpHandler::SimplePost(result, NULL, - serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), + serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), RequestOrigin_Lua, uri, bodyData, bodySize, headers) == HttpStatus_200_Ok : IHttpHandler::SimplePut(result, NULL, - serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), + serverContext->GetHttpHandler().RestrictToOrthancRestApi(builtin), RequestOrigin_Lua, uri, bodyData, bodySize, headers) == HttpStatus_200_Ok) { lua_pushlstring(state, result.c_str(), result.size()); @@ -558,7 +558,7 @@ std::map headers; LuaContext::GetDictionaryArgument(headers, state, 3, true /* HTTP header key to lower case */); - + try { std::string bodyIgnored; @@ -604,7 +604,7 @@ const char* resourceId = lua_tostring(state, 1); bool newStateIsStable = lua_toboolean(state, 2); - + try { bool hasStateChanged = false; @@ -669,7 +669,7 @@ const char* storeId = lua_tostring(state, 1); const char* key = lua_tostring(state, 2); const char* value = lua_tostring(state, 3); - + try { serverContext->GetIndex().StoreKeyValue(storeId, key, value); @@ -720,7 +720,7 @@ const char* storeId = lua_tostring(state, 1); const char* key = lua_tostring(state, 2); - + try { std::string value; @@ -780,7 +780,7 @@ const char* storeId = lua_tostring(state, 1); const char* key = lua_tostring(state, 2); - + try { serverContext->GetIndex().DeleteKeyValue(storeId, key); @@ -934,7 +934,7 @@ Json::Value operations; LuaFunctionCall call2(lua_, "_AccessJob"); call2.ExecuteToJson(operations, false); - + if (operations.type() != Json::arrayValue) { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); @@ -961,7 +961,7 @@ std::string operation = parameters["Operation"].asString(); size_t index = ParseOperation(context_, lock, operation, operations[i]); - + std::string resource = parameters["Resource"].asString(); if (!resource.empty()) { @@ -1026,13 +1026,13 @@ Logging::ScopedCurrentThreadNameSetter setter("LUA-HEARTBEAT"); static const unsigned int GRANULARITY = 100; // In milliseconds - + const boost::posix_time::time_duration PERIODICITY = boost::posix_time::seconds(that->heartBeatPeriod_); - + boost::posix_time::ptime next = boost::posix_time::microsec_clock::universal_time() + PERIODICITY; - + bool shouldStop = false; while (!shouldStop) @@ -1107,7 +1107,7 @@ { LOG(INFO) << "Starting the Lua engine"; eventThread_ = boost::thread(EventThread, this); - + LuaScripting::Lock luaLock(*this); if (heartBeatPeriod_ > 0 && luaLock.GetLua().IsExistingFunction(ON_HEART_BEAT)) @@ -1154,8 +1154,8 @@ { Json::Value metadata = Json::objectValue; - for (ServerIndex::MetadataMap::const_iterator - it = instance.GetMetadata().begin(); + for (ServerIndex::MetadataMap::const_iterator + it = instance.GetMetadata().begin(); it != instance.GetMetadata().end(); ++it) { if (it->first.first == ResourceType_Instance) @@ -1307,7 +1307,7 @@ std::string command; Orthanc::ServerResources::GetFileResource(command, Orthanc::ServerResources::LUA_TOOLBOX); lua_.Execute(command); - } + } std::list luaScripts; configLock.GetConfiguration().GetListOfStringsParameter(luaScripts, "LuaScripts"); @@ -1327,7 +1327,7 @@ } } - + void LuaScripting::SignalJobEvent(const JobEvent& event) { // Lua has its own event thread and queue to dissociate it completely from the main JobEventsThread diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/LuaScripting.h --- a/OrthancServer/Sources/LuaScripting.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/LuaScripting.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ State_Running, State_Done }; - + class ExecuteEvent; class IEvent; class OnStoredInstanceEvent; @@ -64,7 +64,7 @@ static int RestApiDelete(lua_State *state); static int GetOrthancConfiguration(lua_State *state); static int SetStableStatus(lua_State* state); - + static int StoreKeyValue(lua_State* state); static int GetKeyValue(lua_State* state); static int DeleteKeyValue(lua_State* state); @@ -99,8 +99,8 @@ boost::recursive_mutex::scoped_lock lock_; public: - explicit Lock(LuaScripting& that) : - that_(that), + explicit Lock(LuaScripting& that) : + that_(that), lock_(that.mutex_) { } @@ -118,7 +118,7 @@ void Start(); void Stop(); - + void SignalStoredInstance(const std::string& publicId, const DicomInstanceToStore& instance, const Json::Value& simplifiedTags); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancConfiguration.cpp --- a/OrthancServer/Sources/OrthancConfiguration.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancConfiguration.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -211,7 +211,7 @@ { for (size_t j = 0; j < s.size(); j++) { - if (!isalnum(s[j]) && + if (!isalnum(s[j]) && s[j] != '-' && s[j] != '_') { throw OrthancException(ErrorCode_BadFileFormat, @@ -341,18 +341,18 @@ if (!source[name].isUInt()) { throw OrthancException(ErrorCode_BadFileFormat, - "Bad format for \"" + std::string(JOBS_ENGINE_THREADS_COUNT) + "." + name + + "Bad format for \"" + std::string(JOBS_ENGINE_THREADS_COUNT) + "." + name + "\". It should be an unsigned integer"); } jobsEngineThreadsCount_[name] = source[name].asUInt(); - } + } } } unsigned int OrthancConfiguration::GetJobsEngineWorkersThread(const std::string& jobType) const { unsigned int workersThread = 1; - + const JobsEngineThreadsCount::const_iterator it = jobsEngineThreadsCount_.find(jobType); if (it != jobsEngineThreadsCount_.end()) { @@ -370,7 +370,7 @@ std::string OrthancConfiguration::GetOrthancAET() const { std::string aet = GetStringParameter(ORTHANC_CONFIG_DICOM_AET); - + if (!Toolbox::IsValidAet(aet)) { throw OrthancException(ErrorCode_BadFileFormat, std::string("Option \"") + ORTHANC_CONFIG_DICOM_AET + @@ -441,7 +441,7 @@ } } - + void OrthancConfiguration::SavePeersToJson(Json::Value& target) { target = Json::objectValue; @@ -449,15 +449,15 @@ for (Peers::const_iterator it = peers_.begin(); it != peers_.end(); ++it) { Json::Value peer; - it->second.Serialize(peer, - false /* use simple format if possible */, + it->second.Serialize(peer, + false /* use simple format if possible */, true /* include passwords */); target[it->first] = peer; } - } - - + } + + void OrthancConfiguration::SaveModalities() { if (GetBooleanParameter(DICOM_MODALITIES_IN_DB)) @@ -474,7 +474,7 @@ std::string s; Toolbox::WriteFastJson(s, modalities); - + serverIndex_->SetGlobalProperty(GlobalProperty_Modalities, false /* not shared */, s); } } @@ -629,7 +629,7 @@ } } - + static bool LookupUnsignedIntegerParameterInternal(unsigned int& target, const Json::Value& config, const std::string& parameter) @@ -756,7 +756,7 @@ { return boost::filesystem::absolute(first).string(); } - } + } } @@ -855,7 +855,7 @@ { target.clear(); - for (Modalities::const_iterator + for (Modalities::const_iterator it = modalities_.begin(); it != modalities_.end(); ++it) { target.insert(it->first); @@ -933,7 +933,7 @@ RegisteredUsersStatus_NoUser); } } - + boost::filesystem::path OrthancConfiguration::InterpretStringParameterAsPath( const std::string& parameter) const @@ -941,12 +941,12 @@ return SystemToolbox::InterpretRelativePath(defaultDirectory_, parameter); } - + void OrthancConfiguration::GetListOfStringsParameter(std::list& target, const std::string& key) const { target.clear(); - + if (!userConfiguration_.isMember(key)) { return; @@ -962,7 +962,7 @@ for (Json::Value::ArrayIndex i = 0; i < lst.size(); i++) { target.push_back(lst[i].asString()); - } + } } @@ -970,7 +970,7 @@ const std::string& key) const { target.clear(); - + if (!userConfiguration_.isMember(key)) { return; @@ -986,7 +986,7 @@ for (Json::Value::ArrayIndex i = 0; i < lst.size(); i++) { target.insert(lst[i].asString()); - } + } } @@ -1024,7 +1024,7 @@ return false; } - + void OrthancConfiguration::LookupDicomModalitiesUsingAETitle(std::list& modalities, const std::string& aet) const { @@ -1045,7 +1045,7 @@ const std::string& ip) const { RemoteModalityParameters modality; - + if (!LookupDicomModalityUsingAETitle(modality, aet)) { LOG(WARNING) << "Modality \"" << aet @@ -1068,7 +1068,7 @@ } - RemoteModalityParameters + RemoteModalityParameters OrthancConfiguration::GetModalityUsingSymbolicName(const std::string& name) const { RemoteModalityParameters modality; @@ -1077,12 +1077,12 @@ return modality; } - - RemoteModalityParameters + + RemoteModalityParameters OrthancConfiguration::GetModalityUsingAet(const std::string& aet) const { RemoteModalityParameters modality; - + if (LookupDicomModalityUsingAETitle(modality, aet)) { return modality; @@ -1094,12 +1094,12 @@ } } - + void OrthancConfiguration::UpdateModality(const std::string& symbolicName, const RemoteModalityParameters& modality) { CheckAlphanumeric(symbolicName); - + modalities_[symbolicName] = modality; SaveModalities(); } @@ -1119,12 +1119,12 @@ } } - + void OrthancConfiguration::UpdatePeer(const std::string& symbolicName, const WebServiceParameters& peer) { CheckAlphanumeric(symbolicName); - + peer.CheckClientCertificate(); peers_[symbolicName] = peer; @@ -1202,7 +1202,7 @@ serverIndex_ = NULL; } - + TemporaryFile* OrthancConfiguration::CreateTemporaryFile() const { std::string temporaryDirectory = "."; @@ -1424,15 +1424,15 @@ std::set ignoreTagLength; dicom.ExtractDicomSummary(target, ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); } - - + + void OrthancConfiguration::DefaultExtractDicomSummary(DicomMap& target, DcmDataset& dicom) { std::set ignoreTagLength; FromDcmtkBridge::ExtractDicomSummary(target, dicom, ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); - } - + } + void OrthancConfiguration::DefaultDicomDatasetToJson(Json::Value& target, const ParsedDicomFile& dicom) @@ -1446,19 +1446,19 @@ DcmDataset& dicom, const std::set& ignoreTagLength) { - FromDcmtkBridge::ExtractDicomAsJson(target, dicom, DicomToJsonFormat_Full, DicomToJsonFlags_Default, - ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); - } - - + FromDcmtkBridge::ExtractDicomAsJson(target, dicom, DicomToJsonFormat_Full, DicomToJsonFlags_Default, + ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); + } + + void OrthancConfiguration::DefaultDicomDatasetToJson(Json::Value& target, const ParsedDicomFile& dicom, const std::set& ignoreTagLength) { - dicom.DatasetToJson(target, DicomToJsonFormat_Full, DicomToJsonFlags_Default, + dicom.DatasetToJson(target, DicomToJsonFormat_Full, DicomToJsonFlags_Default, ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength); } - + void OrthancConfiguration::DefaultDicomHeaderToJson(Json::Value& target, const ParsedDicomFile& dicom) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancConfiguration.h --- a/OrthancServer/Sources/OrthancConfiguration.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancConfiguration.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -101,19 +101,19 @@ OrthancConfiguration(); void LoadModalitiesFromJson(const Json::Value& source); - + void LoadPeersFromJson(const Json::Value& source); - + void LoadModalities(); - + void LoadPeers(); - + void SaveModalitiesToJson(Json::Value& target); - + void SavePeersToJson(Json::Value& target); - + void SaveModalities(); - + void SavePeers(); static OrthancConfiguration& GetInstance(); @@ -199,7 +199,7 @@ // If the parameter is not part of the user configuration, it it retrieved from the default configuration std::string GetStringParameter(const std::string& parameter) const; - + bool LookupIntegerParameter(int& target, const std::string& parameter) const; @@ -234,7 +234,7 @@ bool& hasInsecureUser) const; boost::filesystem::path InterpretStringParameterAsPath(const std::string& parameter) const; - + void GetListOfStringsParameter(std::list& target, const std::string& key) const; @@ -254,14 +254,14 @@ const std::string& ip) const; RemoteModalityParameters GetModalityUsingSymbolicName(const std::string& name) const; - + RemoteModalityParameters GetModalityUsingAet(const std::string& aet) const; - + void UpdateModality(const std::string& symbolicName, const RemoteModalityParameters& modality); void RemoveModality(const std::string& symbolicName); - + void UpdatePeer(const std::string& symbolicName, const WebServiceParameters& peer); @@ -280,7 +280,7 @@ } void Format(std::string& result) const; - + void SetDefaultEncoding(Encoding encoding); bool HasConfigurationChanged() const; @@ -323,7 +323,7 @@ { return GetUnsignedIntegerParameter(ORTHANC_CONFIG_MAXIMUM_PATIENT_COUNT); } - + unsigned int GetDicomPort() const { return GetUnsignedIntegerParameter(ORTHANC_CONFIG_DICOM_PORT); @@ -359,18 +359,18 @@ static void DefaultExtractDicomSummary(DicomMap& target, DcmDataset& dicom); - + static void DefaultDicomDatasetToJson(Json::Value& target, const ParsedDicomFile& dicom); - + static void DefaultDicomDatasetToJson(Json::Value& target, DcmDataset& dicom, const std::set& ignoreTagLength); - + static void DefaultDicomDatasetToJson(Json::Value& target, const ParsedDicomFile& dicom, const std::set& ignoreTagLength); - + static void DefaultDicomHeaderToJson(Json::Value& target, const ParsedDicomFile& dicom); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancFindRequestHandler.cpp --- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -36,7 +36,7 @@ #include "ServerContext.h" #include "ServerToolbox.h" -#include +#include namespace Orthanc @@ -116,7 +116,7 @@ const DicomConnectionInfo& connection) { static const char* LUA_CALLBACK = "IncomingFindRequestFilter"; - + LuaScripting::Lock lock(context_.GetLuaScripting()); if (!lock.GetLua().IsExistingFunction(LUA_CALLBACK)) @@ -387,7 +387,7 @@ // remove tags that are not used for matching if (tag == DICOM_TAG_QUERY_RETRIEVE_LEVEL || tag == DICOM_TAG_SPECIFIC_CHARACTER_SET || - tag == DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC) // time zone is not directly used for matching. Once we support "Timezone query adjustment", we may use it to adjust date-time filters but for now, just ignore it + tag == DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC) // time zone is not directly used for matching. Once we support "Timezone query adjustment", we may use it to adjust date-time filters but for now, just ignore it { continue; } @@ -430,7 +430,7 @@ } else { - CLOG(INFO, DICOM) << "Because of a patch for the manufacturer of the remote modality, " + CLOG(INFO, DICOM) << "Because of a patch for the manufacturer of the remote modality, " << "ignoring constraint on tag (" << tag.Format() << ") " << FromDcmtkBridge::GetTagName(element); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancFindRequestHandler.h --- a/OrthancServer/Sources/OrthancFindRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancFindRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -27,7 +27,7 @@ namespace Orthanc { class ServerContext; - + class OrthancFindRequestHandler : public IFindRequestHandler { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancGetRequestHandler.cpp --- a/OrthancServer/Sources/OrthancGetRequestHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancGetRequestHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -82,7 +82,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + if (instancesLoader_.get() == NULL || !instancesLoader_->HasNext()) { @@ -117,7 +117,7 @@ { throw OrthancException(ErrorCode_InternalError); } - + OFString a, b; if (!dicom.GetDcmtkObject().getDataset()->findAndGetOFString(DCM_SOPClassUID, a).good() || !dicom.GetDcmtkObject().getDataset()->findAndGetOFString(DCM_SOPInstanceUID, b).good()) @@ -134,7 +134,7 @@ } } - + void OrthancGetRequestHandler::AddFailedUIDInstance(const std::string& sopInstance) { if (failedUIDs_.empty()) @@ -174,7 +174,7 @@ if (pc->result == ASC_P_ACCEPTANCE) { DicomTransferSyntax transferSyntax; - + if (LookupTransferSyntax(transferSyntax, pc->acceptedTransferSyntax)) { /*CLOG(TRACE, DICOM) << "C-GET SCP accepted: SOP class " << pc->abstractSyntax @@ -190,19 +190,19 @@ << pc->acceptedTransferSyntax; } } - + pc = reinterpret_cast(LST_Next(l)); } } - + /** * 2. Select the preferred transfer syntaxes, which corresponds to * the source transfer syntax, plus all the uncompressed transfer * syntaxes if transcoding is enabled. * This way, we minimize the transcoding on our side. **/ - + std::list preferred; preferred.push_back(sourceSyntax); @@ -231,7 +231,7 @@ * 3. Lookup whether one of the preferred transfer syntaxes was * accepted. **/ - + for (std::list::const_iterator it = preferred.begin(); it != preferred.end(); ++it) { @@ -255,7 +255,7 @@ } return false; - } + } bool OrthancGetRequestHandler::PerformGetSubOp(T_ASC_Association* assoc, @@ -268,7 +268,7 @@ { failedCount_++; AddFailedUIDInstance(sopInstanceUid); - throw OrthancException(ErrorCode_NetworkProtocol, + throw OrthancException(ErrorCode_NetworkProtocol, "C-GET SCP: Unknown transfer syntax: (" + std::string(dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT")) + ") " + sopClassUid); @@ -313,7 +313,7 @@ } const DIC_US msgId = assoc->nextMsgID++; - + T_DIMSE_C_StoreRQ req; memset(&req, 0, sizeof(req)); req.MessageID = msgId; @@ -322,13 +322,13 @@ req.DataSetType = DIMSE_DATASET_PRESENT; req.Priority = DIMSE_PRIORITY_MEDIUM; req.opts = 0; - + T_DIMSE_C_StoreRSP rsp; memset(&rsp, 0, sizeof(rsp)); CLOG(INFO, DICOM) << "Store SCU RQ: MsgID " << msgId << ", (" << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ")"; - + T_DIMSE_DetectedCancelParameters cancelParameters; memset(&cancelParameters, 0, sizeof(cancelParameters)); @@ -362,7 +362,7 @@ std::set ts; ts.insert(selectedSyntax); - + if (context_.GetTranscoder()->Transcode(transcoded, source, ts, TranscodingSopInstanceUidMode_AllowNew)) { // Transcoding has succeeded @@ -384,11 +384,11 @@ "C-GET SCP: Cannot transcode " + sopClassUid + " from transfer syntax " + GetTransferSyntaxUid(sourceSyntax) + " to " + GetTransferSyntaxUid(selectedSyntax)); - } + } } bool isContinue; - + if (cond.good()) { { @@ -396,7 +396,7 @@ CLOG(TRACE, DICOM) << "Received Store Response following a C-GET:" << std::endl << DIMSE_dumpMessage(str, rsp, DIMSE_INCOMING); } - + if (cancelParameters.cancelEncountered) { CLOG(INFO, DICOM) << "C-GET SCP: Received C-Cancel RQ"; @@ -435,14 +435,14 @@ << DimseCondition::dump(temp_str, cond); isContinue = true; } - + if (stDetail.get() != NULL) { std::stringstream s; // DcmObject::PrintHelper cannot be used with VS2008 stDetail->print(s); CLOG(INFO, DICOM) << " Status Detail: " << s.str(); } - + return isContinue; } @@ -462,11 +462,11 @@ tag = (input.HasTag(DICOM_TAG_ACCESSION_NUMBER) ? DICOM_TAG_ACCESSION_NUMBER : DICOM_TAG_STUDY_INSTANCE_UID); break; - + case ResourceType_Series: tag = DICOM_TAG_SERIES_INSTANCE_UID; break; - + case ResourceType_Instance: tag = DICOM_TAG_SOP_INSTANCE_UID; break; @@ -511,7 +511,7 @@ } } - return true; + return true; } } @@ -564,7 +564,7 @@ "C-GET request without the tag 0008,0052 (QueryRetrieveLevel)"); } - ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); + ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); /** @@ -576,7 +576,7 @@ if (!LookupIdentifiers(publicIds, level, input)) { CLOG(ERROR, DICOM) << "Cannot determine what resources are requested by C-GET"; - return false; + return false; } localAet_ = context_.GetDefaultLocalApplicationEntityTitle(); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancGetRequestHandler.h --- a/OrthancServer/Sources/OrthancGetRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancGetRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,7 +33,7 @@ { class ParsedDicomFile; class ServerContext; - + class OrthancGetRequestHandler : public IGetRequestHandler { private: @@ -50,25 +50,25 @@ unsigned int warningCount_; unsigned int failedCount_; std::string failedUIDs_; - + uint32_t timeout_; bool allowTranscoding_; bool LookupIdentifiers(std::list& publicIds, ResourceType level, const DicomMap& input) const; - + // Returns "false" iff cancel bool PerformGetSubOp(T_ASC_Association *assoc, const std::string& sopClassUid, const std::string& sopInstanceUid, ParsedDicomFile& dicom); - + void AddFailedUIDInstance(const std::string& sopInstance); public: explicit OrthancGetRequestHandler(ServerContext& context); - + virtual bool Handle(const DicomMap& input, const std::string& originatorIp, const std::string& originatorAet, @@ -76,30 +76,30 @@ uint32_t timeout) ORTHANC_OVERRIDE; virtual bool DoNext(T_ASC_Association *assoc) ORTHANC_OVERRIDE; - + virtual unsigned int GetSubOperationCount() const ORTHANC_OVERRIDE { return static_cast(instancesIds_.size()); } - + virtual unsigned int GetCompletedCount() const ORTHANC_OVERRIDE { return completedCount_; } - + virtual unsigned int GetWarningCount() const ORTHANC_OVERRIDE { return warningCount_; } - + virtual unsigned int GetFailedCount() const ORTHANC_OVERRIDE { return failedCount_; } - + virtual const std::string& GetFailedUids() const ORTHANC_OVERRIDE { return failedUIDs_; - } + } }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancHttpHandler.cpp --- a/OrthancServer/Sources/OrthancHttpHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancHttpHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - for (Handlers::const_iterator it = handlers_.begin(); it != handlers_.end(); ++it) + for (Handlers::const_iterator it = handlers_.begin(); it != handlers_.end(); ++it) { if ((*it)->CreateChunkedRequestReader (target, origin, remoteIp, username, method, uri, headers, authenticationPayload)) @@ -75,9 +75,9 @@ size_t bodySize, const std::string& authenticationPayload) { - for (Handlers::const_iterator it = handlers_.begin(); it != handlers_.end(); ++it) + for (Handlers::const_iterator it = handlers_.begin(); it != handlers_.end(); ++it) { - if ((*it)->Handle(output, origin, remoteIp, username, method, uri, + if ((*it)->Handle(output, origin, remoteIp, username, method, uri, headers, getArguments, bodyData, bodySize, authenticationPayload)) { return true; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancHttpHandler.h --- a/OrthancServer/Sources/OrthancHttpHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancHttpHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancInitialization.cpp --- a/OrthancServer/Sources/OrthancInitialization.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancInitialization.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -77,7 +77,7 @@ static void RegisterUserMetadata(const Json::Value& config) { static const char* const USER_METADATA = "UserMetadata"; - + if (config.isMember(USER_METADATA)) { const Json::Value& parameter = config[USER_METADATA]; @@ -93,9 +93,9 @@ "Not a number in this user-defined metadata: " + name); } - int metadata = parameter[name].asInt(); + int metadata = parameter[name].asInt(); - LOG(INFO) << "Registering user-defined metadata: " << name << " (index " + LOG(INFO) << "Registering user-defined metadata: " << name << " (index " << metadata << ")"; try @@ -115,7 +115,7 @@ static void RegisterUserContentType(const Json::Value& config) { static const char* const USER_CONTENT_TYPE = "UserContentType"; - + if (config.isMember(USER_CONTENT_TYPE)) { const Json::Value& parameter = config[USER_CONTENT_TYPE]; @@ -147,7 +147,7 @@ "Not a number in this user-defined attachment type: " + name); } - LOG(INFO) << "Registering user-defined attachment type: " << name << " (index " + LOG(INFO) << "Registering user-defined attachment type: " << name << " (index " << contentType << ") with MIME type \"" << mime << "\""; try @@ -166,7 +166,7 @@ static void LoadExternalDictionaries(const Json::Value& configuration) { static const char* const EXTERNAL_DICTIONARIES = "ExternalDictionaries"; - + if (configuration.type() == Json::objectValue && configuration.isMember(EXTERNAL_DICTIONARIES)) { @@ -180,7 +180,7 @@ static void LoadCustomDictionary(const Json::Value& configuration) { static const char* const DICTIONARY = "Dictionary"; - + if (configuration.type() != Json::objectValue || !configuration.isMember(DICTIONARY) || configuration[DICTIONARY].type() != Json::objectValue) @@ -219,7 +219,7 @@ static void LoadMainDicomTags(const Json::Value& configuration) { static const char* const EXTRA_MAIN_DICOM_TAGS = "ExtraMainDicomTags"; - + DicomMap::ResetDefaultMainDicomTags(); if (configuration.type() != Json::objectValue || @@ -275,8 +275,8 @@ { LOG(WARNING) << " - !!! " << tagName << " is already defined as a standard MainDicomTags, it is useless to include it in the ExtraMainDicomTags"; } - - + + } } } @@ -288,7 +288,7 @@ static const char* const MODULE = "Module"; static const char* const VERBOSE = "Verbose"; static const char* const PIN = "Pin"; - + if (config.type() != Json::objectValue || !config.isMember(MODULE) || config[MODULE].type() != Json::stringValue) @@ -338,13 +338,13 @@ static const char* const DEFAULT_ENCODING = "DefaultEncoding"; static const char* const MALLOC_ARENA_MAX = "MallocArenaMax"; static const char* const LOAD_PRIVATE_DICTIONARY = "LoadPrivateDictionary"; - + OrthancConfiguration::WriterLock lock; #if ORTHANC_ENABLE_PLUGINS == 1 GOOGLE_PROTOBUF_VERIFY_VERSION; #endif - + InitializeServerEnumerations(); // Read the user-provided configuration @@ -427,7 +427,7 @@ { OrthancConfiguration::ReaderLock lock; - std::string storageDirectoryStr = + std::string storageDirectoryStr = lock.GetConfiguration().GetStringParameter(ORTHANC_CONFIG_STORAGE_DIRECTORY); std::string indexDirectoryStr; @@ -471,7 +471,7 @@ } virtual void Create(const std::string& uuid, - const void* content, + const void* content, size_t size, FileContentType type) ORTHANC_OVERRIDE { @@ -517,13 +517,13 @@ { static const char* const SYNC_STORAGE_AREA = "SyncStorageArea"; static const char* const STORE_DICOM = "StoreDicom"; - + OrthancConfiguration::ReaderLock lock; - std::string storageDirectoryStr = + std::string storageDirectoryStr = lock.GetConfiguration().GetStringParameter(ORTHANC_CONFIG_STORAGE_DIRECTORY); - boost::filesystem::path storageDirectory = + boost::filesystem::path storageDirectory = lock.GetConfiguration().InterpretStringParameterAsPath(storageDirectoryStr); LOG(WARNING) << "Storage directory: " << SystemToolbox::PathToUtf8(storageDirectory); @@ -557,7 +557,7 @@ static void SetDcmtkVerbosity(Verbosity verbosity) { - // INFO_LOG_LEVEL was the DCMTK log level in Orthanc <= 1.8.0 + // INFO_LOG_LEVEL was the DCMTK log level in Orthanc <= 1.8.0 // https://support.dcmtk.org/docs-dcmrt/classOFLogger.html#ae20bf2616f15313c1f089da2eefb8245 OFLogger::LogLevel dataLevel, networkLevel; @@ -586,7 +586,7 @@ OFLog::configure(dataLevel); assert(dcmtk::log4cplus::Logger::getRoot().getChainedLogLevel() == dataLevel); - + DCM_dcmdataLogger.setLogLevel(dataLevel); // This seems to be implied by "OFLog::configure()" DCM_dcmnetLogger.setLogLevel(networkLevel); // This will display PDU in DICOM networking } @@ -595,7 +595,7 @@ void SetGlobalVerbosity(Verbosity verbosity) { SetDcmtkVerbosity(verbosity); - + switch (verbosity) { case Verbosity_Default: @@ -618,7 +618,7 @@ } } - + Verbosity GetGlobalVerbosity() { if (Logging::IsTraceLevelEnabled()) @@ -635,7 +635,7 @@ } } - + void SetCategoryVerbosity(Logging::LogCategory category, Verbosity verbosity) { @@ -665,7 +665,7 @@ SetDcmtkVerbosity(verbosity); } } - + Verbosity GetCategoryVerbosity(Logging::LogCategory category) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancInitialization.h --- a/OrthancServer/Sources/OrthancInitialization.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancInitialization.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancMoveRequestHandler.cpp --- a/OrthancServer/Sources/OrthancMoveRequestHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancMoveRequestHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -175,7 +175,7 @@ std::unique_ptr job_; size_t position_; size_t countInstances_; - + public: AsynchronousMove(ServerContext& context, const std::string& targetAet, @@ -240,12 +240,12 @@ { return Status_Failure; } - + if (position_ == 0) { context_.GetJobsEngine().GetRegistry().Submit(job_.release(), 0 /* priority */); } - + position_ ++; return Status_Success; } @@ -295,11 +295,11 @@ tag = DICOM_TAG_STUDY_INSTANCE_UID; } break; - + case ResourceType_Series: tag = DICOM_TAG_SERIES_INSTANCE_UID; break; - + case ResourceType_Instance: tag = DICOM_TAG_SOP_INSTANCE_UID; break; @@ -357,7 +357,7 @@ throw OrthancException(ErrorCode_BadRequest, "C-MOVE request matching no resource stored in Orthanc"); } - + bool synchronous; { @@ -440,7 +440,7 @@ } assert(levelTmp != NULL); - ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); + ResourceType level = StringToResourceType(levelTmp->GetContent().c_str()); /** diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancMoveRequestHandler.h --- a/OrthancServer/Sources/OrthancMoveRequestHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancMoveRequestHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -28,7 +28,7 @@ namespace Orthanc { class ServerContext; - + class OrthancMoveRequestHandler : public IMoveRequestHandler { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -69,7 +69,7 @@ { // Modification of DICOM instances ------------------------------------------ - + static std::string GeneratePatientName(ServerContext& context) { uint64_t seq = context.GetIndex().IncrementGlobalSequence(GlobalProperty_AnonymizationSequence, true /* shared */); @@ -163,7 +163,7 @@ OrthancConfiguration::ReaderLock lock; target.SetPrivateCreator(lock.GetConfiguration().GetDefaultPrivateCreator()); } - + if (call.ParseJsonRequest(request)) { target.ParseModifyRequest(request); @@ -185,7 +185,7 @@ OrthancConfiguration::ReaderLock lock; target.SetPrivateCreator(lock.GetConfiguration().GetDefaultPrivateCreator()); } - + if (call.ParseJsonRequest(request) && request.isObject()) { @@ -230,7 +230,7 @@ std::unique_ptr dicom(context.ReadParsedDicom(id)); modified.reset(dicom->Clone()); } - + modification.Apply(modified); modified->Answer(call.GetOutput()); } @@ -264,7 +264,7 @@ lossyQuality = lock.GetConfiguration().GetDicomLossyTranscodingQuality(); } - if (request.isMember(LOSSY_QUALITY)) + if (request.isMember(LOSSY_QUALITY)) { lossyQuality = SerializationToolbox::ReadUnsignedInteger(request, LOSSY_QUALITY); } @@ -404,7 +404,7 @@ { job->SetMultipleResourcesModification(modification.release(), isAnonymization); } - + job->SetOrigin(call); SetKeepSource(*job, body); @@ -442,12 +442,12 @@ // This was the only flavor in Orthanc <= 1.9.3 std::set resources; resources.insert(call.GetUriComponent("id", "")); - + SubmitModificationJob(modification, isAnonymization, call, body, outputLevel, true /* single resource */, resources); } - + static void SubmitBulkJob(std::unique_ptr& modification, bool isAnonymization, RestApiPostCall& call, @@ -469,7 +469,7 @@ { OrthancRestApi::DocumentSubmitCommandsJob(call); DocumentModifyOptions(call); - const std::string r = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); + const std::string r = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); call.GetDocumentation() .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) .SetSummary("Modify " + r) @@ -480,14 +480,14 @@ .SetUriArgument("id", "Orthanc identifier of the " + r + " of interest"); return; } - + std::unique_ptr modification(new DicomModification); Json::Value body; ParseModifyRequest(body, *modification, call); modification->SetLevel(resourceType); - + SubmitModificationJob(modification, false /* not an anonymization */, call, body, resourceType); } @@ -515,7 +515,7 @@ .AddAnswerType(MimeType_Json, "The list of all the resources that have been altered by this modification"); return; } - + std::unique_ptr modification(new DicomModification); Json::Value body; @@ -542,7 +542,7 @@ { OrthancRestApi::DocumentSubmitCommandsJob(call); DocumentAnonymizationOptions(call); - const std::string r = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); + const std::string r = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); call.GetDocumentation() .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) .SetSummary("Anonymize " + r) @@ -757,7 +757,7 @@ catch (OrthancException&) { // Error: Remove the newly-created series - + std::string series; if (context.GetIndex().LookupParent(series, someInstance)) { @@ -782,7 +782,7 @@ static const char* const SPECIFIC_CHARACTER_SET_2 = "SpecificCharacterSet"; static const char* const TYPE = "Type"; static const char* const VALUE = "Value"; - + assert(request.isObject()); ServerContext& context = OrthancRestApi::GetContext(call); @@ -881,7 +881,7 @@ for (;;) { DicomTag::AddTagsForModule(moduleTags, GetModule(type)); - + if (type == ResourceType_Patient) { break; // We're done @@ -1139,7 +1139,7 @@ "These instances must all be children of the same source study, that is specified in the URI.", false); return; } - + ServerContext& context = OrthancRestApi::GetContext(call); Json::Value request; @@ -1151,7 +1151,7 @@ const std::string study = call.GetUriComponent("id", ""); - std::unique_ptr job(new SplitStudyJob(context, study)); + std::unique_ptr job(new SplitStudyJob(context, study)); job->SetOrigin(call); bool ok = false; @@ -1182,8 +1182,8 @@ if (!ok) { throw OrthancException(ErrorCode_BadRequest, "Both the \"Series\" and the \"Instances\" fields are missing"); - } - + } + job->AddTrailingStep(); SetKeepSource(*job, request); @@ -1220,7 +1220,7 @@ for (size_t i = 0; i < tags.size(); i++) { const Json::Value& value = request[REPLACE][tags[i]]; - + if (value.type() != Json::stringValue) { throw OrthancException(ErrorCode_BadFileFormat); @@ -1268,7 +1268,7 @@ const std::string study = call.GetUriComponent("id", ""); - std::unique_ptr job(new MergeStudyJob(context, study)); + std::unique_ptr job(new MergeStudyJob(context, study)); job->SetOrigin(call); std::vector resources; @@ -1286,7 +1286,7 @@ OrthancRestApi::GetApi(call).SubmitCommandsJob (call, job.release(), true /* synchronous by default */, request); } - + void OrthancRestApi::RegisterAnonymizeModify() { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -51,7 +51,7 @@ result["ID"] = publicId; result["Path"] = GetBasePath(resourceType, publicId); } - + result["Status"] = EnumerationToString(status); } @@ -143,7 +143,7 @@ sample["ParentStudy"] = "66c8e41e-ac3a9029-0b85e42a-8195ee0a-92c2e62e"; sample["Path"] = "/instances/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5"; sample["Status"] = "Success"; - + call.GetDocumentation() .SetTag("Instances") .SetSummary("Upload DICOM instances") @@ -177,7 +177,7 @@ std::unique_ptr reader(ZipReader::CreateFromMemory(call.GetBodyData(), call.GetBodySize())); Json::Value answer = Json::arrayValue; - + std::string filename, content; while (reader->ReadNextFile(filename, content)) { @@ -219,7 +219,7 @@ } } } - } + } call.GetOutput().AnswerJson(answer); } @@ -240,7 +240,7 @@ else { toStore.reset(DicomInstanceToStore::CreateFromBuffer(call.GetBodyData(), call.GetBodySize())); - } + } toStore->SetOrigin(DicomInstanceOrigin::FromRest(call)); @@ -255,13 +255,13 @@ // Registration of the various REST handlers -------------------------------- - OrthancRestApi::OrthancRestApi(ServerContext& context, - bool orthancExplorerEnabled) : + OrthancRestApi::OrthancRestApi(ServerContext& context, + bool orthancExplorerEnabled) : context_(context), leaveBarrier_(false), resetRequestReceived_(false), - activeRequests_(context.GetMetricsRegistry(), - "orthanc_rest_api_active_requests", + activeRequests_(context.GetMetricsRegistry(), + "orthanc_rest_api_active_requests", MetricsUpdatePolicy_MaxOver10Seconds) { RegisterSystem(orthancExplorerEnabled); @@ -281,7 +281,7 @@ LOG(WARNING) << "READ-ONLY SYSTEM: deactivating POST /instances route"; } - + // Auto-generated directories Register("/tools", RestApi::AutoListChildren); @@ -329,7 +329,7 @@ static const char* KEY_ASYNCHRONOUS = "Asynchronous"; static const char* KEY_USER_DATA = "UserData"; - + bool OrthancRestApi::IsSynchronousJobRequest(bool isDefaultSynchronous, const Json::Value& body) { @@ -351,7 +351,7 @@ } } - + int OrthancRestApi::GetJobRequestPriority(const Json::Value& body) { if (body.type() != Json::objectValue || @@ -359,12 +359,12 @@ { return 0; // Default priority } - else + else { return SerializationToolbox::ReadInteger(body, KEY_PRIORITY); } } - + void OrthancRestApi::SubmitGenericJob(RestApiOutput& output, ServerContext& context, @@ -373,7 +373,7 @@ int priority) { std::unique_ptr raii(job); - + if (job == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -402,7 +402,7 @@ } } - + void OrthancRestApi::SubmitGenericJob(RestApiPostCall& call, IJob* job, bool isDefaultSynchronous, @@ -421,21 +421,21 @@ SubmitGenericJob(call.GetOutput(), context_, raii.release(), synchronous, priority); } - + void OrthancRestApi::SubmitCommandsJob(RestApiPostCall& call, SetOfCommandsJob* job, bool isDefaultSynchronous, const Json::Value& body) const { std::unique_ptr raii(job); - + if (body.type() != Json::objectValue) { throw OrthancException(ErrorCode_BadFileFormat); } job->SetDescription("REST API"); - + if (body.isMember(KEY_PERMISSIVE)) { job->SetPermissive(SerializationToolbox::ReadBoolean(body, KEY_PERMISSIVE)); @@ -459,14 +459,14 @@ const Json::Value& body) const { std::unique_ptr raii(job); - + if (body.type() != Json::objectValue) { throw OrthancException(ErrorCode_BadFileFormat); } job->SetDescription("REST API"); - + if (body.isMember(KEY_PERMISSIVE)) { job->SetPermissive(SerializationToolbox::ReadBoolean(body, KEY_PERMISSIVE)); @@ -482,7 +482,7 @@ } SubmitGenericJob(call, raii.release(), isDefaultSynchronous, body); - } + } void OrthancRestApi::DocumentSubmitGenericJob(RestApiPostCall& call) { @@ -499,7 +499,7 @@ .SetAnswerField("ID", RestApiCallDocumentation::Type_String, "In asynchronous mode, identifier of the job") .SetAnswerField("Path", RestApiCallDocumentation::Type_String, "In asynchronous mode, path to access the job in the REST API"); } - + void OrthancRestApi::DocumentSubmitCommandsJob(RestApiPostCall& call) { @@ -592,21 +592,21 @@ call.GetDocumentation().SetHttpGetArgument( GET_SIMPLIFY, RestApiCallDocumentation::Type_Boolean, "If present, " + DOCUMENT_SIMPLIFY, false); } - + if (defaultFormat != DicomToJsonFormat_Short) { call.GetDocumentation().SetHttpGetArgument( GET_SHORT, RestApiCallDocumentation::Type_Boolean, "If present, " + DOCUMENT_SHORT, false); } - + if (defaultFormat != DicomToJsonFormat_Full) { call.GetDocumentation().SetHttpGetArgument( GET_FULL, RestApiCallDocumentation::Type_Boolean, "If present, " + DOCUMENT_FULL, false); - } + } } - - + + void OrthancRestApi::DocumentDicomFormat(RestApiPostCall& call, DicomToJsonFormat defaultFormat) { @@ -615,13 +615,13 @@ call.GetDocumentation().SetRequestField(POST_SIMPLIFY, RestApiCallDocumentation::Type_Boolean, "If set to `true`, " + DOCUMENT_SIMPLIFY, false); } - + if (defaultFormat != DicomToJsonFormat_Short) { call.GetDocumentation().SetRequestField(POST_SHORT, RestApiCallDocumentation::Type_Boolean, "If set to `true`, " + DOCUMENT_SHORT, false); } - + if (defaultFormat != DicomToJsonFormat_Full) { call.GetDocumentation().SetRequestField(POST_FULL, RestApiCallDocumentation::Type_Boolean, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestApi.h --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -113,15 +113,15 @@ static bool IsSynchronousJobRequest(bool isDefaultSynchronous, const Json::Value& body); - + static int GetJobRequestPriority(const Json::Value& body); - + static void SubmitGenericJob(RestApiOutput& output, ServerContext& context, IJob* job, bool synchronous, int priority); - + void SubmitGenericJob(RestApiPostCall& call, IJob* job, bool isDefaultSynchronous, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -75,7 +75,7 @@ throw OrthancException(ErrorCode_BadFileFormat, "Expected a list of strings (Orthanc identifiers)"); } - + for (Json::Value::ArrayIndex i = 0; i < resources.size(); i++) { if (resources[i].type() != Json::stringValue) @@ -90,7 +90,7 @@ } } - + static void AddResourcesOfInterest(ArchiveJob& job /* inout */, const Json::Value& body /* in */) { @@ -117,7 +117,7 @@ } } - + static void GetJobParameters(bool& synchronous, /* out */ bool& extended, /* out */ bool& transcode, /* out */ @@ -152,13 +152,13 @@ { transcode = true; syntax = Orthanc::GetTransferSyntax(SerializationToolbox::ReadString(body, KEY_TRANSCODE)); - + { OrthancConfiguration::ReaderLock lock; lossyQuality = lock.GetConfiguration().GetDicomLossyTranscodingQuality(); } - if (body.isMember(KEY_LOSSY_QUALITY)) + if (body.isMember(KEY_LOSSY_QUALITY)) { lossyQuality = SerializationToolbox::ReadUnsignedInteger(body, KEY_LOSSY_QUALITY); } @@ -241,7 +241,7 @@ } }; - + class SynchronousZipStream : public ZipWriter::IOutputStream { private: @@ -332,7 +332,7 @@ for (;;) { std::unique_ptr obj(queue_->Dequeue(100)); - + if (obj.get() == NULL) { // Check that the job is still active, which indicates @@ -379,7 +379,7 @@ return (chunk_.empty() ? NULL : chunk_.c_str()); } } - + virtual size_t GetChunkSize() ORTHANC_OVERRIDE { if (done_) @@ -393,7 +393,7 @@ } }; - + class SynchronousTemporaryStream : public ZipWriter::IOutputStream { private: @@ -412,7 +412,7 @@ throw OrthancException(ErrorCode_CannotWriteFile); } } - + virtual uint64_t GetArchiveSize() const ORTHANC_OVERRIDE { return archiveSize_; @@ -427,10 +427,10 @@ if (static_cast(chunk.size()) > std::numeric_limits::max()) { throw OrthancException(ErrorCode_InternalError, "Chunk too large"); - } - + } + file_.write(chunk.c_str(), static_cast(chunk.size())); - + if (!file_.good()) { file_.close(); @@ -446,7 +446,7 @@ throw OrthancException(ErrorCode_CannotWriteFile); } } - + archiveSize_ += chunk.size(); } @@ -468,7 +468,7 @@ }; } - + static void SubmitJob(RestApiOutput& output, ServerContext& context, std::unique_ptr& job, @@ -486,7 +486,7 @@ if (synchronous) { bool streaming; - + { OrthancConfiguration::ReaderLock lock; streaming = lock.GetConfiguration().GetBooleanParameter("SynchronousZipStream"); // New in Orthanc 1.9.4 @@ -524,7 +524,7 @@ Json::Value publicContent; context.GetJobsEngine().GetRegistry().SubmitAndWait (publicContent, job.release(), priority); - + { // The archive is now created: Prepare the sending of the ZIP file FilesystemHttpSender sender(tmp->GetPath(), MimeType_Zip); @@ -590,7 +590,7 @@ } } - + template static void CreateBatchPost(RestApiPostCall& call) @@ -632,7 +632,7 @@ GetJobParameters(synchronous, extended, transcode, transferSyntax, lossyQuality, priority, filename, userData, allowUtf8, body, DEFAULT_IS_EXTENDED, "Archive.zip", defaultUtf8); - + std::unique_ptr job(new ArchiveJob(context, IS_MEDIA, extended, ResourceType_Patient)); AddResourcesOfInterest(*job, body); @@ -641,7 +641,7 @@ job->SetTranscode(transferSyntax); job->SetLossyQuality(lossyQuality); } - + job->SetAllowUtf8(allowUtf8); job->SetUserData(userData); @@ -661,7 +661,7 @@ OrthancConfiguration::ReaderLock lock; lossyQuality = lock.GetConfiguration().GetDicomLossyTranscodingQuality(); lossyQuality = call.GetUnsignedInteger32Argument(GET_LOSSY_QUALITY, lossyQuality); - + return lossyQuality; } @@ -694,7 +694,7 @@ } ServerContext& context = OrthancRestApi::GetContext(call); - + if (!call.HasArgument(GET_RESOURCES)) { throw OrthancException(Orthanc::ErrorCode_BadRequest, std::string("Missing ") + GET_RESOURCES + " argument"); @@ -826,7 +826,7 @@ GetJobParameters(synchronous, extended, transcode, transferSyntax, lossyQuality, priority, filename, userData, allowUtf8, body, false /* by default, not extented */, id + ".zip", defaultUtf8); - + std::unique_ptr job(new ArchiveJob(context, IS_MEDIA, extended, LEVEL)); job->AddResource(id, true, LEVEL); @@ -847,7 +847,7 @@ } } - + void OrthancRestApi::RegisterArchive() { if (context_.IsPatientLevelEnabled()) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestChanges.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestChanges.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestChanges.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -31,7 +31,7 @@ // Changes API -------------------------------------------------------------- static const unsigned int DEFAULT_LIMIT = 100; static const int64_t DEFAULT_TO = -1; - + static void GetSinceToAndLimit(int64_t& since, int64_t& to, unsigned int& limit, @@ -85,7 +85,7 @@ .SetHttpGetSample("https://orthanc.uclouvain.be/demo/changes?since=0&limit=2", true); return; } - + ServerContext& context = OrthancRestApi::GetContext(call); int64_t since, to; @@ -152,7 +152,7 @@ // Exports API -------------------------------------------------------------- - + static void GetExports(RestApiGetCall& call) { if (call.IsDocumentation()) @@ -207,7 +207,7 @@ OrthancRestApi::GetIndex(call).DeleteExportedResources(); call.GetOutput().AnswerBuffer("", MimeType_PlainText); } - + void OrthancRestApi::RegisterChanges() { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -58,7 +58,7 @@ static const char* const SOP_CLASS_UID = "SOPClassUID"; static const char* const SOP_INSTANCE_UID = "SOPInstanceUID"; static const char* const KEY_RETRIEVE_METHOD = "RetrieveMethod"; - + static RemoteModalityParameters MyGetModalityUsingSymbolicName(const std::string& name) { OrthancConfiguration::ReaderLock lock; @@ -79,7 +79,7 @@ static DicomAssociationParameters GetAssociationParameters(RestApiPostCall& call, const Json::Value& body) - { + { const std::string& localAet = OrthancRestApi::GetContext(call).GetDefaultLocalApplicationEntityTitle(); const RemoteModalityParameters remote = @@ -87,7 +87,7 @@ DicomAssociationParameters params(localAet, remote); InjectAssociationTimeout(params, body); - + return params; } @@ -100,10 +100,10 @@ { throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse the JSON body"); } - + return GetAssociationParameters(call, body); } - + static void DocumentModalityParametersShared(RestApiCall& call, bool includePermissions) @@ -158,7 +158,7 @@ const Json::Value& body) { bool checkFind = false; - + if (body.type() == Json::objectValue && body.isMember(KEY_CHECK_FIND)) { @@ -171,7 +171,7 @@ } ScuOperationFlags operations = ScuOperationFlags_Echo; - + if (checkFind) { operations = static_cast(operations | ScuOperationFlags_Find); @@ -185,7 +185,7 @@ { // Issue a C-FIND request at the study level about a random Study Instance UID const std::string studyInstanceUid = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study); - + DicomMap query; query.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyInstanceUid, false); @@ -214,8 +214,8 @@ "modality knows about Orthanc. This field defaults to the value of the `DicomEchoChecksFind` " "configuration option. New in Orthanc 1.8.1.", false); } - - + + static void DicomEcho(RestApiPostCall& call) { if (call.IsDocumentation()) @@ -245,7 +245,7 @@ throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse the JSON body"); } } - + static void DicomEchoTool(RestApiPostCall& call) { @@ -269,7 +269,7 @@ const std::string& localAet = OrthancRestApi::GetContext(call).GetDefaultLocalApplicationEntityTitle(); - + DicomAssociationParameters params(localAet, modality); InjectAssociationTimeout(params, body); @@ -432,8 +432,8 @@ fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2) { return; - } - + } + DicomFindAnswers answers(false); { @@ -476,8 +476,8 @@ fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent().size() <= 2) { return; - } - + } + DicomFindAnswers answers(false); { @@ -521,8 +521,8 @@ fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent().size() <= 2) { return; - } - + } + DicomFindAnswers answers(false); { @@ -574,9 +574,9 @@ { return; } - + DicomControlUserConnection connection(GetAssociationParameters(call), ScuOperationFlags_Find); - + DicomFindAnswers patients(false); FindPatient(patients, connection, m); @@ -599,7 +599,7 @@ FindStudy(studies, connection, m); patient["Studies"] = Json::arrayValue; - + // Loop over the found studies for (size_t j = 0; j < studies.GetSize(); j++) { @@ -632,7 +632,7 @@ result.append(patient); } - + call.GetOutput().AnswerJson(result); } @@ -653,16 +653,16 @@ } handler->Run(); - + std::string s = context.GetQueryRetrieveArchive().Add(handler.release()); Json::Value result = Json::objectValue; result["ID"] = s; result["Path"] = "/queries/" + s; - + call.GetOutput().AnswerJson(result); } - + static void DicomQuery(RestApiPostCall& call) { if (call.IsDocumentation()) @@ -726,7 +726,7 @@ else { std::unique_ptr handler(new QueryRetrieveHandler(context)); - + handler->SetModality(call.GetUriComponent("id", "")); handler->SetLevel(StringToResourceType(request[KEY_LEVEL].asCString())); @@ -817,7 +817,7 @@ { throw OrthancException(ErrorCode_UnknownResource); } - } + } QueryRetrieveHandler& GetHandler() const { @@ -842,7 +842,7 @@ if (call.IsDocumentation()) { OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); - + call.GetDocumentation() .SetTag("Networking") .SetSummary("List answers to a query") @@ -850,7 +850,7 @@ "on some DICOM modality, whose identifier is provided in the URL") .SetUriArgument("id", "Identifier of the query of interest") .SetHttpGetArgument("expand", RestApiCallDocumentation::Type_String, - "If present, retrieve detailed information about the individual answers", false) + "If present, retrieve detailed information about the individual answers", false) .AddAnswerType(MimeType_Json, "JSON array containing the indices of the answers, or detailed information " "about the reported answers (if `expand` argument is provided)"); return; @@ -858,7 +858,7 @@ const bool expand = call.HasArgument("expand") && call.GetBooleanArgument("expand", true); const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full); - + QueryAccessor query(call); size_t count = query.GetHandler().GetAnswersCount(); @@ -870,7 +870,7 @@ // New in Orthanc 1.5.0 DicomMap value; query.GetHandler().GetAnswer(value, i); - + Json::Value json = Json::objectValue; FromDcmtkBridge::ToJson(json, value, format); @@ -937,12 +937,12 @@ { OrthancConfiguration::ReaderLock lock; - targetAet = Toolbox::GetJsonStringField(body, KEY_TARGET_AET, targetAet); + targetAet = Toolbox::GetJsonStringField(body, KEY_TARGET_AET, targetAet); timeout = Toolbox::GetJsonIntegerField(body, KEY_TIMEOUT, -1); - + std::string strRetrieveMethod = SerializationToolbox::ReadString(body, KEY_RETRIEVE_METHOD, ""); - + if (!strRetrieveMethod.empty()) { retrieveMethod = StringToRetrieveMethod(strRetrieveMethod); @@ -956,7 +956,7 @@ call.BodyToString(targetAet); } } - + if (retrieveMethod == RetrieveMethod_SystemDefault) { retrieveMethod = context.GetDefaultDicomRetrieveMethod(); @@ -1040,7 +1040,7 @@ "DicomModalities->..->RetrieveMethod", false) .AddRequestType(MimeType_PlainText, "AET of the target modality"); } - + static void RetrieveOneAnswer(RestApiPostCall& call) { @@ -1171,7 +1171,7 @@ } // Ensure that the query of interest does exist - QueryAccessor query(call); + QueryAccessor query(call); RestApi::AutoListChildren(call); } @@ -1220,7 +1220,7 @@ default: break; } - + call.GetOutput().AnswerJson(answer); } @@ -1232,10 +1232,10 @@ assert(CHILDREN_LEVEL == ResourceType_Study || CHILDREN_LEVEL == ResourceType_Series || CHILDREN_LEVEL == ResourceType_Instance); - + if (call.IsDocumentation()) { - const std::string resources = GetResourceTypeText(CHILDREN_LEVEL, true /* plural */, false /* lower case */); + const std::string resources = GetResourceTypeText(CHILDREN_LEVEL, true /* plural */, false /* lower case */); call.GetDocumentation() .SetTag("Networking") .SetSummary("Query the child " + resources + " of an answer") @@ -1257,11 +1257,11 @@ ServerContext& context = OrthancRestApi::GetContext(call); std::unique_ptr handler(new QueryRetrieveHandler(context)); - + { const QueryAccessor parent(call); const ResourceType level = parent.GetHandler().GetLevel(); - + const size_t index = boost::lexical_cast(call.GetUriComponent("index", "")); Json::Value request; @@ -1280,7 +1280,7 @@ level != ResourceType_Study) { throw OrthancException(ErrorCode_UnknownResource); - } + } else if (CHILDREN_LEVEL == ResourceType_Instance && level != ResourceType_Patient && level != ResourceType_Study && @@ -1350,10 +1350,10 @@ } } } - + AnswerQueryHandler(call, handler); } - + /*************************************************************************** @@ -1471,7 +1471,7 @@ static const char* KEY_MOVE_ORIGINATOR_AET = "MoveOriginatorAet"; static const char* KEY_MOVE_ORIGINATOR_ID = "MoveOriginatorID"; static const char* KEY_STORAGE_COMMITMENT = "StorageCommitment"; - + if (call.IsDocumentation()) { OrthancRestApi::DocumentSubmitCommandsJob(call); @@ -1525,7 +1525,7 @@ localAet = remoteModality.GetLocalAet(); } localAet = Toolbox::GetJsonStringField(request, KEY_LOCAL_AET, localAet); // from the payload - + std::string moveOriginatorAET = Toolbox::GetJsonStringField (request, KEY_MOVE_ORIGINATOR_AET, context.GetDefaultLocalApplicationEntityTitle()); int moveOriginatorID = Toolbox::GetJsonIntegerField @@ -1587,14 +1587,14 @@ std::string sopClassUid, sopInstanceUid; connection.Store(sopClassUid, sopInstanceUid, call.GetBodyData(), - call.GetBodySize(), - false /* Not a C-MOVE */, + call.GetBodySize(), + false /* Not a C-MOVE */, "", 0); Json::Value answer = Json::objectValue; answer[SOP_CLASS_UID] = sopClassUid; answer[SOP_INSTANCE_UID] = sopInstanceUid; - + call.GetOutput().AnswerJson(answer); } @@ -1642,14 +1642,14 @@ resource.SetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL, std::string(ResourceTypeToDicomQueryRetrieveLevel(level)), false); - job.AddQuery(resource); + job.AddQuery(resource); } } /*************************************************************************** * DICOM C-Move SCU ***************************************************************************/ - + static void DicomMove(RestApiPostCall& call) { if (call.IsDocumentation()) @@ -1696,7 +1696,7 @@ /*************************************************************************** * DICOM C-Get SCU ***************************************************************************/ - + static void DicomGet(RestApiPostCall& call) { if (call.IsDocumentation()) @@ -1777,7 +1777,7 @@ it = peers.begin(); it != peers.end(); ++it) { WebServiceParameters peer; - + if (lock.GetConfiguration().LookupOrthancPeer(peer, *it)) { Json::Value info; @@ -1869,14 +1869,14 @@ { job->SetCompress(SerializationToolbox::ReadBoolean(request, KEY_COMPRESS)); } - + { OrthancConfiguration::ReaderLock lock; - + WebServiceParameters peer; if (lock.GetConfiguration().LookupOrthancPeer(peer, remote)) { - job->SetPeer(peer); + job->SetPeer(peer); } else { @@ -1940,7 +1940,7 @@ sample["Password"] = Json::nullValue; sample["Pkcs11"] = false; sample["Url"] = "http://127.0.1.1:5000/"; - sample["Username"] = "alice"; + sample["Username"] = "alice"; call.GetDocumentation() .SetTag("Networking") .SetSummary("Get peer configuration") @@ -1954,7 +1954,7 @@ OrthancConfiguration::ReaderLock lock; const std::string peer = call.GetUriComponent("id", ""); - WebServiceParameters info; + WebServiceParameters info; if (lock.GetConfiguration().LookupOrthancPeer(info, peer)) { Json::Value answer; @@ -1997,7 +1997,7 @@ const std::string peer = call.GetUriComponent("id", ""); - WebServiceParameters info; + WebServiceParameters info; { OrthancConfiguration::ReaderLock lock; @@ -2061,7 +2061,7 @@ it = modalities.begin(); it != modalities.end(); ++it) { const RemoteModalityParameters& remote = lock.GetConfiguration().GetModalityUsingSymbolicName(*it); - + Json::Value info; remote.Serialize(info, true /* force advanced format */); result[*it] = info; @@ -2207,7 +2207,7 @@ OrthancConfiguration::ReaderLock lock; lock.GetConfiguration().GetModalityUsingSymbolicName(modality).Serialize(answer, true /* force advanced format */); } - + call.GetOutput().AnswerJson(answer); } @@ -2395,7 +2395,7 @@ if (json.isMember(ORTHANC_RESOURCES)) { const Json::Value& resources = json[ORTHANC_RESOURCES]; - + if (resources.type() != Json::arrayValue) { throw OrthancException(ErrorCode_BadFileFormat, @@ -2415,7 +2415,7 @@ std::list instances; context.GetIndex().GetChildInstances(instances, resources[i].asString()); - + for (std::list::const_iterator it = instances.begin(); it != instances.end(); ++it) { @@ -2441,7 +2441,7 @@ if (json.isMember(DICOM_INSTANCES)) { const Json::Value& instances = json[DICOM_INSTANCES]; - + if (instances.type() != Json::arrayValue) { throw OrthancException(ErrorCode_BadFileFormat, @@ -2514,7 +2514,7 @@ const std::string& remoteAet = remote.GetApplicationEntityTitle(); const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle(); - + // Create a "pending" storage commitment report BEFORE the // actual SCU call in order to avoid race conditions context.GetStorageCommitmentReports().Store( @@ -2522,7 +2522,7 @@ DicomAssociationParameters parameters(localAet, remote); InjectAssociationTimeout(parameters, json); - + std::vector a(sopClassUids.begin(), sopClassUids.end()); std::vector b(sopInstanceUids.begin(), sopInstanceUids.end()); DicomAssociation::RequestStorageCommitment(parameters, transactionUid, a, b); @@ -2580,7 +2580,7 @@ } } } - + static void RemoveAfterStorageCommitment(RestApiPostCall& call) { @@ -2636,12 +2636,12 @@ context.GetIndex().DeleteResource(tmp, orthancId[j], ResourceType_Instance); } } - + call.GetOutput().AnswerBuffer("{}", MimeType_Json); } } } - + void OrthancRestApi::RegisterModalities() { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -75,24 +75,24 @@ case Orthanc::ResourceType_Instance: return "https://orthanc.uclouvain.be/demo/instances/6582b1c0-292ad5ab-ba0f088f-f7a1766f-9a29a54f"; break; - + case Orthanc::ResourceType_Series: return "https://orthanc.uclouvain.be/demo/series/37836232-d13a2350-fa1dedc5-962b31aa-010f8e52"; break; - + case Orthanc::ResourceType_Study: return "https://orthanc.uclouvain.be/demo/studies/27f7126f-4f66fb14-03f4081b-f9341db2-53925988"; break; - + case Orthanc::ResourceType_Patient: return "https://orthanc.uclouvain.be/demo/patients/46e6332c-677825b6-202fcf7c-f787bc5f-7b07c382"; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + static void AnswerDicomAsJson(RestApiCall& call, const Json::Value& dicom, @@ -138,7 +138,7 @@ bool retrieveMetadata) { ResponseContentFlags responseContent = ResponseContentFlags_ExpandTrue; - + if (retrieveMetadata) { responseContent = static_cast(static_cast(responseContent) | ResponseContentFlags_Metadata); @@ -152,7 +152,7 @@ // List all the patients, studies, series or instances ---------------------- - + template static void ListResources(RestApiGetCall& call) { @@ -179,12 +179,12 @@ std::set requestedTags; ResponseContentFlags responseContent; - + OrthancRestApi::GetRequestedTags(requestedTags, call); OrthancRestApi::GetResponseContentAndExpand(responseContent, call); - ResourceFinder finder(resourceType, - responseContent, + ResourceFinder finder(resourceType, + responseContent, OrthancRestApi::GetContext(call).GetFindStorageAccessMode(), OrthancRestApi::GetContext(call).GetIndex().HasFindSupport()); finder.AddRequestedTags(requestedTags); @@ -244,8 +244,8 @@ const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); - ResourceFinder finder(resourceType, - ResponseContentFlags_ExpandTrue, + ResourceFinder finder(resourceType, + ResponseContentFlags_ExpandTrue, OrthancRestApi::GetContext(call).GetFindStorageAccessMode(), OrthancRestApi::GetContext(call).GetIndex().HasFindSupport()); finder.AddRequestedTags(requestedTags); @@ -281,7 +281,7 @@ // Get information about a single patient ----------------------------------- - + static void IsProtectedPatient(RestApiGetCall& call) { if (call.IsDocumentation()) @@ -293,7 +293,7 @@ .AddAnswerType(MimeType_PlainText, "`1` if protected, `0` if not protected"); return; } - + std::string publicId = call.GetUriComponent("id", ""); bool isProtected = OrthancRestApi::GetIndex(call).IsProtectedPatient(publicId); call.GetOutput().AnswerBuffer(isProtected ? "1" : "0", MimeType_PlainText); @@ -313,7 +313,7 @@ .SetUriArgument("id", "Orthanc identifier of the patient of interest"); return; } - + ServerContext& context = OrthancRestApi::GetContext(call); std::string publicId = call.GetUriComponent("id", ""); @@ -324,7 +324,7 @@ // Get information about a single instance ---------------------------------- - + static void GetInstanceFile(RestApiGetCall& call) { static const char* const GET_TRANSCODE = "transcode"; @@ -371,7 +371,7 @@ mime == MimeType_DicomWebXml) { DicomWebJsonVisitor visitor; - + { std::unique_ptr dicom(context.ReadParsedDicom(publicId)); DicomDataSource::Dicom::Lock lock(*dicom); @@ -389,7 +389,7 @@ visitor.FormatXml(xml); call.GetOutput().AnswerBuffer(xml, MimeType_DicomWebXml); } - + return; } } @@ -583,7 +583,7 @@ } } - + static void GetInstanceSimplifiedTags(RestApiGetCall& call) { if (call.IsDocumentation()) @@ -601,7 +601,7 @@ } } - + static void ListFrames(RestApiGetCall& call) { if (call.IsDocumentation()) @@ -612,7 +612,7 @@ .SetDescription("List the frames that are available in the DICOM instance of interest") .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") .AddAnswerType(MimeType_Json, "The list of the indices of the available frames") - .SetHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/frames", true); + .SetHttpGetSample("https://orthanc.uclouvain.be/demo/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/frames", true); return; } @@ -621,19 +621,19 @@ std::string publicId = call.GetUriComponent("id", ""); unsigned int numberOfFrames; - + { std::unique_ptr dicom(context.ReadParsedDicom(publicId)); DicomDataSource::Dicom::Lock lock(*dicom); numberOfFrames = lock.GetContent().GetFramesCount(); } - + Json::Value result = Json::arrayValue; for (unsigned int i = 0; i < numberOfFrames; i++) { result.append(i); } - + call.GetOutput().AnswerJson(result); } @@ -808,10 +808,10 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + std::string description; std::string verb = (isRendered ? "Render" : "Decode"); - + if (call.HasUriComponent("frame")) { description = verb + " one frame of interest from the given DICOM instance."; @@ -859,7 +859,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } - + call.GetDocumentation() .SetTag("Instances") .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") @@ -873,7 +873,7 @@ return; } - + ServerContext& context = OrthancRestApi::GetContext(call); std::string frameId = call.GetUriComponent("frame", "0"); @@ -901,7 +901,7 @@ throw OrthancException(ErrorCode_NotImplemented, "Cannot decode DICOM instance with ID: " + publicId); } - + if (handler.RequiresDicomTags()) { /** @@ -1005,7 +1005,7 @@ DicomMap tags; OrthancConfiguration::DefaultExtractDicomSummary(tags, *dicom); - + DicomImageInformation info(tags); invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); } @@ -1102,10 +1102,10 @@ if (call.HasArgument(ARG_SMOOTH)) { smooth = RestApiCall::ParseBoolean(call.GetArgument(ARG_SMOOTH, "")); - } + } } - - + + public: virtual void Handle(RestApiGetCall& call, std::unique_ptr& decoded, @@ -1116,15 +1116,15 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + PhotometricInterpretation photometric; const bool invert = (dicom->LookupPhotometricInterpretation(photometric) && photometric == PhotometricInterpretation_Monochrome1); - + double rescaleIntercept, rescaleSlope, windowCenter, windowWidth; dicom->GetRescale(rescaleIntercept, rescaleSlope, frame); dicom->GetDefaultWindowing(windowCenter, windowWidth, frame); - + unsigned int argWidth, argHeight; bool smooth; GetUserArguments(windowWidth, windowCenter, argWidth, argHeight, smooth, call); @@ -1152,11 +1152,11 @@ { ratio = static_cast(argHeight) / static_cast(decoded->GetHeight()); } - + targetWidth = Math::iround(ratio * static_cast(decoded->GetWidth())); targetHeight = Math::iround(ratio * static_cast(decoded->GetHeight())); } - + if (decoded->GetFormat() == PixelFormat_RGB24 || decoded->GetFormat() == PixelFormat_RGB48) { if (targetWidth == decoded->GetWidth() && @@ -1168,14 +1168,14 @@ { std::unique_ptr resized( new Image(decoded->GetFormat(), targetWidth, targetHeight, false)); - + if (smooth && (targetWidth < decoded->GetWidth() || targetHeight < decoded->GetHeight())) { ImageProcessing::SmoothGaussian5x5(*decoded, false /* be fast, don't round */); } - + ImageProcessing::Resize(*resized, *decoded); DefaultHandler(call, resized, ImageExtractionMode_Preview, false); } @@ -1214,14 +1214,14 @@ { std::unique_ptr resized( new Image(PixelFormat_Grayscale8, targetWidth, targetHeight, false)); - + if (smooth && (targetWidth < decoded->GetWidth() || targetHeight < decoded->GetHeight())) { ImageProcessing::SmoothGaussian5x5(*rescaled, false /* be fast, don't round */); } - + ImageProcessing::Resize(*resized, *rescaled); DefaultHandler(call, resized, ImageExtractionMode_UInt8, invert); } @@ -1320,7 +1320,7 @@ { NumpyWriter::WriteHeader(buffer_, depth_, width_, height_, PixelFormat_Float32); } - + double rescaleIntercept, rescaleSlope; dicom.GetRescale(rescaleIntercept, rescaleSlope, frame); @@ -1499,7 +1499,7 @@ if (call.IsDocumentation()) { std::string description; - + if (call.HasUriComponent("frame")) { description = "Decode one frame of interest from the given DICOM instance"; @@ -1677,8 +1677,8 @@ unsigned int countStudies, countSeries, countInstances; OrthancRestApi::GetIndex(call).GetResourceStatistics( - diskSize, uncompressedSize, countStudies, countSeries, - countInstances, dicomDiskSize, dicomUncompressedSize, resourceType, publicId); + diskSize, uncompressedSize, countStudies, countSeries, + countInstances, dicomDiskSize, dicomUncompressedSize, resourceType, publicId); Json::Value result = Json::objectValue; result["DiskSize"] = boost::lexical_cast(diskSize); result["DiskSizeMB"] = static_cast(diskSize / MEGABYTE); @@ -1751,7 +1751,7 @@ if (call.HasArgument("expand") && call.GetBooleanArgument("expand", true)) { result = Json::objectValue; - + for (Metadata::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { std::string key; @@ -1770,9 +1770,9 @@ else { result = Json::arrayValue; - + for (Metadata::const_iterator it = metadata.begin(); it != metadata.end(); ++it) - { + { if (isNumeric) { result.append(it->first); @@ -1797,7 +1797,7 @@ const std::string etag = "\"" + boost::lexical_cast(revision) + "-" + md5 + "\""; output.GetLowLevelOutput().AddHeader("ETag", etag); } - + static void SetBufferContentETag(const RestApiOutput& output, int64_t revision, @@ -1809,7 +1809,7 @@ const std::string etag = "\"" + boost::lexical_cast(revision) + "-" + md5 + "\""; output.GetLowLevelOutput().AddHeader("ETag", etag); } - + static void SetAttachmentETag(const RestApiOutput& output, int64_t revision, @@ -1836,7 +1836,7 @@ { std::string lower; Toolbox::ToLowerCase(lower, header); - + HttpToolbox::Arguments::const_iterator found = call.GetHttpHeaders().find(lower); if (found == call.GetHttpHeaders().end()) { @@ -1855,7 +1855,7 @@ md5 = value.substr(comma + 1); return true; } - } + } throw OrthancException(ErrorCode_ParameterOutOfRange, "The \"" + header + "\" HTTP header should contain the ETag (revision followed by MD5 hash), but found: " + value); @@ -2069,7 +2069,7 @@ call.GetOutput().AnswerJson(result); } - + static void GetLabel(RestApiGetCall& call) { @@ -2094,7 +2094,7 @@ std::set labels; OrthancRestApi::GetIndex(call).ListLabels(labels, publicId, level); - + if (labels.find(label) != labels.end()) { call.GetOutput().AnswerBuffer("", MimeType_PlainText); @@ -2150,7 +2150,7 @@ call.GetOutput().AnswerBuffer("", MimeType_PlainText); } - + // Handling of attached files ----------------------------------------------- @@ -2182,8 +2182,8 @@ if (call.HasArgument("full")) { result = Json::objectValue; - - for (std::set::const_iterator + + for (std::set::const_iterator it = attachments.begin(); it != attachments.end(); ++it) { std::string key = EnumerationToString(*it); @@ -2193,8 +2193,8 @@ else { result = Json::arrayValue; - - for (std::set::const_iterator + + for (std::set::const_iterator it = attachments.begin(); it != attachments.end(); ++it) { result.append(EnumerationToString(*it)); @@ -2215,7 +2215,7 @@ .SetHttpHeader("If-None-Match", "Optional revision of the attachment, to check if its content has changed"); } - + static bool GetAttachmentInfo(FileInfo& info /* out */, int64_t& revision /* out */, ResourceType level, @@ -2303,7 +2303,7 @@ } } - + template static void GetAttachmentData(RestApiGetCall& call) { @@ -2328,7 +2328,7 @@ .SetAnswerHeader("ETag", "Revision of the attachment, to be used in further `PUT` or `DELETE` operations") .SetHttpHeader("If-None-Match", "Optional revision of the attachment, to check if its content has changed") .SetHttpHeader("Range", "Optional content range to access part of the attachment (new in Orthanc 1.12.5)"); - + return; } @@ -2431,7 +2431,7 @@ int64_t revision; if (GetAttachmentInfo(info, revision, level, call)) { - Json::Value result = Json::objectValue; + Json::Value result = Json::objectValue; result["Uuid"] = info.GetUuid(); result["ContentType"] = info.GetContentType(); result["UncompressedSize"] = Json::Value::UInt64(info.GetUncompressedSize()); @@ -2564,7 +2564,7 @@ std::unique_ptr compressed(context.ReadAttachment(info, false /* don't uncompress */)); Toolbox::ComputeMD5(compressedMD5, compressed->GetData(), compressed->GetSize()); } - + if (compressedMD5 == info.GetCompressedMD5()) { // The compressed data is OK. If a compression algorithm was @@ -2619,7 +2619,7 @@ } ServerContext& context = OrthancRestApi::GetContext(call); - + std::string publicId = call.GetUriComponent("id", ""); std::string name = call.GetUriComponent("name", ""); @@ -2706,7 +2706,7 @@ } } - if (allowed) + if (allowed) { bool found; int64_t revision; @@ -2938,7 +2938,7 @@ } - template static void GetModule(RestApiGetCall& call) { @@ -2963,7 +2963,7 @@ default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); call.GetDocumentation() @@ -3017,7 +3017,7 @@ } context.ReadDicomAsJson(tags, publicId, ignoreTagLength); - + // Filter the tags of the instance according to the module Json::Value result = Json::objectValue; for (ModuleTags::const_iterator tag = moduleTags.begin(); tag != moduleTags.end(); ++tag) @@ -3026,7 +3026,7 @@ if (tags.isMember(s)) { result[s] = tags[s]; - } + } } AnswerDicomAsJson(call, result, OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)); @@ -3081,18 +3081,18 @@ AccumulateLookupResults(resources, index, DICOM_TAG_SERIES_INSTANCE_UID, tag, ResourceType_Series); AccumulateLookupResults(resources, index, DICOM_TAG_SOP_INSTANCE_UID, tag, ResourceType_Instance); - Json::Value result = Json::arrayValue; - for (LookupResults::const_iterator + Json::Value result = Json::arrayValue; + for (LookupResults::const_iterator it = resources.begin(); it != resources.end(); ++it) - { + { ResourceType type = it->first; const std::string& id = it->second; - + Json::Value item = Json::objectValue; item["Type"] = EnumerationToString(type); item["ID"] = id; item["Path"] = GetBasePath(type, id); - + result.append(item); } @@ -3154,7 +3154,7 @@ "Limit the reported resources to descendants of this series (new in Orthanc 1.12.5)", true) .SetRequestField(KEY_METADATA_QUERY, RestApiCallDocumentation::Type_JsonObject, "Associative array containing the filter on the values of the metadata (new in Orthanc 1.12.5)", true); - + switch (requestType) { case FindType_Find: @@ -3185,7 +3185,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_NotImplemented); } - + return; } @@ -3195,97 +3195,97 @@ if (!call.ParseJsonRequest(request) || request.type() != Json::objectValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "The body must contain a JSON object"); } else if (!request.isMember(KEY_LEVEL) || request[KEY_LEVEL].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_LEVEL) + "\" is missing, or should be a string"); } else if (!request.isMember(KEY_QUERY) && request[KEY_QUERY].type() != Json::objectValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_QUERY) + "\" is missing, or should be a JSON object"); } - else if (request.isMember(KEY_CASE_SENSITIVE) && + else if (request.isMember(KEY_CASE_SENSITIVE) && request[KEY_CASE_SENSITIVE].type() != Json::booleanValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_CASE_SENSITIVE) + "\" must be a Boolean"); } else if (request.isMember(KEY_LABELS) && request[KEY_LABELS].type() != Json::arrayValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_LABELS) + "\" must be an array of strings"); } else if (request.isMember(KEY_LABELS_CONSTRAINT) && request[KEY_LABELS_CONSTRAINT].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_LABELS_CONSTRAINT) + "\" must be an array of strings"); } else if (request.isMember(KEY_METADATA_QUERY) && request[KEY_METADATA_QUERY].type() != Json::objectValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_METADATA_QUERY) + "\" must be an JSON object"); } else if (request.isMember(KEY_PARENT_PATIENT) && request[KEY_PARENT_PATIENT].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_PARENT_PATIENT) + "\" must be a string"); } else if (request.isMember(KEY_PARENT_STUDY) && request[KEY_PARENT_STUDY].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_PARENT_STUDY) + "\" must be a string"); } else if (request.isMember(KEY_PARENT_SERIES) && request[KEY_PARENT_SERIES].type() != Json::stringValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_PARENT_SERIES) + "\" must be a string"); } - else if (requestType == FindType_Find && request.isMember(KEY_LIMIT) && + else if (requestType == FindType_Find && request.isMember(KEY_LIMIT) && request[KEY_LIMIT].type() != Json::intValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_LIMIT) + "\" must be an integer"); } else if (requestType == FindType_Find && request.isMember(KEY_SINCE) && request[KEY_SINCE].type() != Json::intValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_SINCE) + "\" must be an integer"); } else if (requestType == FindType_Find && request.isMember(KEY_REQUESTED_TAGS) && request[KEY_REQUESTED_TAGS].type() != Json::arrayValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_REQUESTED_TAGS) + "\" must be an array"); } else if (requestType == FindType_Find && request.isMember(KEY_RESPONSE_CONTENT) && request[KEY_RESPONSE_CONTENT].type() != Json::arrayValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_RESPONSE_CONTENT) + "\" must be an array"); } else if (requestType == FindType_Find && request.isMember(KEY_ORDER_BY) && request[KEY_ORDER_BY].type() != Json::arrayValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "Field \"" + std::string(KEY_ORDER_BY) + "\" must be an array"); } else if (true) { ResponseContentFlags responseContent = ResponseContentFlags_ID; - + if (requestType == FindType_Find) { if (request.isMember(KEY_RESPONSE_CONTENT)) @@ -3378,7 +3378,7 @@ { std::vector items; Toolbox::TokenizeString(items, value, '\\'); - + finder.AddMetadataConstraint(new DatabaseMetadataConstraint(metadata, ConstraintType_List, items, caseSensitive)); } else if (value.find('*') != std::string::npos || value.find('?') != std::string::npos) @@ -3603,7 +3603,7 @@ } - template static void GetChildResources(RestApiGetCall& call) { @@ -3635,8 +3635,8 @@ std::set requestedTags; OrthancRestApi::GetRequestedTags(requestedTags, call); - ResourceFinder finder(end, - (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID), + ResourceFinder finder(end, + (expand ? ResponseContentFlags_ExpandTrue : ResponseContentFlags_ID), OrthancRestApi::GetContext(call).GetFindStorageAccessMode(), OrthancRestApi::GetContext(call).GetIndex().HasFindSupport()); finder.SetOrthancId(start, call.GetUriComponent("id", "")); @@ -3644,10 +3644,10 @@ Json::Value answer; finder.Execute(answer, OrthancRestApi::GetContext(call), format, false /* no "Metadata" field */); - + // Given the data model, if there are no children, it means there is no parent. // https://discourse.orthanc-server.org/t/patients-id-instances-quirk/5498 - if (answer.size() == 0) + if (answer.size() == 0) { throw OrthancException(ErrorCode_UnknownResource); } @@ -3710,13 +3710,13 @@ result[*it] = full; } } - + call.GetOutput().AnswerJson(result); } - template static void GetParentResource(RestApiGetCall& call) { @@ -3756,7 +3756,7 @@ // another concurrent call return; } - + current = parent; currentType = GetParentResourceType(currentType); } @@ -3891,19 +3891,19 @@ } ServerIndex& index = OrthancRestApi::GetIndex(call); - + // Loop over the instances, grouping them by parent studies so as // to avoid large memory consumption std::list studies; index.GetAllUuids(studies, ResourceType_Study); - for (std::list::const_iterator + for (std::list::const_iterator study = studies.begin(); study != studies.end(); ++study) { std::list instances; index.GetChildInstances(instances, *study, ResourceType_Study); - for (std::list::const_iterator + for (std::list::const_iterator instance = instances.begin(); instance != instances.end(); ++instance) { index.DeleteAttachment(*instance, FileContentType_DicomAsJson, @@ -4020,12 +4020,12 @@ context.GetIndex().GetAllUuids(studies, ResourceType_Study); bool reconstructFiles = GetReconstructFilesField(call); - for (std::list::const_iterator + for (std::list::const_iterator study = studies.begin(); study != studies.end(); ++study) { ServerToolbox::ReconstructResource(context, *study, reconstructFiles, false, ResourceType_Study /* dummy */); } - + call.GetOutput().AnswerBuffer("", MimeType_PlainText); } @@ -4081,7 +4081,7 @@ if (!call.ParseJsonRequest(request) || request.type() != Json::objectValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "The body must contain a JSON object"); } else @@ -4095,7 +4095,7 @@ } ServerIndex& index = OrthancRestApi::GetIndex(call); - + Json::Value answer = Json::arrayValue; if (request.isMember(LEVEL)) @@ -4155,7 +4155,7 @@ { // Need to explore parents std::string current = *it; - + for (;;) { std::string parent; @@ -4184,7 +4184,7 @@ CLOG(INFO, HTTP) << "Unknown resource during a bulk content retrieval: " << *it; } } - + for (std::set::const_iterator it = interest.begin(); it != interest.end(); ++it) { @@ -4250,14 +4250,14 @@ if (!call.ParseJsonRequest(request) || request.type() != Json::objectValue) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, "The body must contain a JSON object"); } else { - if (!request.isMember(KEY_RESOURCES) || !request[KEY_RESOURCES].isArray()) + if (!request.isMember(KEY_RESOURCES) || !request[KEY_RESOURCES].isArray()) { - throw OrthancException(ErrorCode_BadRequest, + throw OrthancException(ErrorCode_BadRequest, std::string("The body must contain a ") + KEY_RESOURCES + " array"); } @@ -4269,7 +4269,7 @@ if (resource.isString()) { ResourceType type; - + const std::string& resourceId = resource.asString(); if (!context.GetIndex().LookupResourceType(type, resourceId) || @@ -4282,7 +4282,7 @@ && resource.isMember(KEY_LEVEL) && resource[KEY_LEVEL].isString()) { ResourceType type = StringToResourceType(resource[KEY_LEVEL].asString().c_str()); - + const std::string& resourceId = resource[KEY_ID].asString(); if (!context.DeleteResource(remainingAncestor, resourceId, type)) @@ -4295,7 +4295,7 @@ throw OrthancException(ErrorCode_BadRequest, "Invalid payload"); } } - + call.GetOutput().AnswerBuffer("", MimeType_PlainText); } } @@ -4390,7 +4390,7 @@ { Register("/patients/{id}/protected", IsProtectedPatient); } - + if (!context_.IsReadOnly()) { if (context_.IsPatientLevelEnabled()) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -47,7 +47,7 @@ { call.GetOutput().Redirect("app/explorer.html"); } - + static void ServeFavicon(RestApiGetCall& call) { call.GetOutput().Redirect("app/images/favicon.ico"); @@ -283,9 +283,9 @@ } uint64_t diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances; - OrthancRestApi::GetIndex(call).GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + OrthancRestApi::GetIndex(call).GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); - + Json::Value result = Json::objectValue; result["TotalDiskSize"] = boost::lexical_cast(diskSize); result["TotalUncompressedSize"] = boost::lexical_cast(uncompressedSize); @@ -461,17 +461,17 @@ { std::set syntaxes; OrthancRestApi::GetContext(call).GetAcceptedTransferSyntaxes(syntaxes); - + Json::Value json = Json::arrayValue; for (std::set::const_iterator syntax = syntaxes.begin(); syntax != syntaxes.end(); ++syntax) { json.append(GetTransferSyntaxUid(*syntax)); } - + call.GetOutput().AnswerJson(json); } - + static void GetAcceptedTransferSyntaxes(RestApiGetCall& call) { @@ -522,7 +522,7 @@ } OrthancRestApi::GetContext(call).SetAcceptedTransferSyntaxes(syntaxes); - + AnswerAcceptedTransferSyntaxes(call); } @@ -542,14 +542,14 @@ std::set sopClasses; OrthancRestApi::GetContext(call).GetAcceptedSopClasses(sopClasses, 0); - + Json::Value json = Json::arrayValue; for (std::set::const_iterator sop = sopClasses.begin(); sop != sopClasses.end(); ++sop) { json.append(*sop); } - + call.GetOutput().AnswerJson(json); } @@ -588,7 +588,7 @@ } - + // Plugins information ------------------------------------------------------ static void ListPlugins(RestApiGetCall& call) @@ -614,7 +614,7 @@ std::list plugins; OrthancRestApi::GetContext(call).GetPlugins().GetManager().ListPlugins(plugins); - for (std::list::const_iterator + for (std::list::const_iterator it = plugins.begin(); it != plugins.end(); ++it) { v.append(*it); @@ -774,7 +774,7 @@ v.append(*it); } } - + call.GetOutput().AnswerJson(v); } @@ -798,7 +798,7 @@ sample["State"] = "Success"; sample["Timestamp"] = "20201228T160340.253201"; sample["Type"] = "Media"; - + call.GetDocumentation() .SetTag("Jobs") .SetSummary("Get job") @@ -871,7 +871,7 @@ std::string value; MimeType mime; std::string filename; - + if (OrthancRestApi::GetContext(call).GetJobsEngine(). GetRegistry().GetJobOutput(value, mime, filename, job, key)) { @@ -943,7 +943,7 @@ case JobAction_Pause: verb = "Pause"; break; - + case JobAction_Resubmit: verb = "Resubmit"; break; @@ -954,8 +954,8 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); - } - + } + call.GetDocumentation() .SetTag("Jobs") .SetSummary(verb + " job") @@ -980,7 +980,7 @@ case JobAction_Pause: ok = OrthancRestApi::GetContext(call).GetJobsEngine().GetRegistry().Pause(id); break; - + case JobAction_Resubmit: ok = OrthancRestApi::GetContext(call).GetJobsEngine().GetRegistry().Resubmit(id); break; @@ -992,14 +992,14 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + if (ok) { call.GetOutput().AnswerBuffer("{}", MimeType_Json); } } - + static void GetMetricsPrometheus(RestApiGetCall& call) { if (call.IsDocumentation()) @@ -1020,7 +1020,7 @@ ServerContext& context = OrthancRestApi::GetContext(call); uint64_t diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances; - context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); unsigned int jobsPending, jobsRunning; @@ -1120,7 +1120,7 @@ call.BodyToString(body); SetGlobalVerbosity(StringToVerbosity(body)); - + // Success LOG(WARNING) << "REST API call has switched the log level to: " << body; call.GetOutput().AnswerBuffer("", MimeType_PlainText); @@ -1144,7 +1144,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + static void GetLogLevelCategory(RestApiGetCall& call) { @@ -1183,7 +1183,7 @@ Verbosity verbosity = StringToVerbosity(body); Logging::LogCategory category = GetCategory(call); SetCategoryVerbosity(category, verbosity); - + // Success LOG(WARNING) << "REST API call has switched the log level of category \"" << Logging::GetCategoryName(category) << "\" to \"" @@ -1212,7 +1212,7 @@ { json.append(*it); } - + call.GetOutput().AnswerJson(json); } @@ -1224,7 +1224,7 @@ Register("/", ServeRoot); Register("/favicon.ico", ServeFavicon); // New in Orthanc 1.9.0 } - + Register("/system", GetSystemInformation); Register("/statistics", GetStatistics); Register("/tools/generate-uid", GenerateUid); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.cpp --- a/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.h --- a/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/ThirdPartyVersions.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancWebDav.cpp --- a/OrthancServer/Sources/OrthancWebDav.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -66,7 +66,7 @@ target = GetNow(); } } - + static void LookupTime(boost::posix_time::ptime& target, ServerContext& context, @@ -85,7 +85,7 @@ } } - + class OrthancWebDav::DicomIdentifiersVisitorV2 : public ResourceFinder::IVisitor { private: @@ -264,7 +264,7 @@ assert(pathToResource_[it->second] == it->first); } #endif - } + } void AddTags(DicomMap& target, const std::string& resourceId, @@ -287,12 +287,12 @@ DicomMap tags; AddTags(tags, resourceId, level_); - + if (level_ == ResourceType_Study) { AddTags(tags, resourceId, ResourceType_Patient); } - + DicomArray arr(tags); for (size_t i = 0; i < arr.GetSize(); i++) { @@ -302,7 +302,7 @@ { const std::string tag = FromDcmtkBridge::GetTagName(element.GetTag(), ""); boost::replace_all(name, "{{" + tag + "}}", element.GetValue().GetContent()); - } + } } // Blank the tags that were not matched @@ -365,17 +365,17 @@ // Detect the resources that have been removed since last refresh removedPaths.clear(); std::set removedResources; - + for (Map::iterator it = resourceToPath_.begin(); it != resourceToPath_.end(); ++it) { if (resources.find(it->first) == resources.end()) { const std::string& path = it->second; - + assert(pathToResource_.find(path) != pathToResource_.end()); pathToResource_.erase(path); removedPaths.insert(path); - + removedResources.insert(it->first); // Delay the removal to avoid disturbing the iterator } } @@ -464,9 +464,9 @@ resource->SetContentLength(info.GetUncompressedSize()); resource->SetCreationTime(time); target.AddResource(resource.release()); - } + } } - + return true; } else @@ -477,7 +477,7 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& time, + boost::posix_time::ptime& time, const UriComponents& path) ORTHANC_OVERRIDE { std::string instanceId; @@ -553,7 +553,7 @@ /** * The "InternalNode" class corresponds to a non-leaf node in the * WebDAV tree, that only contains subfolders (no file). - * + * * TODO: Implement a LRU index to dynamically remove the oldest * children on high RAM usage. **/ @@ -570,7 +570,7 @@ if (child == children_.end()) { INode* node = CreateSubfolder(path); - + if (node == NULL) { return NULL; @@ -599,11 +599,11 @@ children_.erase(child); } } - + virtual void Refresh() = 0; - + virtual bool ListSubfolders(IWebDavBucket::Collection& target) = 0; - + virtual INode* CreateSubfolder(const std::string& path) = 0; public: @@ -621,7 +621,7 @@ ORTHANC_OVERRIDE ORTHANC_FINAL { Refresh(); - + if (path.empty()) { return ListSubfolders(target); @@ -646,7 +646,7 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& time, + boost::posix_time::ptime& time, const UriComponents& path) ORTHANC_OVERRIDE ORTHANC_FINAL { @@ -658,7 +658,7 @@ { // Recursivity Refresh(); - + INode* child = GetChild(path[0]); if (child == NULL) { @@ -718,7 +718,7 @@ } } }; - + class OrthancWebDav::ListOfResources : public InternalNode { @@ -755,7 +755,7 @@ else { const ResourcesIndex::Map& paths = index_->GetPathToResource(); - + for (ResourcesIndex::Map::const_iterator it = paths.begin(); it != paths.end(); ++it) { boost::posix_time::ptime time; @@ -791,7 +791,7 @@ virtual void GetCurrentResources(std::list& resources) = 0; virtual INode* CreateResourceNode(const std::string& resource) = 0; - + public: ListOfResources(ServerContext& context, ResourceType level, @@ -804,9 +804,9 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - + index_.reset(new ResourcesIndex(context, level, t->second)); - + if (level == ResourceType_Instance) { timeMetadata_ = MetadataType_Instance_ReceptionDate; @@ -828,15 +828,15 @@ } }; - + class OrthancWebDav::SingleDicomResource : public ListOfResources { private: ResourceType parentLevel_; std::string parentId_; - - protected: + + protected: virtual void GetCurrentResources(std::list& resources) ORTHANC_OVERRIDE { try @@ -878,11 +878,11 @@ { } }; - - + + class OrthancWebDav::RootNode : public ListOfResources { - protected: + protected: virtual void GetCurrentResources(std::list& resources) ORTHANC_OVERRIDE { GetContext().GetIndex().GetAllUuids(resources, GetLevel()); @@ -938,8 +938,8 @@ resources_.push_back(resource.GetIdentifier()); } }; - - protected: + + protected: virtual void GetCurrentResources(std::list& resources) ORTHANC_OVERRIDE { DatabaseLookup query; @@ -987,13 +987,13 @@ { private: std::set months_; - + public: const std::set& GetMonths() const { return months_; } - + virtual void MarkAsComplete() ORTHANC_OVERRIDE { } @@ -1068,7 +1068,7 @@ } }; - + class OrthancWebDav::ListOfStudiesByYear : public InternalNode { private: @@ -1086,7 +1086,7 @@ context_.GetIndex().GetAllUuids(resources, ResourceType_Study); std::set years; - + for (std::list::const_iterator it = resources.begin(); it != resources.end(); ++it) { DicomMap tags; @@ -1098,7 +1098,7 @@ years.insert(studyDate.substr(0, 4)); // Get the year from "YYYYMMDD" } } - + for (std::set::const_iterator it = years.begin(); it != years.end(); ++it) { target.AddResource(new IWebDavBucket::Folder(*it)); @@ -1147,7 +1147,7 @@ context_.DeleteResource(info, resource.GetIdentifier(), level_); } }; - + void OrthancWebDav::AddVirtualFile(Collection& collection, const UriComponents& path, @@ -1201,12 +1201,12 @@ } } - + void OrthancWebDav::Upload(const std::string& path) { UriComponents uri; Toolbox::SplitUriComponents(uri, path); - + LOG(INFO) << "Upload from WebDAV: " << path; MimeType mime; @@ -1227,14 +1227,14 @@ if (!uncompressedFile.empty()) { LOG(INFO) << "Uploading DICOM file extracted from a ZIP archive in WebDAV: " << filename; - + std::unique_ptr instance(DicomInstanceToStore::CreateFromBuffer(uncompressedFile)); instance->SetOrigin(DicomInstanceOrigin::FromWebDav()); try { std::string publicId; - + context_.Store(publicId, *instance); } catch (OrthancException& e) @@ -1300,7 +1300,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } } - + OrthancWebDav::OrthancWebDav(ServerContext& context, bool allowDicomDelete, @@ -1324,7 +1324,7 @@ } - bool OrthancWebDav::IsExistingFolder(const UriComponents& path) + bool OrthancWebDav::IsExistingFolder(const UriComponents& path) { if (path.empty()) { @@ -1353,9 +1353,9 @@ } } - + bool OrthancWebDav::ListCollection(Collection& collection, - const UriComponents& path) + const UriComponents& path) { if (path.empty()) { @@ -1368,9 +1368,9 @@ { collection.AddResource(new Folder(UPLOADS)); } - + return true; - } + } else if (path[0] == BY_UIDS) { DatabaseLookup query; @@ -1388,7 +1388,7 @@ level = ResourceType_Series; query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], true /* case sensitive */, true /* mandatory tag */); - } + } else if (path.size() == 3) { AddVirtualFile(collection, path, SERIES_INFO); @@ -1449,7 +1449,7 @@ } } - + static bool GetOrthancJson(std::string& target, ServerContext& context, ResourceType level, @@ -1479,8 +1479,8 @@ bool OrthancWebDav::GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, - const UriComponents& path) + boost::posix_time::ptime& modificationTime, + const UriComponents& path) { if (path.empty()) { @@ -1506,7 +1506,7 @@ true /* case sensitive */, true /* mandatory tag */); query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], true /* case sensitive */, true /* mandatory tag */); - + mime = MimeType_Json; return GetOrthancJson(content, context_, ResourceType_Series, query); } @@ -1514,7 +1514,7 @@ boost::ends_with(path[3], ".dcm")) { const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); - + DatabaseLookup query; query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], true /* case sensitive */, true /* mandatory tag */); @@ -1522,7 +1522,7 @@ true /* case sensitive */, true /* mandatory tag */); query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, true /* case sensitive */, true /* mandatory tag */); - + mime = MimeType_Dicom; ResourceFinder finder(ResourceType_Instance, ResponseContentFlags_ID, context_.GetFindStorageAccessMode(), context_.GetIndex().HasFindSupport()); @@ -1557,9 +1557,9 @@ } } - + bool OrthancWebDav::StoreFile(const std::string& content, - const UriComponents& path) + const UriComponents& path) { if (allowUpload_ && path.size() >= 1 && @@ -1601,8 +1601,8 @@ } } - - bool OrthancWebDav::DeleteItem(const std::vector& path) + + bool OrthancWebDav::DeleteItem(const std::vector& path) { if (path.empty()) { @@ -1627,7 +1627,7 @@ { return true; // Allow deletion of virtual files (to avoid blocking recursive DELETE) } - + query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], true /* case sensitive */, true /* mandatory tag */); level = ResourceType_Series; @@ -1689,8 +1689,8 @@ } } - - void OrthancWebDav::Start() + + void OrthancWebDav::Start() { if (uploadRunning_) { @@ -1704,8 +1704,8 @@ } } - - void OrthancWebDav::Stop() + + void OrthancWebDav::Stop() { if (uploadRunning_) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OrthancWebDav.h --- a/OrthancServer/Sources/OrthancWebDav.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -31,7 +31,7 @@ namespace Orthanc { class ServerContext; - + class OrthancWebDav : public IWebDavBucket { private: @@ -64,7 +64,7 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& time, + boost::posix_time::ptime& time, const UriComponents& path) = 0; virtual bool DeleteItem(const UriComponents& path) = 0; @@ -74,13 +74,13 @@ void AddVirtualFile(Collection& collection, const UriComponents& path, const std::string& filename); - + static void UploadWorker(OrthancWebDav* that); void Upload(const std::string& path); INode& GetRootNode(const std::string& rootPath); - + ServerContext& context_; bool allowDicomDelete_; bool allowUpload_; @@ -93,7 +93,7 @@ SharedMessageQueue uploadQueue_; boost::thread uploadThread_; bool uploadRunning_; - + public: OrthancWebDav(ServerContext& context, bool allowDicomDelete, @@ -111,9 +111,9 @@ virtual bool GetFileContent(MimeType& mime, std::string& content, - boost::posix_time::ptime& modificationTime, + boost::posix_time::ptime& modificationTime, const UriComponents& path) ORTHANC_OVERRIDE; - + virtual bool StoreFile(const std::string& content, const UriComponents& path) ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OutgoingDicomInstance.cpp --- a/OrthancServer/Sources/OutgoingDicomInstance.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OutgoingDicomInstance.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/OutgoingDicomInstance.h --- a/OrthancServer/Sources/OutgoingDicomInstance.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/OutgoingDicomInstance.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/PrecompiledHeadersServer.cpp --- a/OrthancServer/Sources/PrecompiledHeadersServer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/PrecompiledHeadersServer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/PrecompiledHeadersServer.h --- a/OrthancServer/Sources/PrecompiledHeadersServer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/PrecompiledHeadersServer.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/QueryRetrieveHandler.cpp --- a/OrthancServer/Sources/QueryRetrieveHandler.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/QueryRetrieveHandler.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -69,7 +69,7 @@ fixed.Assign(query_); // Secondly, possibly fix the query with the user-provider Lua callback - FixQueryLua(fixed, context_, modality_.GetApplicationEntityTitle()); + FixQueryLua(fixed, context_, modality_.GetApplicationEntityTitle()); { DicomAssociationParameters params(localAet_, modality_); @@ -78,7 +78,7 @@ { params.SetTimeout(timeout_); } - + DicomControlUserConnection connection(params, static_cast(ScuOperationFlags_Find)); connection.Find(answers_, level_, fixed, findNormalized_); } @@ -88,7 +88,7 @@ } - QueryRetrieveHandler::QueryRetrieveHandler(ServerContext& context) : + QueryRetrieveHandler::QueryRetrieveHandler(ServerContext& context) : context_(context), localAet_(context.GetDefaultLocalApplicationEntityTitle()), done_(false), @@ -171,7 +171,7 @@ answers_.GetAnswer(i).ExtractDicomSummary(target, 0 /* don't truncate tags */); } - + void QueryRetrieveHandler::SetFindNormalized(bool normalized) { Invalidate(); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/QueryRetrieveHandler.h --- a/OrthancServer/Sources/QueryRetrieveHandler.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/QueryRetrieveHandler.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -29,7 +29,7 @@ namespace Orthanc { class ServerContext; - + class QueryRetrieveHandler : public IDynamicObject { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ResourceFinder.cpp --- a/OrthancServer/Sources/ResourceFinder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ResourceFinder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -297,7 +297,7 @@ { uint32_t expectedNumberOfInstances; SeriesStatus status = GetSeriesStatus(expectedNumberOfInstances, resource); - + if (responseContent_ & ResponseContentFlags_Status ) { target["Status"] = EnumerationToString(status); @@ -466,7 +466,7 @@ for (std::map::const_iterator it = attachments.begin(); it != attachments.end(); ++it) { - Json::Value attachment = Json::objectValue; + Json::Value attachment = Json::objectValue; attachment["Uuid"] = it->second.GetUuid(); attachment["ContentType"] = it->second.GetContentType(); attachment["UncompressedSize"] = Json::Value::UInt64(it->second.GetUncompressedSize()); @@ -585,13 +585,13 @@ { case ResourceType_Patient: request_.GetChildrenSpecification(ResourceType_Study).SetRetrieveIdentifiers(responseContent_ & ResponseContentFlags_Children); - request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); + request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); break; case ResourceType_Study: request_.GetChildrenSpecification(ResourceType_Series).SetRetrieveIdentifiers(responseContent_ & ResponseContentFlags_Children); request_.SetRetrieveParentIdentifier(responseContent_ & ResponseContentFlags_Parent); - request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); + request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); break; case ResourceType_Series: @@ -601,12 +601,12 @@ } request_.GetChildrenSpecification(ResourceType_Instance).SetRetrieveIdentifiers(responseContent_ & ResponseContentFlags_Children); request_.SetRetrieveParentIdentifier(responseContent_ & ResponseContentFlags_Parent); - request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); + request_.SetRetrieveAttachments(responseContent_ & ResponseContentFlags_Attachments); break; case ResourceType_Instance: request_.SetRetrieveAttachments((responseContent_ & ResponseContentFlags_AttachmentsLegacy) // for FileSize & FileUuid - || (responseContent_ & ResponseContentFlags_Attachments)); + || (responseContent_ & ResponseContentFlags_Attachments)); request_.SetRetrieveParentIdentifier(true); break; @@ -852,7 +852,7 @@ { // This is neither a main DICOM tag, nor a computed DICOM tag: // We might need to access a DICOM file or the MainDicomSequences metadata - + request_.SetRetrieveMetadata(true); if (request_.GetLevel() != ResourceType_Instance) @@ -889,9 +889,9 @@ if (resource.GetMetadata(level).size() > 0) { GetMainDicomSequencesFromMetadata(m, resource, level); // read DicomSequences from metadata - + // check which tags have been saved in DB; that's the way to know if they are missing because they were not saved or because they have no value - + std::string signature = DicomMap::GetDefaultMainDicomTagsSignatureFrom1_11(level); // default signature in case it's not in the metadata (= the signature for 1.11.0) if (resource.LookupMetadata(signature, level, MetadataType_MainDicomTagsSignature)) { @@ -1157,14 +1157,14 @@ // if SOPClassUID has been requested, we might still find it at metadata level (useful e.g. for StoneViewer) std::string sopClassUidFromMetadata; if (resource.GetLevel() == ResourceType_Instance && - remainingRequestedTags.find(DICOM_TAG_SOP_CLASS_UID) != remainingRequestedTags.end() && + remainingRequestedTags.find(DICOM_TAG_SOP_CLASS_UID) != remainingRequestedTags.end() && resource.LookupMetadata(sopClassUidFromMetadata, ResourceType_Instance, MetadataType_Instance_SopClassUid)) { outRequestedTags.SetValue(DICOM_TAG_SOP_CLASS_UID, sopClassUidFromMetadata, false); remainingRequestedTags.erase(DICOM_TAG_SOP_CLASS_UID); } - if (!remainingRequestedTags.empty() && + if (!remainingRequestedTags.empty() && !DicomMap::HasOnlyComputedTags(remainingRequestedTags)) // if the only remaining tags are computed tags, it is worthless to read them from disk { // If a lookup tag is not available from DB, it is included in remainingRequestedTags and it will always be included in the answer too @@ -1192,7 +1192,7 @@ << "/" << resource.GetIdentifier() << "/reconstruct to update the list of tags saved in DB or run the Housekeeper plugin. Some MainDicomTags might be missing from this answer."; } - else if (isWarning004Enabled && + else if (isWarning004Enabled && request_.IsRetrieveMetadata() && !resource.LookupMetadata(mainDicomTagsSignature, resource.GetLevel(), MetadataType_MainDicomTagsSignature)) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseDicomTagConstraint.cpp --- a/OrthancServer/Sources/Search/DatabaseDicomTagConstraint.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseDicomTagConstraint.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -55,9 +55,9 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - } + } - + const std::string& DatabaseDicomTagConstraint::GetValue(size_t index) const { if (index >= values_.size()) @@ -89,7 +89,7 @@ std::vector& tmpValues) const { memset(&constraint, 0, sizeof(constraint)); - + tmpValues.resize(values_.size()); for (size_t i = 0; i < values_.size(); i++) @@ -107,5 +107,5 @@ constraint.valuesCount = values_.size(); constraint.values = (tmpValues.empty() ? NULL : &tmpValues[0]); } -#endif +#endif } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseDicomTagConstraint.h --- a/OrthancServer/Sources/Search/DatabaseDicomTagConstraint.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseDicomTagConstraint.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -52,7 +52,7 @@ const std::vector& values, bool caseSensitive, bool mandatory); - + ResourceType GetLevel() const { return level_; @@ -96,6 +96,6 @@ #if ORTHANC_ENABLE_PLUGINS == 1 void EncodeForPlugins(OrthancPluginDatabaseConstraint& constraint, std::vector& tmpValues) const; -#endif +#endif }; } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseDicomTagConstraints.cpp --- a/OrthancServer/Sources/Search/DatabaseDicomTagConstraints.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseDicomTagConstraints.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseDicomTagConstraints.h --- a/OrthancServer/Sources/Search/DatabaseDicomTagConstraints.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseDicomTagConstraints.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseLookup.cpp --- a/OrthancServer/Sources/Search/DatabaseLookup.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseLookup.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -118,7 +118,7 @@ if (value.get() == NULL || value->IsNull()) { - return isOptionalConstraint; + return isOptionalConstraint; } else if (value->IsBinary() || !constraints_[i]->IsMatch(value->GetContent())) @@ -234,7 +234,7 @@ * whether matching is case-sensitive or case-insensitive. * * Reference: DICOM PS 3.4 - * - C.2.2.2.1 ("Single Value Matching") + * - C.2.2.2.1 ("Single Value Matching") * - C.2.2.2.4 ("Wild Card Matching") * http://medical.nema.org/Dicom/2011/11_04pu.pdf * @@ -245,7 +245,7 @@ * character sets where a letter may have multiple encodings (e.g., * based on its case, its position in a word, or whether it is * accented) - * + * * For Attributes with a PN Value Representation (e.g., Patient Name * (0010,0010)), an application may perform literal matching that is * either case-sensitive, or that is insensitive to some or all @@ -258,7 +258,7 @@ * (0020,000D) UI StudyInstanceUID => Case-sensitive * (0020,000E) UI SeriesInstanceUID => Case-sensitive **/ - + if (vr == ValueRepresentation_PersonName) { AddDicomConstraintInternal(tag, vr, dicomQuery, caseSensitivePN, mandatoryTag); @@ -283,7 +283,7 @@ bool DatabaseLookup::HasOnlyMainDicomTags() const { std::set notUsed; - + return HasOnlyMainDicomTags(notUsed); } @@ -296,7 +296,7 @@ for (size_t i = 0; i < constraints_.size(); i++) { assert(constraints_[i] != NULL); - + if (allMainTags.find(constraints_[i]->GetTag()) == allMainTags.end()) { // This is not a main DICOM tag @@ -311,7 +311,7 @@ std::string DatabaseLookup::Format() const { std::string s; - + for (size_t i = 0; i < constraints_.size(); i++) { assert(constraints_[i] != NULL); @@ -322,7 +322,7 @@ return s; } - + bool DatabaseLookup::HasTag(const DicomTag& tag) const { for (size_t i = 0; i < constraints_.size(); i++) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseLookup.h --- a/OrthancServer/Sources/Search/DatabaseLookup.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseLookup.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseMetadataConstraint.cpp --- a/OrthancServer/Sources/Search/DatabaseMetadataConstraint.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseMetadataConstraint.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange); } - } + } DatabaseMetadataConstraint::DatabaseMetadataConstraint(MetadataType metadata, @@ -62,7 +62,7 @@ } values_.push_back(value); - } + } const std::string& DatabaseMetadataConstraint::GetValue(size_t index) const { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DatabaseMetadataConstraint.h --- a/OrthancServer/Sources/Search/DatabaseMetadataConstraint.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DatabaseMetadataConstraint.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DicomTagConstraint.cpp --- a/OrthancServer/Sources/Search/DicomTagConstraint.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DicomTagConstraint.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -152,7 +152,7 @@ mandatory_(other.mandatory_) { } - + DicomTagConstraint::DicomTagConstraint(const DatabaseDicomTagConstraint& constraint) : tag_(constraint.GetTag()), @@ -176,13 +176,13 @@ * tables in the database (since at least Orthanc 1.3.2), so this * shouldn't be an issue. **/ - + if (constraint.IsIdentifier()) { // This conversion is only available for main DICOM tags, not for identifers throw OrthancException(ErrorCode_BadSequenceOfCalls); } - + if (constraintType_ == ConstraintType_List) { for (size_t i = 0; i < constraint.GetValuesCount(); i++) @@ -386,7 +386,7 @@ DicomTagType tagType) const { bool isIdentifier, caseSensitive; - + switch (tagType) { case DicomTagType_Identifier: @@ -429,5 +429,5 @@ return new DatabaseDicomTagConstraint(level, tag_, isIdentifier, constraintType_, values, caseSensitive, mandatory_); - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/DicomTagConstraint.h --- a/OrthancServer/Sources/Search/DicomTagConstraint.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/DicomTagConstraint.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -61,7 +61,7 @@ bool mandatory); explicit DicomTagConstraint(const DicomTagConstraint& other); - + explicit DicomTagConstraint(const DatabaseDicomTagConstraint& constraint); const DicomTag& GetTag() const @@ -78,7 +78,7 @@ { return constraintType_; } - + bool IsCaseSensitive() const { return caseSensitive_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/HierarchicalMatcher.cpp --- a/OrthancServer/Sources/Search/HierarchicalMatcher.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/HierarchicalMatcher.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -86,7 +86,7 @@ sequences_.find(tag) != sequences_.end()) { // A constraint already exists on this tag - throw OrthancException(ErrorCode_BadRequest); + throw OrthancException(ErrorCode_BadRequest); } if (FromDcmtkBridge::LookupValueRepresentation(tag) == ValueRepresentation_Sequence) @@ -105,7 +105,7 @@ } else { - throw OrthancException(ErrorCode_BadRequest); + throw OrthancException(ErrorCode_BadRequest); } } else @@ -158,7 +158,7 @@ s += c.Format() + "\n"; tags.insert(c.GetTag()); } - + // Loop over the universal constraints for (std::set::const_iterator it = flatTags_.begin(); it != flatTags_.end(); ++it) @@ -192,7 +192,7 @@ { bool hasCodeExtensions; Encoding encoding = dicom.DetectEncoding(hasCodeExtensions); - + return MatchInternal(*dicom.GetDcmtkObject().getDataset(), encoding, hasCodeExtensions); } @@ -206,7 +206,7 @@ { return false; } - + for (Sequences::const_iterator it = sequences_.begin(); it != sequences_.end(); ++it) { @@ -255,7 +255,7 @@ it != flatTags_.end(); ++it) { DcmTagKey tag = ToDcmtkBridge::Convert(*it); - + DcmElement* element = NULL; if (source.findAndGetElement(tag, element).good() && element != NULL) @@ -318,7 +318,7 @@ { bool hasCodeExtensions; Encoding encoding = dicom.DetectEncoding(hasCodeExtensions); - + std::unique_ptr dataset(ExtractInternal(*dicom.GetDcmtkObject().getDataset(), encoding, hasCodeExtensions)); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/HierarchicalMatcher.h --- a/OrthancServer/Sources/Search/HierarchicalMatcher.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/HierarchicalMatcher.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/IDatabaseConstraint.h --- a/OrthancServer/Sources/Search/IDatabaseConstraint.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/IDatabaseConstraint.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -34,7 +34,7 @@ virtual ~IDatabaseConstraint() { } - + virtual ConstraintType GetConstraintType() const = 0; virtual size_t GetValuesCount() const = 0; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/ISqlLookupFormatter.cpp --- a/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -43,20 +43,20 @@ { case ResourceType_Patient: return "patients"; - + case ResourceType_Study: return "studies"; - + case ResourceType_Series: return "series"; - + case ResourceType_Instance: return "instances"; default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - } + } static std::string FormatLevel(const char* prefix, ResourceType level) { @@ -64,20 +64,20 @@ { case ResourceType_Patient: return std::string(prefix) + "patients"; - + case ResourceType_Study: return std::string(prefix) + "studies"; - + case ResourceType_Series: return std::string(prefix) + "series"; - + case ResourceType_Instance: return std::string(prefix) + "instances"; default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - } + } static bool FormatComparison(std::string& target, @@ -89,7 +89,7 @@ std::string tag = "t" + boost::lexical_cast(index); std::string comparison; - + switch (constraint.GetConstraintType()) { case ConstraintType_Equal: @@ -102,15 +102,15 @@ case ConstraintType_Equal: op = "="; break; - + case ConstraintType_SmallerOrEqual: op = "<="; break; - + case ConstraintType_GreaterOrEqual: op = ">="; break; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -137,7 +137,7 @@ { comparison += ", "; } - + std::string parameter = formatter.GenerateParameter(constraint.GetValue(i)); if (constraint.IsCaseSensitive()) @@ -158,7 +158,7 @@ { comparison = "lower(" + tag + ".value) IN (" + comparison + ")"; } - + break; } @@ -212,7 +212,7 @@ else { escaped += value[i]; - } + } } std::string parameter = formatter.GenerateParameter(escaped); @@ -228,7 +228,7 @@ parameter + ") " + formatter.FormatWildcardEscape()); } } - + break; } @@ -430,15 +430,15 @@ case ConstraintType_Equal: op = "="; break; - + case ConstraintType_SmallerOrEqual: op = "<="; break; - + case ConstraintType_GreaterOrEqual: op = ">="; break; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -485,7 +485,7 @@ { comparison = " AND lower(value) IN (" + values + ")"; } - + break; } @@ -539,7 +539,7 @@ else { escaped += value[i]; - } + } } std::string parameter = formatter.GenerateParameter(escaped); @@ -553,7 +553,7 @@ comparison = " AND lower(value) LIKE lower(" + parameter + ") " + formatter.FormatWildcardEscape(); } } - + break; } @@ -586,7 +586,7 @@ assert(ResourceType_Patient < ResourceType_Study && ResourceType_Study < ResourceType_Series && ResourceType_Series < ResourceType_Instance); - + lowerLevel = queryLevel; upperLevel = queryLevel; @@ -605,7 +605,7 @@ } } } - + // Note: this is used only when disabling ExtendedFind in SQLite in order to validate the GenericFind compatibility layer void ISqlLookupFormatter::Apply(std::string& sql, @@ -624,17 +624,17 @@ queryLevel <= lowerLevel); const bool escapeBrackets = formatter.IsEscapeBrackets(); - + std::string joins, comparisons; size_t count = 0; - + for (size_t i = 0; i < lookup.GetSize(); i++) { const DatabaseDicomTagConstraint& constraint = lookup.GetConstraint(i); std::string comparison; - + if (FormatComparison(comparison, formatter, constraint, count, escapeBrackets)) { std::string join; @@ -645,7 +645,7 @@ { comparisons += " AND " + comparison; } - + count ++; } } @@ -662,7 +662,7 @@ FormatLevel(static_cast(level)) + ".internalId=" + FormatLevel(static_cast(level + 1)) + ".parentId"); } - + for (int level = queryLevel + 1; level <= lowerLevel; level++) { sql += (" INNER JOIN Resources " + @@ -696,19 +696,19 @@ case LabelsConstraint_Any: condition = "> 0"; break; - + case LabelsConstraint_All: condition = "= " + boost::lexical_cast(labels.size()); break; - + case LabelsConstraint_None: condition = "= 0"; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + where.push_back("(SELECT COUNT(1) FROM Labels AS selectedLabels WHERE selectedLabels.id = " + FormatLevel(queryLevel) + ".internalId AND selectedLabels.label IN (" + Join(formattedLabels, "", ", ") + ")) " + condition); } @@ -724,8 +724,8 @@ sql += " LIMIT " + boost::lexical_cast(limit); } } - - + + void ISqlLookupFormatter::Apply(std::string& sql, ISqlLookupFormatter& formatter, const FindRequest& request) @@ -763,7 +763,7 @@ THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } orderingJoins += orderingJoin; - + std::string orderByField; #if ORTHANC_SQLITE_VERSION < 3030001 @@ -812,7 +812,7 @@ sql = ("SELECT " + strQueryLevel + ".publicId, " + strQueryLevel + ".internalId, " + - ordering + + ordering + " FROM Resources AS " + strQueryLevel); @@ -849,14 +849,14 @@ } size_t count = 0; - + const DatabaseDicomTagConstraints& dicomTagsConstraints = request.GetDicomTagConstraints(); for (size_t i = 0; i < dicomTagsConstraints.GetSize(); i++) { const DatabaseDicomTagConstraint& constraint = dicomTagsConstraints.GetConstraint(i); std::string comparison; - + if (FormatComparison(comparison, formatter, constraint, count, escapeBrackets)) { std::string join; @@ -869,9 +869,9 @@ else if (constraint.GetLevel() == queryLevel + 1 && !comparison.empty()) { // new in v 1.12.6, the constraints on child tags are actually looking for one child with this value - comparison = " EXISTS (SELECT 1 FROM Resources AS " + FormatLevel(static_cast(queryLevel + 1)) + - join + - " WHERE " + comparison + " AND " + + comparison = " EXISTS (SELECT 1 FROM Resources AS " + FormatLevel(static_cast(queryLevel + 1)) + + join + + " WHERE " + comparison + " AND " + FormatLevel(static_cast(queryLevel + 1)) + ".parentId = " + FormatLevel(static_cast(queryLevel)) + ".internalId) "; } @@ -887,7 +887,7 @@ for (std::deque::const_iterator it = request.GetMetadataConstraint().begin(); it != request.GetMetadataConstraint().end(); ++it) { std::string comparison; - + if (FormatComparison(comparison, formatter, *(*it), count, escapeBrackets)) { std::string join; @@ -898,7 +898,7 @@ { comparisons += " AND " + comparison; } - + count ++; } } @@ -910,7 +910,7 @@ FormatLevel(static_cast(level)) + ".internalId=" + FormatLevel(static_cast(level + 1)) + ".parentId"); } - + // disabled in v 1.12.6 now that the child levels are considered as "is there at least one child that meets this constraint" // for (int level = queryLevel + 1; level <= lowerLevel; level++) // { @@ -947,19 +947,19 @@ case LabelsConstraint_Any: condition = "> 0"; break; - + case LabelsConstraint_All: condition = "= " + boost::lexical_cast(labels.size()); break; - + case LabelsConstraint_None: condition = "= 0"; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + where.push_back("(SELECT COUNT(1) FROM Labels AS selectedLabels WHERE selectedLabels.id = " + strQueryLevel + ".internalId AND selectedLabels.label IN (" + Join(formattedLabels, "", ", ") + ")) " + condition); } @@ -989,12 +989,12 @@ { ResourceType lowerLevel, upperLevel; GetLookupLevels(lowerLevel, upperLevel, queryLevel, lookup); - + assert(upperLevel == queryLevel && queryLevel == lowerLevel); const bool escapeBrackets = formatter.IsEscapeBrackets(); - + std::vector mainDicomTagsComparisons, dicomIdentifiersComparisons; for (size_t i = 0; i < lookup.GetSize(); i++) @@ -1002,7 +1002,7 @@ const DatabaseDicomTagConstraint& constraint = lookup.GetConstraint(i); std::string comparison; - + if (FormatComparison2(comparison, formatter, constraint, escapeBrackets)) { if (!comparison.empty()) @@ -1021,7 +1021,7 @@ sql = ("SELECT publicId, internalId " "FROM Resources " - "WHERE resourceType = " + formatter.FormatResourceType(queryLevel) + "WHERE resourceType = " + formatter.FormatResourceType(queryLevel) + " "); if (dicomIdentifiersComparisons.size() > 0) @@ -1063,21 +1063,21 @@ condition = "> 0"; inOrNotIn = "IN"; break; - + case LabelsConstraint_All: condition = "= " + boost::lexical_cast(labels.size()); inOrNotIn = "IN"; break; - + case LabelsConstraint_None: condition = "> 0"; inOrNotIn = "NOT IN"; break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - + sql += (" AND internalId " + inOrNotIn + " (SELECT id" " FROM (SELECT id, COUNT(1) AS labelsCount " "FROM Labels " diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/Search/ISqlLookupFormatter.h --- a/OrthancServer/Sources/Search/ISqlLookupFormatter.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerContext.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -282,7 +282,7 @@ if (elapsed.total_seconds() > intervalInSeconds) { - // If possible, gives memory back to the system + // If possible, gives memory back to the system // (see OrthancServer/Resources/ImplementationNotes/memory_consumption.txt) { MetricsRegistry::Timer timer(that->GetMetricsRegistry(), "orthanc_memory_trimming_duration_ms"); @@ -296,7 +296,7 @@ } #endif - + void ServerContext::ChangeThread(ServerContext* that, unsigned int sleepDelay) { @@ -305,13 +305,13 @@ while (!that->done_) { std::unique_ptr obj(that->pendingChanges_.Dequeue(sleepDelay)); - + if (obj.get() != NULL) { const ServerIndexChange& change = dynamic_cast(*obj.get()); boost::shared_lock lock(that->listenersMutex_); - for (ServerListeners::iterator it = that->listeners_.begin(); + for (ServerListeners::iterator it = that->listeners_.begin(); it != that->listeners_.end(); ++it) { try @@ -349,13 +349,13 @@ while (!that->done_) { std::unique_ptr obj(that->pendingJobEvents_.Dequeue(sleepDelay)); - + if (obj.get() != NULL) { const JobEvent& event = dynamic_cast(*obj.get()); boost::shared_lock lock(that->listenersMutex_); - for (ServerListeners::iterator it = that->listeners_.begin(); + for (ServerListeners::iterator it = that->listeners_.begin(); it != that->listeners_.end(); ++it) { try @@ -392,10 +392,10 @@ static const boost::posix_time::time_duration PERIODICITY = boost::posix_time::seconds(10); - + boost::posix_time::ptime next = boost::posix_time::microsec_clock::universal_time() + PERIODICITY; - + while (!that->done_) { boost::this_thread::sleep(boost::posix_time::milliseconds(sleepDelay)); @@ -409,14 +409,14 @@ } } } - + void ServerContext::SignalJobSubmitted(const std::string& jobId) { haveJobsChanged_ = true; pendingJobEvents_.Enqueue(new JobEvent(JobEventType_Submitted, jobId)); } - + void ServerContext::SignalJobSuccess(const std::string& jobId) { @@ -426,7 +426,7 @@ pendingJobEvents_.Enqueue(new JobEvent(JobEventType_Success, jobId)); } - + void ServerContext::SignalJobFailure(const std::string& jobId) { metricsRegistry_->IncrementIntegerValue("orthanc_jobs_total_completed", 1); @@ -455,7 +455,7 @@ { LOG(WARNING) << "Cannot unserialize the jobs engine, starting anyway: " << e.What(); } - catch (const std::string& s) + catch (const std::string& s) { LOG(WARNING) << "Cannot unserialize the jobs engine, starting anyway: \"" << s << "\""; } @@ -494,7 +494,7 @@ if (lastModification > lastSerializedModification) { LOG(TRACE) << "Serializing the content of the jobs engine"; - + try { Json::Value value; @@ -663,7 +663,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Unknown preferred transfer syntax: " + s); } - + CLOG(INFO, DICOM) << "Preferred transfer syntax for Orthanc C-STORE SCU: " << GetTransferSyntaxUid(preferredTransferSyntax_); @@ -706,7 +706,7 @@ listeners_.push_back(ServerListener(luaListener_, "Lua")); changeThread_ = boost::thread(ChangeThread, this, (unitTesting ? 20 : 100)); jobEventsThread_ = boost::thread(JobEventsThread, this, (unitTesting ? 20 : 100)); - + #if HAVE_MALLOC_TRIM == 1 LOG(INFO) << "Starting memory trimming thread at 30 seconds interval"; memoryTrimmingThread_ = boost::thread(MemoryTrimmingThread, this, 30); @@ -719,7 +719,7 @@ uint64_t storageCacheSize, storageMemoryCapacity, dicomParserMemoryCapacity; uint64_t dicomParserCacheSize, transcoderMemoryCapacity, transcoderCacheSize, sequentialReaderWindowCapacity; - + { OrthancConfiguration::ReaderLock lock; @@ -915,7 +915,7 @@ } - + ServerContext::~ServerContext() { if (!done_) @@ -1078,7 +1078,7 @@ DicomTransferSyntax transferSyntax; bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax); - + DicomMap summary; dicom.GetSummary(summary); // -> from Orthanc 1.11.1, this includes the leaf nodes and sequences @@ -1160,7 +1160,7 @@ break; } } - + } catch (OrthancException& e) { @@ -1210,7 +1210,7 @@ typedef std::map InstanceMetadata; InstanceMetadata instanceMetadata; - try + try { result.SetStatus(index_.Store( instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwriteInDb, @@ -1233,7 +1233,7 @@ { RemoveFile(dicomUntilPixelData); } - + throw; } @@ -1245,7 +1245,7 @@ { dicom.AddMetadata(ResourceType_Instance, it->first, it->second); } - + if (result.GetStatus() != StoreStatus_Success) { if (!isAdoption) @@ -1259,7 +1259,7 @@ } } - if (!isReconstruct) + if (!isReconstruct) { // skip logs in case of reconstruction switch (result.GetStatus()) @@ -1322,7 +1322,7 @@ { LOG(ERROR) << summary.FormatMissingTagsForStore(); } - + throw; } } @@ -1330,7 +1330,7 @@ ServerContext::StoreResult ServerContext::Store(std::string& resultPublicId, DicomInstanceToStore& receivedDicom) - { + { DicomInstanceToStore* dicom = &receivedDicom; #if ORTHANC_ENABLE_PLUGINS == 1 @@ -1355,7 +1355,7 @@ result.SetStatus(StoreStatus_FilteredOut); return result; } - + case OrthancPluginReceivedInstanceAction_KeepAsIs: // This path is also used when no ReceivedInstanceCallback is installed by the plugins break; @@ -1364,7 +1364,7 @@ if (modifiedBuffer.GetSize() > 0 && modifiedBuffer.GetData() != NULL) { - CLOG(INFO, PLUGINS) << "A plugin has modified the instance in its ReceivedInstanceCallback"; + CLOG(INFO, PLUGINS) << "A plugin has modified the instance in its ReceivedInstanceCallback"; modifiedDicom.reset(DicomInstanceToStore::CreateFromBuffer(modifiedBuffer.GetData(), modifiedBuffer.GetSize())); modifiedDicom->SetOrigin(receivedDicom.GetOrigin()); dicom = modifiedDicom.get(); @@ -1374,7 +1374,7 @@ throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is not returning a modified buffer while it has modified the instance"); } break; - + default: throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback has returned an invalid value"); } @@ -1418,7 +1418,7 @@ { // This is an uncompressed transfer syntax (new in Orthanc 1.8.2) transcode = ingestTranscodingOfUncompressed_; - + // If the DICOM does not have any pixel data (e.g. a DICOM SR, an ECG, a PDF, RTSTRUCT, ...), it makes no sense // to transcode it to a compressed Transfer Syntax and it might actually be considered invalid or poorly handled // by some softwares receiving the data. Therefore, we skip transcoding in this case unless @@ -1444,12 +1444,12 @@ // Trancoding std::set syntaxes; syntaxes.insert(ingestTransferSyntax_); - + IDicomTranscoder::DicomImage source; source.SetExternalBuffer(dicom->GetBufferData(), dicom->GetBufferSize()); - + IDicomTranscoder::DicomImage transcoded; - + if (dicom->HasPixelData()) {// check that the target image has a valid/reasonable size before transcoding to avoid possible crash or OOB during transcoding DicomMap summary; @@ -1490,7 +1490,7 @@ } } - + void ServerContext::AnswerAttachment(RestApiOutput& output, const FileInfo& attachment, const std::string& filename) @@ -1513,9 +1513,9 @@ CompressionType compression) { LOG(INFO) << "Changing compression type for attachment " - << EnumerationToString(attachmentType) - << " of resource " << resourceId << " to " - << compression; + << EnumerationToString(attachmentType) + << " of resource " << resourceId << " to " + << compression; FileInfo attachment; int64_t revision; @@ -1555,7 +1555,7 @@ { RemoveFile(modified); throw; - } + } } @@ -1610,7 +1610,7 @@ } } - + void ServerContext::ReadDicomAsJson(Json::Value& result, const std::string& instancePublicId, const std::set& ignoreTagLength) @@ -1661,7 +1661,7 @@ * area does not support range reads, or if "StorageCompression" * is enabled). Simply return this attachment. **/ - + FileInfo attachment; if (LookupAttachment(attachment, FileContentType_DicomUntilPixelData, instanceAttachments)) @@ -1683,7 +1683,7 @@ * attachment. Lookup whether the pixel data offset has already * been computed for this instance. **/ - + bool hasPixelDataOffset = false; uint64_t pixelDataOffset = 0; // dummy initialization @@ -1722,7 +1722,7 @@ DicomDataSource::Dicom::Lock lock(*dicom); OrthancConfiguration::DefaultDicomDatasetToJson(result, lock.GetContent(), ignoreTagLength); } - + InjectEmptyPixelData(result); } else if (ignoreTagLength.empty() && @@ -1920,7 +1920,7 @@ const std::string& oldMD5) { LOG(INFO) << "Adding attachment " << EnumerationToString(attachmentType) << " to resource " << resourceId; - + // TODO Should we use "gzip" instead? CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None); @@ -2051,9 +2051,9 @@ // introduced in Orthanc 1.2.0. The fact that // "LookupMetadata()" has failed indicates that this database // comes from an older release of Orthanc. - + DicomTag tag(0, 0); - + switch (metadata) { case MetadataType_Instance_SopClassUid: @@ -2067,7 +2067,7 @@ default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + Json::Value dicomAsJson; ReadDicomAsJson(dicomAsJson, publicId); @@ -2126,7 +2126,7 @@ instancesIds.reserve(instancesIds.size() + orderedInstances.GetInstancesCount()); filesInfo.reserve(filesInfo.size() + orderedInstances.GetInstancesCount()); - + for (size_t i = 0; i < orderedInstances.GetInstancesCount(); ++i) { instancesIds.push_back(orderedInstances.GetInstanceId(i)); @@ -2134,7 +2134,7 @@ } }; break; case ResourceType_Instance: - { + { FileInfo fileInfo; int64_t revisionNotUsed; @@ -2161,7 +2161,7 @@ #endif } - + void ServerContext::SignalUpdatedPeers() { #if ORTHANC_ENABLE_PLUGINS == 1 @@ -2291,7 +2291,7 @@ { return emptyContent; } - + if (deidentifyLogs_ && !element.GetValue().GetContent().empty() && logsDeidentifierRules_.IsAlteredTag(tag)) @@ -2370,7 +2370,7 @@ } } } - + // now remove all rejected syntaxes if (rejectedSopClasses.size() > 0) { @@ -2420,7 +2420,7 @@ boost::mutex::scoped_lock lock(dynamicOptionsMutex_); syntaxes = acceptedTransferSyntaxes_; } - + void ServerContext::SetAcceptedTransferSyntaxes(const std::set& syntaxes) { @@ -2432,7 +2432,7 @@ void ServerContext::GetProposedStorageTransferSyntaxes(std::list& syntaxes) const { boost::mutex::scoped_lock lock(dynamicOptionsMutex_); - + // // TODO: investigate: actually, neither Orthanc 1.12.4 nor DCM4CHEE will accept to send a LittleEndianExplicit file // // while e.g., Jpeg-LS has been presented (and accepted) as the preferred TS for the C-Store SCP. // // if we have defined IngestTranscoding, let's propose this TS first to avoid any unnecessary transcoding @@ -2440,12 +2440,12 @@ // { // syntaxes.push_back(ingestTransferSyntax_); // } - + // then, propose the default ones syntaxes.push_back(DicomTransferSyntax_LittleEndianExplicit); syntaxes.push_back(DicomTransferSyntax_LittleEndianImplicit); } - + bool ServerContext::IsUnknownSopClassAccepted() const { @@ -2453,7 +2453,7 @@ return isUnknownSopClassAccepted_; } - + void ServerContext::SetUnknownSopClassAccepted(bool accepted) { boost::mutex::scoped_lock lock(dynamicOptionsMutex_); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerContext.h --- a/OrthancServer/Sources/ServerContext.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerContext.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -48,7 +48,7 @@ class ServerTranscoder; class SharedArchive; class StorageCommitmentReports; - + /** * This class is responsible for maintaining the storage area on the @@ -60,7 +60,7 @@ private JobsRegistry::IObserver { friend class ServerIndex; // To access "RemoveFile()" - + public: struct StoreResult { @@ -92,7 +92,7 @@ return cstoreStatusCode_; } }; - + private: class LuaServerListener : public IServerListener { @@ -111,7 +111,7 @@ { context_.mainLua_.SignalStoredInstance(publicId, instance, simplifiedTags); } - + virtual void SignalChange(const ServerIndexChange& change) ORTHANC_OVERRIDE { context_.mainLua_.SignalChange(change); @@ -142,7 +142,7 @@ } }; - + class ServerListener { private: @@ -205,14 +205,14 @@ LuaScripting filterLua_; LuaServerListener luaListener_; std::unique_ptr mediaArchive_; - + // The "JobsEngine" must be *after* "LuaScripting", as // "LuaScripting" embeds "LuaJobManager" that registers as an // observer to "SequenceOfOperationsJob", whose lifetime // corresponds to that of "JobsEngine". It must also be after // "mediaArchive_", as jobs might access this archive. JobsEngine jobsEngine_; - + #if ORTHANC_ENABLE_PLUGINS == 1 OrthancPlugins* plugins_; #endif @@ -229,7 +229,7 @@ boost::thread jobEventsThread_; boost::thread saveJobsThread_; boost::thread memoryTrimmingThread_; - + std::unique_ptr queryRetrieveArchive_; std::string defaultLocalAet_; RetrieveMethod defaultDicomRetrieveMethod_; @@ -262,7 +262,7 @@ std::list acceptedSopClasses_; // ordered; the most 120 common ones first bool readOnly_; bool patientLevelEnabled_; - + StoreResult StoreAfterTranscoding(std::string& resultPublicId, DicomInstanceToStore& dicom, bool isReconstruct); @@ -537,7 +537,7 @@ { overwriteInstances_ = overwrite; } - + OverwriteInstancesMode GetOverwriteInstances() const { return overwriteInstances_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerEnumerations.cpp --- a/OrthancServer/Sources/ServerEnumerations.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerEnumerations.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -46,7 +46,7 @@ dictMetadataType_.Clear(); dictContentType_.Clear(); - + dictMetadataType_.Add(MetadataType_Instance_IndexInSeries, "IndexInSeries"); dictMetadataType_.Add(MetadataType_Instance_ReceptionDate, "ReceptionDate"); dictMetadataType_.Add(MetadataType_RemoteAet, "RemoteAET"); @@ -79,23 +79,23 @@ MetadataType type = static_cast(metadata); - if (metadata < 0 || + if (metadata < 0 || !IsUserMetadata(type)) { LOG(ERROR) << "A user content type must have index between " << static_cast(MetadataType_StartUser) << " and " << static_cast(MetadataType_EndUser) << ", but \"" << name << "\" has index " << metadata; - + throw OrthancException(ErrorCode_ParameterOutOfRange); } if (dictMetadataType_.Contains(type)) { LOG(ERROR) << "Cannot associate user content type \"" - << name << "\" with index " << metadata + << name << "\" with index " << metadata << ", as this index is already used"; - + throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -141,23 +141,23 @@ FileContentType type = static_cast(contentType); - if (contentType < 0 || + if (contentType < 0 || !IsUserContentType(type)) { LOG(ERROR) << "A user content type must have index between " << static_cast(FileContentType_StartUser) << " and " << static_cast(FileContentType_EndUser) << ", but \"" << name << "\" has index " << contentType; - + throw OrthancException(ErrorCode_ParameterOutOfRange); } if (dictContentType_.Contains(type)) { LOG(ERROR) << "Cannot associate user content type \"" - << name << "\" with index " << contentType + << name << "\" with index " << contentType << ", as this index is already used"; - + throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -179,7 +179,7 @@ type <= FileContentType_EndUser) { boost::mutex::scoped_lock lock(enumerationsMutex_); - + MimeTypes::const_iterator it = mimeTypes_.find(type); if (it != mimeTypes_.end()) { @@ -226,7 +226,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Configuration option \"StorageAccessOnFind\" " "should be \"Always\", \"Never\" or \"Answers\": " + value); - } + } } bool IsStorageAccessAllowedForAnswers(FindStorageAccessMode mode) @@ -254,7 +254,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Configuration option \"MaxStorageMode\" " "should be \"Recycle\" or \"Reject\": " + value); - } + } } BuiltinDecoderTranscoderOrder StringToBuiltinDecoderTranscoderOrder(const std::string& value) @@ -276,7 +276,7 @@ throw OrthancException(ErrorCode_ParameterOutOfRange, "Configuration option \"BuiltinDecoderTranscoderOrder\" " "should be \"After\", \"Before\" or \"Disabled\": " + value); - } + } } @@ -298,9 +298,9 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange, "Verbosity can be \"default\", \"verbose\" or \"trace\": " + str); - } + } } - + std::string GetBasePath(ResourceType type, const std::string& publicId) @@ -318,7 +318,7 @@ case ResourceType_Instance: return "/instances/" + publicId; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -520,19 +520,19 @@ { case Verbosity_Default: return "default"; - + case Verbosity_Verbose: return "verbose"; - + case Verbosity_Trace: return "trace"; default: throw OrthancException(ErrorCode_ParameterOutOfRange); } - } + } - + bool IsUserMetadata(MetadataType metadata) { return (metadata >= MetadataType_StartUser && @@ -546,12 +546,12 @@ target.clear(); switch (source) - { + { // Transfer syntaxes supported since Orthanc 0.7.2 case TransferSyntaxGroup_Deflated: target.insert(DicomTransferSyntax_DeflatedLittleEndianExplicit); break; - + case TransferSyntaxGroup_Jpeg: target.insert(DicomTransferSyntax_JPEGProcess1); target.insert(DicomTransferSyntax_JPEGProcess2_4); @@ -613,7 +613,7 @@ target.insert(DicomTransferSyntax_HEVCMainProfileLevel5_1); target.insert(DicomTransferSyntax_HEVCMain10ProfileLevel5_1); break; - + default: throw OrthancException(ErrorCode_ParameterOutOfRange); } @@ -665,7 +665,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange, "Unrecognized value for \"ResponseContent\": " + value); - } + } } OverwriteInstancesMode StringToOverwriteInstancesMode(const std::string& value) @@ -686,7 +686,7 @@ { throw OrthancException(ErrorCode_ParameterOutOfRange, "Unrecognized value for \"OverwriteInstances\": " + value); - } + } } const char* EnumerationToString(OverwriteInstancesMode mode) @@ -700,7 +700,7 @@ case OverwriteInstancesMode_IfChanged: return "IfChanged"; default: - throw OrthancException(ErrorCode_ParameterOutOfRange); + throw OrthancException(ErrorCode_ParameterOutOfRange); } } } \ No newline at end of file diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerEnumerations.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -36,7 +36,7 @@ Verbosity_Verbose, Verbosity_Trace }; - + enum SeriesStatus { SeriesStatus_Complete, @@ -140,25 +140,25 @@ ResponseContentFlags_IsProtected = (1 << 13), ResponseContentFlags_INTERNAL_CountResources = (1 << 30), - + // Some predefined combinations ResponseContentFlags_ExpandTrue = (ResponseContentFlags_ID | ResponseContentFlags_Type | ResponseContentFlags_RequestedTags | ResponseContentFlags_MainDicomTags | ResponseContentFlags_MetadataLegacy | - ResponseContentFlags_AttachmentsLegacy | - ResponseContentFlags_Status | - ResponseContentFlags_Parent | - ResponseContentFlags_Children | + ResponseContentFlags_AttachmentsLegacy | + ResponseContentFlags_Status | + ResponseContentFlags_Parent | + ResponseContentFlags_Children | ResponseContentFlags_Labels | ResponseContentFlags_IsStable | ResponseContentFlags_IsProtected), // equivalent to "Expand": true - + ResponseContentFlags_Default = (ResponseContentFlags_ID | ResponseContentFlags_Type | ResponseContentFlags_RequestedTags) // minimal content as soon as you have a "ResponseContent" - + }; /** @@ -213,7 +213,7 @@ MetadataType_Instance_PixelDataVR = 17, // New in Orthanc 1.12.1 MetadataType_Patient_IsProtected = 18, // New in Orthanc 1.12.9 (used only by DB plugins) MetadataType_Patient_PatientRecyclingOrder = 19, // New in Orthanc 1.12.9 (used only by DB plugins) - + // Make sure that the value "65535" can be stored into this enumeration MetadataType_StartUser = 1024, MetadataType_EndUser = 65535 @@ -290,7 +290,7 @@ FindStorageAccessMode StringToFindStorageAccessMode(const std::string& str); MaxStorageMode StringToMaxStorageMode(const std::string& str); - + bool IsStorageAccessAllowedForAnswers(FindStorageAccessMode mode); bool IsStorageAccessAllowedForLookup(FindStorageAccessMode mode); @@ -313,7 +313,7 @@ const char* EnumerationToString(StoreStatus status); const char* EnumerationToString(ChangeType type); - + ChangeType StringToChangeType(const std::string& value); const char* EnumerationToString(Verbosity verbosity); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerIndex.cpp --- a/OrthancServer/Sources/ServerIndex.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerIndex.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -67,7 +67,7 @@ return customData_; } - FileContentType GetContentType() const + FileContentType GetContentType() const { return type_; } @@ -94,7 +94,7 @@ void CommitFilesToRemove() { - for (std::list::const_iterator + for (std::list::const_iterator it = pendingFilesToRemove_.begin(); it != pendingFilesToRemove_.end(); ++it) { @@ -112,8 +112,8 @@ void CommitChanges() { - for (std::list::const_iterator - it = pendingChanges_.begin(); + for (std::list::const_iterator + it = pendingChanges_.begin(); it != pendingChanges_.end(); ++it) { context_.SignalChange(*it); @@ -148,7 +148,7 @@ hasRemainingLevel_ = true; remainingType_ = parentType; remainingPublicId_ = publicId; - } + } } virtual void SignalAttachmentDeleted(const FileInfo& info) ORTHANC_OVERRIDE @@ -166,8 +166,8 @@ virtual void SignalChange(const ServerIndexChange& change) ORTHANC_OVERRIDE { - LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type " - << EnumerationToString(change.GetResourceType()) << ": " + LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type " + << EnumerationToString(change.GetResourceType()) << ": " << EnumerationToString(change.GetChangeType()); pendingChanges_.push_back(change); @@ -190,7 +190,7 @@ else { return false; - } + } }; virtual void MarkAsUnstable(ResourceType type, @@ -212,7 +212,7 @@ // been successfully committed. Some files might have to be // deleted because of recycling. CommitFilesToRemove(); - + // Send all the pending changes to the Orthanc plugins CommitChanges(); } @@ -229,7 +229,7 @@ { private: ServerContext& context_; - + public: explicit TransactionContextFactory(ServerContext& context) : context_(context) @@ -242,9 +242,9 @@ // issue because we simply create an object return new TransactionContext(context_); } - }; - - + }; + + class ServerIndex::UnstableResourcePayload { private: @@ -256,7 +256,7 @@ { } - explicit UnstableResourcePayload(const std::string& publicId) : + explicit UnstableResourcePayload(const std::string& publicId) : publicId_(publicId), time_(boost::posix_time::second_clock::local_time()) { @@ -266,7 +266,7 @@ { return (boost::posix_time::second_clock::local_time() - time_).total_seconds(); } - + const std::string& GetPublicId() const { return publicId_; @@ -295,12 +295,12 @@ { boost::this_thread::sleep(boost::posix_time::milliseconds(threadSleepGranularityMilliseconds)); count++; - + if (count >= countThreshold) { Logging::Flush(); that->FlushToDisk(); - + count = 0; } } @@ -391,12 +391,12 @@ } - void ServerIndex::SetMaximumPatientCount(unsigned int count) + void ServerIndex::SetMaximumPatientCount(unsigned int count) { { boost::recursive_mutex::scoped_lock lock(monitoringMutex_); maximumPatients_ = count; - + if (count == 0) { LOG(WARNING) << "No limit on the number of stored patients"; @@ -410,13 +410,13 @@ StandaloneRecycling(maximumStorageMode_, maximumStorageSize_, maximumPatients_); } - - void ServerIndex::SetMaximumStorageSize(uint64_t size) + + void ServerIndex::SetMaximumStorageSize(uint64_t size) { { boost::recursive_mutex::scoped_lock lock(monitoringMutex_); maximumStorageSize_ = size; - + if (size == 0) { LOG(WARNING) << "No limit on the size of the storage area"; @@ -430,12 +430,12 @@ StandaloneRecycling(maximumStorageMode_, maximumStorageSize_, maximumPatients_); } - void ServerIndex::SetMaximumStorageMode(MaxStorageMode mode) + void ServerIndex::SetMaximumStorageMode(MaxStorageMode mode) { { boost::recursive_mutex::scoped_lock lock(monitoringMutex_); maximumStorageMode_ = mode; - + if (mode == MaxStorageMode_Recycle) { if (maximumStorageSize_ > 0 || maximumPatients_ > 0) @@ -461,7 +461,7 @@ Logging::ScopedCurrentThreadNameSetter setter("UNSTABLE-MON"); unsigned int stableAge = 0; - + { OrthancConfiguration::ReaderLock lock; stableAge = lock.GetConfiguration().GetUnsignedIntegerParameter("StableAge"); @@ -485,7 +485,7 @@ ResourceType stableLevel; int64_t stableId; - { + { boost::recursive_mutex::scoped_lock lock(that->monitoringMutex_); if (!that->unstableResources_.IsEmpty() && @@ -512,7 +512,7 @@ LOG(INFO) << "Closing the monitor thread for stable resources"; } - + void ServerIndex::LogStableChange(ResourceType stableLevel, int64_t stableId, const std::string& publicId) @@ -531,15 +531,15 @@ case ResourceType_Patient: LogChange(stableId, ChangeType_StablePatient, publicId, ResourceType_Patient); break; - + case ResourceType_Study: LogChange(stableId, ChangeType_StableStudy, publicId, ResourceType_Study); break; - + case ResourceType_Series: LogChange(stableId, ChangeType_StableSeries, publicId, ResourceType_Series); break; - + default: THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } @@ -547,7 +547,7 @@ catch (OrthancException& e) { LOG(ERROR) << "Cannot log a change about a stable resource into the database"; - } + } } @@ -631,7 +631,7 @@ uint64_t maximumStorageSize; unsigned int maximumPatients; MaxStorageMode maximumStorageMode; - + { boost::recursive_mutex::scoped_lock lock(monitoringMutex_); maximumStorageSize = maximumStorageSize_; @@ -645,7 +645,7 @@ maximumStorageSize, maximumPatients, isReconstruct); } - + StoreStatus ServerIndex::AddAttachment(int64_t& newRevision, const FileInfo& attachment, const std::string& publicId, @@ -655,7 +655,7 @@ { uint64_t maximumStorageSize; unsigned int maximumPatients; - + { boost::recursive_mutex::scoped_lock lock(monitoringMutex_); maximumStorageSize = maximumStorageSize_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerIndex.h --- a/OrthancServer/Sources/ServerIndex.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerIndex.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -31,7 +31,7 @@ namespace Orthanc { class ServerContext; - + class ServerIndex : public StatelessDatabaseOperations { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerIndexChange.cpp --- a/OrthancServer/Sources/ServerIndexChange.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerIndexChange.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerIndexChange.h --- a/OrthancServer/Sources/ServerIndexChange.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerIndexChange.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ArchiveJob.cpp --- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -47,7 +47,7 @@ #define snprintf _snprintf #endif -static const char* const MEDIA_IMAGES_FOLDER = "IMAGES"; +static const char* const MEDIA_IMAGES_FOLDER = "IMAGES"; static const char* const KEY_DESCRIPTION = "Description"; static const char* const KEY_INSTANCES_COUNT = "InstancesCount"; static const char* const KEY_UNCOMPRESSED_SIZE_MB = "UncompressedSizeMB"; @@ -162,7 +162,7 @@ case ArchiveResourceType_Study: return ArchiveResourceType_Series; - + case ArchiveResourceType_Series: return ArchiveResourceType_Instance; @@ -212,7 +212,7 @@ case ResourceType_Instance: instance_ = current; GoToParent(index, current); - + case ResourceType_Series: series_ = current; GoToParent(index, current); @@ -356,7 +356,7 @@ uint32_t indexInSeries = 0; FileInfo fileInfo; int64_t revisionNotUsed; - + if (index.LookupMetadata(strIndexInSeries, id, ResourceType_Instance, MetadataType_Instance_IndexInSeries)) { SerializationToolbox::ParseUnsignedInteger32(indexInSeries, strIndexInSeries); @@ -413,7 +413,7 @@ if (level_ == ArchiveResourceType_Series) { - // Instances ordering is important ! + // Instances ordering is important ! // From 1.12.6, when possible, the id in the filename will match the index in series. // Only if there are duplicate index in series, we'll use a simple counter SimpleInstanceOrdering orderedInstances(index, it->first); @@ -428,7 +428,7 @@ std::list children; index.GetChildren(children, GetResourceLevel(level_), it->first); - for (std::list::const_iterator + for (std::list::const_iterator it2 = children.begin(); it2 != children.end(); ++it2) { child->AddResourceToExpand(*it2); @@ -440,7 +440,7 @@ assert(it->second != NULL); it->second->Expand(index); - } + } } @@ -448,11 +448,11 @@ { if (level_ == ArchiveResourceType_Instance) { - for (std::list::const_iterator + for (std::list::const_iterator it = instances_.begin(); it != instances_.end(); ++it) { visitor.AddInstance(it->id_, it->index_, it->fileInfo_); - } + } } else { @@ -591,18 +591,18 @@ } } }; - + std::deque commands_; uint64_t uncompressedSize_; unsigned int instancesCount_; - + public: explicit ZipCommands() : uncompressedSize_(0), instancesCount_(0) { } - + ~ZipCommands() { for (std::deque::iterator it = commands_.begin(); @@ -666,8 +666,8 @@ } } }; - - + + class ArchiveJob::ArchiveIndexVisitor : public IArchiveVisitor { @@ -704,7 +704,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - + snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); } @@ -750,34 +750,34 @@ std::string seriesNumber = GetTag(tags, DICOM_TAG_SERIES_NUMBER); std::string modality = GetTag(tags, DICOM_TAG_MODALITY); std::string seriesDescription = GetTag(tags, DICOM_TAG_SERIES_DESCRIPTION); - + if (!seriesNumber.empty()) { pathParts.push_back(seriesNumber); } - + if (!modality.empty()) { pathParts.push_back(modality); } - + if (!seriesDescription.empty()) { pathParts.push_back(seriesDescription); } - + if (modality.size() == 0) { snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); } else if (modality.size() == 1) { - snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", + snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", toupper(modality[0])); } else if (modality.size() >= 2) { - snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", + snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", toupper(modality[0]), toupper(modality[1])); } @@ -791,7 +791,7 @@ Toolbox::JoinStrings(path, pathParts, " - "); path = Toolbox::StripSpaces(path); - if (path.empty() + if (path.empty() || (static_cast(boost::count(path, '^')) == path.size())) // this happens with non ASCII patient names: only the '^' remains and this is not a valid zip folder name { path = std::string("Unknown ") + EnumerationToString(GetResourceLevel(level)); @@ -816,7 +816,7 @@ } }; - + class ArchiveJob::MediaIndexVisitor : public IArchiveVisitor { private: @@ -881,7 +881,7 @@ MediaIndexVisitor visitor(commands_); archive.Expand(context.GetIndex()); - commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); + commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); archive.Apply(visitor); commands_.AddCloseDirectory(); @@ -1048,7 +1048,7 @@ { } - + ArchiveJob::~ArchiveJob() { if (!mediaArchiveId_.empty()) @@ -1061,7 +1061,7 @@ void ArchiveJob::AcquireSynchronousTarget(ZipWriter::IOutputStream* target) { std::unique_ptr protection(target); - + if (target == NULL) { throw OrthancException(ErrorCode_NullPointer); @@ -1123,7 +1123,7 @@ "Missing resource while creating an archive: " + publicId); } } - + ResourceIdentifiers resource(context_.GetIndex(), publicId); archive_->Add(context_.GetIndex(), resource); } @@ -1177,7 +1177,7 @@ "Cannot resubmit the creation of an archive"); } - + void ArchiveJob::Start() { if (writer_.get() != NULL) @@ -1197,10 +1197,10 @@ { OrthancConfiguration::ReaderLock lock; asynchronousTarget_.reset(lock.GetConfiguration().CreateTemporaryFile()); - + assert(asynchronousTarget_.get() != NULL); asynchronousTarget_->Touch(); // Make sure we can write to the temporary file - + writer_.reset(new ZipWriterIterator(context_, *archive_, isMedia_, enableExtendedSopClass_, allowUtf8_)); writer_->SetOutputFile(asynchronousTarget_->GetPath()); } @@ -1208,7 +1208,7 @@ else { assert(synchronousTarget_.get() != NULL); - + writer_.reset(new ZipWriterIterator(context_, *archive_, isMedia_, enableExtendedSopClass_, allowUtf8_)); writer_->AcquireOutputStream(synchronousTarget_.release()); } @@ -1257,7 +1257,7 @@ } }; } - + void ArchiveJob::FinalizeTarget() { @@ -1277,7 +1277,7 @@ new DynamicTemporaryFile(asynchronousTarget_.release())); } } - + JobStepResult ArchiveJob::Step(const std::string& jobId) { @@ -1329,10 +1329,10 @@ reason == JobStopReason_Retry) { writer_->CancelStream(); - + // First delete the writer, as it holds a reference to "(a)synchronousTarget_", cf. (*) writer_.reset(); - + synchronousTarget_.reset(); asynchronousTarget_.reset(); @@ -1356,7 +1356,7 @@ } } - + void ArchiveJob::GetJobType(std::string& target) const { if (isMedia_) @@ -1402,7 +1402,7 @@ MimeType& mime, std::string& filename, const std::string& key) - { + { if (key == "archive" && !mediaArchiveId_.empty()) { @@ -1420,7 +1420,7 @@ { return false; } - } + } else { return false; @@ -1428,7 +1428,7 @@ } bool ArchiveJob::DeleteOutput(const std::string& key) - { + { if (key == "archive" && !mediaArchiveId_.empty()) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ArchiveJob.h --- a/OrthancServer/Sources/ServerJobs/ArchiveJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -76,13 +76,13 @@ bool allowUtf8_; void FinalizeTarget(); - + public: ArchiveJob(ServerContext& context, bool isMedia, bool enableExtendedSopClass, ResourceType jobLevel); - + virtual ~ArchiveJob() ORTHANC_OVERRIDE; void AcquireSynchronousTarget(ZipWriter::IOutputStream* synchronousTarget); @@ -122,7 +122,7 @@ virtual float GetProgress() const ORTHANC_OVERRIDE; virtual void GetJobType(std::string& target) const ORTHANC_OVERRIDE; - + virtual void GetPublicContent(Json::Value& value) const ORTHANC_OVERRIDE; virtual bool Serialize(Json::Value& value) const ORTHANC_OVERRIDE diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/CleaningInstancesJob.cpp --- a/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ return true; } - + void CleaningInstancesJob::SetKeepSource(bool keep) { if (IsStarted()) @@ -82,7 +82,7 @@ } } - + bool CleaningInstancesJob::Serialize(Json::Value& target) const { if (!SetOfInstancesJob::Serialize(target)) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/CleaningInstancesJob.h --- a/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -28,16 +28,16 @@ namespace Orthanc { class ServerContext; - + class CleaningInstancesJob : public SetOfInstancesJob { private: ServerContext& context_; bool keepSource_; - + protected: virtual bool HandleTrailingStep() ORTHANC_OVERRIDE; - + public: CleaningInstancesJob(ServerContext& context, bool keepSource) : @@ -54,12 +54,12 @@ { return context_; } - + bool IsKeepSource() const { return keepSource_; } - + void SetKeepSource(bool keep); virtual bool Serialize(Json::Value& target) const ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp --- a/OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ DicomRetrieveScuBaseJob* job = reinterpret_cast(callbackContext); std::unique_ptr toStore(DicomInstanceToStore::CreateFromDcmDataset(dataset)); - + if (toStore->GetBufferSize() > 0) { toStore->SetOrigin(DicomInstanceOrigin::FromDicomProtocol @@ -76,28 +76,28 @@ if (sopClassesFromResourcesToRetrieve_.size() > 0) { std::set acceptedSopClasses; - - context_.GetAcceptedSopClasses(acceptedSopClasses, 0); + + context_.GetAcceptedSopClasses(acceptedSopClasses, 0); // keep the sop classes from the resources to retrieve only if they are accepted by Orthanc Toolbox::GetIntersection(sopClassesToPropose, sopClassesFromResourcesToRetrieve_, acceptedSopClasses); } else { - // when we don't know what SOP Classes to use, we include the 120 most common SOP Classes because + // when we don't know what SOP Classes to use, we include the 120 most common SOP Classes because // there are only 128 presentation contexts available - context_.GetAcceptedSopClasses(sopClassesToPropose, 120); + context_.GetAcceptedSopClasses(sopClassesToPropose, 120); } if (sopClassesToPropose.size() == 0) { - throw OrthancException(ErrorCode_NoPresentationContext, "Cannot perform C-Get, no SOPClassUID have been accepted by Orthanc."); + throw OrthancException(ErrorCode_NoPresentationContext, "Cannot perform C-Get, no SOPClassUID have been accepted by Orthanc."); } context_.GetProposedStorageTransferSyntaxes(proposedTransferSyntaxes); - connection_.reset(new DicomControlUserConnection(parameters_, - ScuOperationFlags_Get, + connection_.reset(new DicomControlUserConnection(parameters_, + ScuOperationFlags_Get, sopClassesToPropose, proposedTransferSyntaxes)); } @@ -111,7 +111,7 @@ DicomRetrieveScuBaseJob::AddFindAnswer(answer); std::set sopClassesInStudy; - if (answer.HasTag(DICOM_TAG_SOP_CLASSES_IN_STUDY) + if (answer.HasTag(DICOM_TAG_SOP_CLASSES_IN_STUDY) && answer.LookupStringValues(sopClassesInStudy, DICOM_TAG_SOP_CLASSES_IN_STUDY, false)) { for (std::set::const_iterator it = sopClassesInStudy.begin(); it != sopClassesInStudy.end(); ++it) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomGetScuJob.h --- a/OrthancServer/Sources/ServerJobs/DicomGetScuJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomGetScuJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -31,14 +31,14 @@ namespace Orthanc { class ServerContext; - + class DicomGetScuJob : public DicomRetrieveScuBaseJob { private: std::set sopClassesFromResourcesToRetrieve_; virtual void Retrieve(const DicomMap& findAnswer) ORTHANC_OVERRIDE; - + public: explicit DicomGetScuJob(ServerContext& context) : DicomRetrieveScuBaseJob(context) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp --- a/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -48,7 +48,7 @@ assert(IsStarted()); OpenConnection(); - LOG(INFO) << "Sending instance " << instance << " to modality \"" + LOG(INFO) << "Sending instance " << instance << " to modality \"" << parameters_.GetRemoteModality().GetApplicationEntityTitle() << "\""; std::unique_ptr item; @@ -79,21 +79,21 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + if (sopClassUids_.size() == GetInstancesCount()) { assert(IsStarted()); connection_.reset(NULL); - + const std::string& remoteAet = parameters_.GetRemoteModality().GetApplicationEntityTitle(); - + LOG(INFO) << "Sending storage commitment request to modality: " << remoteAet; // Create a "pending" storage commitment report BEFORE the // actual SCU call in order to avoid race conditions context_.GetStorageCommitmentReports().Store( transactionUid_, new StorageCommitmentReports::Report(remoteAet)); - + std::vector a(sopClassUids_.begin(), sopClassUids_.end()); std::vector b(sopInstanceUids_.begin(), sopInstanceUids_.end()); @@ -105,7 +105,7 @@ return true; } - + bool DicomModalityStoreJob::HandleTrailingStep() { @@ -147,7 +147,7 @@ } } - + void DicomModalityStoreJob::SetTimeout(uint32_t seconds) { if (IsStarted()) @@ -173,7 +173,7 @@ } } - + uint16_t DicomModalityStoreJob::GetMoveOriginatorId() const { if (HasMoveOriginator()) @@ -194,7 +194,7 @@ { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - else if (id < 0 || + else if (id < 0 || id >= 65536) { throw OrthancException(ErrorCode_ParameterOutOfRange); @@ -222,7 +222,7 @@ sopInstanceUids_.clear(); } } - + void DicomModalityStoreJob::Reset() { @@ -236,19 +236,19 @@ **/ ResetStorageCommitment(); } - + void DicomModalityStoreJob::EnableStorageCommitment(bool enabled) { storageCommitment_ = enabled; ResetStorageCommitment(); } - + void DicomModalityStoreJob::GetPublicContent(Json::Value& value) const { SetOfInstancesJob::GetPublicContent(value); - + value["LocalAet"] = parameters_.GetLocalApplicationEntityTitle(); value["RemoteAet"] = parameters_.GetRemoteModality().GetApplicationEntityTitle(); @@ -268,7 +268,7 @@ static const char* MOVE_ORIGINATOR_AET = "MoveOriginatorAet"; static const char* MOVE_ORIGINATOR_ID = "MoveOriginatorId"; static const char* STORAGE_COMMITMENT = "StorageCommitment"; - + DicomModalityStoreJob::DicomModalityStoreJob(ServerContext& context, const Json::Value& serialized) : @@ -297,5 +297,5 @@ target[STORAGE_COMMITMENT] = storageCommitment_; return true; } - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.h --- a/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -32,7 +32,7 @@ namespace Orthanc { class ServerContext; - + class DicomModalityStoreJob : public StoreJob { private: @@ -53,7 +53,7 @@ protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE; - + virtual bool HandleTrailingStep() ORTHANC_OVERRIDE; public: @@ -77,9 +77,9 @@ { return moveOriginatorId_ != 0; } - + const std::string& GetMoveOriginatorAet() const; - + uint16_t GetMoveOriginatorId() const; void SetMoveOriginator(const std::string& aet, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp --- a/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -40,15 +40,15 @@ { connection_.reset(new DicomControlUserConnection(parameters_, ScuOperationFlags_Move)); } - + connection_->SetProgressListener(this); - + // we use a unique message ID in order to know to which Move request a stored instance relates to. connection_->Move(targetAet_, findAnswer, GetMessageId(GetParameters().GetLocalApplicationEntityTitle())); } - + void DicomMoveScuJob::SetTargetAet(const std::string& aet) { if (IsStarted()) @@ -61,7 +61,7 @@ } } - + void DicomMoveScuJob::GetPublicContent(Json::Value& value) const @@ -79,7 +79,7 @@ { } - + bool DicomMoveScuJob::Serialize(Json::Value& target) const { if (!DicomRetrieveScuBaseJob::Serialize(target)) @@ -89,7 +89,7 @@ else { target[TARGET_AET] = targetAet_; - + return true; } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomMoveScuJob.h --- a/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,14 +33,14 @@ namespace Orthanc { class ServerContext; - + class DicomMoveScuJob : public DicomRetrieveScuBaseJob { private: std::string targetAet_; - + virtual void Retrieve(const DicomMap& findAnswer) ORTHANC_OVERRIDE; - + public: explicit DicomMoveScuJob(ServerContext& context) : DicomRetrieveScuBaseJob(context) @@ -54,7 +54,7 @@ { return targetAet_; } - + void SetTargetAet(const std::string& aet); virtual void GetJobType(std::string& target) const ORTHANC_OVERRIDE diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.cpp --- a/OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -38,7 +38,7 @@ static const char* const REMOTE = "Remote"; static const char* const TIMEOUT = "Timeout"; -static std::map messagesRegistry; +static std::map messagesRegistry; static uint16_t messageRegistryCurrentId = 1000; static boost::mutex messageRegistryMutex; @@ -53,17 +53,17 @@ { assert(currentCommand_ != NULL); boost::mutex::scoped_lock lock(messageRegistryMutex); - - // Each resource retrieval (command) has its own messageId. + + // Each resource retrieval (command) has its own messageId. // We start at 1000 to clearly differentiate them from other messages. We can actually use ANY value between 0 & 65535. messageRegistryCurrentId = std::max(1000, (messageRegistryCurrentId + 1) % 0xFFFF); messagesRegistry[GetKey(localAet, messageRegistryCurrentId)] = currentCommand_; - + return messageRegistryCurrentId; } - void DicomRetrieveScuBaseJob::AddReceivedInstanceFromCStore(uint16_t originatorMessageId, - const std::string& originatorAet, + void DicomRetrieveScuBaseJob::AddReceivedInstanceFromCStore(uint16_t originatorMessageId, + const std::string& originatorAet, const std::string& instanceId) { boost::mutex::scoped_lock lock(messageRegistryMutex); @@ -157,7 +157,7 @@ query.GetAnswer(query.GetSize() - 1).Remove(DICOM_TAG_SPECIFIC_CHARACTER_SET); } - // this method is used to implement the retrieve part of a Q&R + // this method is used to implement the retrieve part of a Q&R // it keeps only the main dicom tags from the C-Find answer void DicomRetrieveScuBaseJob::AddFindAnswer(const DicomMap& answer) { @@ -169,7 +169,7 @@ item.CopyTagIfExists(answer, DICOM_TAG_SOP_INSTANCE_UID); item.CopyTagIfExists(answer, DICOM_TAG_ACCESSION_NUMBER); AddToQuery(query_, item); - + AddCommand(new Command(*this, answer)); } @@ -179,7 +179,7 @@ DicomMap answer; query.GetAnswer(answer, i); AddFindAnswer(answer); - } + } // this method is used to implement a C-Move // it keeps all tags from the C-Move query @@ -188,7 +188,7 @@ AddToQuery(query_, query); AddCommand(new Command(*this, query)); } - + void DicomRetrieveScuBaseJob::SetLocalAet(const std::string& aet) { @@ -202,7 +202,7 @@ } } - + void DicomRetrieveScuBaseJob::SetRemoteModality(const RemoteModalityParameters& remote) { if (IsStarted()) @@ -228,12 +228,12 @@ } } - + void DicomRetrieveScuBaseJob::Stop(JobStopReason reason) { connection_.reset(); } - + void DicomRetrieveScuBaseJob::SetQueryFormat(DicomToJsonFormat format) { @@ -259,7 +259,7 @@ query_.ToJson(value[QUERY], queryFormat_); value["Details"] = Json::arrayValue; - + for (size_t i = 0; i < GetCommandsCount(); ++i) { const DicomRetrieveScuBaseJob::Command& command = dynamic_cast(GetCommand(i)); @@ -320,7 +320,7 @@ } } - + bool DicomRetrieveScuBaseJob::Serialize(Json::Value& target) const { if (!SetOfCommandsJob::Serialize(target)) @@ -336,7 +336,7 @@ query_.ToJson(target[QUERY], DicomToJsonFormat_Short); target[QUERY_FORMAT] = EnumerationToString(queryFormat_); - + return true; } } @@ -357,7 +357,7 @@ float DicomRetrieveScuBaseJob::GetProgress() const { boost::mutex::scoped_lock lock(progressMutex_); - + uint32_t totalOperations = nbRemainingSubOperations_ + nbCompletedSubOperations_ + nbFailedSubOperations_ + nbWarningSubOperations_; if (totalOperations == 0) { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.h --- a/OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/DicomRetrieveScuBaseJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -37,7 +37,7 @@ { protected: uint16_t GetMessageId(const std::string& localAet); - + class Command : public SetOfCommandsJob::ICommand { private: @@ -89,7 +89,7 @@ DicomRetrieveScuBaseJob &that_; public: - explicit Unserializer(DicomRetrieveScuBaseJob &that) : + explicit Unserializer(DicomRetrieveScuBaseJob &that) : that_(that) { } @@ -170,8 +170,8 @@ void AddReceivedInstance(const std::string& instanceId); - static void AddReceivedInstanceFromCStore(uint16_t originatorMessageId, - const std::string& originatorAet, + static void AddReceivedInstanceFromCStore(uint16_t originatorMessageId, + const std::string& originatorAet, const std::string& instanceId); virtual void LookupErrorPayload(ErrorPayload& payload) const ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/IStorageCommitmentFactory.h --- a/OrthancServer/Sources/ServerJobs/IStorageCommitmentFactory.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/IStorageCommitmentFactory.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/LuaJobManager.cpp --- a/OrthancServer/Sources/ServerJobs/LuaJobManager.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/LuaJobManager.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -59,7 +59,7 @@ trailingTimeout_(5000) { unsigned int dicomTimeout; - + { OrthancConfiguration::ReaderLock lock; dicomTimeout = lock.GetConfiguration().GetUnsignedIntegerParameter("DicomAssociationCloseDelay"); @@ -152,11 +152,11 @@ LuaJobManager::Lock::~Lock() { bool isEmpty; - + assert(jobLock_.get() != NULL); isEmpty = (isNewJob_ && jobLock_->GetOperationsCount() == 0); - + jobLock_.reset(NULL); if (isNewJob_) @@ -196,23 +196,23 @@ { assert(jobLock_.get() != NULL); return jobLock_->AddOperation(new StoreScuOperation( - context, that_.connectionManager_, localAet, modality)); + context, that_.connectionManager_, localAet, modality)); } size_t LuaJobManager::Lock::AddStorePeerOperation(const WebServiceParameters& peer) { assert(jobLock_.get() != NULL); - return jobLock_->AddOperation(new StorePeerOperation(peer)); + return jobLock_->AddOperation(new StorePeerOperation(peer)); } size_t LuaJobManager::Lock::AddSystemCallOperation(const std::string& command) { assert(jobLock_.get() != NULL); - return jobLock_->AddOperation(new SystemCallOperation(command)); + return jobLock_->AddOperation(new SystemCallOperation(command)); } - + size_t LuaJobManager::Lock::AddSystemCallOperation (const std::string& command, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/LuaJobManager.h --- a/OrthancServer/Sources/ServerJobs/LuaJobManager.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/LuaJobManager.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -32,7 +32,7 @@ namespace Orthanc { class ServerContext; - + class LuaJobManager : private SequenceOfOperationsJob::IObserver { private: @@ -96,7 +96,7 @@ size_t AddModifyInstanceOperation(ServerContext& context, DicomModification* modification); - void AddNullInput(size_t operation); + void AddNullInput(size_t operation); void AddStringInput(size_t operation, const std::string& content); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp --- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -42,7 +42,7 @@ target[series] = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series); } } - + void MergeStudyJob::AddSourceSeriesInternal(const std::string& series) { @@ -88,11 +88,11 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls, "AddTrailingStep() should have been called after AddSourceXXX()"); } - + /** * Retrieve the DICOM instance to be modified **/ - + std::unique_ptr modified; try @@ -131,7 +131,7 @@ { modified->Remove(*it); } - + for (Replacements::const_iterator it = replacements_.begin(); it != replacements_.end(); ++it) { @@ -142,7 +142,7 @@ /** * Store the new instance into Orthanc **/ - + modified->ReplacePlainString(DICOM_TAG_SERIES_INSTANCE_UID, targetSeriesUid->second); // Fix since Orthanc 1.5.8: Assign new "SOPInstanceUID", as the instance has been modified @@ -162,7 +162,7 @@ return true; } - + MergeStudyJob::MergeStudyJob(ServerContext& context, const std::string& targetStudy) : CleaningInstancesJob(context, false /* by default, remove source instances */), @@ -171,7 +171,7 @@ /** * Check the validity of the input ID **/ - + ResourceType type; if (!GetContext().GetIndex().LookupResourceType(type, targetStudy) || @@ -189,10 +189,10 @@ DicomTag::AddTagsForModule(removals_, DicomModule_Patient); DicomTag::AddTagsForModule(removals_, DicomModule_Study); - + std::list instances; GetContext().GetIndex().GetChildInstances(instances, targetStudy, ResourceType_Study); - + if (instances.empty()) { throw OrthancException(ErrorCode_UnknownResource); @@ -213,7 +213,7 @@ { const DicomValue* value = dicom.TestAndGetValue(*it); std::string str; - + if (value != NULL && value->CopyToString(str, false)) { @@ -222,7 +222,7 @@ } } } - + void MergeStudyJob::SetOrigin(const DicomInstanceOrigin& origin) { @@ -236,7 +236,7 @@ } } - + void MergeStudyJob::SetOrigin(const RestApiCall& call) { SetOrigin(DicomInstanceOrigin::FromRest(call)); @@ -246,7 +246,7 @@ void MergeStudyJob::AddSource(const std::string& publicId) { ResourceType level; - + if (IsStarted()) { throw OrthancException(ErrorCode_BadSequenceOfCalls); @@ -263,23 +263,23 @@ case ResourceType_Study: AddSourceStudyInternal(publicId); break; - + case ResourceType_Series: AddSourceSeries(publicId); break; - + case ResourceType_Instance: AddSourceInstance(publicId); break; - + default: throw OrthancException(ErrorCode_UnknownResource, "This resource is neither a study, nor a series, nor an instance: " + publicId + " is a " + std::string(EnumerationToString(level))); } - } + } } - + void MergeStudyJob::AddSourceSeries(const std::string& series) { @@ -303,7 +303,7 @@ else { AddSourceSeriesInternal(series); - } + } } @@ -324,7 +324,7 @@ else { AddSourceStudyInternal(study); - } + } } @@ -352,9 +352,9 @@ { RegisterSeries(seriesUidMap_, parentSeries); AddInstance(instance); - } + } } - + void MergeStudyJob::GetPublicContent(Json::Value& value) const { @@ -388,7 +388,7 @@ origin_ = DicomInstanceOrigin(serialized[ORIGIN]); } - + bool MergeStudyJob::Serialize(Json::Value& target) const { if (!CleaningInstancesJob::Serialize(target)) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/MergeStudyJob.h --- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -30,14 +30,14 @@ namespace Orthanc { class ServerContext; - + class MergeStudyJob : public CleaningInstancesJob { private: typedef std::map SeriesUidMap; typedef std::map Replacements; - - + + std::string targetStudy_; Replacements replacements_; std::set removals_; @@ -52,7 +52,7 @@ // Make setter methods private to prevent incorrect calls using SetOfInstancesJob::AddParentResource; using SetOfInstancesJob::AddInstance; - + protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.h --- a/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -29,7 +29,7 @@ namespace Orthanc { class ServerContext; - + class DeleteResourceOperation : public IJobOperation { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.h --- a/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -29,7 +29,7 @@ namespace Orthanc { class ServerContext; - + class DicomInstanceOperationValue : public IJobOperationValue { private: @@ -48,7 +48,7 @@ { return Type_DicomInstance; } - + ServerContext& GetServerContext() const { return context_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -44,7 +44,7 @@ { throw OrthancException(ErrorCode_NullPointer); } - + modification_->SetAllowManualIdentifiers(true); if (modification_->IsReplaced(DICOM_TAG_PATIENT_ID)) @@ -85,7 +85,7 @@ LOG(INFO) << "Lua: Modifying instance " << instance.GetId(); std::unique_ptr modified; - + { std::unique_ptr dicom(context_.ReadParsedDicom(instance.GetId())); modified.reset(dicom->Clone()); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.h --- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -30,14 +30,14 @@ namespace Orthanc { class ServerContext; - + class ModifyInstanceOperation : public IJobOperation { private: ServerContext& context_; RequestOrigin origin_; std::unique_ptr modification_; - + public: ModifyInstanceOperation(ServerContext& context, RequestOrigin origin, @@ -50,7 +50,7 @@ { return origin_; } - + const DicomModification& GetModification() const { return *modification_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -48,7 +48,7 @@ const DicomInstanceOperationValue& instance = dynamic_cast(input); - LOG(INFO) << "Lua: Sending instance " << instance.GetId() << " to Orthanc peer \"" + LOG(INFO) << "Lua: Sending instance " << instance.GetId() << " to Orthanc peer \"" << peer_.GetUrl() << "\""; try @@ -58,7 +58,7 @@ instance.ReadDicom(body); client.SetExternalBody(body); // Avoids a memcpy() - + std::string answer; if (!client.Apply(answer)) { @@ -75,12 +75,12 @@ outputs.Append(input.Clone()); } - + void StorePeerOperation::Serialize(Json::Value& result) const { result = Json::objectValue; result["Type"] = "StorePeer"; - peer_.Serialize(result["Peer"], + peer_.Serialize(result["Peer"], true /* force advanced format */, true /* include passwords */); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.h --- a/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -37,7 +37,7 @@ const IJobOperationValue& input) { TimeoutDicomConnectionManager::Lock lock(connectionManager_, localAet_, modality_); - + if (input.GetType() != IJobOperationValue::Type_DicomInstance) { throw OrthancException(ErrorCode_BadParameterType); @@ -46,7 +46,7 @@ const DicomInstanceOperationValue& instance = dynamic_cast(input); - LOG(INFO) << "Lua: Sending instance " << instance.GetId() << " to modality \"" + LOG(INFO) << "Lua: Sending instance " << instance.GetId() << " to modality \"" << modality_.GetApplicationEntityTitle() << "\""; try @@ -61,14 +61,14 @@ } catch (OrthancException& e) { - LOG(ERROR) << "Lua: Unable to send instance " << instance.GetId() << " to modality \"" + LOG(ERROR) << "Lua: Unable to send instance " << instance.GetId() << " to modality \"" << modality_.GetApplicationEntityTitle() << "\": " << e.What(); } outputs.Append(input.Clone()); } - + void StoreScuOperation::Serialize(Json::Value& result) const { result = Json::objectValue; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.h --- a/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -30,7 +30,7 @@ namespace Orthanc { class ServerContext; - + class StoreScuOperation : public IJobOperation { private: @@ -38,7 +38,7 @@ TimeoutDicomConnectionManager& connectionManager_; std::string localAet_; RemoteModalityParameters modality_; - + public: StoreScuOperation(ServerContext& context, TimeoutDicomConnectionManager& connectionManager, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -49,7 +49,7 @@ } } - + const std::string& SystemCallOperation::GetPostArgument(size_t i) const { if (i >= postArguments_.size()) @@ -71,7 +71,7 @@ arguments.reserve(arguments.size() + postArguments_.size() + 1); std::unique_ptr tmp; - + switch (input.GetType()) { case IJobOperationValue::Type_DicomInstance: @@ -88,7 +88,7 @@ } tmp->Write(dicom); - + arguments.push_back(SystemToolbox::PathToUtf8(tmp->GetPath())); break; } @@ -119,7 +119,7 @@ { info += " " + arguments[i]; } - + LOG(INFO) << "Lua: System call: \"" << info << "\""; try diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.h --- a/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -36,7 +36,7 @@ std::string command_; std::vector preArguments_; std::vector postArguments_; - + public: explicit SystemCallOperation(const std::string& command) : command_(command) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.cpp --- a/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.h --- a/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -28,7 +28,7 @@ namespace Orthanc { class ServerContext; - + class OrthancJobUnserializer : public GenericJobUnserializer { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp --- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -51,8 +51,8 @@ client_->AddHeader("Content-Encoding", "gzip"); } } - - LOG(INFO) << "Sending instance " << instance << " to peer \"" + + LOG(INFO) << "Sending instance " << instance << " to peer \"" << peer_.GetUrl() << "\""; // Lifetime of "body" must exceed the call to "client_->Apply()" because of "SetExternalBody()" @@ -69,7 +69,7 @@ { std::set syntaxes; syntaxes.insert(transferSyntax_); - + IDicomTranscoder::DicomImage source, transcoded; source.SetExternalBuffer(dicom.GetData(), dicom.GetSize()); @@ -129,7 +129,7 @@ throw OrthancException(ErrorCode_NetworkProtocol); } } - + bool OrthancPeerStoreJob::HandleTrailingStep() { @@ -161,7 +161,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - + void OrthancPeerStoreJob::SetTranscode(DicomTransferSyntax syntax) { @@ -173,9 +173,9 @@ { transcode_ = true; transferSyntax_ = syntax; - } + } } - + void OrthancPeerStoreJob::SetTranscode(const std::string& transferSyntaxUid) { @@ -214,7 +214,7 @@ else { compress_ = compress; - } + } } @@ -229,14 +229,14 @@ void OrthancPeerStoreJob::GetPublicContent(Json::Value& value) const { SetOfInstancesJob::GetPublicContent(value); - + Json::Value v; - peer_.Serialize(v, + peer_.Serialize(v, false /* allow simple format if possible */, false /* don't include passwords */); value["Peer"] = v; value["Compress"] = compress_; - + if (transcode_) { value["Transcode"] = GetTransferSyntaxUid(transferSyntax_); @@ -309,8 +309,8 @@ target[COMPRESS] = compress_; target[SIZE] = boost::lexical_cast(size_); - + return true; } - } + } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h --- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,7 +33,7 @@ namespace Orthanc { class ServerContext; - + class OrthancPeerStoreJob : public StoreJob { private: @@ -46,7 +46,7 @@ protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE; - + virtual bool HandleTrailingStep() ORTHANC_OVERRIDE; public: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp --- a/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -45,7 +45,7 @@ target["ID"] = id; target["Path"] = GetBasePath(level, id); } - + class ResourceModificationJob::SingleOutput : public IOutput { private: @@ -64,7 +64,7 @@ level_ != ResourceType_Series) { throw OrthancException(ErrorCode_ParameterOutOfRange); - } + } } virtual void Update(DicomInstanceHasher& hasher) ORTHANC_OVERRIDE @@ -115,7 +115,7 @@ return level_; } }; - + class ResourceModificationJob::MultipleOutputs : public IOutput { @@ -131,10 +131,10 @@ { Json::Value item = Json::objectValue; FormatResource(item, level, *it); - target.append(item); + target.append(item); } } - + std::set instances_; std::set series_; std::set studies_; @@ -195,7 +195,7 @@ GetContext().GetIndex().ReconstructInstance(modifiedDicom, false, ResourceType_Instance /* dummy */); } } - + } bool ResourceModificationJob::HandleInstance(const std::string& instance) @@ -207,20 +207,20 @@ "No modification was provided for this job"); } - + LOG(INFO) << "Modifying instance in a job: " << instance; /** * Retrieve the original instance from the DICOM cache. **/ - + std::unique_ptr originalHasher; std::unique_ptr modified; std::set instanceLabels; std::set seriesLabels; std::set studyLabels; std::set patientLabels; - + try { std::unique_ptr dicom(GetContext().ReadParsedDicom(instance)); @@ -258,7 +258,7 @@ } const std::string modifiedUid = IDicomTranscoder::GetSopInstanceUid(modified->GetDcmtkObject()); - + if (transcode_) { std::set syntaxes; @@ -266,7 +266,7 @@ IDicomTranscoder::DicomImage source; source.AcquireParsed(*modified); // "modified" is invalid below this point - + IDicomTranscoder::DicomImage transcoded; if (GetContext().GetTranscoder()->Transcode(transcoded, source, syntaxes, TranscodingSopInstanceUidMode_AllowNew)) { @@ -303,7 +303,7 @@ **/ DicomInstanceHasher modifiedHasher = modified->GetHasher(); - + MetadataType metadataType = (isAnonymization_ ? MetadataType_AnonymizedFrom : MetadataType_ModifiedFrom); @@ -369,7 +369,7 @@ // add an instance to reconstruct for each series instancesToReconstruct_.insert(modifiedHasher.HashInstance()); } - + } return true; @@ -438,7 +438,7 @@ } } - + void ResourceModificationJob::SetOrigin(const RestApiCall& call) { SetOrigin(DicomInstanceOrigin::FromRest(call)); @@ -470,7 +470,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - + void ResourceModificationJob::SetTranscode(DicomTransferSyntax syntax) { @@ -482,7 +482,7 @@ { transcode_ = true; transferSyntax_ = syntax; - } + } } @@ -529,7 +529,7 @@ return output_->IsSingleResource(); } } - + ResourceType ResourceModificationJob::GetOutputLevel() const { @@ -575,7 +575,7 @@ static const char* TRANSCODE = "Transcode"; static const char* OUTPUT_LEVEL = "OutputLevel"; static const char* IS_SINGLE_RESOURCE = "IsSingleResource"; - + ResourceModificationJob::ResourceModificationJob(ServerContext& context, const Json::Value& serialized) : @@ -611,7 +611,7 @@ if (isSingleResource) { ResourceType outputLevel; - + if (serialized.isMember(OUTPUT_LEVEL)) { // New in Orthanc 1.9.4. This fixes an *incorrect* behavior in @@ -633,7 +633,7 @@ outputLevel = ResourceType_Patient; } } - + SetSingleResourceModification(modification.release(), outputLevel, isAnonymization); } else @@ -642,7 +642,7 @@ SetMultipleResourcesModification(modification.release(), isAnonymization); } } - + bool ResourceModificationJob::Serialize(Json::Value& value) const { if (modification_.get() == NULL) @@ -656,7 +656,7 @@ else { assert(value.type() == Json::objectValue); - + value[IS_ANONYMIZATION] = isAnonymization_; if (transcode_) @@ -665,12 +665,12 @@ } origin_.Serialize(value[ORIGIN]); - + Json::Value tmp; { boost::recursive_mutex::scoped_lock lock(mutex_); // DicomModification object is not thread safe, we must protect it from here - + modification_->Serialize(tmp); } @@ -682,7 +682,7 @@ { value[OUTPUT_LEVEL] = EnumerationToString(GetOutputLevel()); } - + return true; } } @@ -736,13 +736,13 @@ for (std::map::const_iterator it = parentResources_.begin(); it != parentResources_.end(); ++it) { // When modifying a study, you may not modify patient tags as you wish. - // - If this is the patient's only study, you may modify all patient tags. This could be performed in 2 steps (modify the patient and then, the study) but, + // - If this is the patient's only study, you may modify all patient tags. This could be performed in 2 steps (modify the patient and then, the study) but, // for many use cases, it's helpful to be able to do it one step (e.g, to modify a name in a study that has just been acquired) - // - If the patient already has other studies, you may only 'attach' the study to an existing patient by modifying + // - If the patient already has other studies, you may only 'attach' the study to an existing patient by modifying // all patient tags from the study to match those of the target patient. // - Otherwise, you can't modify the patient tags const std::string& studyId = it->first; - + std::string targetPatientId; if (modification_->IsReplaced(DICOM_TAG_PATIENT_ID)) { @@ -807,7 +807,7 @@ std::set mainPatientTags; DicomMap::GetMainDicomTags(mainPatientTags, ResourceType_Patient); - + for (std::set::const_iterator mainPatientTag = mainPatientTags.begin(); mainPatientTag != mainPatientTags.end(); ++mainPatientTag) { @@ -834,14 +834,14 @@ else if (!targetPatientTags.HasTag(*mainPatientTag) && modification_->IsReplaced(*mainPatientTag) ) { throw OrthancException(ErrorCode_BadRequest, std::string("Trying to change patient tags in a study. " - "The Patient already exists and has other studies. You are trying to replace a tag that is not defined yet in this patient. " + "The Patient already exists and has other studies. You are trying to replace a tag that is not defined yet in this patient. " "Try using /patients/../modify instead to modify the patient. Failing tag: ") + mainPatientTag->Format()); } } } } } - } + } } } } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ResourceModificationJob.h --- a/OrthancServer/Sources/ServerJobs/ResourceModificationJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ResourceModificationJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -32,7 +32,7 @@ namespace Orthanc { class ServerContext; - + class ResourceModificationJob : public ThreadedSetOfInstancesJob { private: @@ -49,12 +49,12 @@ virtual bool IsSingleResource() const = 0; }; - + class SingleOutput; class MultipleOutputs; mutable boost::recursive_mutex outputMutex_; - + std::unique_ptr modification_; boost::shared_ptr output_; bool isAnonymization_; @@ -66,7 +66,7 @@ protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE; - + virtual void PostProcessInstances() ORTHANC_OVERRIDE; public: @@ -122,7 +122,7 @@ } virtual void GetPublicContent(Json::Value& value) const ORTHANC_OVERRIDE; - + virtual bool Serialize(Json::Value& value) const ORTHANC_OVERRIDE; virtual void Reset() ORTHANC_OVERRIDE; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp --- a/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -44,18 +44,18 @@ } } - + void SplitStudyJob::Setup() { SetPermissive(false); - + DicomTag::AddTagsForModule(allowedTags_, DicomModule_Patient); DicomTag::AddTagsForModule(allowedTags_, DicomModule_Study); allowedTags_.erase(DICOM_TAG_STUDY_INSTANCE_UID); allowedTags_.erase(DICOM_TAG_SERIES_INSTANCE_UID); } - + bool SplitStudyJob::HandleInstance(const std::string& instance) { if (!HasTrailingStep()) @@ -63,11 +63,11 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls, "AddTrailingStep() should have been called after AddSourceSeries()"); } - + /** * Retrieve the DICOM instance to be modified **/ - + std::unique_ptr modified; try @@ -107,7 +107,7 @@ { modified->Remove(*it); } - + for (Replacements::const_iterator it = replacements_.begin(); it != replacements_.end(); ++it) { @@ -118,7 +118,7 @@ /** * Store the new instance into Orthanc **/ - + modified->ReplacePlainString(DICOM_TAG_STUDY_INSTANCE_UID, targetStudyUid_); modified->ReplacePlainString(DICOM_TAG_SERIES_INSTANCE_UID, targetSeriesUid->second); @@ -129,7 +129,7 @@ { targetStudy_ = modified->GetHasher().HashStudy(); } - + std::unique_ptr toStore(DicomInstanceToStore::CreateFromParsedDicomFile(*modified)); toStore->SetOrigin(origin_); @@ -144,7 +144,7 @@ return true; } - + SplitStudyJob::SplitStudyJob(ServerContext& context, const std::string& sourceStudy) : CleaningInstancesJob(context, false /* by default, remove source instances */), @@ -152,9 +152,9 @@ targetStudyUid_(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)) { Setup(); - + ResourceType type; - + if (!GetContext().GetIndex().LookupResourceType(type, sourceStudy) || type != ResourceType_Study) { @@ -162,7 +162,7 @@ "Cannot split unknown study " + sourceStudy); } } - + void SplitStudyJob::SetOrigin(const DicomInstanceOrigin& origin) { @@ -176,7 +176,7 @@ } } - + void SplitStudyJob::SetOrigin(const RestApiCall& call) { SetOrigin(DicomInstanceOrigin::FromRest(call)); @@ -192,7 +192,7 @@ target[series] = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series); } } - + void SplitStudyJob::AddSourceSeries(const std::string& series) { @@ -221,7 +221,7 @@ { AddInstance(*it); } - } + } } @@ -244,7 +244,7 @@ { RegisterSeries(seriesUidMap_, series); AddInstance(instance); - } + } } @@ -276,7 +276,7 @@ removals_.insert(tag); } - + void SplitStudyJob::Replace(const DicomTag& tag, const std::string& value) { @@ -305,8 +305,8 @@ return true; } } - - + + void SplitStudyJob::GetPublicContent(Json::Value& value) const { CleaningInstancesJob::GetPublicContent(value); @@ -315,7 +315,7 @@ { value["TargetStudy"] = targetStudy_; } - + value["TargetStudyUID"] = targetStudyUid_; } @@ -351,7 +351,7 @@ SerializationToolbox::ReadSetOfTags(removals_, serialized, REMOVALS); } - + bool SplitStudyJob::Serialize(Json::Value& target) const { if (!CleaningInstancesJob::Serialize(target)) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/SplitStudyJob.h --- a/OrthancServer/Sources/ServerJobs/SplitStudyJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/SplitStudyJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -30,14 +30,14 @@ namespace Orthanc { class ServerContext; - + class SplitStudyJob : public CleaningInstancesJob { private: typedef std::map SeriesUidMap; typedef std::map Replacements; - - + + std::set allowedTags_; std::string sourceStudy_; std::string targetStudy_; @@ -48,13 +48,13 @@ std::set removals_; void CheckAllowedTag(const DicomTag& tag) const; - + void Setup(); // Make setter methods private to prevent incorrect calls using SetOfInstancesJob::AddParentResource; using SetOfInstancesJob::AddInstance; - + protected: virtual bool HandleInstance(const std::string& instance) ORTHANC_OVERRIDE; @@ -83,18 +83,18 @@ void AddSourceSeries(const std::string& series); void AddSourceInstance(const std::string& instance); // New in Orthanc 1.9.4 - + bool LookupTargetSeriesUid(std::string& uid, const std::string& series) const; void Replace(const DicomTag& tag, const std::string& value); - + bool LookupReplacement(std::string& value, const DicomTag& tag) const; void Remove(const DicomTag& tag); - + bool IsRemoved(const DicomTag& tag) const { return removals_.find(tag) != removals_.end(); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp --- a/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -55,7 +55,7 @@ virtual CommandType GetType() const = 0; }; - + class StorageCommitmentScpJob::SetupCommand : public StorageCommitmentCommand { private: @@ -71,7 +71,7 @@ { return CommandType_Setup; } - + virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE { that_.Setup(jobId); @@ -108,7 +108,7 @@ { return CommandType_Lookup; } - + virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE { failureReason_ = that_.Lookup(index_); @@ -141,7 +141,7 @@ } }; - + class StorageCommitmentScpJob::AnswerCommand : public StorageCommitmentCommand { private: @@ -165,7 +165,7 @@ { return CommandType_Answer; } - + virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE { that_.Answer(); @@ -178,7 +178,7 @@ target[TYPE] = ANSWER; } }; - + class StorageCommitmentScpJob::Unserializer : public SetOfCommandsJob::ICommandUnserializer { @@ -223,11 +223,11 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + for (size_t i = 0; i < n; i++) { const CommandType type = dynamic_cast(GetCommand(i)).GetType(); - + if ((i == 0 && type != CommandType_Setup) || (i >= 1 && i < n - 1 && type != CommandType_Lookup) || (i == n - 1 && type != CommandType_Answer)) @@ -245,7 +245,7 @@ } } } - + void StorageCommitmentScpJob::Setup(const std::string& jobId) { @@ -277,7 +277,7 @@ bool success = false; StorageCommitmentFailureReason reason = StorageCommitmentFailureReason_NoSuchObjectInstance /* 0x0112 == 274 */; - + try { std::vector orthancId; @@ -321,10 +321,10 @@ return reason; } } - - + + void StorageCommitmentScpJob::Answer() - { + { CheckInvariants(); LOG(INFO) << " Storage commitment SCP job: Sending answer"; @@ -346,7 +346,7 @@ DicomAssociation::ReportStorageCommitment( parameters, transactionUid_, sopClassUids_, sopInstanceUids_, failureReasons); } - + StorageCommitmentScpJob::StorageCommitmentScpJob(ServerContext& context, const std::string& transactionUid, @@ -367,7 +367,7 @@ AddCommand(new SetupCommand(*this)); } - + void StorageCommitmentScpJob::Reserve(size_t size) { @@ -383,7 +383,7 @@ sopInstanceUids_.reserve(size); } } - + void StorageCommitmentScpJob::AddInstance(const std::string& sopClassUid, const std::string& sopInstanceUid) @@ -400,7 +400,7 @@ sopInstanceUids_.push_back(sopInstanceUid); } } - + void StorageCommitmentScpJob::MarkAsReady() { @@ -411,7 +411,7 @@ void StorageCommitmentScpJob::GetPublicContent(Json::Value& value) const { SetOfCommandsJob::GetPublicContent(value); - + value["CalledAet"] = connection_->GetCalledAet(); value["RemoteAet"] = connection_->GetRemoteAet(); value["RemoteIp"] = connection_->GetRemoteIp(); @@ -437,7 +437,7 @@ std::string remoteAet = SerializationToolbox::ReadString(serialized[REMOTE_MODALITY], "AET"); std::string remoteIp = SerializationToolbox::ReadString(serialized[REMOTE_MODALITY], "Host"); connection_.reset(new DicomConnectionInfo(remoteIp, remoteAet, calledAet)); - } + } if (connection_.get() == NULL) { @@ -456,7 +456,7 @@ SerializationToolbox::ReadArrayOfStrings(sopClassUids_, serialized, SOP_CLASS_UIDS); SerializationToolbox::ReadArrayOfStrings(sopInstanceUids_, serialized, SOP_INSTANCE_UIDS); } - + bool StorageCommitmentScpJob::Serialize(Json::Value& target) const { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.h --- a/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -35,7 +35,7 @@ namespace Orthanc { class ServerContext; - + class StorageCommitmentScpJob : public SetOfCommandsJob { private: @@ -45,7 +45,7 @@ CommandType_Lookup, CommandType_Answer }; - + class StorageCommitmentCommand; class SetupCommand; class LookupCommand; @@ -63,13 +63,13 @@ std::unique_ptr lookupHandler_; void CheckInvariants(); - + void Setup(const std::string& jobId); - + StorageCommitmentFailureReason Lookup(size_t index); - + void Answer(); - + public: StorageCommitmentScpJob(ServerContext& context, const std::string& transactionUid, @@ -79,7 +79,7 @@ const Json::Value& serialized); virtual void Reserve(size_t size) ORTHANC_OVERRIDE; - + void AddInstance(const std::string& sopClassUid, const std::string& sopInstanceUid); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/StoreJob.cpp --- a/OrthancServer/Sources/ServerJobs/StoreJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/StoreJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -144,7 +144,7 @@ } } - + void StoreJob::Stop(JobStopReason reason) { // clear the loader threads (also when simply pausing the job) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/StoreJob.h --- a/OrthancServer/Sources/ServerJobs/StoreJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/StoreJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp --- a/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -149,7 +149,7 @@ // No instances to handle: We're done return JobStepResult::Success(); } - + try { if (currentStep_ == ThreadedJobStep_NotStarted) @@ -268,7 +268,7 @@ } bool processed = false; - + try { processed = that->HandleInstance(instanceId->GetValue()); @@ -297,12 +297,12 @@ { boost::recursive_mutex::scoped_lock lock(that->mutex_); - + that->processedInstances_.insert(instanceId->GetValue()); if (!processed) { - that->failedInstances_.insert(instanceId->GetValue()); + that->failedInstances_.insert(instanceId->GetValue()); } } @@ -313,7 +313,7 @@ size_t ThreadedSetOfInstancesJob::GetInstancesCount() const { boost::recursive_mutex::scoped_lock lock(mutex_); - + return instancesToProcess_.size(); } @@ -429,14 +429,14 @@ std::string type; GetJobType(type); target[KEY_TYPE] = type; - + target[KEY_PERMISSIVE] = permissive_; target[KEY_USER_DATA] = userData_; target[KEY_CURRENT_STEP] = static_cast(currentStep_); target[KEY_DESCRIPTION] = description_; target[KEY_KEEP_SOURCE] = keepSource_; target[KEY_WORKERS_COUNT] = static_cast(workersCount_); - + SerializationToolbox::WriteSetOfStrings(target, instancesToProcess_, KEY_INSTANCES); SerializationToolbox::WriteSetOfStrings(target, failedInstances_, KEY_FAILED_INSTANCES); SerializeResources(target, parentResources_, false); @@ -485,7 +485,7 @@ { SerializationToolbox::ReadMapOfResourcesAndTypes(parentResources_, source, KEY_RESOURCES); } - + if (source.isMember(KEY_KEEP_SOURCE)) { keepSource_ = SerializationToolbox::ReadBoolean(source, KEY_KEEP_SOURCE); @@ -550,7 +550,7 @@ { size_t totalProgress = GetInstancesCount(); size_t currentProgress = processedInstances_.size(); - + if (HasPostProcessingStep()) { ++totalProgress; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h --- a/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerJobs/ThreadedSetOfInstancesJob.h Wed Aug 19 14:11:33 2026 +0200 @@ -68,7 +68,7 @@ ServerContext& context_; bool keepSource_; ErrorCode errorCode_; - + protected: mutable boost::recursive_mutex mutex_; std::map parentResources_; @@ -136,9 +136,9 @@ void SetPermissive(bool permissive); virtual void Reset() ORTHANC_OVERRIDE; - + virtual void Start() ORTHANC_OVERRIDE; - + virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE; virtual float GetProgress() const ORTHANC_OVERRIDE; @@ -146,9 +146,9 @@ bool IsStarted() const; virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE; - + virtual void GetPublicContent(Json::Value& value) const ORTHANC_OVERRIDE; - + virtual bool Serialize(Json::Value& target) const ORTHANC_OVERRIDE; virtual bool GetOutput(std::string& output, diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerToolbox.cpp --- a/OrthancServer/Sources/ServerToolbox.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerToolbox.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -38,14 +38,14 @@ namespace Orthanc { - static const DicomTag PATIENT_IDENTIFIERS[] = + static const DicomTag PATIENT_IDENTIFIERS[] = { DICOM_TAG_PATIENT_ID, DICOM_TAG_PATIENT_NAME, DICOM_TAG_PATIENT_BIRTH_DATE }; - static const DicomTag STUDY_IDENTIFIERS[] = + static const DicomTag STUDY_IDENTIFIERS[] = { DICOM_TAG_PATIENT_ID, DICOM_TAG_PATIENT_NAME, @@ -56,12 +56,12 @@ DICOM_TAG_STUDY_DATE }; - static const DicomTag SERIES_IDENTIFIERS[] = + static const DicomTag SERIES_IDENTIFIERS[] = { DICOM_TAG_SERIES_INSTANCE_UID }; - static const DicomTag INSTANCE_IDENTIFIERS[] = + static const DicomTag INSTANCE_IDENTIFIERS[] = { DICOM_TAG_SOP_INSTANCE_UID }; @@ -90,7 +90,7 @@ } resource = children.front(); - type = GetChildResourceType(type); + type = GetChildResourceType(type); } } @@ -306,7 +306,7 @@ return false; } - + void ReconstructResource(ServerContext& context, const std::string& resource, bool reconstructFiles, @@ -314,7 +314,7 @@ ResourceType limitToLevel) { LOG(WARNING) << "Reconstructing resource " << resource; - + std::list instances; context.GetIndex().GetChildInstances(instances, resource); @@ -328,7 +328,7 @@ } else { - for (std::list::const_iterator + for (std::list::const_iterator it = instances.begin(); it != instances.end(); ++it) { std::unique_ptr dicom(context.ReadParsedDicom(*it)); @@ -337,7 +337,7 @@ // Delay the reconstruction of DICOM-as-JSON to its next access through "ServerContext" context.GetIndex().DeleteAttachment(*it, FileContentType_DicomAsJson, false /* no revision */, -1 /* dummy revision */, "" /* dummy MD5 */); - + context.GetIndex().ReconstructInstance(lock.GetContent(), false, ResourceType_Instance /* dummy */); if (reconstructFiles) @@ -355,7 +355,7 @@ } } - + bool IsValidLabel(const std::string& label) { if (label.empty()) @@ -369,7 +369,7 @@ // column of undefined length as a primary key return false; } - + for (size_t i = 0; i < label.size(); i++) { if (!(label[i] == '_' || diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerToolbox.h --- a/OrthancServer/Sources/ServerToolbox.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerToolbox.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerTranscoder.cpp --- a/OrthancServer/Sources/ServerTranscoder.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerTranscoder.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/ServerTranscoder.h --- a/OrthancServer/Sources/ServerTranscoder.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/ServerTranscoder.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/SimpleInstanceOrdering.cpp --- a/OrthancServer/Sources/SimpleInstanceOrdering.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/SimpleInstanceOrdering.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -64,7 +64,7 @@ { return indexInSeries_; } - + const FileInfo& GetFileInfo() const { return fileInfo_; @@ -75,7 +75,7 @@ const SimpleInstanceOrdering::Instance* b) { return a->GetIndexInSeries() < b->GetIndexInSeries(); - } + } SimpleInstanceOrdering::SimpleInstanceOrdering(ServerIndex& index, @@ -100,7 +100,7 @@ uint32_t indexInSeries = 0; FileInfo fileInfo; int64_t revisionNotUsed; - + if (resource.LookupMetadata(strIndexInSeries, ResourceType_Instance, MetadataType_Instance_IndexInSeries)) { SerializationToolbox::ParseUnsignedInteger32(indexInSeries, strIndexInSeries); @@ -109,14 +109,14 @@ if (resource.LookupAttachment(fileInfo, revisionNotUsed, FileContentType_Dicom)) { std::string instanceId = resource.GetIdentifier(); - + allIndexInSeries.insert(indexInSeries); instances_.push_back(new SimpleInstanceOrdering::Instance(instanceId, indexInSeries, fileInfo)); } } // if there are duplicates, the set will be smaller than the vector - hasDuplicateIndexInSeries_ = allIndexInSeries.size() != instances_.size(); + hasDuplicateIndexInSeries_ = allIndexInSeries.size() != instances_.size(); std::sort(instances_.begin(), instances_.end(), IndexInSeriesComparator); } @@ -143,7 +143,7 @@ if (hasDuplicateIndexInSeries_) { // if there are duplicates, we count the instances from 0 - return index; + return index; } else { diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/SimpleInstanceOrdering.h --- a/OrthancServer/Sources/SimpleInstanceOrdering.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/SimpleInstanceOrdering.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/SliceOrdering.cpp --- a/OrthancServer/Sources/SliceOrdering.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/SliceOrdering.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -93,7 +93,7 @@ return fabs(x) < 10.0 * std::numeric_limits::epsilon(); } - + bool SliceOrdering::ComputeNormal(Vector& normal, const DicomMap& dicom) { @@ -142,15 +142,15 @@ } } - + struct SliceOrdering::Instance : public boost::noncopyable { private: std::string instanceId_; bool hasPosition_; - Vector position_; + Vector position_; bool hasNormal_; - Vector normal_; + Vector normal_; bool hasIndexInSeries_; unsigned int indexInSeries_; unsigned int framesCount_; @@ -174,7 +174,7 @@ { SerializationToolbox::ParseUnsignedInteger(framesCount_, Toolbox::StripSpaces(frames->GetContent())); } - + std::vector tmp; hasPosition_ = TokenizeVector(tmp, instance, DICOM_TAG_IMAGE_POSITION_PATIENT, 3); @@ -189,7 +189,7 @@ hasIndexInSeries_ = false; std::string s; - + if (index.LookupMetadata(s, instanceId, ResourceType_Instance, MetadataType_Instance_IndexInSeries)) { hasIndexInSeries_ = SerializationToolbox::ParseUnsignedInteger(indexInSeries_, Toolbox::StripSpaces(s)); @@ -209,7 +209,7 @@ float ComputeRelativePosition(const Vector& normal) const { assert(HasPosition()); - return (normal[0] * position_[0] + + return (normal[0] * position_[0] + normal[1] * position_[1] + normal[2] * position_[2]); } @@ -218,7 +218,7 @@ { return hasIndexInSeries_; } - + unsigned int GetIndexInSeries() const { assert(HasIndexInSeries()); @@ -252,7 +252,7 @@ explicit PositionComparator(const Vector& normal) : normal_(normal) { } - + int operator() (const Instance* a, const Instance* b) const { @@ -265,7 +265,7 @@ const SliceOrdering::Instance* b) { return a->GetIndexInSeries() < b->GetIndexInSeries(); - } + } void SliceOrdering::ComputeNormal() @@ -292,7 +292,7 @@ instances_.push_back(new Instance(index_, *it)); } } - + bool SliceOrdering::SortUsingPositions() { @@ -360,7 +360,7 @@ } std::sort(instances_.begin(), instances_.end(), IndexInSeriesComparator); - + for (size_t i = 1; i < instances_.size(); i++) { if (instances_[i - 1]->GetIndexInSeries() == instances_[i]->GetIndexInSeries()) @@ -436,7 +436,7 @@ { result = Json::objectValue; result["Type"] = (isVolume_ ? "Volume" : "Sequence"); - + Json::Value tmp = Json::arrayValue; for (size_t i = 0; i < GetInstancesCount(); i++) { @@ -460,7 +460,7 @@ tmp2.append(GetInstanceId(i)); tmp2.append(0); tmp2.append(GetFramesCount(i)); - + slicesShort.append(tmp2); } diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/SliceOrdering.h --- a/OrthancServer/Sources/SliceOrdering.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/SliceOrdering.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -28,7 +28,7 @@ namespace Orthanc { class ServerIndex; - + class SliceOrdering { private: diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/StorageCommitmentReports.cpp --- a/OrthancServer/Sources/StorageCommitmentReports.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/StorageCommitmentReports.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -75,7 +75,7 @@ } } - + StorageCommitmentReports::Report::Status StorageCommitmentReports::Report::GetStatus() const { if (!isComplete_) @@ -104,12 +104,12 @@ static const char* const FIELD_SUCCESS = "Success"; static const char* const FIELD_FAILURES = "Failures"; - + json = Json::objectValue; json[FIELD_REMOTE_AET] = remoteAet_; bool pending; - + switch (GetStatus()) { case Status_Pending: @@ -200,12 +200,12 @@ } } - + void StorageCommitmentReports::Store(const std::string& transactionUid, Report* report) { std::unique_ptr protection(report); - + boost::mutex::scoped_lock lock(mutex_); { @@ -226,7 +226,7 @@ content_.GetSize() == maxSize_) { assert(!content_.IsEmpty()); - + Report* oldest = NULL; content_.RemoveOldest(oldest); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/StorageCommitmentReports.h --- a/OrthancServer/Sources/StorageCommitmentReports.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/StorageCommitmentReports.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -41,21 +41,21 @@ Status_Failure, Status_Pending }; - + private: struct Success { std::string sopClassUid_; std::string sopInstanceUid_; }; - + struct Failure { std::string sopClassUid_; std::string sopInstanceUid_; StorageCommitmentFailureReason reason_; }; - + bool isComplete_; std::list success_; std::list failures_; @@ -91,7 +91,7 @@ private: typedef LeastRecentlyUsedIndex Content; - + boost::mutex mutex_; Content content_; size_t maxSize_; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/Sources/main.cpp --- a/OrthancServer/Sources/main.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/Sources/main.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -98,10 +98,10 @@ const std::string& remoteAet, const std::string& calledAet, uint16_t originatorMessageId, - const std::string& originatorAet) ORTHANC_OVERRIDE + const std::string& originatorAet) ORTHANC_OVERRIDE { std::unique_ptr toStore(DicomInstanceToStore::CreateFromDcmDataset(dicom)); - + if (toStore->GetBufferSize() > 0) { toStore->SetOrigin(DicomInstanceOrigin::FromDicomProtocol @@ -129,7 +129,7 @@ { private: ServerContext& context_; - + public: explicit OrthancStorageCommitmentRequestHandler(ServerContext& context) : context_(context) @@ -145,7 +145,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + std::unique_ptr job( new StorageCommitmentScpJob(context_, transactionUid, connection)); @@ -173,7 +173,7 @@ { THROW_WITH_FILE_AND_LINE_INFO(ErrorCode_InternalError); } - + std::unique_ptr report( new StorageCommitmentReports::Report(connection.GetRemoteAet())); @@ -214,9 +214,9 @@ }; -class MyDicomServerFactory : +class MyDicomServerFactory : public IStoreRequestHandlerFactory, - public IFindRequestHandlerFactory, + public IFindRequestHandlerFactory, public IMoveRequestHandlerFactory, public IGetRequestHandlerFactory, public IStorageCommitmentRequestHandlerFactory @@ -250,7 +250,7 @@ } else { - LOG(INFO) << "Maximum " << result->GetMaxResults() + LOG(INFO) << "Maximum " << result->GetMaxResults() << " results for C-FIND queries at the Patient, Study and Series levels"; } @@ -260,7 +260,7 @@ } else { - LOG(INFO) << "Maximum " << result->GetMaxInstances() + LOG(INFO) << "Maximum " << result->GetMaxInstances() << " instances will be returned for C-FIND queries at the Instance level"; } @@ -271,17 +271,17 @@ { return new OrthancMoveRequestHandler(context_); } - + virtual IGetRequestHandler* ConstructGetRequestHandler() ORTHANC_OVERRIDE { return new OrthancGetRequestHandler(context_); } - + virtual IStorageCommitmentRequestHandler* ConstructStorageCommitmentRequestHandler() ORTHANC_OVERRIDE { return new OrthancStorageCommitmentRequestHandler(context_); } - + void Done() { @@ -367,7 +367,7 @@ << EnumerationToString(type) << " is not allowed for this modality " << "according to configuration option \"DicomModalities\""; } - + virtual bool IsAllowedRequest(const std::string& remoteIp, const std::string& remoteAet, @@ -376,7 +376,7 @@ { LOG(INFO) << "Incoming " << EnumerationToString(type) << " request from AET " << remoteAet << " on IP " << remoteIp << ", calling AET " << calledAet; - + if (type == DicomRequestType_Echo && alwaysAllowEcho_) { @@ -423,7 +423,7 @@ lock.GetConfiguration().LookupDicomModalitiesUsingAETitle(modalities, remoteAet); checkIp = lock.GetConfiguration().GetBooleanParameter("DicomCheckModalityHost"); } - + if (modalities.empty()) { LOG(WARNING) << "DICOM authorization rejected for AET " << remoteAet @@ -455,7 +455,7 @@ } else { - // If there are multiple modalities with the same AET, consider the one matching this IP + // If there are multiple modalities with the same AET, consider the one matching this IP // or check if the operation is allowed for all modalities bool allowedForAllModalities = true; @@ -522,7 +522,7 @@ { context_.GetProposedStorageTransferSyntaxes(target); } - + virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp, const std::string& remoteAet, const std::string& calledAet) ORTHANC_OVERRIDE @@ -546,7 +546,7 @@ public: MyIncomingHttpRequestFilter(ServerContext& context, - OrthancPlugins* plugins) : + OrthancPlugins* plugins) : context_(context), plugins_(plugins) { @@ -559,9 +559,9 @@ plugins_->IsValidAuthorizationToken(token)); #else return false; -#endif +#endif } - + virtual bool IsAllowed(HttpMethod method, const char* uri, const char* ip, @@ -677,7 +677,7 @@ { LOG(ERROR) << "Exception in the HTTP handler: " << exception.What(); } - } + } Json::Value message = Json::objectValue; ErrorCode errorCode = exception.GetErrorCode(); @@ -734,7 +734,7 @@ static void PrintHelp(const boost::filesystem::path& path, const boost::program_options::options_description& all) { - std::cout + std::cout << "Usage: " << SystemToolbox::PathToUtf8(path) << " [OPTION]... [CONFIGURATION]" << std::endl << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." << std::endl << std::endl @@ -752,7 +752,7 @@ << "\"--verbose --trace-dicom --logfile=dicom.log\"" << std::endl; std::cout << all; - + std::cout << std::endl << "Exit status:" << std::endl @@ -784,8 +784,8 @@ static void PrintErrorCode(ErrorCode code, const char* description) { - std::cout - << std::right << std::setw(16) + std::cout + << std::right << std::setw(16) << static_cast(code) << " " << description << std::endl; } @@ -795,9 +795,9 @@ { std::cout << SystemToolbox::PathToUtf8(path) << " " << ORTHANC_VERSION << std::endl - << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." + << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." << std::endl << std::endl - << "List of error codes that could be returned by Orthanc:" + << "List of error codes that could be returned by Orthanc:" << std::endl << std::endl; // The content of the following brackets is automatically generated @@ -944,7 +944,7 @@ LOG(WARNING) << "Loading plugin(s) from: " << path; plugins.GetManager().RegisterPlugin(path); - } + } } #endif @@ -973,7 +973,7 @@ ServerBarrierEvent event = SystemToolbox::ServerBarrier(restApi.LeaveBarrierFlag()); restart = restApi.IsResetRequestReceived(); - if (!restart && + if (!restart && event == ServerBarrierEvent_Reload) { // Handling of SIGHUP @@ -1083,14 +1083,14 @@ #else # error "Either Mongoose or Civetweb must be enabled to compile this file" #endif - + httpServer.SetMetricsRegistry(context.GetMetricsRegistry()); { OrthancConfiguration::ReaderLock lock; - + httpDescribeErrors = lock.GetConfiguration().GetBooleanParameter("HttpDescribeErrors"); - + // HTTP server httpServer.SetThreadsCount(lock.GetConfiguration().GetHttpThreadsCount()); httpServer.SetPortNumber(lock.GetConfiguration().GetHttpPort()); @@ -1098,7 +1098,7 @@ lock.GetConfiguration().GetSetOfStringsParameter(httpBindAddresses, "HttpBindAddresses"); httpServer.SetBindAddresses(httpBindAddresses); httpServer.SetRemoteAccessAllowed(lock.GetConfiguration().GetBooleanParameter("RemoteAccessAllowed")); - + lock.GetConfiguration().LookupBooleanParameter(keepAlive, "KeepAlive"); // we cannot use GetBooleanParameter because the default value depends on the HttpServer lib that is used httpServer.SetKeepAliveEnabled(keepAlive); httpServer.SetKeepAliveTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("KeepAliveTimeout")); @@ -1154,7 +1154,7 @@ // remote access without having explicitly disabled user // authentication. LOG(WARNING) << "Remote access is allowed but \"AuthenticationEnabled\" is not in the configuration, " - << "automatically enabling HTTP authentication for security"; + << "automatically enabling HTTP authentication for security"; httpServer.SetAuthenticationEnabled(true); } else @@ -1199,14 +1199,14 @@ << "if you cannot access Orthanc as expected"; } } - + if (lock.GetConfiguration().GetBooleanParameter("SslEnabled")) { boost::filesystem::path certificate = lock.GetConfiguration().InterpretStringParameterAsPath( lock.GetConfiguration().GetStringParameter("SslCertificate")); httpServer.SetSslEnabled(true); httpServer.SetSslCertificate(certificate.c_str()); - + // Default to TLS 1.2+1.3 as SSL minimum // See https://github.com/civetweb/civetweb/blob/master/docs/UserManual.md "ssl_protocol_version" for mapping unsigned int minimumVersion = lock.GetConfiguration().GetUnsignedIntegerParameter("SslMinimumProtocolVersion"); @@ -1223,7 +1223,7 @@ } else { - // Defaults to FIPS 140-2 ciphers + // Defaults to FIPS 140-2 ciphers CLOG(INFO, HTTP) << "No configuration option \"" << SSL_CIPHERS_ACCEPTED << "\", will accept the FIPS 140-2 ciphers"; @@ -1240,7 +1240,7 @@ ciphers.push_back("AES256-SHA"); ciphers.push_back("AES128-SHA"); } - + httpServer.SetSslCiphers(ciphers); } else @@ -1290,7 +1290,7 @@ { const bool allowDelete = lock.GetConfiguration().GetBooleanParameter("WebDavDeleteAllowed"); const bool allowUpload = lock.GetConfiguration().GetBooleanParameter("WebDavUploadAllowed"); - + UriComponents root; root.push_back("webdav"); httpServer.Register(root, new OrthancWebDav(context, allowDelete, allowUpload)); @@ -1305,20 +1305,20 @@ #endif MyHttpExceptionFormatter exceptionFormatter(httpDescribeErrors, plugins); - + httpServer.SetIncomingHttpRequestFilter(httpFilter); httpServer.SetHttpExceptionFormatter(exceptionFormatter); httpServer.Register(context.GetHttpHandler()); if (httpServer.GetPortNumber() < 1024) { - LOG(WARNING) << "The HTTP port is privileged (" + LOG(WARNING) << "The HTTP port is privileged (" << httpServer.GetPortNumber() << " is below 1024), " << "make sure you run Orthanc as root/administrator"; } httpServer.Start(); - + MetricsLoggingListener loggingMetrics(context.GetMetricsRegistry()); Logging::AddLoggingListener(&loggingMetrics); @@ -1355,8 +1355,8 @@ MyDicomServerFactory serverFactory(context); OrthancApplicationEntityFilter dicomFilter(context); ModalitiesFromConfiguration modalities; - - // Setup the DICOM server + + // Setup the DICOM server DicomServer dicomServer("DICOM-SERVER", "DICOM"); dicomServer.SetMetricsRegistry(context.GetMetricsRegistry()); dicomServer.SetRemoteModalities(modalities); @@ -1392,7 +1392,7 @@ } dicomServer.SetMinimumTlsVersion( lock.GetConfiguration().GetUnsignedIntegerParameter(KEY_DICOM_TLS_MINIMUM_PROTOCOL_VERSION)); - + std::set acceptedCiphers; lock.GetConfiguration().GetSetOfStringsParameter(acceptedCiphers, KEY_DICOM_TLS_ACCEPTED_CIPHERS); dicomServer.SetAcceptedCiphers(acceptedCiphers); @@ -1429,13 +1429,13 @@ if (dicomServer.GetPortNumber() < 1024) { - LOG(WARNING) << "The DICOM port is privileged (" + LOG(WARNING) << "The DICOM port is privileged (" << dicomServer.GetPortNumber() << " is below 1024), " << "make sure you run Orthanc as root/administrator"; } dicomServer.Start(); - LOG(WARNING) << "DICOM server listening with AET " << dicomServer.GetApplicationEntityTitle() + LOG(WARNING) << "DICOM server listening with AET " << dicomServer.GetApplicationEntityTitle() << " on port: " << dicomServer.GetPortNumber(); bool restart = false; @@ -1480,7 +1480,7 @@ context.GetHttpHandler().Register(*plugins, false); } #endif - + // Secondly, apply the "static resources" layer #if ORTHANC_STANDALONE == 1 EmbeddedResourceHttpHandler staticResources("/app", ServerResources::ORTHANC_EXPLORER); @@ -1527,7 +1527,7 @@ LOG(WARNING) << "Starting the upgrade of the database schema"; LOG(WARNING) << "Current database version: " << currentVersion; LOG(WARNING) << "Database version expected by Orthanc: " << ORTHANC_DATABASE_VERSION; - + if (currentVersion == ORTHANC_DATABASE_VERSION) { LOG(WARNING) << "No upgrade is needed, start Orthanc without the \"--upgrade\" argument"; @@ -1555,7 +1555,7 @@ << "https://orthanc.uclouvain.be/book/users/replication.html"; throw; } - + // Sanity check currentVersion = database.GetDatabaseVersion(); if (ORTHANC_DATABASE_VERSION != currentVersion) @@ -1652,9 +1652,9 @@ // The value "0" below makes the class HttpClient use its default // value (DEFAULT_HTTP_TIMEOUT = 60 seconds in Orthanc 1.5.7) HttpClient::SetDefaultTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("HttpTimeout")); - + HttpClient::SetDefaultProxy(lock.GetConfiguration().GetStringParameter("HttpProxy")); - + DicomAssociationParameters::SetDefaultTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomScuTimeout")); maxCompletedJobs = lock.GetConfiguration().GetUnsignedIntegerParameter("JobsHistorySize"); @@ -1666,7 +1666,7 @@ // New option in Orthanc 1.12.5 readOnly = lock.GetConfiguration().GetBooleanParameter(ORTHANC_CONFIG_READ_ONLY); - + // New option in Orthanc 1.12.6 maxDcmtkConcurrentTranscoders = lock.GetConfiguration().GetUnsignedIntegerParameter(KEY_MAXIMUM_CONCURRENT_DCMTK_TRANSCODERS); if (maxDcmtkConcurrentTranscoders == 0) @@ -1698,7 +1698,7 @@ #if ORTHANC_ENABLE_PLUGINS == 1 transcoder->SetPlugins(*plugins); #endif - + ServerContext context(database, storageArea, transcoder.release(), false /* not running unit tests */, maxCompletedJobs, readOnly); { @@ -1827,7 +1827,7 @@ { OrthancConfiguration::ReaderLock lock; - + if (lock.GetConfiguration().HasCheckRevisions()) { if (database.GetDatabaseCapabilities().HasRevisionsSupport()) @@ -1840,7 +1840,7 @@ LOG(WARNING) << "The custom database back-end has *no* support for revisions of metadata and attachments, " << "but configuration option \"" << ORTHANC_CONFIG_CHECK_REVISIONS << "\" is set to \"true\""; } - + if (!lock.GetConfiguration().HasStoreMD5ForAttachments()) { throw OrthancException( @@ -1884,7 +1884,7 @@ OrthancConfiguration::ReaderLock lock; databaseServerIdentifier = lock.GetConfiguration().GetDatabaseServerIdentifier(); } - + OrthancPlugins plugins(databaseServerIdentifier); plugins.SetCommandLineArguments(arguments); LoadPlugins(plugins); @@ -2476,16 +2476,16 @@ case Endianness_Little: s += "little endian"; break; - + case Endianness_Big: s += "big endian"; break; - + default: s += "unsupported endianness"; break; } - + LOG(INFO) << s; } @@ -2526,12 +2526,12 @@ status = -1; #endif } - catch (const std::exception& e) + catch (const std::exception& e) { LOG(ERROR) << "Uncaught exception, stopping now: [" << e.what() << "]"; status = -1; } - catch (const std::string& s) + catch (const std::string& s) { LOG(ERROR) << "Uncaught exception, stopping now: [" << s << "]"; status = -1; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp --- a/OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -34,7 +34,7 @@ TEST(DatabaseLookup, SingleConstraint) { { - ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal, + ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal, "HEL*LO", true, true), OrthancException); ASSERT_THROW(DicomTagConstraint tag(DICOM_TAG_PATIENT_NAME, ConstraintType_Equal, "HEL?LO", true, true), OrthancException); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/LuaServerTests.cpp --- a/OrthancServer/UnitTestsSources/LuaServerTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/LuaServerTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -178,7 +178,7 @@ lua.Execute("table.insert(modality, 'ORTHANC')"); lua.Execute("table.insert(modality, 'localhost')"); lua.Execute("table.insert(modality, 4242)"); - + lua.Execute(s, "print(HttpPost(\"http://localhost:8042/tools/execute-script\", \"print('hello world')\"))"); ASSERT_EQ("hello world", Orthanc::Toolbox::StripSpaces(s)); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/PluginsTests.cpp --- a/OrthancServer/UnitTestsSources/PluginsTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/PluginsTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -61,7 +61,7 @@ /** * On the Docker image "debian:buster-slim", the "libSegFault.so" * library does exist, but does not contain any public symbol: - * + * * $ sudo docker run -i -t --rm --entrypoint=bash debian:buster-slim * # apt-get update && apt-get install -y binutils * # nm -C /lib/x86_64-linux-gnu/libSegFault.so @@ -72,10 +72,10 @@ * spread. Reference: * https://groups.google.com/d/msg/orthanc-users/v-QFzpOzgJY/4Hm5NgxKBwAJ **/ - + //ASSERT_TRUE(l.GetFunction("_init") != NULL); //ASSERT_TRUE(l.HasFunction("_init")); - + #elif defined(__linux__) || defined(__FreeBSD_kernel__) /** * Since Orthanc 1.10.0, we test the "libdl.so.2" instead of the @@ -97,7 +97,7 @@ catch (OrthancException&) // NOLINT(bugprone-empty-catch) { } - + try { SharedLibrary l("libdl.so"); // Fallback for backward compat @@ -110,7 +110,7 @@ catch (OrthancException&) // NOLINT(bugprone-empty-catch) { } - + try { SharedLibrary l("libmemusage.so"); // Try another common library @@ -123,7 +123,7 @@ catch (OrthancException&) // NOLINT(bugprone-empty-catch) { } - + ASSERT_TRUE(0); #elif defined(__FreeBSD__) || defined(__OpenBSD__) diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.cpp --- a/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.h --- a/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.h Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.h Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/ServerConfigTests.cpp --- a/OrthancServer/UnitTestsSources/ServerConfigTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/ServerConfigTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/ServerIndexTests.cpp --- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -72,7 +72,7 @@ const std::string fileUuid = info.GetUuid(); deletedFiles_.push_back(fileUuid); LOG(INFO) << "A file must be removed: " << fileUuid; - } + } virtual void SignalResourceDeleted(ResourceType type, const std::string& publicId) ORTHANC_OVERRIDE @@ -108,7 +108,7 @@ { transaction_->Commit(0); transaction_.reset(); - + index_->Close(); index_.reset(NULL); listener_.reset(NULL); @@ -155,7 +155,7 @@ transaction_->GetChildren(j, id); ASSERT_EQ(2u, j.size()); ASSERT_TRUE((expected1 == j.front() && expected2 == j.back()) || - (expected1 == j.back() && expected2 == j.front())); + (expected1 == j.back() && expected2 == j.front())); } void DoLookupIdentifier(std::list& result, @@ -183,7 +183,7 @@ { result.push_back(response.GetResourceByIndex(i).GetIdentifier()); } - } + } void DoLookupIdentifier2(std::list& result, ResourceType level, @@ -197,7 +197,7 @@ result.clear(); std::vector values1, values2; - + values1.push_back(value1); std::unique_ptr lookup1(new DatabaseDicomTagConstraint(level, tag, true, type1, values1, true, true)); @@ -366,12 +366,12 @@ std::list l; transaction_->GetChildrenPublicId(l, a[0]); ASSERT_EQ(1u, l.size()); ASSERT_EQ("b", l.front()); transaction_->GetChildrenPublicId(l, a[1]); ASSERT_EQ(1u, l.size()); ASSERT_EQ("c", l.front()); - transaction_->GetChildrenPublicId(l, a[3]); ASSERT_EQ(0u, l.size()); - transaction_->GetChildrenPublicId(l, a[4]); ASSERT_EQ(0u, l.size()); - transaction_->GetChildrenPublicId(l, a[5]); ASSERT_EQ(0u, l.size()); + transaction_->GetChildrenPublicId(l, a[3]); ASSERT_EQ(0u, l.size()); + transaction_->GetChildrenPublicId(l, a[4]); ASSERT_EQ(0u, l.size()); + transaction_->GetChildrenPublicId(l, a[5]); ASSERT_EQ(0u, l.size()); transaction_->GetChildrenPublicId(l, a[6]); ASSERT_EQ(1u, l.size()); ASSERT_EQ("f", l.front()); - transaction_->GetChildrenPublicId(l, a[2]); ASSERT_EQ(2u, l.size()); + transaction_->GetChildrenPublicId(l, a[2]); ASSERT_EQ(2u, l.size()); if (l.front() == "d") { ASSERT_EQ("e", l.back()); @@ -397,9 +397,9 @@ FileInfo attachment3("world", FileContentType_Dicom, 44, "md5_3"); attachment3.SetCustomData("world"); transaction_->AddAttachment(a[6], attachment3, 44); - + transaction_->SetMetadata(a[4], MetadataType_RemoteAet, "PINNACLE", 42); - + transaction_->GetAllMetadata(md, a[4]); ASSERT_EQ(1u, md.size()); ASSERT_EQ("PINNACLE", md[MetadataType_RemoteAet]); @@ -494,10 +494,10 @@ transaction_->DeleteResource(a[0]); ASSERT_EQ(5u, listener_->deletedResources_.size()); ASSERT_EQ(2u, listener_->deletedFiles_.size()); - ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), + ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), listener_->deletedFiles_.end(), "my json file") == listener_->deletedFiles_.end()); - ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), + ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), listener_->deletedFiles_.end(), "my dicom file") == listener_->deletedFiles_.end()); @@ -522,7 +522,7 @@ ASSERT_EQ("1", tmp); ASSERT_EQ(3u, listener_->deletedFiles_.size()); - ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), + ASSERT_FALSE(std::find(listener_->deletedFiles_.begin(), listener_->deletedFiles_.end(), "world") == listener_->deletedFiles_.end()); } @@ -586,7 +586,7 @@ { std::string p = "Patient " + boost::lexical_cast(i); patients.push_back(transaction_->CreateResource(p, ResourceType_Patient)); - transaction_->AddAttachment(patients[i], FileInfo(p, FileContentType_Dicom, i + 10, + transaction_->AddAttachment(patients[i], FileInfo(p, FileContentType_Dicom, i + 10, "md5-" + boost::lexical_cast(i)), 42); ASSERT_FALSE(transaction_->IsProtectedPatient(patients[i])); } @@ -819,7 +819,7 @@ index.SetMaximumStorageSize(10); uint64_t diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances; - index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_EQ(0u, countPatients); @@ -857,7 +857,7 @@ hasTransferSyntax, transferSyntax, true /* has pixel data */, 42 /* pixel data offset */, ValueRepresentation_PersonName /* pixel data VR */, false)); } - + ASSERT_EQ(8u, instanceMetadata.size()); ASSERT_TRUE(instanceMetadata.find(MetadataType_RemoteAet) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_ReceptionDate) != instanceMetadata.end()); @@ -884,7 +884,7 @@ ids.push_back(hasher.HashInstance()); } - index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_EQ(10u, countPatients); ASSERT_EQ(0u, diskSize); @@ -896,7 +896,7 @@ index.AddAttachment(revision, info, ids[i], false /* no previous revision */, -1, ""); ASSERT_EQ(0, revision); - index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + index.GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_GE(10u, diskSize); } @@ -925,7 +925,7 @@ for (unsigned int i = 0; i < 3; i++) { OverwriteInstancesMode overwriteMode; - if (i == 0) + if (i == 0) overwriteMode = OverwriteInstancesMode_Always; else if (i == 1) overwriteMode = OverwriteInstancesMode_Never; @@ -952,7 +952,7 @@ context.SetOverwriteInstances(overwriteMode); uint64_t diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances; - context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_EQ(0u, countInstances); @@ -964,9 +964,9 @@ // Add a pixel data so as to have one "FileContentType_DicomUntilPixelData" // (because of "context.SetCompressionEnabled(true)") dicom.EmbedImage(image); - + DicomInstanceHasher hasher(instance); - + std::unique_ptr toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom)); toStore->SetOrigin(DicomInstanceOrigin::FromPlugins()); ASSERT_EQ(id, hasher.HashInstance()); @@ -991,7 +991,7 @@ ASSERT_TRUE(context.GetIndex().LookupAttachment(pixelData1, revision, ResourceType_Instance, id, FileContentType_DicomUntilPixelData)); ASSERT_EQ(0, revision); - context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_EQ(1u, countInstances); ASSERT_EQ(dicom1.GetCompressedSize() + pixelData1.GetCompressedSize(), diskSize); @@ -1000,7 +1000,7 @@ Json::Value tmp; context.ReadDicomAsJson(tmp, id); ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); - + { std::unique_ptr dicom(context.ReadParsedDicom(id)); DicomDataSource::Dicom::Lock lock(*dicom); @@ -1042,7 +1042,7 @@ ASSERT_TRUE(context.GetIndex().LookupAttachment(pixelData2, revision, ResourceType_Instance, id, FileContentType_DicomUntilPixelData)); ASSERT_EQ(0, revision); - context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, + context.GetIndex().GetGlobalStatistics(diskSize, uncompressedSize, countPatients, countStudies, countSeries, countInstances); ASSERT_EQ(1u, countInstances); ASSERT_EQ(dicom2.GetCompressedSize() + pixelData2.GetCompressedSize(), diskSize); @@ -1054,10 +1054,10 @@ ASSERT_NE(pixelData1.GetUuid(), pixelData2.GetUuid()); ASSERT_NE(dicom1.GetUncompressedSize(), dicom2.GetUncompressedSize()); ASSERT_NE(pixelData1.GetUncompressedSize(), pixelData2.GetUncompressedSize()); - + context.ReadDicomAsJson(tmp, id); ASSERT_EQ("overwritten", tmp["0010,0010"]["Value"].asString()); - + { std::unique_ptr dicom(context.ReadParsedDicom(id)); DicomDataSource::Dicom::Lock lock(*dicom); @@ -1076,7 +1076,7 @@ context.ReadDicomAsJson(tmp, id); ASSERT_EQ("name", tmp["0010,0010"]["Value"].asString()); - + { std::unique_ptr dicom(context.ReadParsedDicom(id)); DicomDataSource::Dicom::Lock lock(*dicom); @@ -1102,7 +1102,7 @@ for (unsigned int i = 0; i < 2; i++) { const bool compression = (i == 0); - + PluginStorageAreaAdapter storage(new MemoryStorageArea); SQLiteDatabaseWrapper db; // The SQLite DB is in memory db.Open(); @@ -1115,7 +1115,7 @@ const bool withPixelData = (j == 0); ParsedDicomFile dicom(true); - + if (withPixelData) { dicom.EmbedImage(image); @@ -1136,7 +1136,7 @@ context.GetIndex().ListAvailableAttachments(attachments, id, ResourceType_Instance); ASSERT_TRUE(attachments.find(FileContentType_Dicom) != attachments.end()); - + if (compression && withPixelData) { @@ -1152,7 +1152,7 @@ int64_t revision; bool found = context.GetIndex().LookupMetadata(s, revision, id, ResourceType_Instance, MetadataType_Instance_PixelDataOffset); - + if (withPixelData) { ASSERT_TRUE(found); @@ -1162,7 +1162,7 @@ } else { - ASSERT_FALSE(found); + ASSERT_FALSE(found); } } } @@ -1372,14 +1372,14 @@ std::string s; uint64_t valueId0, valueId1, valueId2, valueId3; - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 100)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 100)); ASSERT_EQ("c", s); ASSERT_EQ(3u, op.GetQueueSize("test")); // the reserved values are still counted ! - - ASSERT_TRUE(op.ReserveQueueValue(s, valueId1, "test", QueueOrigin_Back, 100)); + + ASSERT_TRUE(op.ReserveQueueValue(s, valueId1, "test", QueueOrigin_Back, 100)); ASSERT_EQ("b", s); - - ASSERT_TRUE(op.ReserveQueueValue(s, valueId2, "test", QueueOrigin_Back, 100)); + + ASSERT_TRUE(op.ReserveQueueValue(s, valueId2, "test", QueueOrigin_Back, 100)); ASSERT_EQ("a", s); ASSERT_EQ(3u, op.GetQueueSize("test")); @@ -1399,14 +1399,14 @@ op.EnqueueValue("test", "h"); // reserve 2 values front and back and acknowledge only "e" & "f" - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); ASSERT_EQ("d", s); - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); ASSERT_EQ("e", s); op.AcknowledgeQueueValue("test", valueId0); - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); ASSERT_EQ("h", s); - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); ASSERT_EQ("g", s); op.AcknowledgeQueueValue("test", valueId0); @@ -1417,13 +1417,13 @@ SystemToolbox::USleep(2000000); // the granularity being the second, we might have to wait up to 2 seconds // "d" and "h" remain - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Front, 1)); ASSERT_EQ("d", s); - ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); + ASSERT_TRUE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); ASSERT_EQ("h", s); // the queue is empty at this point since "f" has been reserved already - ASSERT_FALSE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); + ASSERT_FALSE(op.ReserveQueueValue(s, valueId0, "test", QueueOrigin_Back, 1)); } db.Close(); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/ServerJobsTests.cpp --- a/OrthancServer/UnitTestsSources/ServerJobsTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/ServerJobsTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -86,7 +86,7 @@ virtual void Reset() ORTHANC_OVERRIDE { } - + virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE { if (fails_) @@ -194,7 +194,7 @@ trailingStepDone_(false) { } - + DummyInstancesJob(const Json::Value& value) : SetOfInstancesJob(value) { @@ -212,7 +212,7 @@ { return trailingStepDone_; } - + virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE { } @@ -258,7 +258,7 @@ } }; - + class DynamicInteger : public IDynamicObject { private: @@ -266,7 +266,7 @@ std::set& target_; public: - DynamicInteger(int value, std::set& target) : + DynamicInteger(int value, std::set& target) : value_(value), target_(target) { } @@ -333,7 +333,7 @@ SetOfInstancesJob& job) { Json::Value a = 42; - + if (!job.Serialize(a)) { return false; @@ -342,10 +342,10 @@ { std::unique_ptr unserialized (dynamic_cast(unserializer.UnserializeJob(a))); - + Json::Value b = 43; if (unserialized->Serialize(b)) - { + { return (CheckSameJson(a, b) && job.HasTrailingStep() == unserialized->HasTrailingStep() && job.GetPosition() == unserialized->GetPosition() && @@ -364,7 +364,7 @@ ThreadedSetOfInstancesJob& job) { Json::Value a = 42; - + if (!job.Serialize(a)) { return false; @@ -373,10 +373,10 @@ { std::unique_ptr unserialized (dynamic_cast(unserializer.UnserializeJob(a))); - + Json::Value b = 43; if (unserialized->Serialize(b)) - { + { return (CheckSameJson(a, b) && job.GetCurrentStep() == unserialized->GetCurrentStep() && job.GetInstancesCount() == unserialized->GetInstancesCount() ); @@ -393,9 +393,9 @@ { Json::Value a = 42; operation.Serialize(a); - + std::unique_ptr unserialized(unserializer.UnserializeOperation(a)); - + Json::Value b = 43; unserialized->Serialize(b); @@ -408,9 +408,9 @@ { Json::Value a = 42; value.Serialize(a); - + std::unique_ptr unserialized(unserializer.UnserializeValue(a)); - + Json::Value b = 43; unserialized->Serialize(b); @@ -419,7 +419,7 @@ TEST(JobsSerialization, GenericOperations) -{ +{ DummyUnserializer unserializer; Json::Value s; @@ -446,7 +446,7 @@ TEST(JobsSerialization, DicomInstanceOrigin) -{ +{ Json::Value s; std::string t; @@ -577,7 +577,7 @@ db_.Close(); } - ServerContext& GetContext() + ServerContext& GetContext() { return *context_; } @@ -605,7 +605,7 @@ Json::Value s; OrthancJobUnserializer unserializer(GetContext()); - + { DicomInstanceOperationValue instance(GetContext(), id); @@ -635,10 +635,10 @@ ASSERT_TRUE(CreateInstance(id)); Json::Value s; - OrthancJobUnserializer unserializer(GetContext()); + OrthancJobUnserializer unserializer(GetContext()); // DeleteResourceOperation - + { DeleteResourceOperation operation(GetContext()); @@ -684,7 +684,7 @@ { TimeoutDicomConnectionManager luaManager; - + { RemoteModalityParameters modality; modality.SetApplicationEntityTitle("REMOTE"); @@ -739,7 +739,7 @@ { std::unique_ptr modification(new DicomModification); modification->SetupAnonymization(DicomVersion_2008); - + ModifyInstanceOperation operation(GetContext(), RequestOrigin_Lua, modification.release()); ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); @@ -757,7 +757,7 @@ { std::unique_ptr modification(new DicomModification); modification->SetupAnonymization(DicomVersion_2023b); - + ModifyInstanceOperation operation(GetContext(), RequestOrigin_Lua, modification.release()); ASSERT_TRUE(CheckIdempotentSerialization(unserializer, operation)); @@ -795,7 +795,7 @@ // DicomModalityStoreJob - OrthancJobUnserializer unserializer(GetContext()); + OrthancJobUnserializer unserializer(GetContext()); { RemoteModalityParameters modality; @@ -838,7 +838,7 @@ OrthancPeerStoreJob job(GetContext()); job.SetPeer(peer); - + ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); ASSERT_TRUE(job.Serialize(s)); } @@ -860,7 +860,7 @@ OrthancPeerStoreJob job(GetContext()); ASSERT_THROW(job.SetTranscode("nope"), OrthancException); job.SetTranscode("1.2.840.10008.1.2.4.50"); - + ASSERT_TRUE(CheckIdempotentSetOfInstances(unserializer, job)); ASSERT_TRUE(job.Serialize(s)); } @@ -918,7 +918,7 @@ ASSERT_TRUE(s.isMember("IsSingleResource")); s.removeMember("OutputLevel"); s.removeMember("IsSingleResource"); - + std::unique_ptr job; job.reset(unserializer.UnserializeJob(s)); @@ -971,7 +971,7 @@ std::set instances; tmp.GetInstances(instances); - + ASSERT_EQ(2u, instances.size()); ASSERT_TRUE(instances.find("toto") != instances.end()); ASSERT_TRUE(instances.find("tutu") != instances.end()); @@ -1055,7 +1055,7 @@ job.Remove(DICOM_TAG_PATIENT_BIRTH_DATE); ASSERT_THROW(job.Replace(DICOM_TAG_SERIES_DESCRIPTION, "nope"), OrthancException); ASSERT_THROW(job.Remove(DICOM_TAG_SERIES_DESCRIPTION), OrthancException); - + ASSERT_TRUE(job.GetTargetStudy().empty()); a = job.GetTargetStudyUid(); ASSERT_TRUE(job.LookupTargetSeriesUid(b, series)); @@ -1116,7 +1116,7 @@ ASSERT_THROW(job.AddSourceStudy("nope"), OrthancException); ASSERT_THROW(job.AddSource("nope"), OrthancException); job.SetOrigin(DicomInstanceOrigin::FromLua()); - + ASSERT_EQ(job.GetTargetStudy(), study); job.AddTrailingStep(); @@ -1189,12 +1189,12 @@ ASSERT_EQ("MY_HOST", p.GetRemoteModality().GetHost()); ASSERT_EQ(43u, p.GetTimeout()); } - + { DicomModalityStoreJob job(GetContext()); job.Serialize(v); } - + { OrthancJobUnserializer unserializer(GetContext()); std::unique_ptr job( @@ -1210,7 +1210,7 @@ ASSERT_THROW(job->GetMoveOriginatorId(), OrthancException); ASSERT_FALSE(job->HasStorageCommitment()); } - + { RemoteModalityParameters r; r.SetApplicationEntityTitle("HELLO"); @@ -1225,7 +1225,7 @@ job.EnableStorageCommitment(true); job.Serialize(v); } - + { OrthancJobUnserializer unserializer(GetContext()); std::unique_ptr job( @@ -1241,12 +1241,12 @@ ASSERT_EQ(100, job->GetMoveOriginatorId()); ASSERT_TRUE(job->HasStorageCommitment()); } - + { DicomMoveScuJob job(GetContext()); job.Serialize(v); } - + { OrthancJobUnserializer unserializer(GetContext()); std::unique_ptr job( @@ -1259,7 +1259,7 @@ ASSERT_EQ(DicomAssociationParameters::GetDefaultTimeout(), job->GetParameters().GetTimeout()); ASSERT_EQ(DicomToJsonFormat_Short, job->GetQueryFormat()); } - + { RemoteModalityParameters r; r.SetApplicationEntityTitle("HELLO"); @@ -1274,7 +1274,7 @@ job.Serialize(v); } - + { OrthancJobUnserializer unserializer(GetContext()); std::unique_ptr job( @@ -1303,12 +1303,12 @@ Json::Value query = Json::objectValue; query["0010,0020"] = "456"; query["0008,0052"] = "STUDY"; - + Json::Value remote = Json::objectValue; remote["AET"] = "REMOTE"; remote["Host"] = "192.168.1.1"; remote["Port"] = 4242; - + Json::Value s = Json::objectValue; s["Permissive"] = true; s["Position"] = 1; diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/UnitTestsMain.cpp --- a/OrthancServer/UnitTestsSources/UnitTestsMain.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/UnitTestsMain.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -242,8 +242,8 @@ ASSERT_TRUE(dataset.insert(sequence.release(), false, false).good()); } - - + + // Check re-encoding DcmElement* element = NULL; ASSERT_TRUE(dataset.findAndGetElement(DCM_StudyDescription, element).good() && @@ -264,16 +264,16 @@ Json::Value dicomAsJson; OrthancConfiguration::DefaultDicomDatasetToJson(dicomAsJson, toStore->GetParsedDicomFile()); - + { // without parsing sequences DicomMap m; m.FromDicomAsJson(dicomAsJson); ASSERT_EQ("ISO_IR 100", m.GetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET).GetContent()); - + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).IsBinary()); ASSERT_EQ("Hello", m.GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); - + ASSERT_FALSE(m.GetValue(DICOM_TAG_STUDY_DESCRIPTION).IsBinary()); ASSERT_EQ(utf8, m.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent()); @@ -298,8 +298,8 @@ DicomArray a(m); ASSERT_EQ(6u, a.GetSize()); - - //dicom.SaveToFile("/tmp/test.dcm"); + + //dicom.SaveToFile("/tmp/test.dcm"); //std::cout << toStore.GetJson() << std::endl; //a.Print(stdout); } @@ -341,7 +341,7 @@ a.append(b); } } - + TEST(FromDcmtkBridge, FromJson) { std::unique_ptr element; @@ -415,7 +415,7 @@ DicomToJsonFlags_Default, 0, Encoding_Ascii, false, ignoreTagLength, 0); ASSERT_EQ(Json::arrayValue, b["0008,1110"].type()); ASSERT_EQ(2u, b["0008,1110"].size()); - + Json::Value::ArrayIndex i = (b["0008,1110"][0]["0010,0010"].asString() == "Hello") ? 0 : 1; ASSERT_EQ(3u, b["0008,1110"][i].size()); diff -r bb9046c96483 -r 4ba287b00973 OrthancServer/UnitTestsSources/VersionsTests.cpp --- a/OrthancServer/UnitTestsSources/VersionsTests.cpp Tue Aug 18 12:13:46 2026 +0200 +++ b/OrthancServer/UnitTestsSources/VersionsTests.cpp Wed Aug 19 14:11:33 2026 +0200 @@ -10,7 +10,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -80,7 +80,7 @@ // http://www.sqlite.org/capi3ref.html#sqlite3_libversion EXPECT_EQ(sqlite3_libversion_number(), SQLITE_VERSION_NUMBER); EXPECT_STREQ(sqlite3_libversion(), SQLITE_VERSION); - + /** * On Orthanc > 1.5.8, we comment out the following test, that is * too strict for some GNU/Linux distributions to apply their own @@ -159,7 +159,7 @@ TEST(Versions, LibIconvStatic) { static const int major = 1; - static const int minor = 15; + static const int minor = 15; ASSERT_EQ((major << 8) + minor, _LIBICONV_VERSION); } #endif