changeset 7079:dcf1dc9e455a streaming

cleanup because ABI compatibility cannot be preserved across Orthanc framework versions
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 Aug 2026 14:38:58 +0200
parents 000558ca57ae
children 2663f94c5fc3
files OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py OrthancFramework/Resources/Graveyard/CheckOrthancFrameworkSymbols.py OrthancFramework/Sources/Compatibility.h OrthancFramework/Sources/DicomFormat/DicomTag.cpp OrthancFramework/Sources/DicomFormat/DicomTag.h OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp OrthancFramework/Sources/FileStorage/FilesystemStorage.h OrthancFramework/Sources/Images/ImageAccessor.cpp OrthancFramework/Sources/Images/ImageAccessor.h OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h OrthancServer/CMakeLists.txt OrthancServer/Sources/ServerTranscoder.cpp OrthancServer/UnitTestsSources/SizeOfTests.cpp OrthancServer/UnitTestsSources/SizeOfTests.impl.h
diffstat 23 files changed, 359 insertions(+), 907 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py	Wed Aug 12 13:14:11 2026 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-#!/usr/bin/env python
-
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-##
-## This maintenance script detects all the public methods in the
-## Orthanc framework that come with an inlined implementation in the
-## header file. Such methods can break the ABI of the shared library,
-## as the actual implementation might change over versions.
-##
-
-
-# Ubuntu 20.04:
-# sudo apt-get install python-clang-6.0
-# ./ParseWebAssemblyExports.py --libclang=libclang-6.0.so.1 ./Test.cpp
-
-# Ubuntu 18.04:
-# sudo apt-get install python-clang-4.0
-# ./ParseWebAssemblyExports.py --libclang=libclang-4.0.so.1 ./Test.cpp
-
-# Ubuntu 14.04:
-# ./ParseWebAssemblyExports.py --libclang=libclang-3.6.so.1 ./Test.cpp
-
-
-import os
-import sys
-import clang.cindex
-import argparse
-
-##
-## Parse the command-line arguments
-##
-
-parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.')
-parser.add_argument('--libclang',
-                    default = '',
-                    help = 'manually provides the path to the libclang shared library')
-parser.add_argument('--target-cpp-size',
-                    default = '',
-                    help = 'where to store C++ source to display the size of each public class')
-
-args = parser.parse_args()
-
-
-if len(args.libclang) != 0:
-    clang.cindex.Config.set_library_file(args.libclang)
-
-index = clang.cindex.Index.create()
-
-
-ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
-SOURCES = []
-
-for root, dirs, files in os.walk(os.path.join(ROOT, '..', 'Sources')):
-    for name in files:
-        if (os.path.splitext(name)[1] == '.h' and
-            not name.endswith('.impl.h')):
-            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',
-    '-DORTHANC_BUILDING_FRAMEWORK_LIBRARY=1',
-    '-DORTHANC_BUILD_UNIT_TESTS=0',
-    '-DORTHANC_ENABLE_BASE64=1',
-    '-DORTHANC_ENABLE_CIVETWEB=1',
-    '-DORTHANC_ENABLE_CURL=1',
-    '-DORTHANC_ENABLE_DCMTK=1',
-    '-DORTHANC_ENABLE_DCMTK_JPEG=1',
-    '-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=1',
-    '-DORTHANC_ENABLE_DCMTK_NETWORKING=1',
-    '-DORTHANC_ENABLE_DCMTK_TRANSCODING=1',
-    '-DORTHANC_ENABLE_JPEG=1',
-    '-DORTHANC_ENABLE_LOCALE=1',
-    '-DORTHANC_ENABLE_LOGGING=1',
-    '-DORTHANC_ENABLE_LOGGING_STDIO=0',
-    '-DORTHANC_ENABLE_LUA=1',
-    '-DORTHANC_ENABLE_MD5=1',
-    '-DORTHANC_ENABLE_MONGOOSE=1',
-    '-DORTHANC_ENABLE_PKCS11=1',
-    '-DORTHANC_ENABLE_PNG=1',
-    '-DORTHANC_ENABLE_PUGIXML=1',
-    '-DORTHANC_ENABLE_SQLITE=1',
-    '-DORTHANC_ENABLE_SSL=1',
-    '-DORTHANC_ENABLE_ZLIB=1',
-    '-DORTHANC_SANDBOXED=0',
-    '-DORTHANC_SQLITE_STANDALONE=0',
-    '-DORTHANC_SQLITE_VERSION=3027001',
-    '-I/usr/include/jsoncpp',  # On Ubuntu 18.04
-    '-I/usr/include/lua5.3',   # On Ubuntu 18.04
-])
-
-
-if len(tu.diagnostics) != 0:
-    for d in tu.diagnostics:
-        print('  ** %s' % d)
-    print('')
-    raise Exception('Error')
-
-
-
-FILES = []
-COUNT = 0
-ALL_TYPES = []
-
-def ReportProblem(message, fqn, cursor):
-    global FILES, COUNT
-    FILES.append(os.path.normpath(str(cursor.location.file)))
-    COUNT += 1
-
-    print('%s: %s::%s()' % (message, '::'.join(fqn), cursor.spelling))
-
-
-def ExploreClass(child, fqn):
-    # Safety check
-    if (child.kind != clang.cindex.CursorKind.CLASS_DECL and
-        child.kind != clang.cindex.CursorKind.STRUCT_DECL):
-        raise Exception()
-
-    # Ignore forward declaration of classes
-    if not child.is_definition():
-        return
-    
-
-    ##
-    ## Verify that the class is publicly exported (its visibility must
-    ## be "default")
-    ##
-    visible = False
-
-    for i in child.get_children():
-        if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and
-            i.spelling == 'default'):
-            visible = True
-
-    if not visible:
-        return
-
-    global ALL_TYPES
-    ALL_TYPES.append('::'.join(fqn))
-    
-    
-    ##
-    ## Ignore pure abstract interfaces, by checking the following
-    ## criteria:
-    ##   - It must be a C++ class (not a struct)
-    ##   - It must start with "I"
-    ##   - 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()):
-        abstract = True
-        isPublic = False
-
-        for i in child.get_children():
-            if i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR:      # "default"
-                pass
-            elif i.kind == clang.cindex.CursorKind.CXX_ACCESS_SPEC_DECL:
-                isPublic = (i.access_specifier == clang.cindex.AccessSpecifier.PUBLIC)
-            elif i.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER:
-                if i.spelling != 'boost::noncopyable':
-                    abstract = False
-            elif isPublic:
-                if i.kind == clang.cindex.CursorKind.CXX_METHOD:
-                    if i.is_pure_virtual_method():
-                        pass  # pure virtual is ok
-                    elif i.is_static_method():
-                        # static method without an inline implementation is ok
-                        for j in i.get_children():
-                            if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
-                                abstract = False
-                    else:
-                        abstract = False
-                elif (i.kind == clang.cindex.CursorKind.DESTRUCTOR and
-                      i.is_virtual_method()):
-                    # The destructor must be virtual, and must do nothing
-                    c = list(i.get_children())
-                    if (len(c) != 1 or
-                        c[0].kind != clang.cindex.CursorKind.COMPOUND_STMT or
-                        len(list(c[0].get_children())) != 0):
-                        abstract = False
-                elif i.kind == clang.cindex.CursorKind.CLASS_DECL:
-                    ExploreClass(i, fqn + [ i.spelling ])
-                elif (i.kind == clang.cindex.CursorKind.TYPEDEF_DECL or  # Allow "typedef"
-                      i.kind == clang.cindex.CursorKind.ENUM_DECL):      # Allow enums
-                    pass
-                else:
-                    abstract = False
-
-        if abstract:
-            print('Detected a pure interface (this is fine): %s' % ('::'.join(fqn)))
-        else:
-            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
-    membersSize = 0
-
-    for i in child.get_children():
-        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)
-
-        elif i.kind == clang.cindex.CursorKind.CLASS_DECL:
-            # This is a subclass
-            if isPublic:
-                ExploreClass(i, fqn + [ i.spelling ])
-
-        elif (i.kind == clang.cindex.CursorKind.CXX_METHOD or
-              i.kind == clang.cindex.CursorKind.CONSTRUCTOR or
-              i.kind == clang.cindex.CursorKind.DESTRUCTOR):
-            if isPublic:
-                hasImplementation = False
-                for j in i.get_children():
-                    if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
-                        hasImplementation = True
-
-                if hasImplementation:
-                    ReportProblem('Exported public method with an implementation', fqn, i)
-
-        elif i.kind == clang.cindex.CursorKind.VAR_DECL:
-            raise Exception('Unsupported: %s, %s' % (i.kind, i.location))
-
-        elif i.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE:
-            # An inline function template is OK, as it is not added to
-            # a shared library, but compiled by the client of the library
-            if isPublic:
-                print('Detected a template function (this is fine, but avoid it as much as possible): %s' % ('::'.join(fqn + [ i.spelling ])))
-                hasImplementation = False
-                for j in i.get_children():
-                    if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
-                        hasImplementation = True
-
-                if not hasImplementation:
-                    ReportProblem('Exported template function without an inline implementation', fqn, i)
-
-        elif (i.kind == clang.cindex.CursorKind.TYPEDEF_DECL or  # Allow "typedef"
-              i.kind == clang.cindex.CursorKind.ENUM_DECL):      # Allow enums
-            pass
-
-        elif i.kind == clang.cindex.CursorKind.FRIEND_DECL:
-            children = list(i.get_children())
-            if (isPublic and
-                (len(children) != 1 or
-                 not children[0].displayname in [
-                     # This is supported for ABI compatibility with Orthanc <= 1.8.0
-                     'operator<<(std::ostream &, const Orthanc::DicomTag &)',
-                 ])):
-                raise Exception('Unsupported: %s, %s' % (i.kind, i.location))
-
-        elif i.kind == clang.cindex.CursorKind.FIELD_DECL:
-            # TODO
-            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))
-
-    #print('Size of %s => (%d,%d)' % ('::'.join(fqn), membersCount, membersSize))
-
-
-def ExploreNamespace(node, namespace):
-    for child in node.get_children():
-        fqn = namespace + [ child.spelling ]
-        
-        if child.kind == clang.cindex.CursorKind.NAMESPACE:
-            ExploreNamespace(child, fqn)
-
-        elif (child.kind == clang.cindex.CursorKind.CLASS_DECL or
-              child.kind == clang.cindex.CursorKind.STRUCT_DECL):
-            ExploreClass(child, fqn)
-
-        elif child.kind == clang.cindex.CursorKind.FUNCTION_DECL:
-            visible = False
-            hasImplementation = False
-            for i in child.get_children():
-                if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and
-                    i.spelling == 'default'):
-                    visible = True
-                elif i.kind == clang.cindex.CursorKind.COMPOUND_STMT:
-                    hasImplementation = True
-
-            if visible and hasImplementation:
-                ReportProblem('Exported public function with an implementation', fqn, i)
-
-
-
-print('')
-
-for node in tu.cursor.get_children():
-    if (node.kind == clang.cindex.CursorKind.NAMESPACE and
-        node.spelling == 'Orthanc'):
-        ExploreNamespace(node, [ 'Orthanc' ])
-
-
-if args.target_cpp_size != '':
-    with open(args.target_cpp_size, 'w') as f:
-        for t in sorted(ALL_TYPES):
-            f.write('  printf("sizeof(::%s) == %%d\\n", static_cast<int>(sizeof(::%s)));\n' % (t, t))
-
-
-print('\nTotal of possibly problematic methods: %d' % COUNT)
-
-print('\nProblematic files:\n')
-for i in sorted(list(set(FILES))):
-    print(i)
-
-print('')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Graveyard/CheckOrthancFrameworkSymbols.py	Wed Aug 12 14:38:58 2026 +0200
@@ -0,0 +1,351 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+##
+## This maintenance script detects all the public methods in the
+## Orthanc framework that come with an inlined implementation in the
+## header file. Such methods can break the ABI of the shared library,
+## as the actual implementation might change over versions.
+##
+
+
+# Ubuntu 20.04:
+# sudo apt-get install python-clang-6.0
+# ./ParseWebAssemblyExports.py --libclang=libclang-6.0.so.1 ./Test.cpp
+
+# Ubuntu 18.04:
+# sudo apt-get install python-clang-4.0
+# ./ParseWebAssemblyExports.py --libclang=libclang-4.0.so.1 ./Test.cpp
+
+# Ubuntu 14.04:
+# ./ParseWebAssemblyExports.py --libclang=libclang-3.6.so.1 ./Test.cpp
+
+
+import os
+import sys
+import clang.cindex
+import argparse
+
+##
+## Parse the command-line arguments
+##
+
+parser = argparse.ArgumentParser(description = 'Parse WebAssembly C++ source file, and create a basic JavaScript wrapper.')
+parser.add_argument('--libclang',
+                    default = '',
+                    help = 'manually provides the path to the libclang shared library')
+parser.add_argument('--target-cpp-size',
+                    default = '',
+                    help = 'where to store C++ source to display the size of each public class')
+
+args = parser.parse_args()
+
+
+if len(args.libclang) != 0:
+    clang.cindex.Config.set_library_file(args.libclang)
+
+index = clang.cindex.Index.create()
+
+
+ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
+SOURCES = []
+
+for root, dirs, files in os.walk(os.path.join(ROOT, '..', 'Sources')):
+    for name in files:
+        if (os.path.splitext(name)[1] == '.h' and
+            not name.endswith('.impl.h')):
+            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',
+    '-DORTHANC_BUILDING_FRAMEWORK_LIBRARY=1',
+    '-DORTHANC_BUILD_UNIT_TESTS=0',
+    '-DORTHANC_ENABLE_BASE64=1',
+    '-DORTHANC_ENABLE_CIVETWEB=1',
+    '-DORTHANC_ENABLE_CURL=1',
+    '-DORTHANC_ENABLE_DCMTK=1',
+    '-DORTHANC_ENABLE_DCMTK_JPEG=1',
+    '-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=1',
+    '-DORTHANC_ENABLE_DCMTK_NETWORKING=1',
+    '-DORTHANC_ENABLE_DCMTK_TRANSCODING=1',
+    '-DORTHANC_ENABLE_JPEG=1',
+    '-DORTHANC_ENABLE_LOCALE=1',
+    '-DORTHANC_ENABLE_LOGGING=1',
+    '-DORTHANC_ENABLE_LOGGING_STDIO=0',
+    '-DORTHANC_ENABLE_LUA=1',
+    '-DORTHANC_ENABLE_MD5=1',
+    '-DORTHANC_ENABLE_MONGOOSE=1',
+    '-DORTHANC_ENABLE_PKCS11=1',
+    '-DORTHANC_ENABLE_PNG=1',
+    '-DORTHANC_ENABLE_PUGIXML=1',
+    '-DORTHANC_ENABLE_SQLITE=1',
+    '-DORTHANC_ENABLE_SSL=1',
+    '-DORTHANC_ENABLE_ZLIB=1',
+    '-DORTHANC_SANDBOXED=0',
+    '-DORTHANC_SQLITE_STANDALONE=0',
+    '-DORTHANC_SQLITE_VERSION=3027001',
+    '-I/usr/include/jsoncpp',  # On Ubuntu 18.04
+    '-I/usr/include/lua5.3',   # On Ubuntu 18.04
+])
+
+
+if len(tu.diagnostics) != 0:
+    for d in tu.diagnostics:
+        print('  ** %s' % d)
+    print('')
+    raise Exception('Error')
+
+
+
+FILES = []
+COUNT = 0
+ALL_TYPES = []
+
+def ReportProblem(message, fqn, cursor):
+    global FILES, COUNT
+    FILES.append(os.path.normpath(str(cursor.location.file)))
+    COUNT += 1
+
+    print('%s: %s::%s()' % (message, '::'.join(fqn), cursor.spelling))
+
+
+def ExploreClass(child, fqn):
+    # Safety check
+    if (child.kind != clang.cindex.CursorKind.CLASS_DECL and
+        child.kind != clang.cindex.CursorKind.STRUCT_DECL):
+        raise Exception()
+
+    # Ignore forward declaration of classes
+    if not child.is_definition():
+        return
+    
+
+    ##
+    ## Verify that the class is publicly exported (its visibility must
+    ## be "default")
+    ##
+    visible = False
+
+    for i in child.get_children():
+        if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and
+            i.spelling == 'default'):
+            visible = True
+
+    if not visible:
+        return
+
+    global ALL_TYPES
+    ALL_TYPES.append('::'.join(fqn))
+    
+    
+    ##
+    ## Ignore pure abstract interfaces, by checking the following
+    ## criteria:
+    ##   - It must be a C++ class (not a struct)
+    ##   - It must start with "I"
+    ##   - 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()):
+        abstract = True
+        isPublic = False
+
+        for i in child.get_children():
+            if i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR:      # "default"
+                pass
+            elif i.kind == clang.cindex.CursorKind.CXX_ACCESS_SPEC_DECL:
+                isPublic = (i.access_specifier == clang.cindex.AccessSpecifier.PUBLIC)
+            elif i.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER:
+                if i.spelling != 'boost::noncopyable':
+                    abstract = False
+            elif isPublic:
+                if i.kind == clang.cindex.CursorKind.CXX_METHOD:
+                    if i.is_pure_virtual_method():
+                        pass  # pure virtual is ok
+                    elif i.is_static_method():
+                        # static method without an inline implementation is ok
+                        for j in i.get_children():
+                            if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
+                                abstract = False
+                    else:
+                        abstract = False
+                elif (i.kind == clang.cindex.CursorKind.DESTRUCTOR and
+                      i.is_virtual_method()):
+                    # The destructor must be virtual, and must do nothing
+                    c = list(i.get_children())
+                    if (len(c) != 1 or
+                        c[0].kind != clang.cindex.CursorKind.COMPOUND_STMT or
+                        len(list(c[0].get_children())) != 0):
+                        abstract = False
+                elif i.kind == clang.cindex.CursorKind.CLASS_DECL:
+                    ExploreClass(i, fqn + [ i.spelling ])
+                elif (i.kind == clang.cindex.CursorKind.TYPEDEF_DECL or  # Allow "typedef"
+                      i.kind == clang.cindex.CursorKind.ENUM_DECL):      # Allow enums
+                    pass
+                else:
+                    abstract = False
+
+        if abstract:
+            print('Detected a pure interface (this is fine): %s' % ('::'.join(fqn)))
+        else:
+            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
+    membersSize = 0
+
+    for i in child.get_children():
+        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)
+
+        elif i.kind == clang.cindex.CursorKind.CLASS_DECL:
+            # This is a subclass
+            if isPublic:
+                ExploreClass(i, fqn + [ i.spelling ])
+
+        elif (i.kind == clang.cindex.CursorKind.CXX_METHOD or
+              i.kind == clang.cindex.CursorKind.CONSTRUCTOR or
+              i.kind == clang.cindex.CursorKind.DESTRUCTOR):
+            if isPublic:
+                hasImplementation = False
+                for j in i.get_children():
+                    if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
+                        hasImplementation = True
+
+                if hasImplementation:
+                    ReportProblem('Exported public method with an implementation', fqn, i)
+
+        elif i.kind == clang.cindex.CursorKind.VAR_DECL:
+            raise Exception('Unsupported: %s, %s' % (i.kind, i.location))
+
+        elif i.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE:
+            # An inline function template is OK, as it is not added to
+            # a shared library, but compiled by the client of the library
+            if isPublic:
+                print('Detected a template function (this is fine, but avoid it as much as possible): %s' % ('::'.join(fqn + [ i.spelling ])))
+                hasImplementation = False
+                for j in i.get_children():
+                    if j.kind == clang.cindex.CursorKind.COMPOUND_STMT:
+                        hasImplementation = True
+
+                if not hasImplementation:
+                    ReportProblem('Exported template function without an inline implementation', fqn, i)
+
+        elif (i.kind == clang.cindex.CursorKind.TYPEDEF_DECL or  # Allow "typedef"
+              i.kind == clang.cindex.CursorKind.ENUM_DECL):      # Allow enums
+            pass
+
+        elif i.kind == clang.cindex.CursorKind.FRIEND_DECL:
+            children = list(i.get_children())
+            if (isPublic and
+                (len(children) != 1 or
+                 not children[0].displayname in [
+                     # This is supported for ABI compatibility with Orthanc <= 1.8.0
+                     'operator<<(std::ostream &, const Orthanc::DicomTag &)',
+                 ])):
+                raise Exception('Unsupported: %s, %s' % (i.kind, i.location))
+
+        elif i.kind == clang.cindex.CursorKind.FIELD_DECL:
+            # TODO
+            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))
+
+    #print('Size of %s => (%d,%d)' % ('::'.join(fqn), membersCount, membersSize))
+
+
+def ExploreNamespace(node, namespace):
+    for child in node.get_children():
+        fqn = namespace + [ child.spelling ]
+        
+        if child.kind == clang.cindex.CursorKind.NAMESPACE:
+            ExploreNamespace(child, fqn)
+
+        elif (child.kind == clang.cindex.CursorKind.CLASS_DECL or
+              child.kind == clang.cindex.CursorKind.STRUCT_DECL):
+            ExploreClass(child, fqn)
+
+        elif child.kind == clang.cindex.CursorKind.FUNCTION_DECL:
+            visible = False
+            hasImplementation = False
+            for i in child.get_children():
+                if (i.kind == clang.cindex.CursorKind.VISIBILITY_ATTR and
+                    i.spelling == 'default'):
+                    visible = True
+                elif i.kind == clang.cindex.CursorKind.COMPOUND_STMT:
+                    hasImplementation = True
+
+            if visible and hasImplementation:
+                ReportProblem('Exported public function with an implementation', fqn, i)
+
+
+
+print('')
+
+for node in tu.cursor.get_children():
+    if (node.kind == clang.cindex.CursorKind.NAMESPACE and
+        node.spelling == 'Orthanc'):
+        ExploreNamespace(node, [ 'Orthanc' ])
+
+
+if args.target_cpp_size != '':
+    with open(args.target_cpp_size, 'w') as f:
+        for t in sorted(ALL_TYPES):
+            f.write('  printf("sizeof(::%s) == %%d\\n", static_cast<int>(sizeof(::%s)));\n' % (t, t))
+
+
+print('\nTotal of possibly problematic methods: %d' % COUNT)
+
+print('\nProblematic files:\n')
+for i in sorted(list(set(FILES))):
+    print(i)
+
+print('')
--- a/OrthancFramework/Sources/Compatibility.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/Compatibility.h	Wed Aug 12 14:38:58 2026 +0200
@@ -36,24 +36,24 @@
 
 
 // Macro "ORTHANC_DEPRECATED" tags a function as having been deprecated
