From d3f58f038068bca03e659dff7c91443d5eb0138f Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Thu, 16 Nov 2023 12:42:28 -0500 Subject: [PATCH 1/7] added environment variable to enable pre-loading of TREs (#601) * merge develop/preload-TREs * fix build errors * #including some TREs * "export" TRE routines as "static" * struct for pre-loaded TREs rather than "void*" * start working on resolving preloaded TREs * retrievePreloadedTREHandler() to match nitf_PluginRegistry_retrieveTREHandler() * preload a TRE * preload several TREs * fix duplicate defs * fix compiler warning * use macros to remove multiple-defined symbols * keep a few TREs as plugins for testing * preloaded TRE stuff needs to be in PluginHandler so that nitf_PluginRegistry_retrieveTREHandler() "just works" * remove another multiple-defined symbols * assume plug-in that fails is "preloaded" * remove VCXPROJ for TREs that are preloaded * don't preload ANY TREs to preserve existing behavior * be sure all nrt_DLL fields are initialized * revert whitespace changes * added a preloaded TEST_PRELOADED_DES TRE * the TRE id could have underscores in it, so search from the end. * preload TREs, but disable them * allow preloaded TREs to be enabled/disabled * allow all TREs to be enabled (or disabled) * don't need to call setNitfPluginPath() as much with preloaded TREs * always build TEST_DES as a DLL * strongly-typed TEST_DES TRE * strongly-typed TEST_DES TRE * set things up so a different set of preloaded handlers could be used * call nitf_PluginRegistry_PreloadedTREHandlerEnable() for TREs used in unittests * only one chance to set NITF_PLUGIN_PATH * allow TREs to be preloaded (enabled) outside of code via NITF_PRELOAD_TRES * fix build error: limited static initialization in C * NRT_BOOL vs bool, C/C++ :-( --- UnitTest/UnitTest.cpp | 4 +- .../c/nitf/include/nitf/PluginIdentifier.h | 2 +- modules/c/nitf/source/PluginRegistry.c | 85 ++++++++++++++++--- modules/c/nitf/source/TREs.c | 4 +- modules/c/nrt/include/nrt/Types.h | 10 ++- 5 files changed, 86 insertions(+), 19 deletions(-) diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 96add941b..ea4c5718f 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -8,6 +8,8 @@ TEST_MODULE_INITIALIZE(methodName) { // module initialization code - nitf_PluginRegistry_PreloadedTREHandlersEnable(NRT_TRUE); + //nitf_PluginRegistry_PreloadedTREHandlersEnable(NRT_TRUE); + _putenv("NITF_PRELOADED_TRE_HANDLERS_ENABLE=default"); + nitf::Test::j2kSetNitfPluginPath(); } \ No newline at end of file diff --git a/modules/c/nitf/include/nitf/PluginIdentifier.h b/modules/c/nitf/include/nitf/PluginIdentifier.h index 125ccd902..4f025bc58 100644 --- a/modules/c/nitf/include/nitf/PluginIdentifier.h +++ b/modules/c/nitf/include/nitf/PluginIdentifier.h @@ -70,7 +70,7 @@ typedef struct _nitf_TREPreloaded const char* name; NITF_PLUGIN_INIT_FUNCTION init; NITF_PLUGIN_TRE_HANDLER_FUNCTION handler; - NITF_BOOL enabled; // most preloaded TREs are disabled by default + int enabled; // most preloaded TREs are "not set" (disabled) by default } nitf_TREPreloaded; /* diff --git a/modules/c/nitf/source/PluginRegistry.c b/modules/c/nitf/source/PluginRegistry.c index e675d5360..992cccd7a 100644 --- a/modules/c/nitf/source/PluginRegistry.c +++ b/modules/c/nitf/source/PluginRegistry.c @@ -522,7 +522,7 @@ nitf_PluginRegistry_loadPlugin(const char* fullName, nitf_Error* error) nitf_Utils_baseName(keyName, fullName, NITF_DLL_EXTENSION); /* Now init the plugin!!! */ - ident = doInit(dll, keyName, error); + ident = doInit(dll, keyName, error); return insertPlugin_("Successfully loaded plugin: [%s] at [%p]\n", reg, ident, dll, error); } @@ -971,8 +971,59 @@ insertCreator(nitf_DLL* dso, // Somebody might want to use a different set of preloadedTREs, or we might even want multiple // sets of preloaded TREs. There's nothing to support either of those right now, but it's easy enough -// to put the infrastructure in place to make it easy to hook-up. -extern nitf_TREPreloaded defaultPreloadedTREs[]; +// to put the infrastructure in place. +static nitf_TREPreloaded* getPreloadedTREs(const char* name) +{ + // Convert a name (e.g., "default") to a set of preloaded TREs. + // Only "default" is currently supported; see TREs.c + if (strcmp(name, "default") == 0) + { + extern nitf_TREPreloaded defaultPreloadedTREs[]; + return defaultPreloadedTREs; + } + return NULL; +} + +static void enable_notset_TREs(nitf_TREPreloaded preloadedTREs[], NITF_BOOL enable) +{ + // NITF_PRELOAD_TRES is set, update all TREs which haven't been touched + for (size_t i = 0;; i++) + { + const char* pKeyName = preloadedTREs[i].name; + if (pKeyName == NULL) // end of list + { + return; + } + if (preloadedTREs[i].enabled < 0) // default is -1 "not set" + { + preloadedTREs[i].enabled = enable; + } + } +} +static nitf_TREPreloaded* getNitfPreloadedTREs(const char* name) +{ + // If NITF_PRELOADED_TRE_HANDLERS_ENABLE is set to *name*", we'll preload those TREs. + // This will NOT override a call to nitf_PluginRegistry_PreloadedTREHandlersEnable(); + // by default, the `enabled` status of TREs is set to -1 "not set." + const char* envVar = getenv("NITF_PRELOADED_TRE_HANDLERS_ENABLE"); + if ((envVar != NULL) && (strcmp(envVar, name) == 0)) + { + nitf_TREPreloaded* preloadedTREs = getPreloadedTREs(name); + if (preloadedTREs != NULL) + { + enable_notset_TREs(preloadedTREs, NRT_TRUE /*enable*/); + return preloadedTREs; + } + } + + // Enviroment variable not set (or not set to *name*), return preloaded TREs as-is. + return getPreloadedTREs(name); +} +static nitf_TREPreloaded* getDefaultPreloadedTREs() +{ + return getNitfPreloadedTREs("default"); +} + static nitf_TREPreloaded* findPreloadedTRE_(nitf_TREPreloaded preloadedTREs[], const char* keyName) { if (preloadedTREs == NULL) @@ -1000,9 +1051,14 @@ static nitf_TREPreloaded* findPreloadedTRE_(nitf_TREPreloaded preloadedTREs[], c static const nitf_TREPreloaded* findPreloadedTRE(nitf_TREPreloaded preloadedTREs[], const char* keyName) { const nitf_TREPreloaded* retval = findPreloadedTRE_(preloadedTREs, keyName); - if ((retval != NULL) && (retval->enabled)) + if (retval != NULL) { - return retval; + if (retval->enabled < 0) + { + return NULL; // "not set" == disabled + } + const NRT_BOOL enabled = retval->enabled ? NRT_TRUE : NRT_FALSE; + return enabled ? retval : NULL; } return NULL; } @@ -1010,10 +1066,15 @@ static const nitf_TREPreloaded* findPreloadedTRE(nitf_TREPreloaded preloadedTREs static NITF_BOOL PreloadedTREHandlerEnable(nitf_TREPreloaded preloadedTREs[], const char* keyName, NITF_BOOL enable) { + if (preloadedTREs == NULL) + { + return NRT_FALSE; + } + nitf_TREPreloaded* result = findPreloadedTRE_(preloadedTREs, keyName); if (result != NULL) { - result->enabled = enable; + result->enabled = enable ? NRT_TRUE : NRT_FALSE; return NRT_TRUE; } return NRT_FALSE; @@ -1021,7 +1082,7 @@ static NITF_BOOL PreloadedTREHandlerEnable(nitf_TREPreloaded preloadedTREs[], NITFAPI(NITF_BOOL) nitf_PluginRegistry_PreloadedTREHandlerEnable(const char* keyName, NITF_BOOL enable) { - return PreloadedTREHandlerEnable(defaultPreloadedTREs, keyName, enable); + return PreloadedTREHandlerEnable(getDefaultPreloadedTREs(), keyName, enable); } static void preloadedTREHandlersEnable(nitf_TREPreloaded preloadedTREs[], NITF_BOOL enable) @@ -1038,14 +1099,13 @@ static void preloadedTREHandlersEnable(nitf_TREPreloaded preloadedTREs[], NITF_B { return; } - - preloadedTREs[i].enabled = enable; + preloadedTREs[i].enabled = enable ? NRT_TRUE : NRT_FALSE; } } NITFAPI(void) nitf_PluginRegistry_PreloadedTREHandlersEnable(NITF_BOOL enable) { - preloadedTREHandlersEnable(defaultPreloadedTREs, enable); + preloadedTREHandlersEnable(getDefaultPreloadedTREs(), enable); } /* @@ -1067,7 +1127,6 @@ static const char** preload_doInit(NITF_PLUGIN_INIT_FUNCTION init, const char* p static NRT_BOOL preloadTRE(nitf_TREPreloaded preloadedTREs[], const char* keyName, nitf_Error* error) { - const char** ident; nitf_PluginRegistry* reg = nitf_PluginRegistry_getInstance(error); /* Construct the DLL object */ @@ -1087,7 +1146,7 @@ static NRT_BOOL preloadTRE(nitf_TREPreloaded preloadedTREs[], dll->dsoMain = (NRT_DLL_FUNCTION_PTR)plugin->handler; /* Now init the plugin!!! */ - ident = preload_doInit(plugin->init, keyName, error); + const char** ident = preload_doInit(plugin->init, keyName, error); return insertPlugin_("Successfully pre-loaded plugin: [%s] at [%p]\n", reg, ident, dll, error); } @@ -1173,7 +1232,7 @@ nitf_PluginRegistry_retrieveTREHandler(nitf_PluginRegistry* reg, int* hadError, nitf_Error* error) { - return retrieveTREHandler(defaultPreloadedTREs, reg, treIdent, hadError, error); + return retrieveTREHandler(getDefaultPreloadedTREs(), reg, treIdent, hadError, error); } NITFPROT(nitf_CompressionInterface*) diff --git a/modules/c/nitf/source/TREs.c b/modules/c/nitf/source/TREs.c index c8cbf1825..8ac463b98 100644 --- a/modules/c/nitf/source/TREs.c +++ b/modules/c/nitf/source/TREs.c @@ -105,7 +105,7 @@ static nitf_TREHandler* TEST_PRELOADED_DES_handler(nitf_Error* error) { /******************************************************************************/ #define NITF_preload_TRE_(Tre_, enabled_) { #Tre_, Tre_##_init, Tre_##_handler, enabled_ } -#define NITF_preload_TRE(Tre_) NITF_preload_TRE_(Tre_, NRT_FALSE /*enabled*/) +#define NITF_preload_TRE(Tre_) NITF_preload_TRE_(Tre_, -1 /*not set*/) nitf_TREPreloaded defaultPreloadedTREs[] = { // Not preloading any TREs right now: with the existing system, @@ -122,7 +122,9 @@ nitf_TREPreloaded defaultPreloadedTREs[] = { NITF_preload_TRE(JITCID), NITF_preload_TRE(PTPRAA), NITF_preload_TRE(RPFHDR), + NITF_preload_TRE(XML_DATA_CONTENT), + //NITF_preload_TRE(TEST_DES), // This should ALWAYS come from the DLL/SO NITF_preload_TRE_(TEST_PRELOADED_DES, NRT_TRUE /*enabled*/), { NULL, NULL, NULL, NRT_FALSE } // end of list diff --git a/modules/c/nrt/include/nrt/Types.h b/modules/c/nrt/include/nrt/Types.h index 5788684fa..58a2a2420 100644 --- a/modules/c/nrt/include/nrt/Types.h +++ b/modules/c/nrt/include/nrt/Types.h @@ -159,9 +159,13 @@ typedef int nrt_CreationFlags; #define NRT_SUCCESS (1) #define NRT_FAILURE (0) -#define NRT_TRUE (1) -#define NRT_FALSE (0) - +#ifdef __cplusplus + #define NRT_TRUE (true) + #define NRT_FALSE (false) +#else + #define NRT_TRUE (1) + #define NRT_FALSE (0) +#endif #if defined(__cplusplus) && !defined(SWIGPYTHON) // "enum class" for C++ w/o SWIG From 8d8184c27e5f9e4ef13dc29e0be917de0cfd36fc Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Fri, 17 Nov 2023 11:16:17 -0500 Subject: [PATCH 2/7] NITRO can now build DLLs (#602) * project changes to minimize changes when building a DLL * CODA_OSS -> NITRO_NITFCPP * build NITF-C++ as a DLL * Revert "build NITF-C++ as a DLL" This reverts commit 617449079da348d7f713e210b2d5e3d5ef5effd6. * more exports from CODA-OSS * link against CODA-OSS.DLL * Function uses '18832' bytes of stack. Consider moving some data to heap. This reverts commit 163e0eddd3c8f3f2152b6ba0447486473ea73649. * get ready to make NITF-C a DLL * fix errors when building as a DLL * need to export all of NRT too * more tweaks in preparation for building DLLs * export functions for unit-testing * build as DLLs in Visual Studio * NRT_DLL -> NITRO_NRT_DLL * remove CODA_OSS_DLL from VCXPROJ * trying to fix cmake build * Revert "trying to fix cmake build" This reverts commit 3caedb8c435aedd5477f39a01ca1b75528770ddb. * back to building LIBs for CMake/WAF --- UnitTest/UnitTest.vcxproj | 6 +- UnitTest/pch.h | 8 -- .../coda-oss/modules/c++/coda-oss.vcxproj | 8 +- .../c++/config/include/config/Exports.h | 11 +-- externals/coda-oss/modules/c++/pch.h | 7 +- .../sio.lite/include/sio/lite/FileHeader.h | 4 +- .../sio.lite/include/sio/lite/FileReader.h | 4 - .../sio.lite/include/sio/lite/SioFileReader.h | 7 +- .../sio.lite/include/sio/lite/StreamReader.h | 4 +- .../modules/c++/sys/include/sys/FileFinder.h | 9 +- modules/c++/nitf-c++.vcxproj | 11 ++- modules/c++/nitf/apps/show_nitf++/pch.h | 5 - .../nitf/apps/show_nitf++/show_nitf++.vcxproj | 3 + modules/c++/nitf/include/nitf/exports.hpp | 21 ++-- modules/c++/pch.h | 8 +- modules/c/j2k/source/OpenJPEGImpl.c | 8 ++ modules/c/nitf-c.vcxproj | 3 + modules/c/nitf-c.vcxproj.filters | 3 + modules/c/nitf/TEST_DES.vcxproj | 2 + modules/c/nitf/include/nitf/BandInfo.h | 2 +- modules/c/nitf/include/nitf/Defines.h | 2 +- modules/c/nitf/include/nitf/Field.h | 4 +- modules/c/nitf/include/nitf/ImageIO.h | 36 +++---- modules/c/nitf/include/nitf/NitfWriter.h | 8 +- modules/c/nitf/include/nitf/PluginRegistry.h | 8 +- modules/c/nitf/include/nitf/System.h | 2 +- modules/c/nitf/source/Field.c | 4 +- modules/c/nitf/source/ImageIO.c | 4 +- modules/c/nitf/source/TRE.c | 2 +- modules/c/nrt/include/nrt/Defines.h | 13 +++ modules/c/nrt/include/nrt/Error.h | 4 +- modules/c/nrt/include/nrt/Exports.h | 97 +++++++++++++++++++ modules/c/nrt/include/nrt/Utils.h | 22 ++--- modules/c/nrt/source/Utils.c | 16 +-- modules/c/pch.h | 3 + nitro.sln | 12 +-- 36 files changed, 241 insertions(+), 130 deletions(-) create mode 100644 modules/c/nrt/include/nrt/Exports.h diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index 1baac7b11..c488c71f1 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -254,15 +254,15 @@ + + {9997e895-5161-4ddf-8f3f-099894cb2f21} + {8f357a19-799e-4971-850e-3f28485c130b} {f06550ad-cfc7-40b8-8727-6c82c69a8982} - - {78849481-d356-4cc7-b182-31c21f857ed1} - diff --git a/UnitTest/pch.h b/UnitTest/pch.h index 37e984a9e..24ccf55db 100644 --- a/UnitTest/pch.h +++ b/UnitTest/pch.h @@ -26,14 +26,6 @@ #include #include -#pragma comment(lib, "io-c++") -#pragma comment(lib, "io-c++") -#pragma comment(lib, "except-c++") -#pragma comment(lib, "sys-c++") -#pragma comment(lib, "str-c++") -#pragma comment(lib, "sio.lite-c++.lib") -#pragma comment(lib, "math-c++") -#pragma comment(lib, "mt-c++") #include #include diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj b/externals/coda-oss/modules/c++/coda-oss.vcxproj index 77af044c5..c500dcd82 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj @@ -531,12 +531,12 @@ - DynamicLibrary + StaticLibrary true v143 - DynamicLibrary + StaticLibrary false v143 true @@ -566,7 +566,7 @@ Level4 true - _DEBUG;_LIB;%(PreprocessorDefinitions);CODA_OSS_EXPORTS;CODA_OSS_DLL;MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 + _DEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 pch.h cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include Use @@ -596,7 +596,7 @@ true true true - NDEBUG;_LIB;%(PreprocessorDefinitions);CODA_OSS_EXPORTS;CODA_OSS_DLL;MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 + NDEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 pch.h cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include Use diff --git a/externals/coda-oss/modules/c++/config/include/config/Exports.h b/externals/coda-oss/modules/c++/config/include/config/Exports.h index 6b77d9fd7..50ea06c85 100644 --- a/externals/coda-oss/modules/c++/config/include/config/Exports.h +++ b/externals/coda-oss/modules/c++/config/include/config/Exports.h @@ -1,5 +1,3 @@ -#ifndef CODA_OSS_config_Exports_h_INCLUDED_ -#define CODA_OSS_config_Exports_h_INCLUDED_ #pragma once #include "config/compiler_extensions.h" @@ -10,8 +8,11 @@ // // Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. #if !defined(CODA_OSS_LIB) && !defined(CODA_OSS_DLL) - #define CODA_OSS_LIB 1 - //#define CODA_OSS_DLL 1 + //#define CODA_OSS_DLL 1 // Symbols must be exported and imported (see below). + #define CODA_OSS_LIB 1 // Static library, all symbols visible. +#endif +#if !defined(CODA_OSS_LIB) && !defined(CODA_OSS_DLL) + #error "One of CODA_OSS_LIB pr CODA_OSS_DLL must be #define'd'" #endif #if defined(CODA_OSS_LIB) && defined(CODA_OSS_DLL) #error "Both CODA_OSS_LIB and CODA_OSS_DLL are #define'd'" @@ -50,5 +51,3 @@ #if defined(_MSC_VER) #pragma warning(disable: 4251) // '...' : class '...' needs to have dll-interface to be used by clients of struct '...' #endif - -#endif // CODA_OSS_config_Exports_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/pch.h b/externals/coda-oss/modules/c++/pch.h index 7952e6efa..664d700de 100644 --- a/externals/coda-oss/modules/c++/pch.h +++ b/externals/coda-oss/modules/c++/pch.h @@ -5,8 +5,10 @@ // Do not add files here that you will be updating frequently as this negates the performance advantage. #pragma once -#ifndef CODA_OSS_pch_h_INCLUDED_ -#define CODA_OSS_pch_h_INCLUDED_ + +// We're building in Visual Studio ... used to control where we get a little bit +// of config info +#define CODA_OSS_PCH 1 #include "coda_oss/CPlusPlus.h" #include "config/disable_compiler_warnings.h" @@ -114,4 +116,3 @@ CODA_OSS_disable_warning_pop #include "hdf5/lite/H5_.h" #pragma comment(lib, "hdf5-c++.lib") -#endif //CODA_OSS_pch_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileHeader.h b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileHeader.h index a5633e509..1a76c1676 100644 --- a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileHeader.h +++ b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileHeader.h @@ -19,6 +19,7 @@ * see . * */ +#pragma once #ifndef __SIO_LITE_FILE_HEADER_H__ #define __SIO_LITE_FILE_HEADER_H__ @@ -28,6 +29,7 @@ #include #include #include +#include "config/Exports.h" #include "sio/lite/UserDataDictionary.h" #include "sio/lite/InvalidHeaderException.h" #include "sio/lite/UnsupportedDataTypeException.h" @@ -37,7 +39,7 @@ namespace sio namespace lite { -class FileHeader +class CODA_OSS_API FileHeader { public: /** Unsigned byte data */ diff --git a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileReader.h b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileReader.h index b94fbc1ae..885b3b68b 100644 --- a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileReader.h +++ b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/FileReader.h @@ -19,10 +19,6 @@ * see . * */ -#ifndef CODA_OSS_sio_lite_FileReader_h_INCLUDED_ -#define CODA_OSS_sio_lite_FileReader_h_INCLUDED_ #pragma once - #include "sio/lite/SioFileReader.h" -#endif // CODA_OSS_sio_lite_FileReader_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/SioFileReader.h b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/SioFileReader.h index 446476dfc..54fe31c32 100644 --- a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/SioFileReader.h +++ b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/SioFileReader.h @@ -19,12 +19,14 @@ * see . * */ +#pragma once #ifndef __SIO_LITE_FILE_READER_H__ #define __SIO_LITE_FILE_READER_H__ #include #include #include +#include "config/Exports.h" #include "sio/lite/InvalidHeaderException.h" #include "sio/lite/StreamReader.h" @@ -80,12 +82,9 @@ namespace lite \endcode */ -class FileReader : public StreamReader, public io::Seekable +class CODA_OSS_API FileReader : public StreamReader, public io::Seekable { - - public: - /** Constructor */ FileReader() : StreamReader() {} diff --git a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/StreamReader.h b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/StreamReader.h index 982b8900f..efa9897ff 100644 --- a/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/StreamReader.h +++ b/externals/coda-oss/modules/c++/sio.lite/include/sio/lite/StreamReader.h @@ -19,10 +19,12 @@ * see . * */ +#pragma once #ifndef __SIO_LITE_STREAM_READER_H__ #define __SIO_LITE_STREAM_READER_H__ #include +#include "config/Exports.h" #include "sio/lite/FileHeader.h" namespace sio @@ -87,7 +89,7 @@ namespace lite \endcode * */ -class StreamReader : public io::InputStream +class CODA_OSS_API StreamReader : public io::InputStream { public: /** Constructor */ diff --git a/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h b/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h index 0485de3c8..00b071c14 100644 --- a/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h +++ b/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h @@ -20,6 +20,7 @@ * */ +#pragma once #ifndef __SYS_FILE_FINDER_H__ #define __SYS_FILE_FINDER_H__ @@ -167,7 +168,7 @@ struct FileFinder final // until either the file is found or we stop at a ".git" directory. // // This (obviously) might take a while, so consider whether the result should be cached. -coda_oss::filesystem::path findFirstFile(const coda_oss::filesystem::path& startingDirectory, const coda_oss::filesystem::path& filename); +CODA_OSS_API coda_oss::filesystem::path findFirstFile(const coda_oss::filesystem::path& startingDirectory, const coda_oss::filesystem::path& filename); coda_oss::filesystem::path findFirstDirectory(const coda_oss::filesystem::path& startingDirectory, const coda_oss::filesystem::path& dir); // This is here most to avoid creating a new module for a few utility routines @@ -175,11 +176,11 @@ namespace test // i.e., sys::test { // Try to find the specified "root" directory starting at the given path. // Used by unittest to find sample files. - coda_oss::filesystem::path findRootDirectory(const coda_oss::filesystem::path& p, const std::string& rootName, + CODA_OSS_API coda_oss::filesystem::path findRootDirectory(const coda_oss::filesystem::path& p, const std::string& rootName, std::function isRoot); - coda_oss::filesystem::path findCMakeBuildRoot(const coda_oss::filesystem::path& p); - bool isCMakeBuild(const coda_oss::filesystem::path& p); + CODA_OSS_API coda_oss::filesystem::path findCMakeBuildRoot(const coda_oss::filesystem::path& p); + bool CODA_OSS_API isCMakeBuild(const coda_oss::filesystem::path& p); coda_oss::filesystem::path findCMakeInstallRoot(const coda_oss::filesystem::path& p); bool isCMakeInstall(const coda_oss::filesystem::path& p); diff --git a/modules/c++/nitf-c++.vcxproj b/modules/c++/nitf-c++.vcxproj index 6d12f0550..ab90809a3 100644 --- a/modules/c++/nitf-c++.vcxproj +++ b/modules/c++/nitf-c++.vcxproj @@ -171,6 +171,9 @@ + + {9997e895-5161-4ddf-8f3f-099894cb2f21} + {f06550ad-cfc7-40b8-8727-6c82c69a8982} @@ -216,7 +219,7 @@ Level4 true - _DEBUG;%(PreprocessorDefinitions) + _DEBUG;%(PreprocessorDefinitions); true $(ProjectDir)nitf\include;$(ProjectDir)..\c\nrt\include;$(ProjectDir)..\c\nitf\include;$(ProjectDir)..\c\j2k\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use @@ -239,7 +242,7 @@ true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\install-$(Configuration)-$(Platform).$(PlatformToolset)\lib\ + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\install-$(Configuration)-$(Platform).$(PlatformToolset)\lib\ @@ -250,7 +253,7 @@ true true true - NDEBUG;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions); true $(ProjectDir)nitf\include;$(ProjectDir)..\c\nrt\include;$(ProjectDir)..\c\nitf\include;$(ProjectDir)..\c\j2k\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use @@ -270,7 +273,7 @@ true true true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\install-$(Configuration)-$(Platform).$(PlatformToolset)\lib\ + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\install-$(Configuration)-$(Platform).$(PlatformToolset)\lib\ diff --git a/modules/c++/nitf/apps/show_nitf++/pch.h b/modules/c++/nitf/apps/show_nitf++/pch.h index 9bb789761..a7ba61b5c 100644 --- a/modules/c++/nitf/apps/show_nitf++/pch.h +++ b/modules/c++/nitf/apps/show_nitf++/pch.h @@ -55,11 +55,6 @@ #include #include -#pragma comment(lib, "io-c++") -#pragma comment(lib, "except-c++") -#pragma comment(lib, "sys-c++") -#pragma comment(lib, "str-c++") - #pragma comment(lib, "ws2_32") diff --git a/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj b/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj index 944eafbc5..17cc8f186 100644 --- a/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj +++ b/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj @@ -113,6 +113,9 @@ + + {9997e895-5161-4ddf-8f3f-099894cb2f21} + {8f357a19-799e-4971-850e-3f28485c130b} diff --git a/modules/c++/nitf/include/nitf/exports.hpp b/modules/c++/nitf/include/nitf/exports.hpp index f87bfc207..54e22b906 100644 --- a/modules/c++/nitf/include/nitf/exports.hpp +++ b/modules/c++/nitf/include/nitf/exports.hpp @@ -1,17 +1,18 @@ -#ifndef NITRO_nitf_exports_hpp_INCLUDED_ -#define NITRO_nitf_exports_hpp_INCLUDED_ #pragma once #include "config/compiler_extensions.h" -// Need to specify how this code will be consumed, either CODA_OSS_LIB (static library) -// or CODA_OSS_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH +// Need to specify how this code will be consumed, either NITRO_NITFCPP_LIB (static library) +// or NITRO_NITFCPP_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH // "exporting" (building this code) and "importing" (consuming). // // Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. #if !defined(NITRO_NITFCPP_LIB) && !defined(NITRO_NITFCPP_DLL) - #define NITRO_NITFCPP_LIB 1 - //#define NITRO_NITFCPP_DLL 1 + //#define NITRO_NITFCPP_DLL 1 // Symbols must be exported and imported (see below). + #define NITRO_NITFCPP_LIB 1 // Static library, all symbols visible. +#endif +#if !defined(NITRO_NITFCPP_LIB) && !defined(NITRO_NITFCPP_DLL) + #error "One of NITRO_NITFCPP_LIB pr NITRO_NITFCPP_DLL must be #define'd'" #endif #if defined(NITRO_NITFCPP_LIB) && defined(NITRO_NITFCPP_DLL) #error "Both NITRO_NITFCPP_LIB and NITRO_NITFCPP_DLL are #define'd'" @@ -21,10 +22,10 @@ #endif // The following ifdef block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the CODA_OSS_EXPORTS +// from a DLL simpler. All files within this DLL are compiled with the NITRO_NITFCPP_EXPORTS // symbol defined on the command line. This symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see -// CODA_OSS_API functions as being imported from a DLL, whereas this DLL sees symbols +// NITRO_NITFCPP_API functions as being imported from a DLL, whereas this DLL sees symbols // defined with this macro as being exported. // https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html #ifdef NITRO_NITFCPP_EXPORTS @@ -39,8 +40,7 @@ // Actually, it seems that the linker is able to figure this out from the .LIB, so // there doesn't seem to be a need for __declspec(dllimport). Clients don't // need to #define NITRO_NITFCPP_DLL ... ? Well, almost ... it looks - // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., - // destructors) correct. + // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., destructors) correct. #define NITRO_NITFCPP_API CODA_OSS_library_import #else #define NITRO_NITFCPP_API /* "importing" a static LIB */ @@ -51,4 +51,3 @@ #pragma warning(disable: 4251) // '...' : class '...' needs to have dll-interface to be used by clients of struct '...' #endif -#endif // NITRO_nitf_exports_hpp_INCLUDED_ diff --git a/modules/c++/pch.h b/modules/c++/pch.h index 03085c4ac..00108586f 100644 --- a/modules/c++/pch.h +++ b/modules/c++/pch.h @@ -31,6 +31,7 @@ CODA_OSS_disable_warning_pop #pragma warning(disable: 5105) // macro expansion producing '...' has undefined behavior #include #pragma warning(pop) +#pragma comment(lib, "Ws2_32") #pragma warning(disable: 4619) // #pragma warning: there is no warning number '...' #pragma warning(disable: 4820) // '...': '...' bytes padding added after data member '...' @@ -58,7 +59,6 @@ CODA_OSS_disable_warning_pop #include "nitf/System.h" #include "nitf/Field.h" #include "nitf/Types.h" -#pragma comment(lib, "nitf-c") #pragma comment(lib, "openjpeg") #pragma warning(disable: 5039) // '...': pointer or reference to potentially throwing function passed to 'extern "C"' function under -EHc. Undefined behavior may occur if this function throws an exception. @@ -78,9 +78,3 @@ CODA_OSS_disable_warning_pop #include "nitf/Handle.hpp" #include "nitf/coda-oss.hpp" -#pragma comment(lib, "io-c++") -#pragma comment(lib, "except-c++") -#pragma comment(lib, "sys-c++") -#pragma comment(lib, "str-c++") -#pragma comment(lib, "mt-c++") -#pragma comment(lib, "math-c++") \ No newline at end of file diff --git a/modules/c/j2k/source/OpenJPEGImpl.c b/modules/c/j2k/source/OpenJPEGImpl.c index 11687c50f..987b6f976 100644 --- a/modules/c/j2k/source/OpenJPEGImpl.c +++ b/modules/c/j2k/source/OpenJPEGImpl.c @@ -649,6 +649,10 @@ OpenJPEG_readHeader(OpenJPEGReaderImpl *impl, nrt_Error *error) return rc; } +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable: 6262) // Function uses '18832' bytes of stack. Consider moving some data to heap. +#endif J2KPRIV( NRT_BOOL) OpenJPEG_initImage_(OpenJPEGWriterImpl *impl, j2k_WriterOptions *writerOps, OPJ_CODEC_FORMAT format, nrt_Error *error) @@ -848,6 +852,10 @@ J2KPRIV( NRT_BOOL) OpenJPEG_initImage_(OpenJPEGWriterImpl *impl, return rc; } +#if _MSC_VER +#pragma warning(pop) +#endif + J2KPRIV(NRT_BOOL) OpenJPEG_initImage_j2k(OpenJPEGWriterImpl* impl, j2k_WriterOptions* writerOps, nrt_Error* error) { return OpenJPEG_initImage_(impl, writerOps, OPJ_CODEC_J2K, error); diff --git a/modules/c/nitf-c.vcxproj b/modules/c/nitf-c.vcxproj index 4ddd12a25..0195fdf5f 100644 --- a/modules/c/nitf-c.vcxproj +++ b/modules/c/nitf-c.vcxproj @@ -74,6 +74,7 @@ true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ @@ -103,6 +104,7 @@ true true true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ @@ -206,6 +208,7 @@ + diff --git a/modules/c/nitf-c.vcxproj.filters b/modules/c/nitf-c.vcxproj.filters index 6dd32c62a..4bcb934f8 100644 --- a/modules/c/nitf-c.vcxproj.filters +++ b/modules/c/nitf-c.vcxproj.filters @@ -361,6 +361,9 @@ j2k + + nrt + diff --git a/modules/c/nitf/TEST_DES.vcxproj b/modules/c/nitf/TEST_DES.vcxproj index 58478f202..5f4c1ef73 100644 --- a/modules/c/nitf/TEST_DES.vcxproj +++ b/modules/c/nitf/TEST_DES.vcxproj @@ -81,6 +81,7 @@ true + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)\target-$(Configuration)\installwindows-latestCMake-Github\lib\ @@ -105,6 +106,7 @@ true true true + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)\target-$(Configuration)\installwindows-latestCMake-Github\lib\ diff --git a/modules/c/nitf/include/nitf/BandInfo.h b/modules/c/nitf/include/nitf/BandInfo.h index e73a9eb68..9672c29df 100644 --- a/modules/c/nitf/include/nitf/BandInfo.h +++ b/modules/c/nitf/include/nitf/BandInfo.h @@ -94,7 +94,7 @@ NITFAPI(void) nitf_BandInfo_destruct(nitf_BandInfo ** info); * \param error An error to populate upon failure * \return A new object that is identical to the old */ -NITFPROT(nitf_BandInfo *) nitf_BandInfo_clone(nitf_BandInfo * source, +NITFAPI(nitf_BandInfo *) nitf_BandInfo_clone(nitf_BandInfo * source, nitf_Error * error); /*! diff --git a/modules/c/nitf/include/nitf/Defines.h b/modules/c/nitf/include/nitf/Defines.h index 8d5038d9b..286fa20fe 100644 --- a/modules/c/nitf/include/nitf/Defines.h +++ b/modules/c/nitf/include/nitf/Defines.h @@ -32,7 +32,7 @@ * _Tre the name of the input TRE */ #ifndef NITF_PLUGIN_FUNCTION_EXPORT -#define NITF_PLUGIN_FUNCTION_EXPORT(retval_) NITFAPI(retval_) +#define NITF_PLUGIN_FUNCTION_EXPORT(retval_) NRTEXPORT(retval_) #endif #define NITF_DECLARE_PLUGIN(_Tre) \ static const char* _Tre##Ident[] = { \ diff --git a/modules/c/nitf/include/nitf/Field.h b/modules/c/nitf/include/nitf/Field.h index 2318c9b25..7df14945a 100644 --- a/modules/c/nitf/include/nitf/Field.h +++ b/modules/c/nitf/include/nitf/Field.h @@ -363,8 +363,8 @@ NITFPROT(NITF_BOOL) nitf_Field_resetLength(nitf_Field * field, * Print the contents of this Field * \param field The field object */ -NITFPROT(void) nitf_Field_print(nitf_Field * field); -NITFPROT(void) nitf_Field_snprint(char* buffer, size_t buf_size, nitf_Field* field); +NITFAPI(void) nitf_Field_print(nitf_Field * field); +NITFAPI(void) nitf_Field_snprint(char* buffer, size_t buf_size, nitf_Field* field); /*! diff --git a/modules/c/nitf/include/nitf/ImageIO.h b/modules/c/nitf/include/nitf/ImageIO.h index 1cbae8790..196456ccf 100644 --- a/modules/c/nitf/include/nitf/ImageIO.h +++ b/modules/c/nitf/include/nitf/ImageIO.h @@ -114,7 +114,7 @@ nitf_BlockingInfo; Memory allocation error\n */ -NITFPROT(nitf_BlockingInfo *) nitf_BlockingInfo_construct(nitf_Error * +NITFAPI(nitf_BlockingInfo *) nitf_BlockingInfo_construct(nitf_Error * error); /*! @@ -125,7 +125,7 @@ NITFPROT(nitf_BlockingInfo *) nitf_BlockingInfo_construct(nitf_Error * \return None */ -NITFPROT(void) nitf_BlockingInfo_destruct(nitf_BlockingInfo ** info); +NITFAPI(void) nitf_BlockingInfo_destruct(nitf_BlockingInfo ** info); /*! @@ -158,7 +158,7 @@ NITFPROT(void) nitf_BlockingInfo_destruct(nitf_BlockingInfo ** info); */ -NITFPROT(NITF_BOOL) nitf_ImageIO_writeSequential(nitf_ImageIO * nitf, +NITFAPI(NITF_BOOL) nitf_ImageIO_writeSequential(nitf_ImageIO * nitf, nitf_IOInterface* io, nitf_Error * error ); @@ -189,7 +189,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_writeSequential(nitf_ImageIO * nitf, */ -NITFPROT(NITF_BOOL) nitf_ImageIO_writeDone(nitf_ImageIO * object, +NITFAPI(NITF_BOOL) nitf_ImageIO_writeDone(nitf_ImageIO * object, nitf_IOInterface* io, nitf_Error * error); @@ -225,7 +225,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_writeDone(nitf_ImageIO * object, Invalid row count */ -NITFPROT(NITF_BOOL) nitf_ImageIO_writeRows(nitf_ImageIO * object, +NITFAPI(NITF_BOOL) nitf_ImageIO_writeRows(nitf_ImageIO * object, nitf_IOInterface* io, uint32_t numRows, uint8_t ** data, @@ -250,7 +250,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_writeRows(nitf_ImageIO * object, I/O errors */ -NITFPROT(NITF_BOOL) nitf_ImageIO_flush(nitf_ImageIO * object, +NITFAPI(NITF_BOOL) nitf_ImageIO_flush(nitf_ImageIO * object, nitf_IOInterface* io, nitf_Error * error ); @@ -686,7 +686,7 @@ typedef int (*NITF_DOWN_SAMPLE_FUNCTION) (void *input, */ -NITFPROT(nitf_ImageIO *) +NITFAPI(nitf_ImageIO *) nitf_ImageIO_construct(nitf_ImageSubheader * subheader, uint64_t offset, uint64_t length, @@ -711,7 +711,7 @@ nitf_ImageIO_construct(nitf_ImageSubheader * subheader, Memory allocation error */ -NITFPROT(nitf_ImageIO *) nitf_ImageIO_clone(nitf_ImageIO * image, +NITFAPI(nitf_ImageIO *) nitf_ImageIO_clone(nitf_ImageIO * image, nitf_Error * error ); @@ -726,7 +726,7 @@ NITFPROT(nitf_ImageIO *) nitf_ImageIO_clone(nitf_ImageIO * image, \return None */ -NITFPROT(void) nitf_ImageIO_destruct(nitf_ImageIO ** nitf); +NITFAPI(void) nitf_ImageIO_destruct(nitf_ImageIO ** nitf); /*! \brief nitf_ImageIO_read - Read a sub-window @@ -765,7 +765,7 @@ NITFPROT(void) nitf_ImageIO_destruct(nitf_ImageIO ** nitf); System I/O or memory allocation errors */ -NITFPROT(NITF_BOOL) nitf_ImageIO_read(nitf_ImageIO * nitf, +NITFAPI(NITF_BOOL) nitf_ImageIO_read(nitf_ImageIO * nitf, nitf_IOInterface* io, nitf_SubWindow * subWindow, uint8_t ** user, @@ -782,7 +782,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_read(nitf_ImageIO * nitf, \return Returns pixel size in bytes */ -NITFPROT(uint32_t) nitf_ImageIO_pixelSize(nitf_ImageIO * nitf); +NITFAPI(uint32_t) nitf_ImageIO_pixelSize(nitf_ImageIO * nitf); /*! \brief nitf_ImageIO_setFileOffset @@ -802,7 +802,7 @@ NITFPROT(uint32_t) nitf_ImageIO_pixelSize(nitf_ImageIO * nitf); I/O operation in progress */ -NITFPROT(NITF_BOOL) nitf_ImageIO_setFileOffset(nitf_ImageIO * nitf, +NITFAPI(NITF_BOOL) nitf_ImageIO_setFileOffset(nitf_ImageIO * nitf, uint64_t offset, nitf_Error * error ); @@ -833,7 +833,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_setFileOffset(nitf_ImageIO * nitf, I/O error */ -NITFPROT(nitf_BlockingInfo *) nitf_ImageIO_getBlockingInfo(nitf_ImageIO * image, +NITFAPI(nitf_BlockingInfo *) nitf_ImageIO_getBlockingInfo(nitf_ImageIO * image, nitf_IOInterface* io, nitf_Error * error ); @@ -846,7 +846,7 @@ NITFPROT(nitf_BlockingInfo *) nitf_ImageIO_getBlockingInfo(nitf_ImageIO * image, \return Returns the current enable/disable state */ -NITFPROT(int) nitf_ImageIO_setWriteCaching +NITFAPI(int) nitf_ImageIO_setWriteCaching ( nitf_ImageIO * nitf, /*!< Object to modify */ int enable /*!< Enable cached writes if true */ @@ -860,7 +860,7 @@ NITFPROT(int) nitf_ImageIO_setWriteCaching \return None */ -NITFPROT(void) nitf_ImageIO_setReadCaching +NITFAPI(void) nitf_ImageIO_setReadCaching ( nitf_ImageIO * nitf /*!< Object to modify */ ); @@ -876,7 +876,7 @@ NITFPROT(void) nitf_ImageIO_setReadCaching \return None */ -NITFPROT(void) nitf_BlockingInfo_print(nitf_BlockingInfo * info, /*!< The structure to print */ +NITFAPI(void) nitf_BlockingInfo_print(nitf_BlockingInfo * info, /*!< The structure to print */ FILE * file /*!< FILE to use for print */ ); @@ -886,7 +886,7 @@ NITFPROT(void) nitf_BlockingInfo_print(nitf_BlockingInfo * info, /*!< The struc \b nitf_ImageIO_setupDirectBlockRead does some simple checks to prepare for reading blocks directly from the NITF (bypassing any reorganization of data) */ -NITFPROT(NITF_BOOL) nitf_ImageIO_setupDirectBlockRead(nitf_ImageIO *nitf, +NITFAPI(NITF_BOOL) nitf_ImageIO_setupDirectBlockRead(nitf_ImageIO *nitf, nitf_IOInterface *io, uint32_t numBands, nitf_Error *error); @@ -903,7 +903,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_setupDirectBlockRead(nitf_ImageIO *nitf, \param blockSize The block size read \param error Error object */ -NITFPROT(uint8_t*) nitf_ImageIO_readBlockDirect(nitf_ImageIO* nitf, +NITFAPI(uint8_t*) nitf_ImageIO_readBlockDirect(nitf_ImageIO* nitf, nitf_IOInterface* io, uint32_t blockNumber, uint64_t* blockSize, diff --git a/modules/c/nitf/include/nitf/NitfWriter.h b/modules/c/nitf/include/nitf/NitfWriter.h index cdd1c3da2..3c764ef43 100644 --- a/modules/c/nitf/include/nitf/NitfWriter.h +++ b/modules/c/nitf/include/nitf/NitfWriter.h @@ -203,7 +203,7 @@ NITFAPI(NITF_BOOL) nitf_Writer_write(nitf_Writer * writer, nitf_Error * error); * \return NITF_SUCCESS on success, NITF_FAILURE otherwise * */ -NITFPROT(NITF_BOOL) nitf_Writer_writeHeader(nitf_Writer* writer, +NITFAPI(NITF_BOOL) nitf_Writer_writeHeader(nitf_Writer* writer, nitf_Off* fileLenOff, uint32_t* hdrLen, nitf_Error* error); @@ -221,7 +221,7 @@ NITFPROT(NITF_BOOL) nitf_Writer_writeHeader(nitf_Writer* writer, * * \return NITF_SUCCESS on success, NITF_FAILURE otherwise */ -NITFPROT(NITF_BOOL) +NITFAPI(NITF_BOOL) nitf_Writer_writeImageSubheader(nitf_Writer* writer, const nitf_ImageSubheader* subhdr, nitf_Version fver, @@ -242,7 +242,7 @@ nitf_Writer_writeImageSubheader(nitf_Writer* writer, * * \return NITF_SUCCESS on success, NITF_FAILURE otherwise */ -NITFPROT(NITF_BOOL) nitf_Writer_writeDESubheader(nitf_Writer* writer, +NITFAPI(NITF_BOOL) nitf_Writer_writeDESubheader(nitf_Writer* writer, const nitf_DESubheader* subhdr, uint32_t* userSublen, nitf_Version fver, @@ -261,7 +261,7 @@ NITFPROT(NITF_BOOL) nitf_Writer_writeDESubheader(nitf_Writer* writer, * * \return NITF_SUCCESS on success, NITF_FAILURE otherwise */ -NITFPROT(NITF_BOOL) nitf_Writer_writeInt64Field(nitf_Writer* writer, +NITFAPI(NITF_BOOL) nitf_Writer_writeInt64Field(nitf_Writer* writer, uint64_t field, uint32_t length, char fill, diff --git a/modules/c/nitf/include/nitf/PluginRegistry.h b/modules/c/nitf/include/nitf/PluginRegistry.h index 54feddb3f..554e04deb 100644 --- a/modules/c/nitf/include/nitf/PluginRegistry.h +++ b/modules/c/nitf/include/nitf/PluginRegistry.h @@ -94,9 +94,9 @@ nitf_PluginRegistry; * along with an error * */ -NITFPROT(nitf_PluginRegistry *) +NITFAPI(nitf_PluginRegistry *) nitf_PluginRegistry_getInstance(nitf_Error * error); -NITFPROT(nitf_PluginRegistry*) +NITFAPI(nitf_PluginRegistry*) nitf_PluginRegistry_getInstanceLog(nitf_Error* error, FILE* log); @@ -242,7 +242,7 @@ nitf_PluginRegistry_unload(nitf_PluginRegistry * reg, nitf_Error * error); * is -1 * \return The plugin main, or NULL */ -NITFPROT(nitf_TREHandler*) +NITFAPI(nitf_TREHandler*) nitf_PluginRegistry_retrieveTREHandler(nitf_PluginRegistry * reg, const char *ident, int *hadError, @@ -281,7 +281,7 @@ nitf_PluginRegistry_retrieveCompConstructor(nitf_PluginRegistry * reg, /* * Retrieves a compression interface for 'comp'. Returns NULL if this fails. */ -NITFPROT(nitf_CompressionInterface* ) +NITFAPI(nitf_CompressionInterface* ) nitf_PluginRegistry_retrieveCompInterface(const char *comp, nitf_Error* error); diff --git a/modules/c/nitf/include/nitf/System.h b/modules/c/nitf/include/nitf/System.h index 5a1bd298e..57431baba 100644 --- a/modules/c/nitf/include/nitf/System.h +++ b/modules/c/nitf/include/nitf/System.h @@ -46,7 +46,7 @@ #define NITF_GUARD NRT_GUARD #define NITF_ENDGUARD NRT_ENDGUARD #define NITF_BOOL NRT_BOOL -#define NITFAPI(RT) NRTAPI(RT) +#define NITFAPI(RT) NRTAPI(RT) #define NITFPROT(RT) NRTPROT(RT) #define NITF_ATO32 NRT_ATO32 #define NITF_ATOU32 NRT_ATOU32 diff --git a/modules/c/nitf/source/Field.c b/modules/c/nitf/source/Field.c index 656b2bd17..bda591d2c 100644 --- a/modules/c/nitf/source/Field.c +++ b/modules/c/nitf/source/Field.c @@ -1121,11 +1121,11 @@ static void nitf_Field_snprint_(char* buffer, size_t buf_size, nitf_Field* field break; } } -NITFPROT(void) nitf_Field_print(nitf_Field * field) +NITFAPI(void) nitf_Field_print(nitf_Field * field) { nitf_Field_snprint_(NULL /*buffer*/, 0 /*buf_size*/, field); } -NITFPROT(void) nitf_Field_snprint(char* buffer, size_t buf_size, nitf_Field* field) +NITFAPI(void) nitf_Field_snprint(char* buffer, size_t buf_size, nitf_Field* field) { nitf_Field_snprint_(buffer, buf_size, field); } diff --git a/modules/c/nitf/source/ImageIO.c b/modules/c/nitf/source/ImageIO.c index 989aef30e..d08e513ba 100644 --- a/modules/c/nitf/source/ImageIO.c +++ b/modules/c/nitf/source/ImageIO.c @@ -3566,7 +3566,7 @@ NITFPROT(NITF_BOOL) nitf_ImageIO_flush(nitf_ImageIO * object, /*========================= nitf_ImageIO_writeSequential =====================*/ -NITFPROT(NITF_BOOL) nitf_ImageIO_writeSequential(nitf_ImageIO * nitf, +NITFAPI(NITF_BOOL) nitf_ImageIO_writeSequential(nitf_ImageIO * nitf, nitf_IOInterface* io, nitf_Error * error) { @@ -3862,7 +3862,7 @@ NITFPROT(nitf_BlockingInfo *) nitf_BlockingInfo_construct(nitf_Error * /*=================== nitf_BlockingInfo_destruct ===========================*/ -NITFPROT(void) nitf_BlockingInfo_destruct(nitf_BlockingInfo ** info) +NITFAPI(void) nitf_BlockingInfo_destruct(nitf_BlockingInfo ** info) { NITF_FREE(*info); *info = NULL; diff --git a/modules/c/nitf/source/TRE.c b/modules/c/nitf/source/TRE.c index 154f9acc2..55058c85d 100644 --- a/modules/c/nitf/source/TRE.c +++ b/modules/c/nitf/source/TRE.c @@ -25,7 +25,7 @@ /* IF desc is null, look for it, if I can't load then fail */ -NITFAPI(nitf_TRE *) nitf_TRE_createSkeleton(const char* tag, +NITFPROT(nitf_TRE *) nitf_TRE_createSkeleton(const char* tag, nitf_Error* error) { nitf_TRE *tre = (nitf_TRE *) NITF_MALLOC(sizeof(nitf_TRE)); diff --git a/modules/c/nrt/include/nrt/Defines.h b/modules/c/nrt/include/nrt/Defines.h index 05cb856d2..ae969fdf7 100644 --- a/modules/c/nrt/include/nrt/Defines.h +++ b/modules/c/nrt/include/nrt/Defines.h @@ -38,6 +38,8 @@ # define NRT_BOOL int #endif +#include "nrt/Exports.h" + #if defined(WIN32) || defined(_WIN32) /* Negotiate the meaning of NRTAPI, NRTPROT (for public and protected) */ # if defined(NRT_MODULE_EXPORTS) @@ -74,6 +76,17 @@ #define NRT_SNPRINTF snprintf #define NRT_VSNPRINTF vsnprintf +// Export no matter what ... when you KNOW you're building a DLL/SO, e.g. a TRE +#define NRTEXPORT(RT) NRT_C NITRO_NRT_library_export RT // extern "C" __declspec(dllexport) void* foo(); + +// Adjust the above ... but w/o chaning too much :-( +#if defined(NITRO_NRT_DLL) // See Exports.h + #ifdef NRTAPI + #undef NRTAPI + #define NRTAPI(RT) NRTEXPORT(RT) + #endif +#endif + /* * This section describes a set of macros to help with * C++ compilation. The 'extern C' set is required to diff --git a/modules/c/nrt/include/nrt/Error.h b/modules/c/nrt/include/nrt/Error.h index 146e06ece..440e909e1 100644 --- a/modules/c/nrt/include/nrt/Error.h +++ b/modules/c/nrt/include/nrt/Error.h @@ -103,7 +103,7 @@ typedef struct _NRT_Error * \param func Context info from NRT_CTXT (if C99) & \param level The level of error (This is an enum value) */ -NRTPROT(void) nrt_Error_init(nrt_Error * error, const char *message, +NRTAPI(void) nrt_Error_init(nrt_Error * error, const char *message, const char *file, int line, const char *func, int level); @@ -138,7 +138,7 @@ NRTAPI(void) nrt_Error_fprintf(nrt_Error * error, FILE * file, * \param level The type of error (an enum value) * \param format A format string */ -NRTPROT(void) nrt_Error_initf(nrt_Error * error, const char *file, int line, +NRTAPI(void) nrt_Error_initf(nrt_Error * error, const char *file, int line, const char *func, int level, const char *format, ...); diff --git a/modules/c/nrt/include/nrt/Exports.h b/modules/c/nrt/include/nrt/Exports.h new file mode 100644 index 000000000..e701de0c7 --- /dev/null +++ b/modules/c/nrt/include/nrt/Exports.h @@ -0,0 +1,97 @@ +/* ========================================================================= + * This file is part of NITRO + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * © Copyright 2023, Maxar Technologies, Inc. + * + * NITRO 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, If not, + * see . + * + */ + +#pragma once + +// Need to specify how this code will be consumed, either NITRO_NRT_LIB (static library) +// or NITRO_NRT_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH +// "exporting" (building this code) and "importing" (consuming). +// +// Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. +#if !defined(NITRO_NRT_LIB) && !defined(NITRO_NRT_DLL) + //#define NITRO_NRT_DLL 1 // Symbols must be exported and imported (see below). + #define NITRO_NRT_LIB 1 // Static library, all symbols visible. +#endif +#if !defined(NITRO_NRT_LIB) && !defined(NITRO_NRT_DLL) + #error "One of NITRO_NRT_LIB pr NITRO_NRT_DLL must be #define'd'" +#endif +#if defined(NITRO_NRT_LIB) && defined(NITRO_NRT_DLL) + #error "Both NITRO_NRT_LIB and NITRO_NRT_DLL are #define'd'" +#endif +#if defined(NITRO_NRT_EXPORTS) && defined(NITRO_NRT_LIB) + #error "Can't export from a LIB'" +#endif + +// https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html +#if !defined(NITRO_NRT_library_export) && !defined(NITRO_NRT_library_import) + #if defined(__GNUC__) // && HAVE_VISIBILITY + // https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html + #define NITRO_NRT_library_export __attribute__((visibility("default"))) + + // For GCC, there's no difference in consuming ("importing") an .a or .so + #define NITRO_NRT_library_import /* no __declspec(dllimport) for GCC */ + + #elif defined(_MSC_VER) // && (defined(_WINDLL) && !defined(_LIB)) + #define NITRO_NRT_library_export __declspec(dllexport) + + // Actually, it seems that the linker is able to figure this out from the .LIB, + // so there doesn't seem to be a need for __declspec(dllimport). Clients don't + // need to #define NITRO_NITFCPP_DLL ... ? Well, almost ... it looks + // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., + // destructors) correct. + #define NITRO_NRT_library_import __declspec(dllimport) + + #else + // https://stackoverflow.com/a/2164853/8877 + #define NITRO_NRT_library_export /* do nothing and hope for the best? */ + #define NITRO_NRT_library_import /* do nothing and hope for the best? */ + #pragma warning Unknown dynamic link import semantics. + #endif +#endif + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the NITRO_NRT_EXPORTS +// symbol defined on the command line. This symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// NITRO_NRT_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#ifdef NITRO_NRT_EXPORTS + #define NITRO_NRT_API NITRO_NRT_library_export +#else + // Either building a static library (no NITRO_NRT_EXPORTS) or + // importing (not building) a shared library. + + // We need to know whether we're consuming (importing) a DLL or static LIB + // The default is a static LIB as that's what existing code/builds expect. + #ifdef NITRO_NRT_DLL + // Actually, it seems that the linker is able to figure this out from the .LIB, so + // there doesn't seem to be a need for __declspec(dllimport). Clients don't + // need to #define NITRO_NRT_DLL ... ? Well, almost ... it looks + // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., + // destructors) correct. + #define NITRO_NRT_API NITRO_NRT_library_import + #else + #define NITRO_NRT_API /* "importing" a static LIB */ + #endif +#endif + diff --git a/modules/c/nrt/include/nrt/Utils.h b/modules/c/nrt/include/nrt/Utils.h index 773b34b8c..caa7fa7fe 100644 --- a/modules/c/nrt/include/nrt/Utils.h +++ b/modules/c/nrt/include/nrt/Utils.h @@ -144,7 +144,7 @@ NRTAPI(NRT_BOOL) nrt_Utils_parseGeographicString(const char *dms, int *degrees, * with 7 elements to hand in to this function, otherwise you will * have memory corruption. */ -NRTPROT(void) nrt_Utils_geographicLatToCharArray(int degrees, int minutes, +NRTAPI(void) nrt_Utils_geographicLatToCharArray(int degrees, int minutes, double seconds, char *buffer7); NRTAPI(NRT_BOOL) nrt_Utils_isGeographicLat(int degrees, int minutes, double seconds); @@ -153,7 +153,7 @@ NRTAPI(NRT_BOOL) nrt_Utils_isGeographicLat(int degrees, int minutes, double seco * with 7 elements to hand in to this function, otherwise you will * have memory corruption. */ -NRTPROT(void) nrt_Utils_geographicLonToCharArray(int degrees, int minutes, +NRTAPI(void) nrt_Utils_geographicLonToCharArray(int degrees, int minutes, double seconds, char *buffer8); NRTAPI(NRT_BOOL) nrt_Utils_isGeographicLon(int degrees, int minutes, double seconds); @@ -162,23 +162,23 @@ NRTAPI(NRT_BOOL) nrt_Utils_isGeographicLon(int degrees, int minutes, double seco * with 7 elements to hand in to this function, otherwise you will * have memory corruption. */ -NRTPROT(void) nrt_Utils_decimalLatToCharArray(double decimal, char *buffer7); +NRTAPI(void) nrt_Utils_decimalLatToCharArray(double decimal, char *buffer7); /*! * Turn the decimal value into a string +-ddd.ddd. You must have a buffer * with 7 elements to hand in to this function, otherwise you will * have memory corruption. */ -NRTPROT(void) nrt_Utils_decimalLonToCharArray(double decimal, char *buffer8); +NRTAPI(void) nrt_Utils_decimalLonToCharArray(double decimal, char *buffer8); -NRTPROT(void) nrt_Utils_decimalLatToGeoCharArray(double decimal, char *buffer7); +NRTAPI(void) nrt_Utils_decimalLatToGeoCharArray(double decimal, char *buffer7); /*! * Turn the decimal value into a string +-ddd.ddd. You must have a buffer * with 7 elements to hand in to this function, otherwise you will * have memory corruption. */ -NRTPROT(void) nrt_Utils_decimalLonToGeoCharArray(double decimal, char *buffer8); +NRTAPI(void) nrt_Utils_decimalLonToGeoCharArray(double decimal, char *buffer8); /*! * Convert the corners type to a string. If for some reason, the type @@ -198,14 +198,14 @@ NRTAPI(char) nrt_Utils_cornersTypeAsCoordRep(nrt_CornersType type); NRTAPI(void) nrt_Utils_byteSwap(uint8_t* value, size_t size); NRTAPI(void) nrt_strcpy_s(char* dest, size_t sz, const char* src); -NRTAPI(void) nrt_strncpy_s(char* dest, size_t dest_sz, const char* src, size_t src_chars); +NRTPROT(void) nrt_strncpy_s(char* dest, size_t dest_sz, const char* src, size_t src_chars); NRTAPI(void) nrt_strcat_s(char* dest, size_t sz, const char* src); NRTAPI(char*) nrt_strdup(const char* src); -NRTAPI(size_t) nrt_strlen(const char* src); // aka strlen() -NRTAPI(uint32_t) nrt_strlen32(const char* src); -NRTAPI(uint16_t) nrt_strlen16(const char* src); -NRTAPI(uint8_t) nrt_strlen8(const char* src); +NRTPROT(size_t) nrt_strlen(const char* src); // aka strlen() +NRTPROT(uint32_t) nrt_strlen32(const char* src); +NRTPROT(uint16_t) nrt_strlen16(const char* src); +NRTPROT(uint8_t) nrt_strlen8(const char* src); NRT_CXX_ENDGUARD #endif diff --git a/modules/c/nrt/source/Utils.c b/modules/c/nrt/source/Utils.c index a538c4ae5..5d5340d0e 100644 --- a/modules/c/nrt/source/Utils.c +++ b/modules/c/nrt/source/Utils.c @@ -744,7 +744,7 @@ NRTAPI(void) nrt_Utils_byteSwap(uint8_t *value, size_t size) } } -NRTAPI(void) nrt_strcpy_s(char* dest, size_t sz, const char* src) +NRTPROT(void) nrt_strcpy_s(char* dest, size_t sz, const char* src) { assert(sz > 0); #ifdef _MSC_VER // str*_s() is in C11 @@ -754,7 +754,7 @@ NRTAPI(void) nrt_strcpy_s(char* dest, size_t sz, const char* src) #endif } -NRTAPI(void) nrt_strncpy_s(char* dest, size_t dest_sz, const char* src, size_t src_chars) +NRTPROT(void) nrt_strncpy_s(char* dest, size_t dest_sz, const char* src, size_t src_chars) { assert(dest_sz > 0); #ifdef _MSC_VER // str*_s() is in C11 @@ -764,7 +764,7 @@ NRTAPI(void) nrt_strncpy_s(char* dest, size_t dest_sz, const char* src, size_t s #endif } -NRTAPI(void) nrt_strcat_s(char* dest, size_t sz, const char* src) +NRTPROT(void) nrt_strcat_s(char* dest, size_t sz, const char* src) { assert(sz > 0); #ifdef _MSC_VER // str*_s() is in C11 @@ -774,7 +774,7 @@ NRTAPI(void) nrt_strcat_s(char* dest, size_t sz, const char* src) #endif } -NRTAPI(char*) nrt_strdup(const char* src) +NRTPROT(char*) nrt_strdup(const char* src) { if (src != NULL) { @@ -790,19 +790,19 @@ NRTAPI(char*) nrt_strdup(const char* src) return NULL; } -NRTAPI(size_t) nrt_strlen(const char* src) +NRTPROT(size_t) nrt_strlen(const char* src) { return strlen(src); } -NRTAPI(uint32_t) nrt_strlen32(const char* src) +NRTPROT(uint32_t) nrt_strlen32(const char* src) { return (uint32_t) strlen(src); } -NRTAPI(uint16_t) nrt_strlen16(const char* src) +NRTPROT(uint16_t) nrt_strlen16(const char* src) { return (uint16_t)strlen(src); } -NRTAPI(uint8_t) nrt_strlen8(const char* src) +NRTPROT(uint8_t) nrt_strlen8(const char* src) { return (uint8_t)strlen(src); } diff --git a/modules/c/pch.h b/modules/c/pch.h index ca4079d2d..e4397b81c 100644 --- a/modules/c/pch.h +++ b/modules/c/pch.h @@ -27,12 +27,15 @@ #if defined(_WIN32) #undef BIGENDIAN #include +#pragma comment(lib, "Ws2_32") #else #include #endif #include #include +#pragma comment(lib, "openjpeg") +#pragma comment(lib, "jpeg") #pragma warning(pop) diff --git a/nitro.sln b/nitro.sln index 0f6fc7c9d..3992b85bd 100644 --- a/nitro.sln +++ b/nitro.sln @@ -16,8 +16,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c", "modules\c\nitf-c. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "modules\c++\nitf-c++.vcxproj", "{8F357A19-799E-4971-850E-3F28485C130B}" ProjectSection(ProjectDependencies) = postProject - {C787537A-0CAC-4D6D-A6D6-A66765A06753} = {C787537A-0CAC-4D6D-A6D6-A66765A06753} {A676EDF3-F231-47C8-A6E6-0FE50B50B71B} = {A676EDF3-F231-47C8-A6E6-0FE50B50B71B} + {C787537A-0CAC-4D6D-A6D6-A66765A06753} = {C787537A-0CAC-4D6D-A6D6-A66765A06753} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "c-nitf-shared", "c-nitf-shared", "{27A2685A-E869-42A2-956D-92994F60C536}" @@ -40,8 +40,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda-oss\modules\c++\coda-oss.vcxproj", "{9997E895-5161-4DDF-8F3F-099894CB2F21}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{8ACE478C-8F6F-4D42-9B43-7D75882D4BE1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" + ProjectSection(ProjectDependencies) = postProject + {53F9F908-C678-4DEE-9309-E71C1D03A45F} = {53F9F908-C678-4DEE-9309-E71C1D03A45F} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TEST_DES", "modules\c\nitf\TEST_DES.vcxproj", "{53F9F908-C678-4DEE-9309-E71C1D03A45F}" EndProject @@ -79,10 +80,6 @@ Global {8ACE478C-8F6F-4D42-9B43-7D75882D4BE1}.Debug|x64.Build.0 = Debug|x64 {8ACE478C-8F6F-4D42-9B43-7D75882D4BE1}.Release|x64.ActiveCfg = Release|x64 {8ACE478C-8F6F-4D42-9B43-7D75882D4BE1}.Release|x64.Build.0 = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.ActiveCfg = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.Build.0 = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.ActiveCfg = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.Build.0 = Release|x64 {53F9F908-C678-4DEE-9309-E71C1D03A45F}.Debug|x64.ActiveCfg = Debug|x64 {53F9F908-C678-4DEE-9309-E71C1D03A45F}.Debug|x64.Build.0 = Debug|x64 {53F9F908-C678-4DEE-9309-E71C1D03A45F}.Release|x64.ActiveCfg = Release|x64 @@ -96,7 +93,6 @@ Global {C787537A-0CAC-4D6D-A6D6-A66765A06753} = {27A2685A-E869-42A2-956D-92994F60C536} {A45CB073-25A7-411D-A7E7-589BCC8AF547} = {5C5727E7-0CFF-42B4-8F5A-D31B3BC81F21} {9997E895-5161-4DDF-8F3F-099894CB2F21} = {7D26D571-0014-4C50-BF86-612E743E64B6} - {78849481-D356-4CC7-B182-31C21F857ED1} = {27A2685A-E869-42A2-956D-92994F60C536} {53F9F908-C678-4DEE-9309-E71C1D03A45F} = {27A2685A-E869-42A2-956D-92994F60C536} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution From 22f11f42b856d8d0c60e7018e467642be4757a23 Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Mon, 20 Nov 2023 14:57:12 -0500 Subject: [PATCH 3/7] build as a DLL in Visual Studio (#603) * project changes to minimize changes when building a DLL * CODA_OSS -> NITRO_NITFCPP * build NITF-C++ as a DLL * Revert "build NITF-C++ as a DLL" This reverts commit 617449079da348d7f713e210b2d5e3d5ef5effd6. * more exports from CODA-OSS * link against CODA-OSS.DLL * Function uses '18832' bytes of stack. Consider moving some data to heap. This reverts commit 163e0eddd3c8f3f2152b6ba0447486473ea73649. * get ready to make NITF-C a DLL * fix errors when building as a DLL * need to export all of NRT too * more tweaks in preparation for building DLLs * export functions for unit-testing * build as DLLs in Visual Studio * NRT_DLL -> NITRO_NRT_DLL * remove CODA_OSS_DLL from VCXPROJ * trying to fix cmake build * Revert "trying to fix cmake build" This reverts commit 3caedb8c435aedd5477f39a01ca1b75528770ddb. * back to building LIBs for CMake/WAF * Build as DLLs (this branch only) * let the C-preprocessor know whether we're building SHARED or STATIC * WIP: fix imports and exports for VS * fix imports and exports for Visual Studio * Fix AdditionalLibraryDirectories --- UnitTest/UnitTest.vcxproj | 4 +-- UnitTest/pch.h | 3 ++ externals/coda-oss/cmake/CodaBuild.cmake | 4 +++ .../coda-oss/modules/c++/coda-oss.vcxproj | 8 ++--- .../c++/config/include/config/Exports.h | 31 ++++++++++++------- externals/coda-oss/modules/c++/pch.h | 3 ++ modules/c++/nitf-c++.vcxproj | 8 ++--- .../nitf/apps/show_nitf++/show_nitf++.vcxproj | 4 +-- modules/c++/nitf/include/nitf/exports.hpp | 31 ++++++++++++------- modules/c++/pch.h | 3 ++ modules/c/j2k/J2KCompress.vcxproj | 4 +-- modules/c/j2k/J2KDecompress.vcxproj | 4 +-- modules/c/nitf-c.vcxproj | 12 +++---- modules/c/nitf/TEST_DES.vcxproj | 10 +++--- modules/c/nrt/include/nrt/Defines.h | 10 +++--- modules/c/nrt/include/nrt/Exports.h | 31 ++++++++++++------- modules/c/pch.h | 3 ++ 17 files changed, 107 insertions(+), 66 deletions(-) diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index c488c71f1..547527c2a 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -58,7 +58,7 @@ Level4 true $(ProjectDir);$(SolutionDir)modules\c\nrt\include;$(SolutionDir)modules\c\nitf\include;$(SolutionDir)modules\c++\nitf\include;$(SolutionDir)modules\c\j2k\include;$(SolutionDir)modules\c;$(SolutionDir)modules\c++;$(SolutionDir)externals\coda-oss\modules\c++;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - _DEBUG;%(PreprocessorDefinitions) + _DEBUG;%(PreprocessorDefinitions);CODA_OSS_LIBRARY_SHARED=1 true pch.h AdvancedVectorExtensions2 @@ -84,7 +84,7 @@ true true $(ProjectDir);$(SolutionDir)modules\c\nrt\include;$(SolutionDir)modules\c\nitf\include;$(SolutionDir)modules\c++\nitf\include;$(SolutionDir)modules\c\j2k\include;$(SolutionDir)modules\c;$(SolutionDir)modules\c++;$(SolutionDir)externals\coda-oss\modules\c++;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions);CODA_OSS_LIBRARY_SHARED=1 true pch.h AdvancedVectorExtensions2 diff --git a/UnitTest/pch.h b/UnitTest/pch.h index 24ccf55db..86707841a 100644 --- a/UnitTest/pch.h +++ b/UnitTest/pch.h @@ -20,6 +20,9 @@ // We're building in Visual Studio ... used to control where we get a little bit of config info #define NITRO_PCH 1 +#ifndef CODA_OSS_LIBRARY_SHARED +#define CODA_OSS_LIBRARY_SHARED 1 +#endif #include #include diff --git a/externals/coda-oss/cmake/CodaBuild.cmake b/externals/coda-oss/cmake/CodaBuild.cmake index 142773788..5ac3ed962 100644 --- a/externals/coda-oss/cmake/CodaBuild.cmake +++ b/externals/coda-oss/cmake/CodaBuild.cmake @@ -128,8 +128,12 @@ macro(coda_initialize_build) option(BUILD_SHARED_LIBS "Build shared libraries instead of static." OFF) if(BUILD_SHARED_LIBS) set(CODA_LIBRARY_TYPE "shared") + add_definitions(-DCODA_OSS_LIBRARY_SHARED=1) + add_definitions(-UCODA_OSS_LIBRARY_STATIC) else() set(CODA_LIBRARY_TYPE "static") + add_definitions(-DCODA_OSS_LIBRARY_STATIC=1) + add_definitions(-UCODA_OSS_LIBRARY_SHARED) endif() option(CODA_BUILD_TESTS "build tests" ON) diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj b/externals/coda-oss/modules/c++/coda-oss.vcxproj index c500dcd82..7278051f6 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj @@ -531,12 +531,12 @@ - StaticLibrary + DynamicLibrary true v143 - StaticLibrary + DynamicLibrary false v143 true @@ -566,7 +566,7 @@ Level4 true - _DEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 + _DEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1;CODA_OSS_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 pch.h cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include Use @@ -596,7 +596,7 @@ true true true - NDEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1 + NDEBUG;%(PreprocessorDefinitions);MT_DEFAULT_PINNING=0;RE_ENABLE_STD_REGEX=1;CODA_OSS_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 pch.h cli\include;coda_oss\include;config\include;dbi\include;except\include;gsl\include;hdf5.lite\include;io\include;logging\include;math\include;math.linear\include;math.poly\include;mem\include;mt\include;net\include;net.ssl\include;plugin\include;polygon\include;re\include;sio.lite\include;std\include;str\include;sys\include;tiff\include;types\include;unique\include;units\include;xml.lite\include;zip\include;$(ProjectDir)include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\$(ProjectName)\out\install\$(Platform)-$(Configuration)\include Use diff --git a/externals/coda-oss/modules/c++/config/include/config/Exports.h b/externals/coda-oss/modules/c++/config/include/config/Exports.h index 50ea06c85..71949e7c7 100644 --- a/externals/coda-oss/modules/c++/config/include/config/Exports.h +++ b/externals/coda-oss/modules/c++/config/include/config/Exports.h @@ -2,22 +2,29 @@ #include "config/compiler_extensions.h" -// Need to specify how this code will be consumed, either CODA_OSS_LIB (static library) -// or CODA_OSS_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH +// Need to specify how this code will be consumed, either CODA_OSS_LIB_ (static library) +// or CODA_OSS_DLL_ (aka "shared" library). For DLLs, it needs to be set for BOTH // "exporting" (building this code) and "importing" (consuming). // // Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. -#if !defined(CODA_OSS_LIB) && !defined(CODA_OSS_DLL) - //#define CODA_OSS_DLL 1 // Symbols must be exported and imported (see below). - #define CODA_OSS_LIB 1 // Static library, all symbols visible. +#if !defined(CODA_OSS_LIB_) && !defined(CODA_OSS_DLL_) + #if CODA_OSS_LIBRARY_SHARED + #if CODA_OSS_LIBRARY_STATIC + #error "CODA_OSS_LIBRARY_SHARED already #define'd'" + #endif + #define CODA_OSS_DLL_ 1 // Symbols must be exported and imported (see below). + #else + // CODA_OSS_LIBRARY_STATIC doesn't have to be defined + #define CODA_OSS_LIB_ 1 // Static library, all symbols visible. + #endif #endif -#if !defined(CODA_OSS_LIB) && !defined(CODA_OSS_DLL) - #error "One of CODA_OSS_LIB pr CODA_OSS_DLL must be #define'd'" +#if !defined(CODA_OSS_LIB_) && !defined(CODA_OSS_DLL_) + #error "One of CODA_OSS_LIB_ pr CODA_OSS_DLL_ must be #define'd'" #endif -#if defined(CODA_OSS_LIB) && defined(CODA_OSS_DLL) - #error "Both CODA_OSS_LIB and CODA_OSS_DLL are #define'd'" +#if defined(CODA_OSS_LIB_) && defined(CODA_OSS_DLL_) + #error "Both CODA_OSS_LIB_ and CODA_OSS_DLL_ are #define'd'" #endif -#if defined(CODA_OSS_EXPORTS) && defined(CODA_OSS_LIB) +#if defined(CODA_OSS_EXPORTS) && defined(CODA_OSS_LIB_) #error "Can't export from a LIB'" #endif @@ -36,10 +43,10 @@ // We need to know whether we're consuming (importing) a DLL or static LIB // The default is a static LIB as that's what existing code/builds expect. - #ifdef CODA_OSS_DLL + #ifdef CODA_OSS_DLL_ // Actually, it seems that the linker is able to figure this out from the .LIB, so // there doesn't seem to be a need for __declspec(dllimport). Clients don't - // need to #define CODA_OSS_DLL ... ? Well, almost ... it looks + // need to #define CODA_OSS_DLL_ ... ? Well, almost ... it looks // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., // destructors) correct. #define CODA_OSS_API CODA_OSS_library_import diff --git a/externals/coda-oss/modules/c++/pch.h b/externals/coda-oss/modules/c++/pch.h index 664d700de..5cda65986 100644 --- a/externals/coda-oss/modules/c++/pch.h +++ b/externals/coda-oss/modules/c++/pch.h @@ -9,6 +9,9 @@ // We're building in Visual Studio ... used to control where we get a little bit // of config info #define CODA_OSS_PCH 1 +#ifndef CODA_OSS_LIBRARY_SHARED +#define CODA_OSS_LIBRARY_SHARED 1 +#endif #include "coda_oss/CPlusPlus.h" #include "config/disable_compiler_warnings.h" diff --git a/modules/c++/nitf-c++.vcxproj b/modules/c++/nitf-c++.vcxproj index ab90809a3..730f30fae 100644 --- a/modules/c++/nitf-c++.vcxproj +++ b/modules/c++/nitf-c++.vcxproj @@ -188,11 +188,11 @@ - StaticLibrary + DynamicLibrary v143 - StaticLibrary + DynamicLibrary v143 true @@ -219,7 +219,7 @@ Level4 true - _DEBUG;%(PreprocessorDefinitions); + _DEBUG;%(PreprocessorDefinitions);;NITRO_NITFCPP_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)nitf\include;$(ProjectDir)..\c\nrt\include;$(ProjectDir)..\c\nitf\include;$(ProjectDir)..\c\j2k\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use @@ -253,7 +253,7 @@ true true true - NDEBUG;%(PreprocessorDefinitions); + NDEBUG;%(PreprocessorDefinitions);;NITRO_NITFCPP_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)nitf\include;$(ProjectDir)..\c\nrt\include;$(ProjectDir)..\c\nitf\include;$(ProjectDir)..\c\j2k\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use diff --git a/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj b/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj index 17cc8f186..503ebe7f5 100644 --- a/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj +++ b/modules/c++/nitf/apps/show_nitf++/show_nitf++.vcxproj @@ -49,7 +49,7 @@ Level4 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);CODA_OSS_LIBRARY_SHARED=1 true $(SolutionDir)modules\c\nrt\include;$(SolutionDir)modules\c\nitf\include;$(SolutionDir)modules\c\jpeg\include;$(SolutionDir)modules\c\j2k\include;$(SolutionDir)modules\c\cgm\include;$(SolutionDir)modules\c;$(SolutionDir)modules\c++;$(SolutionDir)modules\c++\nitf\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use @@ -78,7 +78,7 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);CODA_OSS_LIBRARY_SHARED=1 true $(SolutionDir)modules\c\nrt\include;$(SolutionDir)modules\c\nitf\include;$(SolutionDir)modules\c\jpeg\include;$(SolutionDir)modules\c\j2k\include;$(SolutionDir)modules\c\cgm\include;$(SolutionDir)modules\c;$(SolutionDir)modules\c++;$(SolutionDir)modules\c++\nitf\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include Use diff --git a/modules/c++/nitf/include/nitf/exports.hpp b/modules/c++/nitf/include/nitf/exports.hpp index 54e22b906..7d3b61f8f 100644 --- a/modules/c++/nitf/include/nitf/exports.hpp +++ b/modules/c++/nitf/include/nitf/exports.hpp @@ -2,22 +2,29 @@ #include "config/compiler_extensions.h" -// Need to specify how this code will be consumed, either NITRO_NITFCPP_LIB (static library) -// or NITRO_NITFCPP_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH +// Need to specify how this code will be consumed, either NITRO_NITFCPP_LIB_ (static library) +// or NITRO_NITFCPP_DLL_ (aka "shared" library). For DLLs, it needs to be set for BOTH // "exporting" (building this code) and "importing" (consuming). // // Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. -#if !defined(NITRO_NITFCPP_LIB) && !defined(NITRO_NITFCPP_DLL) - //#define NITRO_NITFCPP_DLL 1 // Symbols must be exported and imported (see below). - #define NITRO_NITFCPP_LIB 1 // Static library, all symbols visible. +#if !defined(NITRO_NITFCPP_LIB_) && !defined(NITRO_NITFCPP_DLL_) + #if CODA_OSS_LIBRARY_SHARED + #if CODA_OSS_LIBRARY_STATIC + #error "CODA_OSS_LIBRARY_SHARED already #define'd'" + #endif + #define NITRO_NITFCPP_DLL_ 1 // Symbols must be exported and imported (see below). + #else + // CODA_OSS_LIBRARY_STATIC doesn't have to be defined + #define NITRO_NITFCPP_LIB_ 1 // Static library, all symbols visible. + #endif #endif -#if !defined(NITRO_NITFCPP_LIB) && !defined(NITRO_NITFCPP_DLL) - #error "One of NITRO_NITFCPP_LIB pr NITRO_NITFCPP_DLL must be #define'd'" +#if !defined(NITRO_NITFCPP_LIB_) && !defined(NITRO_NITFCPP_DLL_) + #error "One of NITRO_NITFCPP_LIB_ pr NITRO_NITFCPP_DLL_ must be #define'd'" #endif -#if defined(NITRO_NITFCPP_LIB) && defined(NITRO_NITFCPP_DLL) - #error "Both NITRO_NITFCPP_LIB and NITRO_NITFCPP_DLL are #define'd'" +#if defined(NITRO_NITFCPP_LIB_) && defined(NITRO_NITFCPP_DLL_) + #error "Both NITRO_NITFCPP_LIB_ and NITRO_NITFCPP_DLL_ are #define'd'" #endif -#if defined(NITRO_NITFCPP_EXPORTS) && defined(NITRO_NITFCPP_LIB) +#if defined(NITRO_NITFCPP_EXPORTS) && defined(NITRO_NITFCPP_LIB_) #error "Can't export from a LIB'" #endif @@ -36,10 +43,10 @@ // We need to know whether we're consuming (importing) a DLL or static LIB // The default is a static LIB as that's what existing code/builds expect. - #ifdef NITRO_NITFCPP_DLL + #ifdef NITRO_NITFCPP_DLL_ // Actually, it seems that the linker is able to figure this out from the .LIB, so // there doesn't seem to be a need for __declspec(dllimport). Clients don't - // need to #define NITRO_NITFCPP_DLL ... ? Well, almost ... it looks + // need to #define NITRO_NITFCPP_DLL_ ... ? Well, almost ... it looks // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., destructors) correct. #define NITRO_NITFCPP_API CODA_OSS_library_import #else diff --git a/modules/c++/pch.h b/modules/c++/pch.h index 00108586f..5598704d5 100644 --- a/modules/c++/pch.h +++ b/modules/c++/pch.h @@ -51,6 +51,9 @@ CODA_OSS_disable_warning_pop // We're building in Visual Studio ... used to control where we get a little bit of config info #define NITRO_PCH 1 +#ifndef CODA_OSS_LIBRARY_SHARED +#define CODA_OSS_LIBRARY_SHARED 1 +#endif // Yes, these are our files ... but they don't change very often, and if they do // change we want to rebuild everything anyway. diff --git a/modules/c/j2k/J2KCompress.vcxproj b/modules/c/j2k/J2KCompress.vcxproj index 021fcb706..7a6a02369 100644 --- a/modules/c/j2k/J2KCompress.vcxproj +++ b/modules/c/j2k/J2KCompress.vcxproj @@ -64,7 +64,7 @@ Level4 true - _DEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;HAVE_J2K_H + _DEBUG;_LIB;%(PreprocessorDefinitions);NITRO_NRT_EXPORTS;NITRO_PCH;HAVE_J2K_H;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;$(ProjectDir)..\nitf\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -91,7 +91,7 @@ true true true - NDEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;HAVE_J2K_H + NDEBUG;_LIB;%(PreprocessorDefinitions);NITRO_NRT_EXPORTS;NITRO_PCH;HAVE_J2K_H;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;$(ProjectDir)..\nitf\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) diff --git a/modules/c/j2k/J2KDecompress.vcxproj b/modules/c/j2k/J2KDecompress.vcxproj index 366e0b421..3fc0690be 100644 --- a/modules/c/j2k/J2KDecompress.vcxproj +++ b/modules/c/j2k/J2KDecompress.vcxproj @@ -64,7 +64,7 @@ Level4 true - _DEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;HAVE_J2K_H + _DEBUG;_LIB;%(PreprocessorDefinitions);NITRO_NRT_EXPORTS;NITRO_PCH;HAVE_J2K_H;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;$(ProjectDir)..\nitf\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -91,7 +91,7 @@ true true true - NDEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;HAVE_J2K_H + NDEBUG;_LIB;%(PreprocessorDefinitions);NITRO_NRT_EXPORTS;NITRO_PCH;HAVE_J2K_H;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;$(ProjectDir)..\nitf\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) diff --git a/modules/c/nitf-c.vcxproj b/modules/c/nitf-c.vcxproj index 0195fdf5f..78b0a8b31 100644 --- a/modules/c/nitf-c.vcxproj +++ b/modules/c/nitf-c.vcxproj @@ -20,11 +20,11 @@ - StaticLibrary + DynamicLibrary v143 - StaticLibrary + DynamicLibrary v143 true @@ -50,7 +50,7 @@ Level4 true - _DEBUG;%(PreprocessorDefinitions);HAVE_OPENJPEG_H + _DEBUG;%(PreprocessorDefinitions);HAVE_OPENJPEG_H;NITRO_NRT_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)nrt\include;$(ProjectDir)nitf\include;$(ProjectDir)jpeg\include;$(ProjectDir)j2k\include;$(ProjectDir)cgm\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;%(AdditionalIncludeDirectories) Use @@ -74,7 +74,7 @@ true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ @@ -82,7 +82,7 @@ true true true - NDEBUG;%(PreprocessorDefinitions);HAVE_OPENJPEG_H + NDEBUG;%(PreprocessorDefinitions);HAVE_OPENJPEG_H;NITRO_NRT_EXPORTS;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)nrt\include;$(ProjectDir)nitf\include;$(ProjectDir)jpeg\include;$(ProjectDir)j2k\include;$(ProjectDir)cgm\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;%(AdditionalIncludeDirectories) Use @@ -104,7 +104,7 @@ true true true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ + $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\ diff --git a/modules/c/nitf/TEST_DES.vcxproj b/modules/c/nitf/TEST_DES.vcxproj index 5f4c1ef73..1457b9fd3 100644 --- a/modules/c/nitf/TEST_DES.vcxproj +++ b/modules/c/nitf/TEST_DES.vcxproj @@ -64,7 +64,7 @@ Level4 true - _DEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH + _DEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -81,7 +81,8 @@ true - $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)\target-$(Configuration)\installwindows-latestCMake-Github\lib\ + + @@ -90,7 +91,7 @@ true true true - NDEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH + NDEBUG;_LIB;%(PreprocessorDefinitions);NRT_MODULE_EXPORTS;NITRO_PCH;CODA_OSS_LIBRARY_SHARED=1 true $(ProjectDir)include;$(ProjectDir)..\nrt\include;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -106,7 +107,8 @@ true true true - $(SolutionDir)out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib\;$(SolutionDir)\target-$(Configuration)\installwindows-latestCMake-Github\lib\ + + diff --git a/modules/c/nrt/include/nrt/Defines.h b/modules/c/nrt/include/nrt/Defines.h index ae969fdf7..7c0fea965 100644 --- a/modules/c/nrt/include/nrt/Defines.h +++ b/modules/c/nrt/include/nrt/Defines.h @@ -76,14 +76,16 @@ #define NRT_SNPRINTF snprintf #define NRT_VSNPRINTF vsnprintf -// Export no matter what ... when you KNOW you're building a DLL/SO, e.g. a TRE +// Export no matter what ... when you KNOW you're building a DLL/SO, e.g. a plugin #define NRTEXPORT(RT) NRT_C NITRO_NRT_library_export RT // extern "C" __declspec(dllexport) void* foo(); // Adjust the above ... but w/o chaning too much :-( -#if defined(NITRO_NRT_DLL) // See Exports.h - #ifdef NRTAPI - #undef NRTAPI +#if defined(NRTAPI) && defined(CODA_OSS_LIBRARY_SHARED) + #undef NRTAPI + #ifdef NITRO_NRT_EXPORTS // See Exports.h #define NRTAPI(RT) NRTEXPORT(RT) + #else + #define NRTAPI(RT) NRT_C NITRO_NRT_library_import RT // extern "C" __declspec(dllimport) void* foo(); #endif #endif diff --git a/modules/c/nrt/include/nrt/Exports.h b/modules/c/nrt/include/nrt/Exports.h index e701de0c7..da4a07d5c 100644 --- a/modules/c/nrt/include/nrt/Exports.h +++ b/modules/c/nrt/include/nrt/Exports.h @@ -23,22 +23,29 @@ #pragma once -// Need to specify how this code will be consumed, either NITRO_NRT_LIB (static library) -// or NITRO_NRT_DLL (aka "shared" library). For DLLs, it needs to be set for BOTH +// Need to specify how this code will be consumed, either NITRO_NRT_LIB_ (static library) +// or NITRO_NRT_DLL_ (aka "shared" library). For DLLs, it needs to be set for BOTH // "exporting" (building this code) and "importing" (consuming). // // Use Windows naming conventions (DLL, LIB) because this really only matters for _MSC_VER, see below. -#if !defined(NITRO_NRT_LIB) && !defined(NITRO_NRT_DLL) - //#define NITRO_NRT_DLL 1 // Symbols must be exported and imported (see below). - #define NITRO_NRT_LIB 1 // Static library, all symbols visible. +#if !defined(NITRO_NRT_LIB_) && !defined(NITRO_NRT_DLL_) + #if CODA_OSS_LIBRARY_SHARED + #if CODA_OSS_LIBRARY_STATIC + #error "CODA_OSS_LIBRARY_SHARED already #define'd'" + #endif + #define NITRO_NRT_DLL_ 1 // Symbols must be exported and imported (see below). + #else + // CODA_OSS_LIBRARY_STATIC doesn't have to be defined + #define NITRO_NRT_LIB_ 1 // Static library, all symbols visible. + #endif #endif -#if !defined(NITRO_NRT_LIB) && !defined(NITRO_NRT_DLL) - #error "One of NITRO_NRT_LIB pr NITRO_NRT_DLL must be #define'd'" +#if !defined(NITRO_NRT_LIB_) && !defined(NITRO_NRT_DLL_) + #error "One of NITRO_NRT_LIB_ pr NITRO_NRT_DLL_ must be #define'd'" #endif -#if defined(NITRO_NRT_LIB) && defined(NITRO_NRT_DLL) - #error "Both NITRO_NRT_LIB and NITRO_NRT_DLL are #define'd'" +#if defined(NITRO_NRT_LIB_) && defined(NITRO_NRT_DLL_) + #error "Both NITRO_NRT_LIB_ and NITRO_NRT_DLL_ are #define'd'" #endif -#if defined(NITRO_NRT_EXPORTS) && defined(NITRO_NRT_LIB) +#if defined(NITRO_NRT_EXPORTS) && defined(NITRO_NRT_LIB_) #error "Can't export from a LIB'" #endif @@ -83,10 +90,10 @@ // We need to know whether we're consuming (importing) a DLL or static LIB // The default is a static LIB as that's what existing code/builds expect. - #ifdef NITRO_NRT_DLL + #ifdef NITRO_NRT_DLL_ // Actually, it seems that the linker is able to figure this out from the .LIB, so // there doesn't seem to be a need for __declspec(dllimport). Clients don't - // need to #define NITRO_NRT_DLL ... ? Well, almost ... it looks + // need to #define NITRO_NRT_DLL_ ... ? Well, almost ... it looks // like __declspec(dllimport) is needed to get virtual "inline"s (e.g., // destructors) correct. #define NITRO_NRT_API NITRO_NRT_library_import diff --git a/modules/c/pch.h b/modules/c/pch.h index e4397b81c..04f052c4f 100644 --- a/modules/c/pch.h +++ b/modules/c/pch.h @@ -2,6 +2,9 @@ // We're building in Visual Studio ... used to control where we get a little bit of config info #define NITRO_PCH 1 +#ifndef CODA_OSS_LIBRARY_SHARED +#define CODA_OSS_LIBRARY_SHARED 1 +#endif // TODO: get rid of these someday? ... from Visual Studio code-analysis #pragma warning(disable: 6385) // Reading invalid data from '...': the readable size is '...' bytes, but '...' bytes may be read. From dc3a8ecf0e5e13c23ec1f2294c323d0bbd222e2a Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Wed, 29 Nov 2023 14:04:22 -0500 Subject: [PATCH 4/7] export more symbols (#604) * project changes to minimize changes when building a DLL * CODA_OSS -> NITRO_NITFCPP * build NITF-C++ as a DLL * Revert "build NITF-C++ as a DLL" This reverts commit 617449079da348d7f713e210b2d5e3d5ef5effd6. * more exports from CODA-OSS * link against CODA-OSS.DLL * Function uses '18832' bytes of stack. Consider moving some data to heap. This reverts commit 163e0eddd3c8f3f2152b6ba0447486473ea73649. * get ready to make NITF-C a DLL * fix errors when building as a DLL * need to export all of NRT too * more tweaks in preparation for building DLLs * export functions for unit-testing * build as DLLs in Visual Studio * NRT_DLL -> NITRO_NRT_DLL * remove CODA_OSS_DLL from VCXPROJ * trying to fix cmake build * Revert "trying to fix cmake build" This reverts commit 3caedb8c435aedd5477f39a01ca1b75528770ddb. * back to building LIBs for CMake/WAF * Build as DLLs (this branch only) * let the C-preprocessor know whether we're building SHARED or STATIC * WIP: fix imports and exports for VS * fix imports and exports for Visual Studio * Fix AdditionalLibraryDirectories * changes to build SIX DLLs --- externals/coda-oss/UnitTest/UnitTest.vcxproj | 1 + .../coda-oss/modules/c++/coda-oss.vcxproj | 1 + .../modules/c++/io/include/io/Serializable.h | 6 +++-- .../c++/logging/include/logging/Setup.h | 4 +++- .../c++/plugin/include/plugin/ErrorHandler.h | 8 ++++--- .../modules/c++/sys/include/sys/DLL.h | 5 +++-- .../modules/c++/sys/include/sys/FileFinder.h | 6 ++--- .../c++/sys/include/sys/sys_filesystem.h | 1 + .../c++/tiff/include/tiff/FileReader.h | 2 +- .../c++/tiff/include/tiff/FileWriter.h | 2 +- .../modules/c++/tiff/include/tiff/Header.h | 6 +++-- .../modules/c++/tiff/include/tiff/IFD.h | 6 +++-- .../modules/c++/tiff/include/tiff/IFDEntry.h | 10 +++++---- .../c++/tiff/include/tiff/ImageReader.h | 5 +++-- .../c++/tiff/include/tiff/ImageWriter.h | 5 +++-- .../modules/c++/tiff/include/tiff/KnownTags.h | 22 +++++++++---------- .../c++/tiff/include/tiff/TiffFileReader.h | 6 +++-- .../c++/tiff/include/tiff/TiffFileWriter.h | 7 ++++-- .../c++/tiff/include/tiff/TypeFactory.h | 6 +++-- .../modules/c++/tiff/source/KnownTags.cpp | 8 ------- .../c++/xml.lite/include/xml/lite/Element.h | 2 +- modules/c/nitf/XML_DATA_CONTENT.vcxproj | 1 + modules/c/nrt/include/nrt/Exports.h | 3 +++ 23 files changed, 71 insertions(+), 52 deletions(-) diff --git a/externals/coda-oss/UnitTest/UnitTest.vcxproj b/externals/coda-oss/UnitTest/UnitTest.vcxproj index f06331de9..020ee7b39 100644 --- a/externals/coda-oss/UnitTest/UnitTest.vcxproj +++ b/externals/coda-oss/UnitTest/UnitTest.vcxproj @@ -71,6 +71,7 @@ true /Zc:__cplusplus %(AdditionalOptions) AdvancedVectorExtensions2 + MultiThreadedDebugDLL Windows diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj b/externals/coda-oss/modules/c++/coda-oss.vcxproj index 7278051f6..0f376dc0c 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj @@ -609,6 +609,7 @@ /Zc:__cplusplus %(AdditionalOptions) AdvancedVectorExtensions2 Level3 + Speed diff --git a/externals/coda-oss/modules/c++/io/include/io/Serializable.h b/externals/coda-oss/modules/c++/io/include/io/Serializable.h index e6d2363ae..4db6eeab7 100644 --- a/externals/coda-oss/modules/c++/io/include/io/Serializable.h +++ b/externals/coda-oss/modules/c++/io/include/io/Serializable.h @@ -19,10 +19,12 @@ * see . * */ - +#pragma once #ifndef __IO_SERIALIZABLE_H__ #define __IO_SERIALIZABLE_H__ +#include "config/Exports.h" + #include "io/InputStream.h" #include "io/OutputStream.h" @@ -46,7 +48,7 @@ namespace io * This object has a known derived type SOAPMessage, which is concretely * defined to handle SOAP objects */ -struct Serializable +struct CODA_OSS_API Serializable { Serializable() = default; virtual ~Serializable() noexcept(false) {} diff --git a/externals/coda-oss/modules/c++/logging/include/logging/Setup.h b/externals/coda-oss/modules/c++/logging/include/logging/Setup.h index ed6334d6e..763767a49 100644 --- a/externals/coda-oss/modules/c++/logging/include/logging/Setup.h +++ b/externals/coda-oss/modules/c++/logging/include/logging/Setup.h @@ -20,6 +20,7 @@ * */ +#pragma once #ifndef CODA_OSS_logging_Setup_h_INCLUDED_ #define CODA_OSS_logging_Setup_h_INCLUDED_ @@ -29,6 +30,7 @@ #include "mem/SharedPtr.h" #include "logging/Logger.h" #include "sys/filesystem.h" +#include "config/Exports.h" namespace logging { @@ -48,7 +50,7 @@ using path = coda_oss::filesystem::path; // still used in SWIG bindings * \param logCount - number of rotating logs to keep (default: 0 no rotation) * \param logBytes - number of bytes per rotating log (default: 0 no rotation) */ -std::unique_ptr setupLogger( +CODA_OSS_API std::unique_ptr setupLogger( const path& program, const std::string& logLevel = "warning", const path& logFile = "console", diff --git a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h index be7ca3c8a..234e6c5a1 100644 --- a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h +++ b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h @@ -19,7 +19,7 @@ * see . * */ - +#pragma once #ifndef __PLUGIN_ERROR_HANDLER_H__ #define __PLUGIN_ERROR_HANDLER_H__ @@ -27,9 +27,11 @@ #include #include +#include "config/Exports.h" + namespace plugin { -class ErrorHandler +class CODA_OSS_API ErrorHandler { public: ErrorHandler() {} @@ -47,7 +49,7 @@ class ErrorHandler virtual void onPluginError(except::Context& c) = 0; }; -class DefaultErrorHandler : public ErrorHandler +class CODA_OSS_API DefaultErrorHandler final : public ErrorHandler { public: DefaultErrorHandler(logging::LoggerPtr logger = logging::LoggerPtr()); diff --git a/externals/coda-oss/modules/c++/sys/include/sys/DLL.h b/externals/coda-oss/modules/c++/sys/include/sys/DLL.h index 28fbb6be5..c384a461b 100644 --- a/externals/coda-oss/modules/c++/sys/include/sys/DLL.h +++ b/externals/coda-oss/modules/c++/sys/include/sys/DLL.h @@ -20,7 +20,7 @@ * */ - +#pragma once #ifndef __SYS_DLL_H__ #define __SYS_DLL_H__ @@ -52,6 +52,7 @@ typedef void* DLL_FUNCTION_PTR; #include "except/Exception.h" #include "sys/Err.h" +#include "config/Exports.h" namespace sys @@ -124,7 +125,7 @@ struct DLLException : public except::Exception */ -struct DLL +struct CODA_OSS_API DLL { /*! * Construct a library object, but dont populate or load it diff --git a/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h b/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h index 00b071c14..e60ec8553 100644 --- a/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h +++ b/externals/coda-oss/modules/c++/sys/include/sys/FileFinder.h @@ -38,7 +38,7 @@ namespace sys /** * Predicate interface for all entries */ -struct FilePredicate +struct CODA_OSS_API FilePredicate { using argument_type = std::string; using result_type = bool; @@ -59,7 +59,7 @@ struct ExistsPredicate : FilePredicate /** * Predicate that matches files only (no directories) */ -struct FileOnlyPredicate: public FilePredicate +struct CODA_OSS_API FileOnlyPredicate : public FilePredicate { virtual ~FileOnlyPredicate() = default; virtual bool operator()(const std::string& entry) const override; @@ -148,7 +148,7 @@ struct LogicalPredicate : public FilePredicate * The FileFinder class allows you to search for * files/directories in a clean way. */ -struct FileFinder final +struct CODA_OSS_API FileFinder final { FileFinder() = default; ~FileFinder() = default; diff --git a/externals/coda-oss/modules/c++/sys/include/sys/sys_filesystem.h b/externals/coda-oss/modules/c++/sys/include/sys/sys_filesystem.h index 59df476a5..3cbab0837 100644 --- a/externals/coda-oss/modules/c++/sys/include/sys/sys_filesystem.h +++ b/externals/coda-oss/modules/c++/sys/include/sys/sys_filesystem.h @@ -79,6 +79,7 @@ struct CODA_OSS_API path final // N.B. this is an INCOMPLETE and NON-STANDARD im { *this = source; } + ~path() = default; path& operator=(const path&) = default; path& operator=(path&&) = default; diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/FileReader.h b/externals/coda-oss/modules/c++/tiff/include/tiff/FileReader.h index 88edb7c41..b80d50833 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/FileReader.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/FileReader.h @@ -20,9 +20,9 @@ * */ +#pragma once #ifndef CODA_OSS_tiff_FileReader_h_INCLUDED_ #define CODA_OSS_tiff_FileReader_h_INCLUDED_ -#pragma once #include "tiff/TiffFileReader.h" diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/FileWriter.h b/externals/coda-oss/modules/c++/tiff/include/tiff/FileWriter.h index d77af0d6f..e86b03453 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/FileWriter.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/FileWriter.h @@ -20,9 +20,9 @@ * */ +#pragma once #ifndef CODA_OSS_tiff_FileWriter_h_INCLUDED_ #define CODA_OSS_tiff_FileWriter_h_INCLUDED_ -#pragma once #include "tiff/TiffFileWriter.h" diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/Header.h b/externals/coda-oss/modules/c++/tiff/include/tiff/Header.h index ed9da4f1e..60b9e8b67 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/Header.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/Header.h @@ -19,11 +19,13 @@ * see . * */ - +#pragma once #ifndef __TIFF_HEADER_H__ #define __TIFF_HEADER_H__ #include +#include + #include "tiff/Common.h" namespace tiff @@ -34,7 +36,7 @@ namespace tiff * @class Header * @brief Contains TIFF header information *********************************************************************/ -class Header : public io::Serializable +class CODA_OSS_API Header : public io::Serializable { public: enum ByteOrder { MM, II }; diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/IFD.h b/externals/coda-oss/modules/c++/tiff/include/tiff/IFD.h index 9120f581a..ea5493db3 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/IFD.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/IFD.h @@ -19,14 +19,16 @@ * see . * */ - +#pragma once #ifndef __TIFF_IFD_H__ #define __TIFF_IFD_H__ #include #include + #include #include +#include #include "tiff/IFDEntry.h" #include "tiff/KnownTags.h" @@ -45,7 +47,7 @@ namespace tiff * Contains functions for adding new entries to the IFD or adding * values to a specific IFD entry. *********************************************************************/ -class IFD : public io::Serializable +class CODA_OSS_API IFD : public io::Serializable { public: //! The IFDType diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/IFDEntry.h b/externals/coda-oss/modules/c++/tiff/include/tiff/IFDEntry.h index 75552676f..e10285b99 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/IFDEntry.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/IFDEntry.h @@ -20,17 +20,19 @@ * */ - +#pragma once #ifndef __TIFF_IFD_ENTRY_H__ #define __TIFF_IFD_ENTRY_H__ -#pragma once #include #include #include + #include -#include "tiff/GenericType.h" #include "sys/Conf.h" +#include "config/Exports.h" + +#include "tiff/GenericType.h" namespace tiff { @@ -47,7 +49,7 @@ namespace tiff * functions for printing out the entry, reading and writing it to a * file, and accessing the data. *********************************************************************/ -class IFDEntry : public io::Serializable +class CODA_OSS_API IFDEntry : public io::Serializable { public: //! Constructor diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/ImageReader.h b/externals/coda-oss/modules/c++/tiff/include/tiff/ImageReader.h index 65898ce70..5ca4354bf 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/ImageReader.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/ImageReader.h @@ -19,11 +19,12 @@ * see . * */ - +#pragma once #ifndef __TIFF_IMAGE_READER_H__ #define __TIFF_IMAGE_READER_H__ #include +#include #include "tiff/IFDEntry.h" #include "tiff/IFD.h" @@ -39,7 +40,7 @@ namespace tiff * Reads a TIFF image and parses out the IFD. Contains functions for * getting data from the image and retrieving the TIFF IFD. *********************************************************************/ -class ImageReader +class CODA_OSS_API ImageReader { public: /** diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/ImageWriter.h b/externals/coda-oss/modules/c++/tiff/include/tiff/ImageWriter.h index 412e291f9..cd4d7a3a2 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/ImageWriter.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/ImageWriter.h @@ -19,11 +19,12 @@ * see . * */ - +#pragma once #ifndef __TIFF_IMAGE_WRITER_H__ #define __TIFF_IMAGE_WRITER_H__ #include +#include #include "tiff/Common.h" #include "tiff/IFDEntry.h" @@ -40,7 +41,7 @@ namespace tiff * Writes a TIFF image to a stream. Contains functions for writing * the image's IFD, and for putting data to a stream. *********************************************************************/ -class ImageWriter +class CODA_OSS_API ImageWriter { public: //! The ideal tile size if a tiled file. diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/KnownTags.h b/externals/coda-oss/modules/c++/tiff/include/tiff/KnownTags.h index 75bd10656..c34779d03 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/KnownTags.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/KnownTags.h @@ -19,13 +19,14 @@ * see . * */ - +#pragma once #ifndef __TIFF_KNOWN_TAGS_H__ #define __TIFF_KNOWN_TAGS_H__ #include #include #include +#include #include "tiff/IFDEntry.h" @@ -35,10 +36,8 @@ namespace tiff /** * This class is a container for known TIFF tags. */ -class KnownTags +struct CODA_OSS_API KnownTags final { -public: - KnownTags(); //! Destructor @@ -71,14 +70,13 @@ class KnownTags tiff::IFDEntry *operator[](const unsigned short tagKey); //! Some common tags - static const char IMAGE_WIDTH[]; - static const char IMAGE_LENGTH[]; - static const char BITS_PER_SAMPLE[]; - static const char COMPRESSION[]; - static const char SAMPLES_PER_PIXEL[]; - static const char PHOTOMETRIC_INTERPRETATION[]; - static const char SAMPLE_FORMAT[]; - + static constexpr auto IMAGE_WIDTH = "ImageWidth"; + static constexpr auto IMAGE_LENGTH = "ImageLength"; + static constexpr auto BITS_PER_SAMPLE = "BitsPerSample"; + static constexpr auto COMPRESSION = "Compression"; + static constexpr auto SAMPLES_PER_PIXEL = "SamplesPerPixel"; + static constexpr auto PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; + static constexpr auto SAMPLE_FORMAT = "SampleFormat"; /** ***************************************************************** diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileReader.h b/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileReader.h index 47417b0db..9d02446e9 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileReader.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileReader.h @@ -19,13 +19,15 @@ * see . * */ - +#pragma once #ifndef __TIFF_FILE_READER_H__ #define __TIFF_FILE_READER_H__ #include #include + #include +#include #include "tiff/Header.h" #include "tiff/ImageReader.h" @@ -42,7 +44,7 @@ namespace tiff * to access a specific image within the file, and to read data from * a specific image in the file. *********************************************************************/ -struct FileReader +struct CODA_OSS_API FileReader { FileReader() = default; diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileWriter.h b/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileWriter.h index f6474c6e2..bf994ba86 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileWriter.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/TiffFileWriter.h @@ -19,13 +19,16 @@ * see . * */ - +#pragma once #ifndef __TIFF_FILE_WRITER_H__ #define __TIFF_FILE_WRITER_H__ #include #include + #include +#include + #include "tiff/Header.h" #include "tiff/ImageWriter.h" @@ -41,7 +44,7 @@ namespace tiff * to the same file. Contains function for manipulating each * sub-image and for writing data. *********************************************************************/ -struct FileWriter +struct CODA_OSS_API FileWriter { //! Constructor FileWriter() : diff --git a/externals/coda-oss/modules/c++/tiff/include/tiff/TypeFactory.h b/externals/coda-oss/modules/c++/tiff/include/tiff/TypeFactory.h index 5c4f21f02..5fe9c4730 100644 --- a/externals/coda-oss/modules/c++/tiff/include/tiff/TypeFactory.h +++ b/externals/coda-oss/modules/c++/tiff/include/tiff/TypeFactory.h @@ -19,10 +19,12 @@ * see . * */ - +#pragma once #ifndef __TIFF_TYPE_FACTORY_H__ #define __TIFF_TYPE_FACTORY_H__ +#include "config/Exports.h" + #include "tiff/GenericType.h" namespace tiff @@ -38,7 +40,7 @@ namespace tiff * assume a specific size for the data, see tiff::Const for the size * of each TIFF type. *********************************************************************/ -class TypeFactory +class CODA_OSS_API TypeFactory final { public: //! Default constructor diff --git a/externals/coda-oss/modules/c++/tiff/source/KnownTags.cpp b/externals/coda-oss/modules/c++/tiff/source/KnownTags.cpp index 60b329079..ad7fa8982 100644 --- a/externals/coda-oss/modules/c++/tiff/source/KnownTags.cpp +++ b/externals/coda-oss/modules/c++/tiff/source/KnownTags.cpp @@ -28,14 +28,6 @@ #include "tiff/IFDEntry.h" #include -const char tiff::KnownTags::IMAGE_WIDTH[] = "ImageWidth"; -const char tiff::KnownTags::IMAGE_LENGTH[] = "ImageLength"; -const char tiff::KnownTags::BITS_PER_SAMPLE[] = "BitsPerSample"; -const char tiff::KnownTags::COMPRESSION[] = "Compression"; -const char tiff::KnownTags::SAMPLES_PER_PIXEL[] = "SamplesPerPixel"; -const char tiff::KnownTags::PHOTOMETRIC_INTERPRETATION[] = "PhotometricInterpretation"; -const char tiff::KnownTags::SAMPLE_FORMAT[] = "SampleFormat"; - tiff::KnownTags::KnownTags() { addEntry(254, tiff::Const::Type::LONG, "NewSubfileType"); diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Element.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Element.h index 323b77aba..ee4e05346 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Element.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/Element.h @@ -499,7 +499,7 @@ struct CODA_OSS_API Element // SOAPElement derives :-( coda_oss::u8string mCharacterData; }; -Element& add(const xml::lite::QName&, const std::string& value, Element& parent); +CODA_OSS_API Element& add(const xml::lite::QName&, const std::string& value, Element& parent); #ifndef SWIG // The (old) version of SWIG we're using doesn't like certain C++11 features. diff --git a/modules/c/nitf/XML_DATA_CONTENT.vcxproj b/modules/c/nitf/XML_DATA_CONTENT.vcxproj index 2760bc1aa..253d043e4 100644 --- a/modules/c/nitf/XML_DATA_CONTENT.vcxproj +++ b/modules/c/nitf/XML_DATA_CONTENT.vcxproj @@ -100,6 +100,7 @@ true AdvancedVectorExtensions2 true + Speed diff --git a/modules/c/nrt/include/nrt/Exports.h b/modules/c/nrt/include/nrt/Exports.h index da4a07d5c..d8bce40e9 100644 --- a/modules/c/nrt/include/nrt/Exports.h +++ b/modules/c/nrt/include/nrt/Exports.h @@ -102,3 +102,6 @@ #endif #endif +#if defined(_MSC_VER) +#pragma warning(disable: 4251) // '...' : class '...' needs to have dll-interface to be used by clients of struct '...' +#endif From 3de4c5059eaf7d1ba2ccd1c16c7bc84efd3f028e Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Fri, 1 Dec 2023 10:31:33 -0500 Subject: [PATCH 5/7] latest from CODA-OSS (#605) * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from c92a55d7c7..03f1a3bdfa 03f1a3bdfa release 2023-10-23 (#747) 4dd7b2fbd5 Merge branch 'main' of github.com:mdaus/coda-oss 9428f12a06 add extensions for .log and known Windows/Linux binaries (#746) c3fd20a88f added some OLD Visual Studio extensions d00db384af everything is text except for known binaries c3813bb29d eol=lf is the default 4a2f472c7a add extensions for .log and known Windows/Linux binaries (#746) 18f2c051fa more FmtX() -> str::Format() changes (#745) 9595326819 reduce use of FmtX macro (#743) fffac7fc41 Fix memory leaks in "cli" (#741) 95ff879bab make it easier to turn on AVX2/AVX512F (#740) a950c848be enable AVX2 and AVX512F CMake builds (#739) 3697370855 use std::ssize() to reduce casts (#738) 8ae7dabace std::size() and std::ssize() (#737) 8db480be5b enable ASAN for GitHub builds (#736) git-subtree-dir: externals/coda-oss git-subtree-split: 03f1a3bdfa72d1baf84625fb6bcf9467e5792ace * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 03f1a3bdfa..3ae8f6afb3 3ae8f6afb3 Merge pull request #751 from mdaus/bugfix/hdf5-missing-files-main 3ec5108610 Add missing files 1693eac7e4 Update build_unittest.yml git-subtree-dir: externals/coda-oss git-subtree-split: 3ae8f6afb3816bbb2ca9a72fbbd9ef78644eb5bf * turn off code-analysis to fix GitHub build * turn off "Warnings as Errors" to fix Github builds * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 3ae8f6afb3..92f8b88c75 92f8b88c75 std::ostringstream overloads 8cb27de275 reduce use of .c_str() and .str() (#752) git-subtree-dir: externals/coda-oss git-subtree-split: 92f8b88c758504e8d0d2a3dfb389b71d49b557e5 * latest from CODA-OSS * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 92f8b88c75..aea8e7b1ee aea8e7b1ee reduce use of str::toString() (#754) 8062154a45 HighFive 2,8,0 (#753) git-subtree-dir: externals/coda-oss git-subtree-split: aea8e7b1ee845039a62fafca207a4df6e8df15e0 * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from aea8e7b1ee..5eae4c1f6e 5eae4c1f6e turn of /Wall for MSVC (#755) 47d4b6b73c return type needs to be explicit (not `auto`) for subsequent specialization git-subtree-dir: externals/coda-oss git-subtree-split: 5eae4c1f6e3d2ba64bb78cd63ec0b525f7f6d98a * Squashed 'externals/coda-oss/' changes from 5eae4c1f6e..df4e0fc1f6 df4e0fc1f6 changes to build SIX DLLs (#757) faf5d05210 allow CMake to switch between building SHARED (DLLs) or STATIC libraires d15173f386 export symbols used by NITRO (#756) 6ed3c048bd use Debug DLL library in Debug git-subtree-dir: externals/coda-oss git-subtree-split: df4e0fc1f6c564c02121d1328e850ed92552bfc1 * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from df4e0fc1f6..28926b6739 28926b6739 provide our own (simple) mdspan implementation (#759) 6bb722454a make SpanRC API match std::mdspan (#758) git-subtree-dir: externals/coda-oss git-subtree-split: 28926b673931c3f148882ceca7d3de203accfa4e --- .../coda-oss/modules/c++/coda-oss.vcxproj | 3 + .../modules/c++/coda-oss.vcxproj.filters | 9 ++ .../c++/coda_oss/include/coda_oss/mdspan.h | 73 +++++++++ .../c++/coda_oss/include/coda_oss/mdspan_.h | 151 ++++++++++++++++++ .../c++/coda_oss/include/coda_oss/optional.h | 7 +- .../coda-oss/modules/c++/gsl/CMakeLists.txt | 2 - .../c++/hdf5.lite/include/hdf5/lite/SpanRC.h | 81 +--------- .../hdf5.lite/include/hdf5/lite/highfive.h | 6 +- .../c++/hdf5.lite/unittests/test_highfive.cpp | 22 +-- .../modules/c++/std/include/import/std.h | 1 + .../modules/c++/std/include/std/mdspan | 46 ++++++ .../modules/c++/types/include/types/RowCol.h | 8 +- 12 files changed, 311 insertions(+), 98 deletions(-) create mode 100644 externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan.h create mode 100644 externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan_.h create mode 100644 externals/coda-oss/modules/c++/std/include/std/mdspan diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj b/externals/coda-oss/modules/c++/coda-oss.vcxproj index 0f376dc0c..6aacf1781 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj @@ -19,6 +19,8 @@ + + @@ -509,6 +511,7 @@ + diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters b/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters index 50db46175..a94b8aafd 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters @@ -951,6 +951,12 @@ str + + coda_oss + + + coda_oss + @@ -1559,5 +1565,8 @@ sys + + std + \ No newline at end of file diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan.h new file mode 100644 index 000000000..3569440f4 --- /dev/null +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan.h @@ -0,0 +1,73 @@ +/* ========================================================================= + * This file is part of coda_oss-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * © Copyright 2023, Maxar Technologies, Inc. + * + * coda_oss-c++ 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 . + * + */ +#pragma once + +#include "coda_oss/CPlusPlus.h" + +// This should always work ... it's in a `details` namespace +#include "coda_oss/mdspan_.h" + +// This logic needs to be here rather than so that `coda_oss::mdspan` will +// be the same as `std::mdspan`. +#ifndef CODA_OSS_HAVE_std_mdspan_ + #define CODA_OSS_HAVE_std_mdspan_ 0 // assume no +#endif +#ifndef CODA_OSS_HAVE_experimental_mdspan_ + #define CODA_OSS_HAVE_experimental_mdspan_ 0 // assume no std::experimental::mdspan +#endif +#if CODA_OSS_cpp17 // __has_include + #if __has_include() // not until C++23 + #include + #undef CODA_OSS_HAVE_std_mdspan_ + #define CODA_OSS_HAVE_std_mdspan_ 1 // provided by the implementation, probably C++23 + #endif + + #if CODA_OSS_cpp20 // Can't even #include this file with older C++14/17 compilers! :-( + // Put this in a __has_include so that it's optional. Our simple implemtnation works + // for our needs, and this brings along a lot of code that our older compilers don't + // like. By the time we need more functionality, maybe we'll be using C++23? + // + // Until then, having this available allows checking our implementation against + // something much more real. https://github.com/kokkos/mdspan + #if __has_include("coda_oss/experimental/mdspan") + #include "coda_oss/experimental/mdspan" + #undef CODA_OSS_HAVE_experimental_mdspan_ + #define CODA_OSS_HAVE_experimental_mdspan_ 1 // provided coda_oss/experimental/mdspan + #endif + #endif +#endif // CODA_OSS_cpp17 + +namespace coda_oss +{ + #if CODA_OSS_HAVE_std_mdspan_ + using std::mdspan; + using std::dextents; + #elif CODA_OSS_HAVE_experimental_mdspan_ + using std::experimental::mdspan; + using std::experimental::dextents; + #else + using details::mdspan; + using details::dextents; + #endif +} + diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan_.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan_.h new file mode 100644 index 000000000..b678051d8 --- /dev/null +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/mdspan_.h @@ -0,0 +1,151 @@ +/* ========================================================================= + * This file is part of coda_oss-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * © Copyright 2023, Maxar Technologies, Inc. + * + * coda_oss-c++ 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 . + * + */ +#pragma once + +#include + +#include + +#include "coda_oss/span.h" + +// This is a simple, partial, and incomplete implementation of `std::mdspan` (in C++23). +// https://en.cppreference.com/w/cpp/container/mdspan +// +// Why? Our (current) needs are much more limited than all the use-cases for `std::mdspan`: +// dynamic (not static) extents, rank of 2 (rows × cols), contiguous memory, ... +// By the time we really need more features, maybe we'll be using C++23? +namespace coda_oss +{ +namespace details +{ + // https://en.cppreference.com/w/cpp/container/mdspan/extents +template +struct dextents final // this is actually supposed to be an alias template with all dynamic extents +{ + static_assert(Rank == 2, "Rank must have a value of 2"); + using index_type = IndexType; + using size_type = index_type; + using rank_type = size_t; + + constexpr dextents() = default; + + // These are supposed to be templates, but we don't need that complication right now. + constexpr dextents(index_type i0, index_type i1) noexcept : exts_{i0, i1} + { + } + constexpr explicit dextents(const std::array& exts) noexcept : exts_(exts) + { + } + + dextents(const dextents&) = default; + dextents& operator=(const dextents&) = default; + dextents(dextents&&) = default; + dextents& operator=(dextents&&) = default; + + constexpr index_type extent(rank_type r) const noexcept + { + return exts_[r]; + } + + static constexpr auto rank() noexcept + { + return Rank; + } + +private: + std::array exts_; +}; + +template +class mdspan final +{ + coda_oss::span s_; // `span` instead of a raw pointer to get more range checking. + TExtents ext_; + + // c.f., `types::RowCol` + template + static size_t area(const dextents& exts) + { + return exts.extent(0) * exts.extent(1); + } + +public: + using extents_type = TExtents; + using size_type = typename extents_type::size_type; + using data_handle_type = T*; + using reference = T&; + + constexpr mdspan() = default; + + // Again, these are supposed to be templates ... + mdspan(data_handle_type p, const extents_type& ext) noexcept : s_(p, area(ext)), ext_(ext) + { + } + mdspan(data_handle_type p, const std::array& dims) noexcept : mdspan(p, extents_type(dims)) + { + } + + mdspan(const mdspan&) = default; + mdspan& operator=(const mdspan&) = default; + mdspan(mdspan&&) = default; + mdspan& operator=(mdspan&&) = default; + + constexpr data_handle_type data_handle() const noexcept + { + return s_.data(); + } + + /*constexpr*/ reference operator[](size_t idx) const noexcept + { + assert(idx < size()); // prevents "constexpr" in C++11 + return data_handle()[idx]; + } + /*constexpr*/ reference operator()(size_t r, size_t c) const noexcept + { + const auto offset = (r * extent(1)) + c; + return (*this)[offset]; + } + + constexpr size_t size() const noexcept + { + return s_.size(); + } + + constexpr bool empty() const noexcept + { + return s_.empty(); + } + + auto extent(size_type rank) const + { + return ext_.extent(rank); + } + + static constexpr auto rank() noexcept + { + return extents_type::rank(); + } +}; +} +} + diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional.h index f1fab3a0b..86298871c 100644 --- a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional.h +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/optional.h @@ -24,6 +24,9 @@ #include "coda_oss/CPlusPlus.h" +// always compile; it's in a details namespace +#include "coda_oss/optional_.h" + // This logic needs to be here rather than so that `coda_oss::optional` will // be the same as `std::optional`. #ifndef CODA_OSS_HAVE_std_optional_ @@ -37,10 +40,6 @@ #endif #endif // CODA_OSS_cpp17 -#if !CODA_OSS_HAVE_std_optional_ -#include "coda_oss/optional_.h" -#endif - namespace coda_oss { #if CODA_OSS_HAVE_std_optional_ diff --git a/externals/coda-oss/modules/c++/gsl/CMakeLists.txt b/externals/coda-oss/modules/c++/gsl/CMakeLists.txt index 6f17aa779..10d694163 100644 --- a/externals/coda-oss/modules/c++/gsl/CMakeLists.txt +++ b/externals/coda-oss/modules/c++/gsl/CMakeLists.txt @@ -4,5 +4,3 @@ coda_add_module( ${MODULE_NAME} VERSION 1.0 DEPS config-c++) - - diff --git a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h index 9392890bb..aea2d9c51 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h +++ b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/SpanRC.h @@ -20,22 +20,11 @@ * */ +#pragma once #ifndef CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ #define CODA_OSS_hdf5_lite_SpanRC_h_INCLUDED_ -#pragma once -/*! - * \file SpanRC.h - * - * This is a super-simple version of C++23's mdspan. It's here because 1) don't want widespread use, and - * 2) CODA already has a View2D. - */ - -#include - -#include "config/Exports.h" -#include "coda_oss/span.h" -#include "types/RowCol.h" +#include "coda_oss/mdspan.h" namespace hdf5 { @@ -43,71 +32,7 @@ namespace lite { template -struct SpanRC final -{ - using size_type = types::RowCol; - using element_type = T; - using pointer = T*; - using reference = T&; - - SpanRC() = default; - SpanRC(pointer p, size_type rc) noexcept : s_(p, rc.area()), rc_(rc) - { - } - SpanRC(pointer p, size_t r, size_t c) noexcept : SpanRC(p, size_type(r, c)) - { - } - SpanRC(const SpanRC&) noexcept = default; - - constexpr pointer data() const noexcept - { - return s_.data(); - } - - /*constexpr*/ reference operator[](size_t idx) const noexcept - { - assert(idx < size()); // prevents "constexpr" in C++11 - return data()[idx]; - } - /*constexpr*/ reference operator()(size_t r, size_t c) const noexcept - { - const auto offset = (r * dims().col) + c; - return (*this)[offset]; - } - /*constexpr*/ reference operator[](size_type idx) const noexcept - { - return (*this)(idx.row, idx.col); - } - - constexpr size_t size() const noexcept - { - assert(s_.size() == rc_.area()); - return s_.size(); - } - constexpr size_t area() const noexcept - { - return size(); - } - - constexpr size_type size_bytes() const noexcept - { - return s_.size_bytes(); - } - - constexpr bool empty() const noexcept - { - return s_.empty(); - } - - const auto& dims() const - { - return rc_; - } - - private: - coda_oss::span s_; - types::RowCol rc_; -}; +using SpanRC = coda_oss::mdspan>; } } diff --git a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h index fb276e681..d5d91987b 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h +++ b/externals/coda-oss/modules/c++/hdf5.lite/include/hdf5/lite/highfive.h @@ -56,10 +56,10 @@ inline auto vv_load(const H5Easy::File& file, const std::string& dataset_name) template inline HighFive::DataSet writeDataSet(H5Easy::File& file, const std::string& dataset_name, SpanRC data /*, TODO ...*/) { - const std::vector dims{data.dims().row, data.dims().col}; + const std::vector dims{data.extent(0), data.extent(1)}; const HighFive::DataSpace dataspace{dims}; auto retval = file.createDataSet(dataset_name, dataspace); - retval.write_raw(data.data()); + retval.write_raw(data.data_handle()); return retval; } @@ -87,7 +87,7 @@ inline SpanRC readDataSet(const HighFive::DataSet& dataSet, std::vector& r result.resize(dims.area()); dataSet.read(result.data()); - return SpanRC(result.data(), dims); + return SpanRC(result.data(), std::array{dims.row, dims.col}); } template diff --git a/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_highfive.cpp b/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_highfive.cpp index f54526ab9..9fbfd7654 100644 --- a/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_highfive.cpp +++ b/externals/coda-oss/modules/c++/hdf5.lite/unittests/test_highfive.cpp @@ -53,10 +53,11 @@ TEST_CASE(test_highfive_load) { std::vector lat; const auto rc = hdf5::lite::loadDataSet(file, "/g4/lat", lat); + static_assert(decltype(rc)::rank() == 2, "wrong rank()"); TEST_ASSERT_EQ(lat.size(), 19); - TEST_ASSERT_EQ(lat.size(), rc.area()); - TEST_ASSERT_EQ(rc.dims().row, 19); - TEST_ASSERT_EQ(rc.dims().col, 1); + TEST_ASSERT_EQ(lat.size(), rc.size()); + TEST_ASSERT_EQ(rc.extent(0), 19); + TEST_ASSERT_EQ(rc.extent(1), 1); TEST_ASSERT_ALMOST_EQ(lat[0], -90.0); TEST_ASSERT_ALMOST_EQ(lat[0], -lat[18]); } @@ -103,9 +104,9 @@ template static auto read_complex(const HighFive::DataSet& r, const HighFive::DataSet& i) { std::vector r_result; - hdf5::lite::readDataSet(r, r_result); + std::ignore = hdf5::lite::readDataSet(r, r_result); std::vector i_result; - hdf5::lite::readDataSet(i, i_result); + std::ignore = hdf5::lite::readDataSet(i, i_result); return std::make_pair(r, i); } template @@ -405,11 +406,11 @@ TEST_CASE(test_highfive_write) const types::RowCol dims{10, 20}; std::vector data_(dims.area()); - const hdf5::lite::SpanRC data(data_.data(), dims); + hdf5::lite::SpanRC data(data_.data(), std::array{dims.row, dims.col}); double d = 0.0; - for (size_t r = 0; r result; const auto rc = hdf5::lite::loadDataSet(file, "/DS1", result); - TEST_ASSERT(rc.dims() == dims); + TEST_ASSERT(rc.extent(0) == dims.row); + TEST_ASSERT(rc.extent(1) == dims.col); TEST_ASSERT_EQ(dims.area(), result.size()); for (size_t i = 0; i < result.size(); i++) { diff --git a/externals/coda-oss/modules/c++/std/include/import/std.h b/externals/coda-oss/modules/c++/std/include/import/std.h index 32702da30..5c41ee61b 100644 --- a/externals/coda-oss/modules/c++/std/include/import/std.h +++ b/externals/coda-oss/modules/c++/std/include/import/std.h @@ -102,6 +102,7 @@ CODA_OSS_disable_warning_system_header_push #include #include #include +#include CODA_OSS_disable_warning_pop diff --git a/externals/coda-oss/modules/c++/std/include/std/mdspan b/externals/coda-oss/modules/c++/std/include/std/mdspan new file mode 100644 index 000000000..b25c5447d --- /dev/null +++ b/externals/coda-oss/modules/c++/std/include/std/mdspan @@ -0,0 +1,46 @@ +/* ========================================================================= + * This file is part of std-c++ + * ========================================================================= + * + * © Copyright 2023, Maxar Technologies, Inc. + * + * std-c++ 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, http://www.gnu.org/licenses/. + * + */ +#pragma once + +#include "coda_oss/mdspan.h" +#include "coda_oss/CPlusPlus.h" + +// Make it (too?) easy for clients to get our various std:: implementations +#ifndef CODA_OSS_NO_std_mdspan + #if CODA_OSS_cpp23 + #include + #define CODA_OSS_NO_std_mdspan 1 // part of C++23 + #else + #define CODA_OSS_NO_std_mdspan 0 // use our own + #endif +#endif + +#if !CODA_OSS_NO_std_mdspan +namespace std // This is slightly uncouth: we're not supposed to augment "std". +{ + using coda_oss::mdspan; + using coda_oss::dextents; +} +#ifndef __cpp_lib_mdspan +#define __cpp_lib_mdspan 202002L // https://en.cppreference.com/w/cpp/feature_test#cpp_lib_mdspan +#endif + +#endif // CODA_OSS_NO_std_mdspan diff --git a/externals/coda-oss/modules/c++/types/include/types/RowCol.h b/externals/coda-oss/modules/c++/types/include/types/RowCol.h index e13f125a2..846280aaa 100644 --- a/externals/coda-oss/modules/c++/types/include/types/RowCol.h +++ b/externals/coda-oss/modules/c++/types/include/types/RowCol.h @@ -19,7 +19,7 @@ * see . * */ - + #pragma once #ifndef __TYPES_ROW_COL_H__ #define __TYPES_ROW_COL_H__ @@ -28,6 +28,7 @@ #include #include #include +#include #include "gsl/gsl.h" @@ -78,6 +79,11 @@ template class RowCol row = p.first; col = p.second; } + explicit RowCol(const std::array& a) noexcept + { + row = a[0]; + col = a[1]; + } template RowCol& operator=(const RowCol& p) noexcept { From 09f2f458fe16fcaa6dd5f6c025b91a1ca657abe4 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Fri, 1 Dec 2023 10:49:42 -0500 Subject: [PATCH 6/7] use $(SolutionDir) to get to externals --- modules/c++/nitf-c++.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/c++/nitf-c++.vcxproj b/modules/c++/nitf-c++.vcxproj index 730f30fae..3293d3a0c 100644 --- a/modules/c++/nitf-c++.vcxproj +++ b/modules/c++/nitf-c++.vcxproj @@ -171,7 +171,7 @@ - + {9997e895-5161-4ddf-8f3f-099894cb2f21} From 8471010142ae5f85f596f2cf1737c8aa5d89c7fa Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Mon, 11 Dec 2023 12:17:17 -0500 Subject: [PATCH 7/7] latest from CODA-OSS (#606) * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from c92a55d7c7..03f1a3bdfa 03f1a3bdfa release 2023-10-23 (#747) 4dd7b2fbd5 Merge branch 'main' of github.com:mdaus/coda-oss 9428f12a06 add extensions for .log and known Windows/Linux binaries (#746) c3fd20a88f added some OLD Visual Studio extensions d00db384af everything is text except for known binaries c3813bb29d eol=lf is the default 4a2f472c7a add extensions for .log and known Windows/Linux binaries (#746) 18f2c051fa more FmtX() -> str::Format() changes (#745) 9595326819 reduce use of FmtX macro (#743) fffac7fc41 Fix memory leaks in "cli" (#741) 95ff879bab make it easier to turn on AVX2/AVX512F (#740) a950c848be enable AVX2 and AVX512F CMake builds (#739) 3697370855 use std::ssize() to reduce casts (#738) 8ae7dabace std::size() and std::ssize() (#737) 8db480be5b enable ASAN for GitHub builds (#736) git-subtree-dir: externals/coda-oss git-subtree-split: 03f1a3bdfa72d1baf84625fb6bcf9467e5792ace * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 03f1a3bdfa..3ae8f6afb3 3ae8f6afb3 Merge pull request #751 from mdaus/bugfix/hdf5-missing-files-main 3ec5108610 Add missing files 1693eac7e4 Update build_unittest.yml git-subtree-dir: externals/coda-oss git-subtree-split: 3ae8f6afb3816bbb2ca9a72fbbd9ef78644eb5bf * turn off code-analysis to fix GitHub build * turn off "Warnings as Errors" to fix Github builds * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 3ae8f6afb3..92f8b88c75 92f8b88c75 std::ostringstream overloads 8cb27de275 reduce use of .c_str() and .str() (#752) git-subtree-dir: externals/coda-oss git-subtree-split: 92f8b88c758504e8d0d2a3dfb389b71d49b557e5 * latest from CODA-OSS * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 92f8b88c75..aea8e7b1ee aea8e7b1ee reduce use of str::toString() (#754) 8062154a45 HighFive 2,8,0 (#753) git-subtree-dir: externals/coda-oss git-subtree-split: aea8e7b1ee845039a62fafca207a4df6e8df15e0 * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from aea8e7b1ee..5eae4c1f6e 5eae4c1f6e turn of /Wall for MSVC (#755) 47d4b6b73c return type needs to be explicit (not `auto`) for subsequent specialization git-subtree-dir: externals/coda-oss git-subtree-split: 5eae4c1f6e3d2ba64bb78cd63ec0b525f7f6d98a * Squashed 'externals/coda-oss/' changes from 5eae4c1f6e..df4e0fc1f6 df4e0fc1f6 changes to build SIX DLLs (#757) faf5d05210 allow CMake to switch between building SHARED (DLLs) or STATIC libraires d15173f386 export symbols used by NITRO (#756) 6ed3c048bd use Debug DLL library in Debug git-subtree-dir: externals/coda-oss git-subtree-split: df4e0fc1f6c564c02121d1328e850ed92552bfc1 * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from df4e0fc1f6..28926b6739 28926b6739 provide our own (simple) mdspan implementation (#759) 6bb722454a make SpanRC API match std::mdspan (#758) git-subtree-dir: externals/coda-oss git-subtree-split: 28926b673931c3f148882ceca7d3de203accfa4e * latest from CODA-OSS * Squashed 'externals/coda-oss/' changes from 28926b6739..ed283d6766 ed283d6766 Only need to actually create/destroy Xerces once (#761) 8087b1e114 utility routines to convert to/from collections of paths a869c8a8eb use a lookup table for str::upper() and str::lower() (#760) 00e3431773 Merge branch 'main' of https://github.com/mdaus/coda-oss 27085f06b7 DefaultErrorHandler is a base class 98ec798356 favor speed over size git-subtree-dir: externals/coda-oss git-subtree-split: ed283d676654023f2ea58fd7b6385fa30c03b08a --- externals/coda-oss/UnitTest/UnitTest.vcxproj | 3 +- .../modules/c++/logging/source/Setup.cpp | 3 +- .../c++/plugin/include/plugin/ErrorHandler.h | 2 +- .../modules/c++/str/include/str/Manip.h | 68 ++++++++- .../modules/c++/str/source/Encoding.cpp | 89 ++++++----- .../coda-oss/modules/c++/str/source/Manip.cpp | 140 ++++++++++++++++-- .../c++/str/unittests/test_base_convert.cpp | 31 ++-- .../modules/c++/str/unittests/test_str.cpp | 70 ++++++++- .../modules/c++/sys/include/sys/Path.h | 14 +- .../modules/c++/sys/source/AbstractOS.cpp | 19 +-- .../modules/c++/sys/source/DateTime.cpp | 20 +-- .../modules/c++/sys/source/FileFinder.cpp | 15 +- .../coda-oss/modules/c++/sys/source/Path.cpp | 17 +++ .../include/xml/lite/UtilitiesXerces.h | 14 +- .../include/xml/lite/ValidatorXerces.h | 14 +- .../include/xml/lite/XMLReaderXerces.h | 2 +- .../c++/xml.lite/source/UtilitiesXerces.cpp | 39 ++++- .../c++/xml.lite/source/ValidatorXerces.cpp | 29 ++-- .../c++/xml.lite/unittests/test_xmlparser.cpp | 4 +- 19 files changed, 426 insertions(+), 167 deletions(-) diff --git a/externals/coda-oss/UnitTest/UnitTest.vcxproj b/externals/coda-oss/UnitTest/UnitTest.vcxproj index 020ee7b39..d79dab6f9 100644 --- a/externals/coda-oss/UnitTest/UnitTest.vcxproj +++ b/externals/coda-oss/UnitTest/UnitTest.vcxproj @@ -23,7 +23,6 @@ DynamicLibrary true v143 - false Unicode @@ -31,7 +30,6 @@ false v143 true - false Unicode @@ -97,6 +95,7 @@ true /Zc:__cplusplus %(AdditionalOptions) AdvancedVectorExtensions2 + Speed Windows diff --git a/externals/coda-oss/modules/c++/logging/source/Setup.cpp b/externals/coda-oss/modules/c++/logging/source/Setup.cpp index 3c1c36363..345c6b516 100644 --- a/externals/coda-oss/modules/c++/logging/source/Setup.cpp +++ b/externals/coda-oss/modules/c++/logging/source/Setup.cpp @@ -53,8 +53,7 @@ logging::setupLogger(const path& program_, // setup logging formatter std::unique_ptr formatter; const auto logFile = logFile_.string(); - auto file = logFile; - str::lower(file); + const auto file = str::lower(logFile); if (str::endsWith(file, ".xml")) { formatter.reset( diff --git a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h index 234e6c5a1..248b61f46 100644 --- a/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h +++ b/externals/coda-oss/modules/c++/plugin/include/plugin/ErrorHandler.h @@ -49,7 +49,7 @@ class CODA_OSS_API ErrorHandler virtual void onPluginError(except::Context& c) = 0; }; -class CODA_OSS_API DefaultErrorHandler final : public ErrorHandler +class CODA_OSS_API DefaultErrorHandler : public ErrorHandler { public: DefaultErrorHandler(logging::LoggerPtr logger = logging::LoggerPtr()); diff --git a/externals/coda-oss/modules/c++/str/include/str/Manip.h b/externals/coda-oss/modules/c++/str/include/str/Manip.h index 0b48673a5..c9c96eb60 100644 --- a/externals/coda-oss/modules/c++/str/include/str/Manip.h +++ b/externals/coda-oss/modules/c++/str/include/str/Manip.h @@ -1,4 +1,4 @@ -/* ========================================================================= +/* ========================================================================= * This file is part of str-c++ * ========================================================================= * @@ -34,6 +34,7 @@ #include "coda_oss/CPlusPlus.h" #include "coda_oss/string.h" #include "str/Convert.h" +#include "str/W1252string.h" namespace str { @@ -177,10 +178,71 @@ CODA_OSS_API std::vector split(const std::string& s, const std::string& splitter = " ", size_t maxSplit = std::string::npos); +/***********************************************************************************/ //! Uses std::transform to convert all chars to lower case //! Uses std::transform to convert all chars to upper case -CODA_OSS_API void lower(std::string& s); -CODA_OSS_API void upper(std::string& s); +//CODA_OSS_API void lower(std::string& s); +//CODA_OSS_API void upper(std::string& s); +// +// Using std::transform() with ::toupper() is considerably slower than a lookup-table +CODA_OSS_API void ascii_lower(std::string& s); +inline void lower(std::string& s) +{ + ascii_lower(s); +} +inline std::string lower(const std::string& s) +{ + std::string retval = s; + lower(retval); + return retval; +} + +CODA_OSS_API void ascii_upper(std::string& s); +inline void upper(std::string& s) +{ + ascii_upper(s); +} +inline std::string upper(const std::string& s) +{ + std::string retval = s; + upper(retval); + return retval; +} + +// At this point, you might want to `lower()` and `upper()` for UTF-8 and/or +// Windows-1252. That can be done, but ... our needs are mostly English (99.9%) +// with a very occassional smattering of French (Canada). We've gotten by this +// long without being able to upper/lower 'ä' and 'Ä' and there's no current +// requirement to do so. +// +// Furthermore, while Windows-1252 is easy as it's a single-byte encoding and +// covers many european languages, the standard is UTF-8. +// Upper/lower-casing in Unicode is quite a bit more complicated as there can be +// numerous rules for various languages. For example, in German, the "old +// rules" where that 'ß' was uppercased to "SS"; however, there is now a 'ẞ'. +// And then there are semantics: in German, no word can begin with 'ß' (or 'ẞ') +// making "ßanything" rather non-sensical. +// +// So for now (until there is a real use case), just "define these problems +// away" by not implementing `w1252_lower()`, `utf8_upper()`, etc. +/* +CODA_OSS_API void w1252_lower(std::string& s); +CODA_OSS_API void w1252_upper(std::string& s); +CODA_OSS_API void lower(str::W1252string& s); +CODA_OSS_API void upper(str::W1252string& s); + +CODA_OSS_API void utf8_lower(std::string& s); +CODA_OSS_API void utf8_upper(std::string& s); +CODA_OSS_API void lower(coda_oss::u8string& s); +CODA_OSS_API void upper(coda_oss::u8string& s); +*/ + +// I've already got these hooked up, keep the code around ... long ugly +// names to discourage use. +CODA_OSS_API str::Windows1252_T to_w1252_upper(str::Windows1252_T); +CODA_OSS_API str::Windows1252_T to_w1252_lower(str::Windows1252_T); + +/***********************************************************************************/ /*! * Replaces any characters that are invalid in XML (&, <, >, ', ") with their diff --git a/externals/coda-oss/modules/c++/str/source/Encoding.cpp b/externals/coda-oss/modules/c++/str/source/Encoding.cpp index eacc016d8..80603dae9 100644 --- a/externals/coda-oss/modules/c++/str/source/Encoding.cpp +++ b/externals/coda-oss/modules/c++/str/source/Encoding.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "gsl/gsl.h" #include "config/compiler_extensions.h" @@ -65,59 +66,58 @@ CODA_OSS_disable_warning_pop // Need to look up characters from \x80 (EURO SIGN) to \x9F (LATIN CAPITAL LETTER Y WITH DIAERESIS) // in a map: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT -inline coda_oss::u8string utf8_(uint32_t i) +inline coda_oss::u8string utf8_(char32_t i) { const auto ch = gsl::narrow(i); return str::to_u8string(std::u32string{ch}); } -static const auto& Windows1252_x80_x9F_to_u8string() -{ - static const std::map retval { - {0x80, utf8_(0x20AC) } // EURO SIGN - // , {0x81, replacement_character } // UNDEFINED - , {0x82, utf8_(0x201A) } // SINGLE LOW-9 QUOTATION MARK - , {0x83, utf8_(0x0192) } // LATIN SMALL LETTER F WITH HOOK - , {0x84, utf8_(0x201E) } // DOUBLE LOW-9 QUOTATION MARK - , {0x85, utf8_(0x2026) } // HORIZONTAL ELLIPSIS - , {0x86, utf8_(0x2020) } // DAGGER - , {0x87, utf8_(0x2021) } // DOUBLE DAGGER - , {0x88, utf8_(0x02C6) } // MODIFIER LETTER CIRCUMFLEX ACCENT - , {0x89, utf8_(0x2030) } // PER MILLE SIGN - , {0x8A, utf8_(0x0160) } // LATIN CAPITAL LETTER S WITH CARON - , {0x8B, utf8_(0x2039) } // SINGLE LEFT-POINTING ANGLE QUOTATION MARK - , {0x8C, utf8_(0x0152) } // LATIN CAPITAL LIGATURE OE - //, {0x8D, replacement_character } // UNDEFINED - , {0x8E, utf8_(0x017D) } // LATIN CAPITAL LETTER Z WITH CARON - //, {0x8F, replacement_character } // UNDEFINED - //, {0x90, replacement_character } // UNDEFINED - , {0x91, utf8_(0x2018) } // LEFT SINGLE QUOTATION MARK - , {0x92, utf8_(0x2019) } // RIGHT SINGLE QUOTATION MARK - , {0x93, utf8_(0x201C) } // LEFT DOUBLE QUOTATION MARK - , {0x94, utf8_(0x201D) } // RIGHT DOUBLE QUOTATION MARK - , {0x95, utf8_(0x2022) } // BULLET - , {0x96, utf8_(0x2013) } // EN DASH - , {0x97, utf8_(0x2014) } // EM DASH - , {0x98, utf8_(0x02DC) } // SMALL TILDE - , {0x99, utf8_(0x2122) } // TRADE MARK SIGN - , {0x9A, utf8_(0x0161) } // LATIN SMALL LETTER S WITH CARON - , {0x9B, utf8_(0x203A) } // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - , {0x9C, utf8_(0x0153) } // LATIN SMALL LIGATURE OE - //, {0x9D, replacement_character } // UNDEFINED - , {0x9E, utf8_(0x017E) } // LATIN SMALL LETTER Z WITH CARON - , {0x9F, utf8_(0x0178) } // LATIN CAPITAL LETTER Y WITH DIAERESIS +static const auto& Windows1252_x80_x9F_to_u8string_() +{ + static const std::map retval{ + {U'\x80', utf8_(U'\x20AC')} // EURO SIGN + // , {U'\x81, replacement_character } // UNDEFINED + , {U'\x82', utf8_(U'\x201A') } // SINGLE LOW-9 QUOTATION MARK + , {U'\x83', utf8_(U'\x0192') } // LATIN SMALL LETTER F WITH HOOK + , {U'\x84', utf8_(U'\x201E') } // DOUBLE LOW-9 QUOTATION MARK + , {U'\x85', utf8_(U'\x2026') } // HORIZONTAL ELLIPSIS + , {U'\x86', utf8_(U'\x2020') } // DAGGER + , {U'\x87', utf8_(U'\x2021') } // DOUBLE DAGGER + , {U'\x88', utf8_(U'\x02C6') } // MODIFIER LETTER CIRCUMFLEX ACCENT + , {U'\x89', utf8_(U'\x2030') } // PER MILLE SIGN + , {U'\x8A', utf8_(U'\x0160') } // LATIN CAPITAL LETTER S WITH CARON + , {U'\x8B', utf8_(U'\x2039') } // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + , {U'\x8C', utf8_(U'\x0152') } // LATIN CAPITAL LIGATURE OE + //, {U'\x8D, replacement_character } // UNDEFINED + , {U'\x8E', utf8_(U'\x017D') } // LATIN CAPITAL LETTER Z WITH CARON + //, {U'\x8F, replacement_character } // UNDEFINED + //, {U'\x90, replacement_character } // UNDEFINED + , {U'\x91', utf8_(U'\x2018') } // LEFT SINGLE QUOTATION MARK + , {U'\x92', utf8_(U'\x2019') } // RIGHT SINGLE QUOTATION MARK + , {U'\x93', utf8_(U'\x201C') } // LEFT DOUBLE QUOTATION MARK + , {U'\x94', utf8_(U'\x201D') } // RIGHT DOUBLE QUOTATION MARK + , {U'\x95', utf8_(U'\x2022') } // BULLET + , {U'\x96', utf8_(U'\x2013') } // EN DASH + , {U'\x97', utf8_(U'\x2014') } // EM DASH + , {U'\x98', utf8_(U'\x02DC') } // SMALL TILDE + , {U'\x99', utf8_(U'\x2122') } // TRADE MARK SIGN + , {U'\x9A', utf8_(U'\x0161') } // LATIN SMALL LETTER S WITH CARON + , {U'\x9B', utf8_(U'\x203A') } // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + , {U'\x9C', utf8_(U'\x0153') } // LATIN SMALL LIGATURE OE + //, {U'\x9D, replacement_character } // UNDEFINED + , {U'\x9E', utf8_(U'\x017E') } // LATIN SMALL LETTER Z WITH CARON + , {U'\x9F', utf8_(U'\x0178') } // LATIN CAPITAL LETTER Y WITH DIAERESIS }; return retval; } - static auto Windows1252_to_u8string() { - auto retval = Windows1252_x80_x9F_to_u8string(); + auto retval = Windows1252_x80_x9F_to_u8string_(); // Add the ISO8859-1 values to the map too. 1) We're already looking // in the map anyway for Windows-1252 characters. 2) Need map // entires for conversion from UTF-8 to Windows-1252. - for (std::u32string::value_type ch = 0xA0; ch <= 0xff; ch++) + for (char32_t ch = U'\xA0'; ch <= U'\xff'; ch++) { // ISO8859-1 can be converted to UTF-8 with bit-twiddling @@ -186,7 +186,14 @@ static void fromWindows1252_(str::W1252string::value_type ch, std::basic_string< // If the input text contains a character that isn't defined in Windows-1252; return a // "replacement character." Yes, this will **corrupt** the input data as information is lost: // https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character - static const coda_oss::u8string replacement_character = utf8_(0xfffd); + // + // Or ... https://en.wikipedia.org/wiki/Windows-1252 + // > According to the information on Microsoft's and the Unicode + // > Consortium's websites, positions 81, 8D, 8F, 90, and 9D are + // > unused; however, the Windows API `MultiByteToWideChar` maps these + // > to the corresponding C1 control codes. The "best fit" mapping + // > documents this behavior, too. + static const coda_oss::u8string replacement_character = utf8_(U'\xfffd'); append(result, replacement_character); } else @@ -229,7 +236,7 @@ inline void w1252to32(str::W1252string::const_pointer p, size_t sz, std::u32stri } template -std::map kv_to_vk(const std::map& kv) +auto kv_to_vk(const std::map& kv) { std::map retval; for (const auto& p : kv) diff --git a/externals/coda-oss/modules/c++/str/source/Manip.cpp b/externals/coda-oss/modules/c++/str/source/Manip.cpp index f8dbce7db..1d6bae1c2 100644 --- a/externals/coda-oss/modules/c++/str/source/Manip.cpp +++ b/externals/coda-oss/modules/c++/str/source/Manip.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "gsl/gsl.h" @@ -40,7 +41,7 @@ namespace { -char transformCheck(int c, int (*transform)(int)) +inline char transformCheck(int c, int (*transform)(int)) { // Ensure the character can be represented // as an unsigned char or is 'EOF', as the @@ -56,12 +57,12 @@ char transformCheck(int c, int (*transform)(int)) } } -char tolowerCheck(char c) +inline char tolowerCheck(char c) { return transformCheck(c, tolower); } -char toupperCheck(char c) +inline char toupperCheck(char c) { return transformCheck(c, toupper); } @@ -239,9 +240,8 @@ bool isAlphanumeric(const std::string& s) bool isAsciiPrintable(const std::string& s) { - for (const auto& ch : s) + for (const auto& c : s) { - char c = ch; if (c < 32 || c > 126) return false; } @@ -290,24 +290,136 @@ std::vector split(const std::string& s, return vec; } -template -inline void transform(std::basic_string& s, Fn f) + +// Calling ::toupper() can be slow as the CRT might check for locales. +// Since we only have 256 values, a lookup table is very fast and doesn't +// use much memory. +static const auto& make_lookup(std::array& result, + char (*to)(char)) +{ + // For each of 256 values, record the corresponding tolower/toupper value; + // this makes converting very fast as no checking or arithmetic must be done. + for (size_t i = 0; i <= 0xff; i++) + { + const auto ch = to(static_cast(i)); + result[i] = static_cast(ch); + } + return result; +} + +template +static void do_lookup(std::basic_string& s, const std::array& lookup) { - (void) std::transform(s.begin(), s.end(), s.begin(), f); + for (auto& ch : s) + { + const auto i = static_cast(ch); + ch = static_cast(lookup[i]); + } } -void lower(std::string& s) + +void ascii_upper(std::string& s) { - transform(s, tolowerCheck); + static std::array lookup_; + static const auto& lookup = make_lookup(lookup_, toupperCheck); + do_lookup(s, lookup); +} + +void ascii_lower(std::string& s) +{ + static std::array lookup_; + static const auto& lookup = make_lookup(lookup_, tolowerCheck); + do_lookup(s, lookup); +} + +inline char to_w1252_upper_(char ch) +{ + if ((ch >= 'a') && (ch <= 'z')) + { + return ch ^ 0x20; // ('a' - 'A'); + } + + // See chart at: https://en.wikipedia.org/wiki/Windows-1252 + constexpr uint8_t s_with_caron = 0x9a /* š */; + constexpr uint8_t oe = 0x9c /* œ */; + constexpr uint8_t z_with_caron = 0x9e /* ž */; + constexpr uint8_t a_with_grave = 0xe0 /* à */; + constexpr uint8_t o_with_diaeresis = 0xf6 /* ö */; + constexpr uint8_t o_with_slash = 0xf8 /* ø */; + constexpr uint8_t small_thorn = 0xfe /* þ */; + constexpr uint8_t y_with_diaeresis = 0xff /* ÿ */; + + const auto u8 = static_cast(ch); + if ((u8 == s_with_caron) || (u8 == oe) || (u8 == z_with_caron)) + { + return ch ^ 0x10; + } + if ((u8 >= a_with_grave) && (u8 <= o_with_diaeresis)) + { + return ch ^ 0x20; + } + if ((u8 >= o_with_slash) && (u8 <= small_thorn)) + { + return ch ^ 0x20; + } + if (u8 == y_with_diaeresis) + { + constexpr uint8_t Y_with_diaeresis = 0x9f /* Ÿ */; + return Y_with_diaeresis; + } + + return ch; +} +str::Windows1252_T to_w1252_upper(str::Windows1252_T ch) +{ + const auto retval = to_w1252_upper_(static_cast(ch)); + return static_cast(retval); +} + +inline char to_w1252_lower_(char ch) +{ + if ((ch >= 'A') && (ch <= 'Z')) + { + return ch | 0x20; + } + + constexpr uint8_t S_with_caron = 0x8a /* Š */; + constexpr uint8_t OE = 0x8c /*Œ */; + constexpr uint8_t Z_with_caron = 0x8e /* Ž */; + constexpr uint8_t Y_with_diaeresis = 0x9f /* Ÿ */; + constexpr uint8_t A_with_grave = 0xc0 /* À */; + constexpr uint8_t O_with_diaeresis = 0xd6 /* Ö */; + constexpr uint8_t O_with_slash = 0xd8 /* Ø */; + constexpr uint8_t capital_thorn = 0xde /* Þ */; + + const auto u8 = static_cast(ch); + if ((u8 == S_with_caron) || (u8 == OE) || (u8 == Z_with_caron)) + { + return ch | 0x10; + } + if (u8 == Y_with_diaeresis) + { + constexpr uint8_t y_with_diaeresis = 0xff /* ÿ */; + return y_with_diaeresis; + } + if ((u8 >= A_with_grave) && (u8 <= O_with_diaeresis)) + { + return ch | 0x20; + } + if ((u8 >= O_with_slash) && (u8 <= capital_thorn)) + { + return ch | 0x20; + } + return ch; } -void upper(std::string& s) +str::Windows1252_T to_w1252_lower(str::Windows1252_T ch) { - transform(s, toupperCheck); + const auto retval = to_w1252_lower_(static_cast(ch)); + return static_cast(retval); } void escapeForXML(std::string& str) { - // & needs to be first or else it'll mess up the other characters that we - // replace + // & needs to be first or else it'll mess up the other characters that we replace replaceAll(str, "&", "&"); replaceAll(str, "<", "<"); replaceAll(str, ">", ">"); diff --git a/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp b/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp index 3b951015a..c2ecf4f36 100644 --- a/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp +++ b/externals/coda-oss/modules/c++/str/unittests/test_base_convert.cpp @@ -216,21 +216,18 @@ TEST_CASE(test_string_to_u8string_iso8859_1) } } -template -static void test_change_case_(const std::string& testName, const TString& lower, const TString& upper) +template +static void test_change_case_(const std::string& testName, + const std::basic_string& lower, const std::basic_string& upper) { - auto s = upper; - str::lower(s); + auto s = str::lower(upper); TEST_ASSERT(s == lower); - s = lower; - str::upper(s); + s = str::upper(lower); TEST_ASSERT(s == upper); - s = upper; - str::upper(s); + s = str::upper(upper); TEST_ASSERT(s == upper); - s = lower; - str::lower(s); + s = str::lower(lower); TEST_ASSERT(s == lower); } TEST_CASE(test_change_case) @@ -243,14 +240,16 @@ TEST_CASE(test_change_case) //const std::wstring abc_w = L"abc"; //test_change_case_(testName, abc_w, ABC_w); - //// Yes, this can really come up, "non classifié" is French (Canadian) for "unclassified". - //const std::string DEF_1252{'D', '\xc9', 'F'}; // "DÉF" Windows-1252 - //const auto DEF8 = from_windows1252(DEF_1252); + // Yes, this can really come up, "non classifié" is French (Canadian) for "unclassified". + const std::string DEF_1252_{'D', '\xc9', 'F'}; // "DÉF" Windows-1252 + const auto DEF_1252 = str::str(DEF_1252_); + const auto DEF8 = str::to_u8string(DEF_1252); - //const std::string def_1252{'d', '\xe9', 'f'}; // "déf" Windows-1252 - //const auto def8 = from_windows1252(def_1252); + const std::string def_1252_{'d', '\xe9', 'f'}; // "déf" Windows-1252 + const auto def_1252 = str::str(def_1252_); + const auto def8 = str::to_u8string(def_1252); - ////test_change_case_(testName, def, DEF); + //test_change_case_(testName, def8, DEF8); //test_change_case_(testName, def_1252, DEF_1252); } diff --git a/externals/coda-oss/modules/c++/str/unittests/test_str.cpp b/externals/coda-oss/modules/c++/str/unittests/test_str.cpp index 2d00862d8..eb4821608 100644 --- a/externals/coda-oss/modules/c++/str/unittests/test_str.cpp +++ b/externals/coda-oss/modules/c++/str/unittests/test_str.cpp @@ -57,16 +57,78 @@ TEST_CASE(testData) TEST_CASE(testUpper) { - std::string s = "test-something1"; + const std::string s_ = "test-something1"; + std::string s = s_; + TEST_ASSERT(str::eq(s, "TEST-SOMETHING1")); str::upper( s); TEST_ASSERT_EQ(s, "TEST-SOMETHING1"); + + //#if _WIN32 + //s = "<×àa`öo\"øo/þb÷>"; + //str::w1252_upper(s); + //TEST_ASSERT_EQ(s, "<×ÀA`ÖO\"ØO/ÞB÷>"); + //#endif +} + +TEST_CASE(test_toupper) +{ + for (uint16_t i = 0x20; i <= 0xff; i++) // uint16_t to avoid wrap-around + { + const auto w1252 = static_cast(i); + const auto w1252_upper = str::to_w1252_upper(w1252); + + const auto w1252_lower = w1252 == w1252_upper ? w1252 : str::to_w1252_lower(w1252_upper); // round-trip + TEST_ASSERT_EQ(static_cast(w1252), static_cast(w1252_lower)); + + if (i <= 0x7f) // ASCII + { + const auto ch = static_cast(i); + const auto upper = toupper(ch); + TEST_ASSERT_EQ(static_cast(upper), static_cast(w1252_upper)); + + const auto lower = ch == upper ? ch : tolower(upper); // round-trip + TEST_ASSERT_EQ(ch, lower); + TEST_ASSERT_EQ(static_cast(lower), static_cast(w1252_lower)); + } + } } TEST_CASE(testLower) { - std::string s = "TEST1"; - str::lower( s); + const std::string s_ = "TEST1"; + std::string s = s_; + TEST_ASSERT(str::eq(s, "test1")); + str::lower(s); TEST_ASSERT_EQ(s, "test1"); + + //#if _WIN32 + //s = "[×ÀÖØÞ÷]"; + //str::w1252_lower(s); + //TEST_ASSERT_EQ(s, "[×àöøþ÷]"); + //#endif +} + +TEST_CASE(test_tolower) +{ + for (uint16_t i = 0x20; i <= 0xff; i++) // uint16_t to avoid wrap-around + { + const auto w1252 = static_cast(i); + const auto w1252_lower = str::to_w1252_lower(w1252); + + const auto w1252_upper = w1252 == w1252_lower ? w1252 : str::to_w1252_upper(w1252_lower); // round-trip + TEST_ASSERT_EQ(static_cast(w1252), static_cast(w1252_upper)); + + if (i <= 0x7f) // ASCII + { + const auto ch = static_cast(i); + const auto lower = tolower(ch); + TEST_ASSERT_EQ(static_cast(lower), static_cast(w1252_lower)); + + const auto upper = ch == lower ? ch : toupper(lower); // round-trip + TEST_ASSERT_EQ(ch, upper); + TEST_ASSERT_EQ(static_cast(upper), static_cast(w1252_upper)); + } + } } TEST_CASE(test_eq_ne) @@ -309,7 +371,9 @@ TEST_MAIN( TEST_CHECK(testTrim); TEST_CHECK(testData); TEST_CHECK(testUpper); + TEST_CHECK(test_toupper); TEST_CHECK(testLower); + TEST_CHECK(test_tolower); TEST_CHECK(test_eq_ne); TEST_CHECK(testReplace); TEST_CHECK(testReplaceAllInfinite); diff --git a/externals/coda-oss/modules/c++/sys/include/sys/Path.h b/externals/coda-oss/modules/c++/sys/include/sys/Path.h index d7d950202..74d78af5c 100644 --- a/externals/coda-oss/modules/c++/sys/include/sys/Path.h +++ b/externals/coda-oss/modules/c++/sys/include/sys/Path.h @@ -27,13 +27,15 @@ #include #include #include +#include #include "config/Exports.h" - #include +#include "coda_oss/span.h" #include "sys/OS.h" #include "sys/filesystem.h" +#include "sys/Span.h" /*! @@ -295,6 +297,16 @@ class CODA_OSS_API Path std::ostream& operator<<(std::ostream& os, const sys::Path& path); std::istream& operator>>(std::istream& os, sys::Path& path); + +// Convert between collections of paths as strings and sys::filesystem::path +CODA_OSS_API std::vector convertPaths(coda_oss::span); +CODA_OSS_API std::vector convertPaths(coda_oss::span); +template +inline auto convertPaths(const std::vector& paths) +{ + return convertPaths(make_span(paths)); +} + } #endif // CODA_OSS_sys_Path_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp b/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp index dd22c3786..436e12bb6 100644 --- a/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp +++ b/externals/coda-oss/modules/c++/sys/source/AbstractOS.cpp @@ -86,29 +86,14 @@ AbstractOS::search(const std::vector& searchPaths, return elementsFound; } -inline auto convert(const std::vector& paths) -{ - std::vector retval; - std::transform(paths.begin(), paths.end(), std::back_inserter(retval), - [](const fs::path& p) { return p.string(); }); - return retval; -} -inline auto convert(const std::vector& paths) -{ - std::vector retval; - std::transform(paths.begin(), paths.end(), std::back_inserter(retval), - [](const auto& p) { return p; }); - return retval; -} - std::vector AbstractOS::search( const std::vector& searchPaths, const std::string& fragment, const std::string& extension, bool recursive) const { - const auto results = search(convert(searchPaths), fragment, extension, recursive); - return convert(results); + const auto results = search(convertPaths(searchPaths), fragment, extension, recursive); + return convertPaths(results); } void AbstractOS::remove(const std::string& path) const diff --git a/externals/coda-oss/modules/c++/sys/source/DateTime.cpp b/externals/coda-oss/modules/c++/sys/source/DateTime.cpp index b6669002d..0679aed62 100644 --- a/externals/coda-oss/modules/c++/sys/source/DateTime.cpp +++ b/externals/coda-oss/modules/c++/sys/source/DateTime.cpp @@ -169,15 +169,13 @@ char* strptime(const char *buf, const char *fmt, struct tm& tm, double& millis) // Full name. len = DAY[i].size(); std::string day(bp, len); - str::lower(day); - if (day == DAY[i]) + if (str::eq(day, DAY[i])) break; // Abbreviated name. len = AB_DAY[i].size(); day = std::string(bp, len); - str::lower(day); - if (day == AB_DAY[i]) + if (str::eq(day, AB_DAY[i])) break; } @@ -202,15 +200,13 @@ char* strptime(const char *buf, const char *fmt, struct tm& tm, double& millis) // Full name. len = MONTH[i].size(); std::string month(bp, len); - str::lower(month); - if (month == MONTH[i]) + if (str::eq(month, MONTH[i])) break; // Abbreviated name. len = AB_MONTH[i].size(); month = std::string(bp, len); - str::lower(month); - if (month == AB_MONTH[i]) + if (str::eq(month, AB_MONTH[i])) break; } @@ -467,9 +463,7 @@ std::string sys::DateTime::dayOfWeekToStringAbbr(int dayOfWeek) int sys::DateTime::monthToValue(const std::string& month) { - std::string m = month; - str::lower(m); - + const auto m = str::lower(month); if (str::startsWith(m, "jan")) return 1; else if (str::startsWith(m, "feb")) @@ -501,9 +495,7 @@ int sys::DateTime::monthToValue(const std::string& month) int sys::DateTime::dayOfWeekToValue(const std::string& dayOfWeek) { - std::string d = dayOfWeek; - str::lower(d); - + const auto d = str::lower(dayOfWeek); if (str::startsWith(d, "sun")) return 1; else if (str::startsWith(d, "mon")) diff --git a/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp b/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp index b33cc47c4..7edf1a512 100644 --- a/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp +++ b/externals/coda-oss/modules/c++/sys/source/FileFinder.cpp @@ -56,12 +56,8 @@ bool sys::FragmentPredicate::operator()(const std::string& entry) const { if (mIgnoreCase) { - std::string base = entry; - str::lower(base); - - std::string match = mFragment; - str::lower(match); - + const auto base = str::lower(entry); + const auto match = str::lower(mFragment); return str::contains(base, match); } else @@ -80,13 +76,10 @@ bool sys::ExtensionPredicate::operator()(const std::string& filename) const if (!sys::FileOnlyPredicate::operator()(filename)) return false; - std::string ext = sys::Path::splitExt(filename).second; + const std::string ext = sys::Path::splitExt(filename).second; if (mIgnoreCase) { - std::string matchExt = mExt; - str::lower(matchExt); - str::lower(ext); - return ext == matchExt; + return str::eq(ext, mExt); } else return ext == mExt; diff --git a/externals/coda-oss/modules/c++/sys/source/Path.cpp b/externals/coda-oss/modules/c++/sys/source/Path.cpp index 4c91e6d18..99233b236 100644 --- a/externals/coda-oss/modules/c++/sys/source/Path.cpp +++ b/externals/coda-oss/modules/c++/sys/source/Path.cpp @@ -22,6 +22,7 @@ #include "sys/Path.h" #include +#include #include namespace fs = coda_oss::filesystem; @@ -849,4 +850,20 @@ std::string Path::expandEnvironmentVariables(const std::string& path, fs::file_t return expandEnvironmentVariables_(path, unused_checkIfExists, &type); } +template +inline auto convertPaths_(coda_oss::span paths, TFunc fun) +{ + std::vector retval; + std::transform(paths.begin(), paths.end(), std::back_inserter(retval), fun); + return retval; +} +std::vector convertPaths(coda_oss::span paths) +{ + return convertPaths_(paths, [](const auto& p) { return p.string(); }); } +std::vector convertPaths(coda_oss::span paths) +{ + return convertPaths_(paths, [](const auto& p) { return p; }); +} + +} \ No newline at end of file diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h index ef2039123..159bbb6ea 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/UtilitiesXerces.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "config/compiler_extensions.h" #include "config/Exports.h" @@ -409,17 +410,20 @@ struct XercesErrorHandler final : public XercesErrorHandlerInterface_T */ struct CODA_OSS_API XercesContext final { - //! Constructor XercesContext(); - - //! Destructor ~XercesContext(); + XercesContext(const XercesContext&) = delete; + XercesContext& operator=(const XercesContext&) = delete; + XercesContext(XercesContext&&) = delete; + XercesContext& operator=(XercesContext&&) = delete; + void destroy(); private: - static std::mutex mMutex; - bool mIsDestroyed; + struct Impl; + static std::shared_ptr getInstance(); + std::shared_ptr mpImpl; }; } } diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h index 8d5d79ba0..56e9689ae 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/ValidatorXerces.h @@ -89,12 +89,8 @@ struct ValidationErrorHandler final : public xercesc::DOMErrorHandler * * This class is the Xercesc schema validator */ -class CODA_OSS_API ValidatorXerces : public ValidatorInterface +struct CODA_OSS_API ValidatorXerces : public ValidatorInterface { - XercesContext mCtxt; //! this must be the first member listed - -public: - /*! * Constructor * \param schemaPaths Vector of both paths and singular schemas @@ -104,10 +100,10 @@ class CODA_OSS_API ValidatorXerces : public ValidatorInterface * input */ ValidatorXerces(const std::vector& schemaPaths, - logging::Logger* log, + logging::Logger* log = nullptr, bool recursive = true); - ValidatorXerces(const std::vector&, // fs::path -> mLegacyStringConversion = false - logging::Logger* log, + ValidatorXerces(const std::vector&, + logging::Logger* log = nullptr, bool recursive = true); ValidatorXerces(const ValidatorXerces&) = delete; @@ -133,6 +129,8 @@ class CODA_OSS_API ValidatorXerces : public ValidatorInterface static std::vector loadSchemas(const std::vector& schemaPaths, bool recursive=true); private: + XercesContext mCtxt; + bool validate_(const coda_oss::u8string& xml, const std::string& xmlID, std::vector& errors) const; diff --git a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h index a808be8d8..d40aea202 100644 --- a/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h +++ b/externals/coda-oss/modules/c++/xml.lite/include/xml/lite/XMLReaderXerces.h @@ -61,7 +61,7 @@ namespace lite */ class CODA_OSS_API XMLReaderXerces final : public XMLReaderInterface { - XercesContext mCtxt; //! this must be the first member listed + XercesContext mCtxt; std::unique_ptr mNative; std::unique_ptr mDriverContentHandler; std::unique_ptr mErrorHandler; diff --git a/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp b/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp index ffb0f7fd7..943eb5e5f 100644 --- a/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp +++ b/externals/coda-oss/modules/c++/xml.lite/source/UtilitiesXerces.cpp @@ -28,8 +28,6 @@ namespace xml { namespace lite { -std::mutex XercesContext::mMutex; - XercesLocalString::XercesLocalString(XMLCh* xmlStr) : mLocal(xmlStr) { @@ -186,8 +184,16 @@ fatalError(const SAXParseException &exception) throw except::Error(Ctxt(xex.getMessage())); } -XercesContext::XercesContext() : - mIsDestroyed(false) +/*! + * \class XercesContext::Impl + * \brief This class safely creates and destroys Xerces + */ +struct XercesContext::Impl final +{ + static std::mutex mMutex; + bool mIsDestroyed = false; + +Impl() { //! XMLPlatformUtils::Initialize is not thread safe! try @@ -203,7 +209,7 @@ XercesContext::XercesContext() : } } -XercesContext::~XercesContext() +~Impl() { try { @@ -214,7 +220,7 @@ XercesContext::~XercesContext() } } -void XercesContext::destroy() +void destroy() { // wrapping it here saves the mutex lock if (!mIsDestroyed) @@ -235,7 +241,28 @@ void XercesContext::destroy() } } } +}; +std::mutex XercesContext::Impl::mMutex; + +std::shared_ptr XercesContext::getInstance() +{ + // The one and only instance; call XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate() just once. + static auto impl = std::make_shared(); + return impl; // increment reference count +} +XercesContext::XercesContext() : mpImpl(getInstance()) // increment reference count +{ +} +XercesContext::~XercesContext() +{ + destroy(); } +void XercesContext::destroy() +{ + mpImpl.reset(); } +} // lite +} // xml + #endif diff --git a/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp b/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp index 3950d1242..dba996bd9 100644 --- a/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp +++ b/externals/coda-oss/modules/c++/xml.lite/source/ValidatorXerces.cpp @@ -37,6 +37,7 @@ CODA_OSS_disable_warning(-Wshadow) CODA_OSS_disable_warning_pop #include +#include #include #include @@ -89,26 +90,11 @@ bool ValidationErrorHandler::handleError( return true; } -inline std::vector convert(const std::vector& schemaPaths) -{ - std::vector retval; - std::transform(schemaPaths.begin(), schemaPaths.end(), std::back_inserter(retval), - [](const fs::path& p) { return p.string(); }); - return retval; -} -inline auto convert(const std::vector& paths) -{ - std::vector retval; - std::transform(paths.begin(), paths.end(), std::back_inserter(retval), - [](const auto& p) { return p; }); - return retval; -} - ValidatorXerces::ValidatorXerces( const std::vector& schemaPaths, logging::Logger* log, bool recursive) : - ValidatorXerces(convert(schemaPaths), log, recursive) + ValidatorXerces(sys::convertPaths(schemaPaths), log, recursive) { } ValidatorXerces::ValidatorXerces( @@ -169,7 +155,7 @@ ValidatorXerces::ValidatorXerces( // load our schemas -- // search each directory for schemas - const auto schemas = loadSchemas(convert(schemaPaths), recursive); + const auto schemas = loadSchemas(sys::convertPaths(schemaPaths), recursive); // add the schema to the validator // add the schema to the validator @@ -179,9 +165,12 @@ ValidatorXerces::ValidatorXerces( xercesc::Grammar::SchemaGrammarType, true)) { - std::ostringstream oss; - oss << "Error: Failure to load schema " << schema; - log->warn(Ctxt(oss)); + if (log != nullptr) + { + std::ostringstream oss; + oss << "Error: Failure to load schema " << schema; + log->warn(Ctxt(oss)); + } } } diff --git a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp index e35911651..b39f411fb 100644 --- a/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp +++ b/externals/coda-oss/modules/c++/xml.lite/unittests/test_xmlparser.cpp @@ -463,8 +463,8 @@ static void testValidateXmlFile_(const std::string& testName, const std::string& static const auto xsd = find_unittest_file("doc.xsd"); const auto path = find_unittest_file(xmlFile); - const std::vector schemaPaths{xsd.parent_path()}; // fs::path -> new string-conversion code - const xml::lite::Validator validator(schemaPaths, nullptr /*log*/); + const std::vector schemaPaths{xsd.parent_path()}; + const xml::lite::Validator validator(schemaPaths); io::FileInputStream fis(path); std::vector errors;