-#if (__cplusplus >= 201402L)  // C++14
-#  define ORTHANC_DEPRECATED(f) [[deprecated]] f
-#elif defined(__GNUC__) || defined(__clang__)
+#if defined(__GNUC__) || defined(__clang__)
 #  define ORTHANC_DEPRECATED(f) f __attribute__((deprecated))
 #elif defined(_MSC_VER)
 #  define ORTHANC_DEPRECATED(f) __declspec(deprecated) f
+#elif (__cplusplus >= 201402L)  // C++14
+#  define ORTHANC_DEPRECATED(f) [[deprecated]] f
 #else
 #  define ORTHANC_DEPRECATED
 #endif
 
 
 // Macro "ORTHANC_DEPRECATED_CLASS" tags a class as having been deprecated
-#if (__cplusplus >= 201402L)  // C++14
-#  define ORTHANC_DEPRECATED_CLASS(f) [[deprecated]] f
-#elif defined(__GNUC__) || defined(__clang__)
+#if defined(__GNUC__) || defined(__clang__)
 #  define ORTHANC_DEPRECATED_CLASS(f) __attribute__((deprecated)) f
 #elif defined(_MSC_VER)
 #  define ORTHANC_DEPRECATED_CLASS(f) __declspec(deprecated) f
+#elif (__cplusplus >= 201402L)  // C++14
+#  define ORTHANC_DEPRECATED_CLASS(f) [[deprecated]] f
 #else
 #  define ORTHANC_DEPRECATED
 #endif
--- a/OrthancFramework/Sources/DicomFormat/DicomTag.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomTag.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -314,13 +314,4 @@
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
   }
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  std::ostream& operator<< (std::ostream& o, const DicomTag& tag)
-  {
-    tag.FormatStream(o);
-    return o;
-  }
-#endif
 }
--- a/OrthancFramework/Sources/DicomFormat/DicomTag.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomTag.h	Wed Aug 12 14:38:58 2026 +0200
@@ -74,10 +74,6 @@
 
     static void AddTagsForModule(std::set<DicomTag>& target,
                                  DicomModule module);
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    ORTHANC_PUBLIC ORTHANC_DEPRECATED(friend std::ostream& operator<<(std::ostream& o, const DicomTag& tag));
-#endif
   };
 
   // Aliases for the most useful tags
--- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -229,28 +229,4 @@
   {
     complete_ = isComplete;
   }
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  void DicomFindAnswers::Add(ParsedDicomFile& dicom)
-  {
-    return Add(const_cast<const ParsedDicomFile&>(dicom));
-  }
-
-  void DicomFindAnswers::ToJson(Json::Value& target,
-                                size_t index,
-                                bool simplify) const
-  {
-    DicomToJsonFormat format = (simplify ? DicomToJsonFormat_Human : DicomToJsonFormat_Full);
-    ToJson(target, index, format);
-  }
-
-
-  void DicomFindAnswers::ToJson(Json::Value& target,
-                                bool simplify) const
-  {
-    DicomToJsonFormat format = (simplify ? DicomToJsonFormat_Human : DicomToJsonFormat_Full);
-    ToJson(target, format);
-  }
-#endif
 }
--- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h	Wed Aug 12 14:38:58 2026 +0200
@@ -38,18 +38,6 @@
 
     void AddAnswerInternal(ParsedDicomFile* answer);
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-    void Add(ParsedDicomFile& dicom);
-
-    void ToJson(Json::Value& target,
-                bool simplify) const;
-
-    void ToJson(Json::Value& target,
-                size_t index,
-                bool simplify) const;
-#endif
-
   public:
     explicit DicomFindAnswers(bool isWorklist);
 
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -1275,13 +1275,4 @@
     IImageWriter::WriteToMemory(writer, result, *image);
   }
 #endif
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  ImageAccessor *DicomImageDecoder::Decode(ParsedDicomFile& dataset,
-                                           unsigned int frame)
-  {
-    return Decode(*dataset.GetDcmtkObject().getDataset(), frame);
-  }
-#endif
 }
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h	Wed Aug 12 14:38:58 2026 +0200
@@ -86,12 +86,6 @@
                                     ImageExtractionMode mode,
                                     bool invert);
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-    static ImageAccessor *Decode(ParsedDicomFile& dataset,
-                                 unsigned int frame);
-#endif
-
   public:
     static bool IsPsmctRle1(DcmDataset& dataset);
 
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -2379,56 +2379,4 @@
       throw OrthancException(ErrorCode_NotImplemented, "Cannot encapsulate pixel data from MIME type: " + mime);
     }
   }
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-  void ParsedDicomFile::DatasetToJson(Json::Value& target,
-                                      DicomToJsonFormat format,
-                                      DicomToJsonFlags flags,
-                                      unsigned int maxStringLength)
-  {
-    return const_cast<const ParsedDicomFile&>(*this).DatasetToJson(target, format, flags, maxStringLength);
-  }
-
-  DcmFileFormat& ParsedDicomFile::GetDcmtkObject() const
-  {
-    return const_cast<ParsedDicomFile&>(*this).GetDcmtkObject();
-  }
-
-  void ParsedDicomFile::Apply(ITagVisitor& visitor)
-  {
-    const_cast<const ParsedDicomFile&>(*this).Apply(visitor);
-  }
-
-  ParsedDicomFile* ParsedDicomFile::Clone(bool keepSopInstanceUid)
-  {
-    return const_cast<const ParsedDicomFile&>(*this).Clone(keepSopInstanceUid);
-  }
-  
-  bool ParsedDicomFile::LookupTransferSyntax(std::string& result)
-  {
-    return const_cast<const ParsedDicomFile&>(*this).LookupTransferSyntax(result);
-  }
-  
-  bool ParsedDicomFile::LookupTransferSyntax(std::string& result) const
-  {
-    DicomTransferSyntax s;
-    if (LookupTransferSyntax(s))
-    {
-      result = GetTransferSyntaxUid(s);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  bool ParsedDicomFile::GetTagValue(std::string& value,
-                                    const DicomTag& tag)
-  {
-    return const_cast<const ParsedDicomFile&>(*this).GetTagValue(value, tag);
-  }
-#endif
 }
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Wed Aug 12 14:38:58 2026 +0200
@@ -110,21 +110,6 @@
 
     explicit ParsedDicomFile(DcmFileFormat* dicom);  // This takes ownership (no clone)
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-    void DatasetToJson(Json::Value& target, 
-                       DicomToJsonFormat format,
-                       DicomToJsonFlags flags,
-                       unsigned int maxStringLength);    
-    DcmFileFormat& GetDcmtkObject() const;
-    void Apply(ITagVisitor& visitor);
-    ParsedDicomFile* Clone(bool keepSopInstanceUid);
-    bool LookupTransferSyntax(std::string& result);
-    bool LookupTransferSyntax(std::string& result) const;
-    bool GetTagValue(std::string& value,
-                     const DicomTag& tag);
-#endif
-
   public:
     explicit ParsedDicomFile(bool createIdentifiers);  // Create a minimal DICOM instance
 
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -333,24 +333,4 @@
   {
     return boost::filesystem::space(root_).available;
   }
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  FilesystemStorage::FilesystemStorage(std::string root) :
-    fsyncOnWrite_(false)
-  {
-    Setup(root);
-  }
-#endif
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  void FilesystemStorage::Read(std::string& content,
-                               const std::string& uuid,
-                               FileContentType type)
-  {
-    std::unique_ptr<IMemoryBuffer> buffer(ReadWhole(uuid, type));
-    buffer->MoveToString(content);
-  }
-#endif
 }
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Wed Aug 12 14:38:58 2026 +0200
@@ -57,18 +57,6 @@
 
     void Setup(const boost::filesystem::path& root);
     
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-    explicit FilesystemStorage(std::string root);
-#endif
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Binary compatibility with Orthanc Framework <= 1.8.2
-    void Read(std::string& content,
-              const std::string& uuid,
-              FileContentType type);
-#endif
-
   public:
     explicit FilesystemStorage(const boost::filesystem::path& root);
 
--- a/OrthancFramework/Sources/Images/ImageAccessor.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/Images/ImageAccessor.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -375,17 +375,4 @@
 
     format_ = format;
   }
-
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  void* ImageAccessor::GetBuffer() const
-  {
-    return const_cast<ImageAccessor&>(*this).GetBuffer();
-  }
-
-  void* ImageAccessor::GetRow(unsigned int y) const
-  {
-    return const_cast<ImageAccessor&>(*this).GetRow(y);
-  }
-#endif
 }
--- a/OrthancFramework/Sources/Images/ImageAccessor.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/Images/ImageAccessor.h	Wed Aug 12 14:38:58 2026 +0200
@@ -63,12 +63,6 @@
       return reinterpret_cast<T*>(row) [x];
     }
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
-    void* GetBuffer() const;
-    void* GetRow(unsigned int y) const;
-#endif
-
   public:
     ImageAccessor();
 
--- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -33,14 +33,6 @@
 
 namespace Orthanc
 {
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  void JobOperationValues::Append(JobOperationValue* value)
-  {
-    throw OrthancException(ErrorCode_DiscontinuedAbi, "Removed in 1.8.1");
-  }
-#endif
-    
-
   void JobOperationValues::Append(JobOperationValues& target,
                                   bool clear)
   {
--- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h	Wed Aug 12 14:38:58 2026 +0200
@@ -33,27 +33,10 @@
 {
   class IJobUnserializer;
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  class JobOperationValue
-  {
-    /**
-     * This is for ABI compatibility with Orthanc framework <= 1.8.0,
-     * only to be able to run unit tests from Orthanc 1.7.2 to
-     * 1.8.0. The class was moved to "IJobOperationValue" in 1.8.1,
-     * and its memory layout has changed. Don't use this anymore.
-     **/
-  };
-#endif
-
   class ORTHANC_PUBLIC JobOperationValues : public boost::noncopyable
   {
   private:
     std::vector<IJobOperationValue*>   values_;
-
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-    // For binary compatibility with Orthanc <= 1.8.0
-    ORTHANC_DEPRECATED(void Append(JobOperationValue* value));
-#endif
     
     void Append(JobOperationValues& target,
                 bool clear);
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -238,15 +238,6 @@
   }
 
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-  void SequenceOfOperationsJob::Lock::AddInput(size_t index,
-                                               const JobOperationValue& value)
-  {
-    throw OrthancException(ErrorCode_DiscontinuedAbi, "Removed in 1.8.1");
-  }
-#endif
-
-
   SequenceOfOperationsJob::Lock::Lock(SequenceOfOperationsJob& that) :
     that_(that),
     lock_(that.mutex_)
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Wed Aug 12 14:38:58 2026 +0200
@@ -87,11 +87,6 @@
       SequenceOfOperationsJob&   that_;
       boost::mutex::scoped_lock  lock_;
 
-#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
-      ORTHANC_DEPRECATED(void AddInput(size_t index,
-                                       const JobOperationValue& value));
-#endif
-      
     public:
       explicit Lock(SequenceOfOperationsJob& that);
 
--- a/OrthancServer/CMakeLists.txt	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancServer/CMakeLists.txt	Wed Aug 12 14:38:58 2026 +0200
@@ -201,7 +201,6 @@
     ${CMAKE_SOURCE_DIR}/UnitTestsSources/ServerConfigTests.cpp
     ${CMAKE_SOURCE_DIR}/UnitTestsSources/ServerIndexTests.cpp
     ${CMAKE_SOURCE_DIR}/UnitTestsSources/ServerJobsTests.cpp
-    ${CMAKE_SOURCE_DIR}/UnitTestsSources/SizeOfTests.cpp
     ${CMAKE_SOURCE_DIR}/UnitTestsSources/UnitTestsMain.cpp
     ${CMAKE_SOURCE_DIR}/UnitTestsSources/VersionsTests.cpp
     )
--- a/OrthancServer/Sources/ServerTranscoder.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ b/OrthancServer/Sources/ServerTranscoder.cpp	Wed Aug 12 14:38:58 2026 +0200
@@ -28,8 +28,9 @@
 #include "../../OrthancFramework/Sources/DataSource/DicomDataSource.h"
 #include "../../OrthancFramework/Sources/DataSource/StorageAreaDataSource.h"
 #include "../../OrthancFramework/Sources/DataSource/TranscoderDataSource.h"
+#include "../../OrthancFramework/Sources/DicomFormat/DicomImageInformation.h"
 #include "../../OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomImageInformation.h"
+#include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "../../OrthancFramework/Sources/OrthancException.h"
 #include "../Plugins/Engine/OrthancPlugins.h"
--- a/OrthancServer/UnitTestsSources/SizeOfTests.cpp	Wed Aug 12 13:14:11 2026 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2023 Osimis S.A., Belgium
- * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
- * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "PrecompiledHeadersUnitTests.h"
-#include <gtest/gtest.h>
-
-#if defined(__GNUC__) || defined(__clang__)
-#  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
-
-#include "../../OrthancFramework/Sources/Cache/ICachePageProvider.h"
-#include "../../OrthancFramework/Sources/Cache/ICacheable.h"
-#include "../../OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h"
-#include "../../OrthancFramework/Sources/Cache/MemoryCache.h"
-#include "../../OrthancFramework/Sources/Cache/MemoryObjectCache.h"
-#include "../../OrthancFramework/Sources/Cache/MemoryStringCache.h"
-#include "../../OrthancFramework/Sources/Cache/SharedArchive.h"
-#include "../../OrthancFramework/Sources/ChunkedBuffer.h"
-#include "../../OrthancFramework/Sources/Compatibility.h"
-#include "../../OrthancFramework/Sources/Compression/DeflateBaseCompressor.h"
-#include "../../OrthancFramework/Sources/Compression/GzipCompressor.h"
-#include "../../OrthancFramework/Sources/Compression/HierarchicalZipWriter.h"
-#include "../../OrthancFramework/Sources/Compression/IBufferCompressor.h"
-#include "../../OrthancFramework/Sources/Compression/ZipReader.h"
-#include "../../OrthancFramework/Sources/Compression/ZipWriter.h"
-#include "../../OrthancFramework/Sources/Compression/ZlibCompressor.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomArray.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomElement.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomImageInformation.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomMap.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomStreamReader.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomTag.h"
-#include "../../OrthancFramework/Sources/DicomFormat/DicomValue.h"
-#include "../../OrthancFramework/Sources/DicomFormat/StreamBlockReader.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomAssociation.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomServer.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IApplicationEntityFilter.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IFindRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IFindRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IGetRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IMoveRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IMoveRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IStoreRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IStoreRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandler.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandlerFactory.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h"
-#include "../../OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h"
-#include "../../OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h"
-#include "../../OrthancFramework/Sources/DicomParsing/DicomDirWriter.h"
-#include "../../OrthancFramework/Sources/DicomParsing/DicomModification.h"
-#include "../../OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h"
-#include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
-#include "../../OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h"
-#include "../../OrthancFramework/Sources/DicomParsing/ITagVisitor.h"
-#include "../../OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.h"
-#include "../../OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h"
-#include "../../OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h"
-#include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h"
-#include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomDir.h"
-#include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
-#include "../../OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.h"
-#include "../../OrthancFramework/Sources/Endianness.h"
-#include "../../OrthancFramework/Sources/EnumerationDictionary.h"
-#include "../../OrthancFramework/Sources/Enumerations.h"
-#include "../../OrthancFramework/Sources/FileBuffer.h"
-#include "../../OrthancFramework/Sources/FileStorage/FileInfo.h"
-#include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h"
-#include "../../OrthancFramework/Sources/FileStorage/IStorageArea.h"
-#include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
-#include "../../OrthancFramework/Sources/FileStorage/StorageAccessor.h"
-#include "../../OrthancFramework/Sources/HttpClient.h"
-#include "../../OrthancFramework/Sources/HttpServer/BufferHttpSender.h"
-#include "../../OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.h"
-#include "../../OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpContentNegociation.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpFileSender.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpOutput.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpServer.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.h"
-#include "../../OrthancFramework/Sources/HttpServer/HttpToolbox.h"
-#include "../../OrthancFramework/Sources/HttpServer/IHttpHandler.h"
-#include "../../OrthancFramework/Sources/HttpServer/IHttpOutputStream.h"
-#include "../../OrthancFramework/Sources/HttpServer/IHttpStreamAnswer.h"
-#include "../../OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h"
-#include "../../OrthancFramework/Sources/HttpServer/IWebDavBucket.h"
-#include "../../OrthancFramework/Sources/HttpServer/MultipartStreamReader.h"
-#include "../../OrthancFramework/Sources/HttpServer/StringHttpOutput.h"
-#include "../../OrthancFramework/Sources/HttpServer/StringMatcher.h"
-#include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h"
-#include "../../OrthancFramework/Sources/IDynamicObject.h"
-#include "../../OrthancFramework/Sources/IMemoryBuffer.h"
-#include "../../OrthancFramework/Sources/Images/Font.h"
-#include "../../OrthancFramework/Sources/Images/FontRegistry.h"
-#include "../../OrthancFramework/Sources/Images/IImageWriter.h"
-#include "../../OrthancFramework/Sources/Images/Image.h"
-#include "../../OrthancFramework/Sources/Images/ImageAccessor.h"
-#include "../../OrthancFramework/Sources/Images/ImageBuffer.h"
-#include "../../OrthancFramework/Sources/Images/ImageProcessing.h"
-#include "../../OrthancFramework/Sources/Images/ImageTraits.h"
-#include "../../OrthancFramework/Sources/Images/JpegReader.h"
-#include "../../OrthancFramework/Sources/Images/JpegWriter.h"
-#include "../../OrthancFramework/Sources/Images/NumpyWriter.h"
-#include "../../OrthancFramework/Sources/Images/PamReader.h"
-#include "../../OrthancFramework/Sources/Images/PamWriter.h"
-#include "../../OrthancFramework/Sources/Images/PixelTraits.h"
-#include "../../OrthancFramework/Sources/Images/PngReader.h"
-#include "../../OrthancFramework/Sources/Images/PngWriter.h"
-#include "../../OrthancFramework/Sources/JobsEngine/GenericJobUnserializer.h"
-#include "../../OrthancFramework/Sources/JobsEngine/IJob.h"
-#include "../../OrthancFramework/Sources/JobsEngine/IJobUnserializer.h"
-#include "../../OrthancFramework/Sources/JobsEngine/JobInfo.h"
-#include "../../OrthancFramework/Sources/JobsEngine/JobStatus.h"
-#include "../../OrthancFramework/Sources/JobsEngine/JobStepResult.h"
-#include "../../OrthancFramework/Sources/JobsEngine/JobsEngine.h"
-#include "../../OrthancFramework/Sources/JobsEngine/JobsRegistry.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/IJobOperation.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/IJobOperationValue.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h"
-#include "../../OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h"
-#include "../../OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h"
-#include "../../OrthancFramework/Sources/Logging.h"
-#include "../../OrthancFramework/Sources/Lua/LuaContext.h"
-#include "../../OrthancFramework/Sources/Lua/LuaFunctionCall.h"
-#include "../../OrthancFramework/Sources/MallocMemoryBuffer.h"
-#include "../../OrthancFramework/Sources/MetricsRegistry.h"
-#include "../../OrthancFramework/Sources/MultiThreading/IRunnableBySteps.h"
-#include "../../OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.h"
-#include "../../OrthancFramework/Sources/MultiThreading/Semaphore.h"
-#include "../../OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h"
-#include "../../OrthancFramework/Sources/OrthancException.h"
-#include "../../OrthancFramework/Sources/OrthancFramework.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApi.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiCall.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiDeleteCall.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiGetCall.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiHierarchy.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiOutput.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiPath.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiPostCall.h"
-#include "../../OrthancFramework/Sources/RestApi/RestApiPutCall.h"
-#include "../../OrthancFramework/Sources/SQLite/Connection.h"
-#include "../../OrthancFramework/Sources/SQLite/FunctionContext.h"
-#include "../../OrthancFramework/Sources/SQLite/IScalarFunction.h"
-#include "../../OrthancFramework/Sources/SQLite/ITransaction.h"
-#include "../../OrthancFramework/Sources/SQLite/NonCopyable.h"
-#include "../../OrthancFramework/Sources/SQLite/OrthancSQLiteException.h"
-#include "../../OrthancFramework/Sources/SQLite/SQLiteTypes.h"
-#include "../../OrthancFramework/Sources/SQLite/Statement.h"
-#include "../../OrthancFramework/Sources/SQLite/StatementId.h"
-#include "../../OrthancFramework/Sources/SQLite/StatementReference.h"
-#include "../../OrthancFramework/Sources/SQLite/Transaction.h"
-#include "../../OrthancFramework/Sources/SerializationToolbox.h"
-#include "../../OrthancFramework/Sources/SharedLibrary.h"
-#include "../../OrthancFramework/Sources/StringMemoryBuffer.h"
-#include "../../OrthancFramework/Sources/SystemToolbox.h"
-#include "../../OrthancFramework/Sources/TemporaryFile.h"
-#include "../../OrthancFramework/Sources/Toolbox.h"
-#include "../../OrthancFramework/Sources/WebServiceParameters.h"
-
-
-TEST(OrthancFramework, SizeOf)
-{
-#include "SizeOfTests.impl.h"
-}
--- a/OrthancServer/UnitTestsSources/SizeOfTests.impl.h	Wed Aug 12 13:14:11 2026 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-  printf("sizeof(::Orthanc::BufferHttpSender) == %d\n", static_cast<int>(sizeof(::Orthanc::BufferHttpSender)));
-  printf("sizeof(::Orthanc::CStringMatcher) == %d\n", static_cast<int>(sizeof(::Orthanc::CStringMatcher)));
-  printf("sizeof(::Orthanc::ChunkedBuffer) == %d\n", static_cast<int>(sizeof(::Orthanc::ChunkedBuffer)));
-  printf("sizeof(::Orthanc::DcmtkTranscoder) == %d\n", static_cast<int>(sizeof(::Orthanc::DcmtkTranscoder)));
-  printf("sizeof(::Orthanc::DeflateBaseCompressor) == %d\n", static_cast<int>(sizeof(::Orthanc::DeflateBaseCompressor)));
-  printf("sizeof(::Orthanc::Deprecated::MemoryCache) == %d\n", static_cast<int>(sizeof(::Orthanc::Deprecated::MemoryCache)));
-  printf("sizeof(::Orthanc::DicomArray) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomArray)));
-  printf("sizeof(::Orthanc::DicomAssociationParameters) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomAssociationParameters)));
-  printf("sizeof(::Orthanc::DicomElement) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomElement)));
-  printf("sizeof(::Orthanc::DicomFindAnswers) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomFindAnswers)));
-  printf("sizeof(::Orthanc::DicomImageDecoder) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomImageDecoder)));
-  printf("sizeof(::Orthanc::DicomImageInformation) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomImageInformation)));
-  printf("sizeof(::Orthanc::DicomInstanceHasher) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomInstanceHasher)));
-  printf("sizeof(::Orthanc::DicomMap) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomMap)));
-  printf("sizeof(::Orthanc::DicomModification) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomModification)));
-  printf("sizeof(::Orthanc::DicomPath) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomPath)));
-  printf("sizeof(::Orthanc::DicomStoreUserConnection) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomStoreUserConnection)));
-  printf("sizeof(::Orthanc::DicomStreamReader) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomStreamReader)));
-  printf("sizeof(::Orthanc::DicomTag) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomTag)));
-  printf("sizeof(::Orthanc::DicomValue) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomValue)));
-  printf("sizeof(::Orthanc::DicomWebJsonVisitor) == %d\n", static_cast<int>(sizeof(::Orthanc::DicomWebJsonVisitor)));
-  printf("sizeof(::Orthanc::FileBuffer) == %d\n", static_cast<int>(sizeof(::Orthanc::FileBuffer)));
-  printf("sizeof(::Orthanc::FileInfo) == %d\n", static_cast<int>(sizeof(::Orthanc::FileInfo)));
-  printf("sizeof(::Orthanc::FilesystemHttpSender) == %d\n", static_cast<int>(sizeof(::Orthanc::FilesystemHttpSender)));
-  printf("sizeof(::Orthanc::FilesystemStorage) == %d\n", static_cast<int>(sizeof(::Orthanc::FilesystemStorage)));
-  printf("sizeof(::Orthanc::Font) == %d\n", static_cast<int>(sizeof(::Orthanc::Font)));
-  printf("sizeof(::Orthanc::FontRegistry) == %d\n", static_cast<int>(sizeof(::Orthanc::FontRegistry)));
-  printf("sizeof(::Orthanc::FromDcmtkBridge) == %d\n", static_cast<int>(sizeof(::Orthanc::FromDcmtkBridge)));
-  printf("sizeof(::Orthanc::FromDcmtkBridge::IDicomPathVisitor) == %d\n", static_cast<int>(sizeof(::Orthanc::FromDcmtkBridge::IDicomPathVisitor)));
-  printf("sizeof(::Orthanc::GenericJobUnserializer) == %d\n", static_cast<int>(sizeof(::Orthanc::GenericJobUnserializer)));
-  printf("sizeof(::Orthanc::GzipCompressor) == %d\n", static_cast<int>(sizeof(::Orthanc::GzipCompressor)));
-  printf("sizeof(::Orthanc::HierarchicalZipWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::HierarchicalZipWriter)));
-  printf("sizeof(::Orthanc::HttpClient) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpClient)));
-  printf("sizeof(::Orthanc::HttpContentNegociation) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpContentNegociation)));
-  printf("sizeof(::Orthanc::HttpFileSender) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpFileSender)));
-  printf("sizeof(::Orthanc::HttpOutput) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpOutput)));
-  printf("sizeof(::Orthanc::HttpServer) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpServer)));
-  printf("sizeof(::Orthanc::HttpStreamTranscoder) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpStreamTranscoder)));
-  printf("sizeof(::Orthanc::HttpToolbox) == %d\n", static_cast<int>(sizeof(::Orthanc::HttpToolbox)));
-  printf("sizeof(::Orthanc::IBufferCompressor) == %d\n", static_cast<int>(sizeof(::Orthanc::IBufferCompressor)));
-  printf("sizeof(::Orthanc::IDicomTranscoder) == %d\n", static_cast<int>(sizeof(::Orthanc::IDicomTranscoder)));
-  printf("sizeof(::Orthanc::IDicomTranscoder::DicomImage) == %d\n", static_cast<int>(sizeof(::Orthanc::IDicomTranscoder::DicomImage)));
-  printf("sizeof(::Orthanc::IDynamicObject) == %d\n", static_cast<int>(sizeof(::Orthanc::IDynamicObject)));
-  printf("sizeof(::Orthanc::IImageWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::IImageWriter)));
-  printf("sizeof(::Orthanc::IJob) == %d\n", static_cast<int>(sizeof(::Orthanc::IJob)));
-  printf("sizeof(::Orthanc::IJobOperation) == %d\n", static_cast<int>(sizeof(::Orthanc::IJobOperation)));
-  printf("sizeof(::Orthanc::IJobOperationValue) == %d\n", static_cast<int>(sizeof(::Orthanc::IJobOperationValue)));
-  printf("sizeof(::Orthanc::IJobUnserializer) == %d\n", static_cast<int>(sizeof(::Orthanc::IJobUnserializer)));
-  printf("sizeof(::Orthanc::Image) == %d\n", static_cast<int>(sizeof(::Orthanc::Image)));
-  printf("sizeof(::Orthanc::ImageAccessor) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageAccessor)));
-  printf("sizeof(::Orthanc::ImageBuffer) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageBuffer)));
-  printf("sizeof(::Orthanc::ImageProcessing) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing)));
-  printf("sizeof(::Orthanc::ImageProcessing::IPolygonFiller) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing::IPolygonFiller)));
-  printf("sizeof(::Orthanc::ImageProcessing::ImagePoint) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing::ImagePoint)));
-  printf("sizeof(::Orthanc::JobInfo) == %d\n", static_cast<int>(sizeof(::Orthanc::JobInfo)));
-  printf("sizeof(::Orthanc::JobOperationValues) == %d\n", static_cast<int>(sizeof(::Orthanc::JobOperationValues)));
-  printf("sizeof(::Orthanc::JobStepResult) == %d\n", static_cast<int>(sizeof(::Orthanc::JobStepResult)));
-  printf("sizeof(::Orthanc::JobsEngine) == %d\n", static_cast<int>(sizeof(::Orthanc::JobsEngine)));
-  printf("sizeof(::Orthanc::JobsRegistry) == %d\n", static_cast<int>(sizeof(::Orthanc::JobsRegistry)));
-  printf("sizeof(::Orthanc::JobsRegistry::IObserver) == %d\n", static_cast<int>(sizeof(::Orthanc::JobsRegistry::IObserver)));
-  printf("sizeof(::Orthanc::JobsRegistry::RunningJob) == %d\n", static_cast<int>(sizeof(::Orthanc::JobsRegistry::RunningJob)));
-  printf("sizeof(::Orthanc::JpegReader) == %d\n", static_cast<int>(sizeof(::Orthanc::JpegReader)));
-  printf("sizeof(::Orthanc::JpegWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::JpegWriter)));
-  printf("sizeof(::Orthanc::LogJobOperation) == %d\n", static_cast<int>(sizeof(::Orthanc::LogJobOperation)));
-  printf("sizeof(::Orthanc::Logging::InternalLogger) == %d\n", static_cast<int>(sizeof(::Orthanc::Logging::InternalLogger)));
-  printf("sizeof(::Orthanc::LuaContext) == %d\n", static_cast<int>(sizeof(::Orthanc::LuaContext)));
-  printf("sizeof(::Orthanc::LuaFunctionCall) == %d\n", static_cast<int>(sizeof(::Orthanc::LuaFunctionCall)));
-  printf("sizeof(::Orthanc::MemoryObjectCache) == %d\n", static_cast<int>(sizeof(::Orthanc::MemoryObjectCache)));
-  printf("sizeof(::Orthanc::MemoryStringCache) == %d\n", static_cast<int>(sizeof(::Orthanc::MemoryStringCache)));
-  printf("sizeof(::Orthanc::MetricsRegistry) == %d\n", static_cast<int>(sizeof(::Orthanc::MetricsRegistry)));
-  printf("sizeof(::Orthanc::MetricsRegistry::ActiveCounter) == %d\n", static_cast<int>(sizeof(::Orthanc::MetricsRegistry::ActiveCounter)));
-  printf("sizeof(::Orthanc::MetricsRegistry::SharedMetrics) == %d\n", static_cast<int>(sizeof(::Orthanc::MetricsRegistry::SharedMetrics)));
-  printf("sizeof(::Orthanc::MetricsRegistry::Timer) == %d\n", static_cast<int>(sizeof(::Orthanc::MetricsRegistry::Timer)));
-  printf("sizeof(::Orthanc::MultipartStreamReader) == %d\n", static_cast<int>(sizeof(::Orthanc::MultipartStreamReader)));
-  printf("sizeof(::Orthanc::NullOperationValue) == %d\n", static_cast<int>(sizeof(::Orthanc::NullOperationValue)));
-  printf("sizeof(::Orthanc::NumpyWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::NumpyWriter)));
-  printf("sizeof(::Orthanc::OrthancException) == %d\n", static_cast<int>(sizeof(::Orthanc::OrthancException)));
-  printf("sizeof(::Orthanc::PamReader) == %d\n", static_cast<int>(sizeof(::Orthanc::PamReader)));
-  printf("sizeof(::Orthanc::PamWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::PamWriter)));
-  printf("sizeof(::Orthanc::ParsedDicomCache) == %d\n", static_cast<int>(sizeof(::Orthanc::ParsedDicomCache)));
-  printf("sizeof(::Orthanc::ParsedDicomCache::Accessor) == %d\n", static_cast<int>(sizeof(::Orthanc::ParsedDicomCache::Accessor)));
-  printf("sizeof(::Orthanc::ParsedDicomDir) == %d\n", static_cast<int>(sizeof(::Orthanc::ParsedDicomDir)));
-  printf("sizeof(::Orthanc::ParsedDicomFile) == %d\n", static_cast<int>(sizeof(::Orthanc::ParsedDicomFile)));
-  printf("sizeof(::Orthanc::PngReader) == %d\n", static_cast<int>(sizeof(::Orthanc::PngReader)));
-  printf("sizeof(::Orthanc::PngWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::PngWriter)));
-  printf("sizeof(::Orthanc::RemoteModalityParameters) == %d\n", static_cast<int>(sizeof(::Orthanc::RemoteModalityParameters)));
-  printf("sizeof(::Orthanc::RestApiHierarchy) == %d\n", static_cast<int>(sizeof(::Orthanc::RestApiHierarchy)));
-  printf("sizeof(::Orthanc::RestApiHierarchy::Resource) == %d\n", static_cast<int>(sizeof(::Orthanc::RestApiHierarchy::Resource)));
-  printf("sizeof(::Orthanc::RestApiPath) == %d\n", static_cast<int>(sizeof(::Orthanc::RestApiPath)));
-  printf("sizeof(::Orthanc::SQLite::Connection) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::Connection)));
-  printf("sizeof(::Orthanc::SQLite::FunctionContext) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::FunctionContext)));
-  printf("sizeof(::Orthanc::SQLite::Statement) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::Statement)));
-  printf("sizeof(::Orthanc::SQLite::StatementId) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::StatementId)));
-  printf("sizeof(::Orthanc::SQLite::StatementReference) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::StatementReference)));
-  printf("sizeof(::Orthanc::SQLite::Transaction) == %d\n", static_cast<int>(sizeof(::Orthanc::SQLite::Transaction)));
-  printf("sizeof(::Orthanc::Semaphore) == %d\n", static_cast<int>(sizeof(::Orthanc::Semaphore)));
-  printf("sizeof(::Orthanc::SequenceOfOperationsJob) == %d\n", static_cast<int>(sizeof(::Orthanc::SequenceOfOperationsJob)));
-  printf("sizeof(::Orthanc::SequenceOfOperationsJob::IObserver) == %d\n", static_cast<int>(sizeof(::Orthanc::SequenceOfOperationsJob::IObserver)));
-  printf("sizeof(::Orthanc::SequenceOfOperationsJob::Lock) == %d\n", static_cast<int>(sizeof(::Orthanc::SequenceOfOperationsJob::Lock)));
-  printf("sizeof(::Orthanc::SerializationToolbox) == %d\n", static_cast<int>(sizeof(::Orthanc::SerializationToolbox)));
-  printf("sizeof(::Orthanc::SetOfCommandsJob) == %d\n", static_cast<int>(sizeof(::Orthanc::SetOfCommandsJob)));
-  printf("sizeof(::Orthanc::SetOfInstancesJob) == %d\n", static_cast<int>(sizeof(::Orthanc::SetOfInstancesJob)));
-  printf("sizeof(::Orthanc::SharedArchive) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedArchive)));
-  printf("sizeof(::Orthanc::SharedArchive::Accessor) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedArchive::Accessor)));
-  printf("sizeof(::Orthanc::SharedLibrary) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedLibrary)));
-  printf("sizeof(::Orthanc::SharedMessageQueue) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedMessageQueue)));
-  printf("sizeof(::Orthanc::StorageAccessor) == %d\n", static_cast<int>(sizeof(::Orthanc::StorageAccessor)));
-  printf("sizeof(::Orthanc::StreamBlockReader) == %d\n", static_cast<int>(sizeof(::Orthanc::StreamBlockReader)));
-  printf("sizeof(::Orthanc::StringMatcher) == %d\n", static_cast<int>(sizeof(::Orthanc::StringMatcher)));
-  printf("sizeof(::Orthanc::StringOperationValue) == %d\n", static_cast<int>(sizeof(::Orthanc::StringOperationValue)));
-  printf("sizeof(::Orthanc::SystemToolbox) == %d\n", static_cast<int>(sizeof(::Orthanc::SystemToolbox)));
-  printf("sizeof(::Orthanc::TemporaryFile) == %d\n", static_cast<int>(sizeof(::Orthanc::TemporaryFile)));
-  printf("sizeof(::Orthanc::Toolbox) == %d\n", static_cast<int>(sizeof(::Orthanc::Toolbox)));
-  printf("sizeof(::Orthanc::Toolbox::LinesIterator) == %d\n", static_cast<int>(sizeof(::Orthanc::Toolbox::LinesIterator)));
-  printf("sizeof(::Orthanc::WebServiceParameters) == %d\n", static_cast<int>(sizeof(::Orthanc::WebServiceParameters)));
-  printf("sizeof(::Orthanc::ZipReader) == %d\n", static_cast<int>(sizeof(::Orthanc::ZipReader)));
-  printf("sizeof(::Orthanc::ZipWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::ZipWriter)));
-  printf("sizeof(::Orthanc::ZipWriter::IOutputStream) == %d\n", static_cast<int>(sizeof(::Orthanc::ZipWriter::IOutputStream)));
-  printf("sizeof(::Orthanc::ZipWriter::MemoryStream) == %d\n", static_cast<int>(sizeof(::Orthanc::ZipWriter::MemoryStream)));
-  printf("sizeof(::Orthanc::ZlibCompressor) == %d\n", static_cast<int>(sizeof(::Orthanc::ZlibCompressor)));