From 205bf8e36368f3154d31c4a6ff0817ccf36f7891 Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Mon, 13 Nov 2023 14:27:02 -0500 Subject: [PATCH] infrastructure for "preloading" TREs (#593) * 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 --- UnitTest/UnitTest.vcxproj | 30 ---- .../c++/nitf/unittests/test_load_plugins.cpp | 7 +- modules/c/nitf-c.vcxproj | 9 ++ modules/c/nitf-c.vcxproj.filters | 12 ++ modules/c/nitf/CMakeLists.txt | 1 + modules/c/nitf/include/nitf/Defines.h | 21 +-- .../c/nitf/include/nitf/PluginIdentifier.h | 7 + modules/c/nitf/include/nitf/PluginRegistry.h | 2 + modules/c/nitf/shared/ACCHZB.c | 4 +- modules/c/nitf/shared/ACFTA.c | 4 +- modules/c/nitf/shared/AIMIDA.c | 2 +- modules/c/nitf/shared/AIMIDB.c | 4 +- modules/c/nitf/shared/CSCRNA.c | 4 +- modules/c/nitf/shared/CSEXRB.c | 4 +- modules/c/nitf/shared/ENGRDA.c | 14 +- modules/c/nitf/shared/EXPLTA.c | 2 +- modules/c/nitf/shared/HISTOA.c | 4 +- modules/c/nitf/shared/IOMAPA.c | 2 +- modules/c/nitf/shared/JITCID.c | 4 +- modules/c/nitf/shared/MENSRA.c | 2 +- modules/c/nitf/shared/PATCHA.c | 2 +- modules/c/nitf/shared/PTPRAA.c | 4 +- modules/c/nitf/shared/RPFHDR.c | 4 +- modules/c/nitf/shared/TEST_DES.c | 22 +-- modules/c/nitf/shared/XML_DATA_CONTENT.c | 4 +- modules/c/nitf/source/PluginRegistry.c | 147 +++++++++++++++--- modules/c/nitf/source/TREs.c | 67 ++++++++ modules/c/nrt/include/nrt/DLL.h | 3 +- modules/c/nrt/source/DLLUnix.c | 11 ++ modules/c/nrt/source/DLLWin32.c | 14 +- nitro.sln | 42 ++--- 31 files changed, 329 insertions(+), 130 deletions(-) create mode 100644 modules/c/nitf/source/TREs.c diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index 91569578c..582a6e41c 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -258,39 +258,9 @@ {f06550ad-cfc7-40b8-8727-6c82c69a8982} - - {53f9f908-c678-4dee-9309-e71c1d03a45f} - - - {730b1e6e-2469-4f9e-b093-d0c6262453c9} - - - {51d7b426-899e-428d-9f69-5ddac9e403fb} - - - {12aa0752-4ee3-4e0a-85af-0e5deadbf343} - - - {023de06d-3967-4406-b1b8-032118bb2552} - - - {0a9bda26-092f-4a2c-bbef-00c64bf0c65e} - {53f9f908-c678-4dee-9309-e71c1e03a45f} - - {d749aa73-4c9a-473d-96bb-070a6d9caa54} - - - {d1d7fcd3-6130-4504-9da0-9d80506be55e} - - - {2baaaca9-a5a4-412c-ae52-b16c2d107f55} - - - {cf5b4f02-364d-4117-9fb9-6c9c7938e412} - {78849481-d356-4cc7-b182-31c21f857ed1} diff --git a/modules/c++/nitf/unittests/test_load_plugins.cpp b/modules/c++/nitf/unittests/test_load_plugins.cpp index c94707f56..4f84931dc 100644 --- a/modules/c++/nitf/unittests/test_load_plugins.cpp +++ b/modules/c++/nitf/unittests/test_load_plugins.cpp @@ -91,7 +91,7 @@ TEST_CASE(test_load_all_TREs) for (const auto& tre : all_TREs()) { - // TREs are quite the same thing as an arbitrary "plug in;" the underlying + // TREs aren't quite the same thing as an arbitrary "plug in;" the underlying // infrastructure is all built on shared-libraries/DLLs, but details differ. // // As a result, we can't expect loadPlugin() will "just work" on a TRE name. @@ -103,9 +103,10 @@ TEST_CASE(test_load_all_TREs) { nitf::PluginRegistry::loadPlugin(tre); } - catch (const nitf::NITFException& ex) + catch (const nitf::NITFException&) { - TEST_FAIL_MSG(ex.toString()); + // assume this is a pre-loaded plugin + retrieveTREHandler(testName, tre.c_str()); } #endif // _WIN32 diff --git a/modules/c/nitf-c.vcxproj b/modules/c/nitf-c.vcxproj index aa32c2a33..370fb800b 100644 --- a/modules/c/nitf-c.vcxproj +++ b/modules/c/nitf-c.vcxproj @@ -258,6 +258,14 @@ + + true + true + + + true + true + @@ -303,6 +311,7 @@ + diff --git a/modules/c/nitf-c.vcxproj.filters b/modules/c/nitf-c.vcxproj.filters index 13705f96b..6dd32c62a 100644 --- a/modules/c/nitf-c.vcxproj.filters +++ b/modules/c/nitf-c.vcxproj.filters @@ -16,6 +16,9 @@ {2e28e7c0-ed75-4c97-84b1-cb70b635b60e} + + {e0402428-7ec8-4079-8b39-48d8db79bf50} + @@ -673,5 +676,14 @@ j2k + + nitf\shared + + + nitf + + + nitf\shared + \ No newline at end of file diff --git a/modules/c/nitf/CMakeLists.txt b/modules/c/nitf/CMakeLists.txt index bc705c715..a12260e1f 100644 --- a/modules/c/nitf/CMakeLists.txt +++ b/modules/c/nitf/CMakeLists.txt @@ -52,6 +52,7 @@ coda_add_module( source/StreamIOWriteHandler.c source/SubWindow.c source/TRE.c + source/TREs.c source/TRECursor.c source/TREPrivateData.c source/TREUtils.c diff --git a/modules/c/nitf/include/nitf/Defines.h b/modules/c/nitf/include/nitf/Defines.h index 82f1df118..8d5038d9b 100644 --- a/modules/c/nitf/include/nitf/Defines.h +++ b/modules/c/nitf/include/nitf/Defines.h @@ -31,19 +31,20 @@ * * _Tre the name of the input TRE */ +#ifndef NITF_PLUGIN_FUNCTION_EXPORT +#define NITF_PLUGIN_FUNCTION_EXPORT(retval_) NITFAPI(retval_) +#endif #define NITF_DECLARE_PLUGIN(_Tre) \ - static const char *ident[] = { \ + static const char* _Tre##Ident[] = { \ NITF_PLUGIN_TRE_KEY, \ #_Tre, \ NULL \ }; \ static nitf_TREHandler _Tre##Handler; \ - NITFAPI(const char**) _Tre##_init(nitf_Error* error){ \ - if (!nitf_TREUtils_createBasicHandler(&descriptionSet,\ - &_Tre##Handler,error)) \ - return NULL; return ident; \ - } \ - NITFAPI(nitf_TREHandler*) _Tre##_handler(nitf_Error* error) { \ + NITF_PLUGIN_FUNCTION_EXPORT(const char**) _Tre##_init(nitf_Error* error){ \ + if (!nitf_TREUtils_createBasicHandler(&_Tre##DescriptionSet, &_Tre##Handler,error)) return NULL; \ + return _Tre##Ident; } \ + NITF_PLUGIN_FUNCTION_EXPORT(nitf_TREHandler*) _Tre##_handler(nitf_Error* error) { \ (void)error; \ return &_Tre##Handler; \ } @@ -55,13 +56,15 @@ * _Description the description to use */ #define NITF_DECLARE_SINGLE_PLUGIN(_Tre, _Description) \ - static nitf_TREDescriptionInfo descriptions[] = { \ + static nitf_TREDescriptionInfo _Tre##Descriptions[] = { \ { #_Tre, _Description, NITF_TRE_DESC_NO_LENGTH }, \ { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } \ }; \ - static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; \ + static nitf_TREDescriptionSet _Tre##DescriptionSet = { 0, _Tre##Descriptions }; \ NITF_DECLARE_PLUGIN(_Tre) +#define NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(_Tre) \ + NITF_DECLARE_SINGLE_PLUGIN(_Tre, _Tre##_description) /** * Reference a TRE that has been statically compiled inside of a library * diff --git a/modules/c/nitf/include/nitf/PluginIdentifier.h b/modules/c/nitf/include/nitf/PluginIdentifier.h index ba130bde6..da1203f2c 100644 --- a/modules/c/nitf/include/nitf/PluginIdentifier.h +++ b/modules/c/nitf/include/nitf/PluginIdentifier.h @@ -64,6 +64,13 @@ typedef int (*NITF_PLUGIN_TRE_HANDLER_FUNCTION) typedef nitf_TREHandler* (*NITF_PLUGIN_TRE_HANDLER_FUNCTION)(nitf_Error * error); +// These are TREs which are linked into NITF rather than loaded at run-time. +typedef struct _nitf_TREPreloaded +{ + const char* name; + NITF_PLUGIN_INIT_FUNCTION init; + NITF_PLUGIN_TRE_HANDLER_FUNCTION handler; +} nitf_TREPreloaded; /* \brief NITF_PLUGIN_COMPRESSION_HANDLER_FUNCTION - Function pointer for diff --git a/modules/c/nitf/include/nitf/PluginRegistry.h b/modules/c/nitf/include/nitf/PluginRegistry.h index cc22d82f6..858d486fe 100644 --- a/modules/c/nitf/include/nitf/PluginRegistry.h +++ b/modules/c/nitf/include/nitf/PluginRegistry.h @@ -165,6 +165,8 @@ NITFAPI(NITF_BOOL) nitf_PluginRegistry_loadDir(const char* dirName, nitf_Error * error); +NITFAPI(NITF_BOOL) + nitf_PluginRegistry_insertPlugin_(const char* msg, nitf_PluginRegistry* reg, const char** ident, nitf_DLL* dll, nitf_Error* error); NITFAPI(NITF_BOOL) nitf_PluginRegistry_loadPlugin(const char* fullPathName, nitf_Error* error); diff --git a/modules/c/nitf/shared/ACCHZB.c b/modules/c/nitf/shared/ACCHZB.c index 2107c87b4..7be1d1ea2 100644 --- a/modules/c/nitf/shared/ACCHZB.c +++ b/modules/c/nitf/shared/ACCHZB.c @@ -24,7 +24,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription ACCHZB_description[] = { {NITF_BCS_N, 2, "Number of horizontal accuracy regions", "NUMACHZ", }, {NITF_LOOP, 0, NULL, "NUMACHZ"}, {NITF_BCS_A, 3, "Unit of Measure for AAH", "UNIAAH" }, @@ -44,6 +44,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(ACCHZB, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(ACCHZB) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/ACFTA.c b/modules/c/nitf/shared/ACFTA.c index 60c7f9ce6..e5d17b906 100644 --- a/modules/c/nitf/shared/ACFTA.c +++ b/modules/c/nitf/shared/ACFTA.c @@ -114,13 +114,13 @@ static nitf_TREDescription descrip_00199[] = { }; /* Define the available descriptions and the default one */ -static nitf_TREDescriptionInfo descriptions[] = { +static nitf_TREDescriptionInfo ACFTADescriptions[] = { { "ACFTA_132", descrip_00132, 132 }, { "ACFTA_154", descrip_00154, 154 }, { "ACFTA_199", descrip_00199, 199 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet ACFTADescriptionSet = { 0, ACFTADescriptions }; #if 1 diff --git a/modules/c/nitf/shared/AIMIDA.c b/modules/c/nitf/shared/AIMIDA.c index d1d6421ff..749008e98 100644 --- a/modules/c/nitf/shared/AIMIDA.c +++ b/modules/c/nitf/shared/AIMIDA.c @@ -100,7 +100,7 @@ static nitf_TREDescriptionInfo descriptions[] = { { "AIMIDA_89", descrip_00089, 89 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet AIMIDADescriptionSet = { 0, descriptions }; NITF_DECLARE_PLUGIN(AIMIDA) diff --git a/modules/c/nitf/shared/AIMIDB.c b/modules/c/nitf/shared/AIMIDB.c index b30cedf03..4f752df7f 100644 --- a/modules/c/nitf/shared/AIMIDB.c +++ b/modules/c/nitf/shared/AIMIDB.c @@ -30,7 +30,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription AIMIDB_description[] = { {NITF_BCS_A, 14, "Acquisition Date/Time", "ACQUISITION_DATE" }, {NITF_BCS_A, 4, "Mission Number", "MISSION_NO" }, {NITF_BCS_A, 10, "Mission ID (ATO)", "MISSION_IDENTIFICATION" }, @@ -52,6 +52,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(AIMIDB, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(AIMIDB) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/CSCRNA.c b/modules/c/nitf/shared/CSCRNA.c index 04d029578..fc8ea62d2 100644 --- a/modules/c/nitf/shared/CSCRNA.c +++ b/modules/c/nitf/shared/CSCRNA.c @@ -30,7 +30,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription CSCRNA_description[] = { {NITF_BCS_A, 1, "predicted corners flag", "PREDICT_CORNERS" }, {NITF_BCS_N, 9, "lat UL", "ULCNR_LAT" }, {NITF_BCS_N, 10, "long UL", "ULCNR_LONG" }, @@ -47,6 +47,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(CSCRNA, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(CSCRNA) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/CSEXRB.c b/modules/c/nitf/shared/CSEXRB.c index ada74d1c3..e9fb5af97 100644 --- a/modules/c/nitf/shared/CSEXRB.c +++ b/modules/c/nitf/shared/CSEXRB.c @@ -30,7 +30,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription CSEXRB_description[] = { {NITF_BCS_A, 36, "UUID Assigned to the Current Image Plane", "IMAGE_UUID"}, {NITF_BCS_N, 3, "Number of GLAS/GFM DES Associated with this Image", "NUM_ASSOC_DES"}, {NITF_IF, 0, "> 0", "NUM_ASSOC_DES"}, @@ -144,6 +144,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(CSEXRB, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(CSEXRB) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/ENGRDA.c b/modules/c/nitf/shared/ENGRDA.c index d9de9d24c..f794003f3 100644 --- a/modules/c/nitf/shared/ENGRDA.c +++ b/modules/c/nitf/shared/ENGRDA.c @@ -31,7 +31,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription ENGRDA_description[] = { {NITF_BCS_A, 20, "Unique Source System Name", "RESRC" }, {NITF_BCS_N, 3, "Record Entry Count", "RECNT" }, {NITF_LOOP, 0, NULL, "RECNT"}, @@ -57,12 +57,12 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -static nitf_TREDescriptionInfo descriptions[] = { - { "ENGRDA", description, NITF_TRE_DESC_NO_LENGTH }, +static nitf_TREDescriptionInfo ENGRDA_descriptions[] = { + { "ENGRDA", ENGRDA_description, NITF_TRE_DESC_NO_LENGTH }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet ENGRDA_descriptionSet = { 0, ENGRDA_descriptions }; static const char *ident[] = { NITF_PLUGIN_TRE_KEY, "ENGRDA", NULL }; @@ -294,9 +294,9 @@ NITFPRIV(NITF_BOOL) ENGRDA_read(nitf_IOInterface* io, return ok; } -NITFAPI(const char**) ENGRDA_init(nitf_Error* error) +NITF_PLUGIN_FUNCTION_EXPORT(const char**) ENGRDA_init(nitf_Error* error) { - if (!nitf_TREUtils_createBasicHandler(&descriptionSet, + if (!nitf_TREUtils_createBasicHandler(&ENGRDA_descriptionSet, &engrdaHandler, error)) { @@ -310,7 +310,7 @@ NITFAPI(const char**) ENGRDA_init(nitf_Error* error) return ident; } -NITFAPI(nitf_TREHandler*) ENGRDA_handler(nitf_Error* error) +NITF_PLUGIN_FUNCTION_EXPORT(nitf_TREHandler*) ENGRDA_handler(nitf_Error* error) { (void)error; return &engrdaHandler; diff --git a/modules/c/nitf/shared/EXPLTA.c b/modules/c/nitf/shared/EXPLTA.c index c5d84e0e8..b7e0c9764 100644 --- a/modules/c/nitf/shared/EXPLTA.c +++ b/modules/c/nitf/shared/EXPLTA.c @@ -73,7 +73,7 @@ static nitf_TREDescriptionInfo descriptions[] = { { "EXPLTA_101", descrip_00101, 101 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet EXPLTADescriptionSet = { 0, descriptions }; NITF_DECLARE_PLUGIN(EXPLTA) diff --git a/modules/c/nitf/shared/HISTOA.c b/modules/c/nitf/shared/HISTOA.c index 1432f6b5c..30b505b1c 100644 --- a/modules/c/nitf/shared/HISTOA.c +++ b/modules/c/nitf/shared/HISTOA.c @@ -30,7 +30,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription HISTOA_description[] = { {NITF_BCS_A, 20, "System Type", "SYSTYPE" }, {NITF_BCS_A, 12, "Prior Compression", "PC" }, {NITF_BCS_A, 4, "Prior Enhancements", "PE" }, @@ -124,6 +124,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(HISTOA, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(HISTOA) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/IOMAPA.c b/modules/c/nitf/shared/IOMAPA.c index a9e412ec8..754055e18 100644 --- a/modules/c/nitf/shared/IOMAPA.c +++ b/modules/c/nitf/shared/IOMAPA.c @@ -81,7 +81,7 @@ static nitf_TREDescriptionInfo descriptions[] = { { "IOMAPA_91", descrip_00091, 91 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet IOMAPADescriptionSet = { 0, descriptions }; NITF_DECLARE_PLUGIN(IOMAPA) diff --git a/modules/c/nitf/shared/JITCID.c b/modules/c/nitf/shared/JITCID.c index 73bacd87a..97b21d6e8 100644 --- a/modules/c/nitf/shared/JITCID.c +++ b/modules/c/nitf/shared/JITCID.c @@ -26,11 +26,11 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription JITCID_description[] = { {NITF_BCS_A, NITF_TRE_GOBBLE, "File Comment", "FILCMT" }, {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(JITCID, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(JITCID) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/MENSRA.c b/modules/c/nitf/shared/MENSRA.c index b8ebacf2a..f59ae864d 100644 --- a/modules/c/nitf/shared/MENSRA.c +++ b/modules/c/nitf/shared/MENSRA.c @@ -109,7 +109,7 @@ static nitf_TREDescriptionInfo descriptions[] = { { "MENSRA_185", descrip_00185, 185 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet MENSRADescriptionSet = { 0, descriptions }; NITF_DECLARE_PLUGIN(MENSRA) diff --git a/modules/c/nitf/shared/PATCHA.c b/modules/c/nitf/shared/PATCHA.c index c3ffd29e5..5a098505a 100644 --- a/modules/c/nitf/shared/PATCHA.c +++ b/modules/c/nitf/shared/PATCHA.c @@ -75,7 +75,7 @@ static nitf_TREDescriptionInfo descriptions[] = { { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet PATCHADescriptionSet = { 0, descriptions }; NITF_DECLARE_PLUGIN(PATCHA) diff --git a/modules/c/nitf/shared/PTPRAA.c b/modules/c/nitf/shared/PTPRAA.c index c0d63301f..fdf222525 100644 --- a/modules/c/nitf/shared/PTPRAA.c +++ b/modules/c/nitf/shared/PTPRAA.c @@ -31,7 +31,7 @@ NITF_CXX_GUARD // MIL-PRF-89034, Table 38 (page 80) -static nitf_TREDescription description[] = { +static nitf_TREDescription PTPRAA_description[] = { {NITF_BCS_A, 4, "Segment Model ID", "SISEGID" }, {NITF_BCS_N, 8, "Segment Absolute CE 90%", "SNACE" }, {NITF_BCS_N, 8, "Segment Absolute LE 90%", "SNALE" }, @@ -66,6 +66,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(PTPRAA, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(PTPRAA) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/RPFHDR.c b/modules/c/nitf/shared/RPFHDR.c index d484e83f2..9b32de32d 100644 --- a/modules/c/nitf/shared/RPFHDR.c +++ b/modules/c/nitf/shared/RPFHDR.c @@ -30,7 +30,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription RPFHDR_description[] = { {NITF_BINARY, 1, "endian flag", "ENDIAN" }, {NITF_BINARY, 2, "header section length", "HDSECL" }, {NITF_BCS_A, 12, "filename", "FILENM" }, @@ -44,6 +44,6 @@ static nitf_TREDescription description[] = { {NITF_END, 0, NULL, NULL} }; -NITF_DECLARE_SINGLE_PLUGIN(RPFHDR, description) +NITF_DECLARE_SINGLE_PLUGIN_SIMPLE(RPFHDR) NITF_CXX_ENDGUARD diff --git a/modules/c/nitf/shared/TEST_DES.c b/modules/c/nitf/shared/TEST_DES.c index c9a06dd95..d09588ed2 100644 --- a/modules/c/nitf/shared/TEST_DES.c +++ b/modules/c/nitf/shared/TEST_DES.c @@ -55,7 +55,7 @@ NITF_CXX_GUARD -static nitf_TREDescription description[] = { +static nitf_TREDescription TEST_DES_description[] = { {NITF_BCS_N, 2, "Number of data values", "TEST_DES_COUNT" }, {NITF_BCS_N, 3, "Start value in ramp", "TEST_DES_START" }, {NITF_BCS_N, 2, "Increment between values in ramp", "TEST_DES_INCREMENT" }, @@ -63,7 +63,7 @@ static nitf_TREDescription description[] = { }; -static const char *ident[] = +static const char *TEST_DES_ident[] = { NITF_PLUGIN_TRE_KEY, "TEST DES", @@ -71,24 +71,24 @@ static const char *ident[] = NULL }; -static nitf_TREDescriptionInfo descriptions[] = { - { "TEST DES", description, NITF_TRE_DESC_NO_LENGTH }, - { "TEST_DES", description, NITF_TRE_DESC_NO_LENGTH }, +static nitf_TREDescriptionInfo TEST_DES_descriptions[] = { + { "TEST DES", TEST_DES_description, NITF_TRE_DESC_NO_LENGTH }, + { "TEST_DES", TEST_DES_description, NITF_TRE_DESC_NO_LENGTH }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet TEST_DES_descriptionSet = { 0, TEST_DES_descriptions }; static nitf_TREHandler TEST_DESHandler; -NITFAPI(const char**) TEST_DES_init(nitf_Error* error) +NITF_PLUGIN_FUNCTION_EXPORT(const char**) TEST_DES_init(nitf_Error* error) { - if (!nitf_TREUtils_createBasicHandler(&descriptionSet, + if (!nitf_TREUtils_createBasicHandler(&TEST_DES_descriptionSet, &TEST_DESHandler,error)) return NULL; - return ident; + return TEST_DES_ident; } -NITFAPI(void) TEST_DES_cleanup(void){} -NITFAPI(nitf_TREHandler*) TEST_DES_handler(nitf_Error* error) { +NITF_PLUGIN_FUNCTION_EXPORT(void) TEST_DES_cleanup(void){} +NITF_PLUGIN_FUNCTION_EXPORT(nitf_TREHandler*) TEST_DES_handler(nitf_Error* error) { (void)error; return &TEST_DESHandler; } diff --git a/modules/c/nitf/shared/XML_DATA_CONTENT.c b/modules/c/nitf/shared/XML_DATA_CONTENT.c index 02dbc8631..4af8240b8 100644 --- a/modules/c/nitf/shared/XML_DATA_CONTENT.c +++ b/modules/c/nitf/shared/XML_DATA_CONTENT.c @@ -65,13 +65,13 @@ static nitf_TREDescription descrip_0773[] = { }; /* Define the available descriptions and the default one */ -static nitf_TREDescriptionInfo descriptions[] = { +static nitf_TREDescriptionInfo XML_DATA_CONTENTDescriptions[] = { { "XML_DATA_CONTENT_005", descrip_0005, 5 }, { "XML_DATA_CONTENT_283", descrip_0283, 283 }, { "XML_DATA_CONTENT_773", descrip_0773, 773 }, { NULL, NULL, NITF_TRE_DESC_NO_LENGTH } }; -static nitf_TREDescriptionSet descriptionSet = { 0, descriptions }; +static nitf_TREDescriptionSet XML_DATA_CONTENTDescriptionSet = { 0, XML_DATA_CONTENTDescriptions }; NITF_DECLARE_PLUGIN(XML_DATA_CONTENT) diff --git a/modules/c/nitf/source/PluginRegistry.c b/modules/c/nitf/source/PluginRegistry.c index 51734ff27..e05bc2a84 100644 --- a/modules/c/nitf/source/PluginRegistry.c +++ b/modules/c/nitf/source/PluginRegistry.c @@ -470,12 +470,34 @@ nitf_PluginRegistry_unload(nitf_PluginRegistry* reg, nitf_Error* error) return success; } +static NITF_BOOL insertPlugin_(const char* msg, + nitf_PluginRegistry* reg, const char** ident, nitf_DLL* dll, nitf_Error* error) +{ + /* If no ident, we have a set error and an invalid plugin */ + if (ident) + { + /* I expect to have problems with this now and then */ + int ok = insertPlugin(reg, ident, dll, error); + + /* If insertion failed, take our toys and leave */ + if (!ok) + { + return NITF_FAILURE; + } + (void)msg; +#ifdef NITF_DEBUG_PLUGIN_REG + printf(msg, keyName, dll); +#endif + return NITF_SUCCESS; + } + return NITF_FAILURE; +} + NITFAPI(NITF_BOOL) nitf_PluginRegistry_loadPlugin(const char* fullName, nitf_Error* error) { /* For now, the key is the dll name minus the extension */ char keyName[NITF_MAX_PATH] = ""; - int ok; nitf_DLL* dll; const char** ident; nitf_PluginRegistry* reg = nitf_PluginRegistry_getInstance(error); @@ -499,24 +521,8 @@ nitf_PluginRegistry_loadPlugin(const char* fullName, nitf_Error* error) /* Now init the plugin!!! */ ident = doInit(dll, keyName, error); - - /* If no ident, we have a set error and an invalid plugin */ - if (ident) - { - /* I expect to have problems with this now and then */ - ok = insertPlugin(reg, ident, dll, error); - - /* If insertion failed, take our toys and leave */ - if (!ok) - { - return NITF_FAILURE; - } -#ifdef NITF_DEBUG_PLUGIN_REG - printf("Successfully loaded plugin: [%s] at [%p]\n", keyName, dll); -#endif - return NITF_SUCCESS; - } - return NITF_FAILURE; + return insertPlugin_("Successfully loaded plugin: [%s] at [%p]\n", + reg, ident, dll, error); } NITFAPI(NITF_BOOL) @@ -945,7 +951,6 @@ insertCreator(nitf_DLL* dso, /* We are trying to find tre_main */ /* Retrieve the main */ NITF_DLL_FUNCTION_PTR dsoMain = nitf_DLL_retrieve(dso, name, error); - if (!dsoMain) { /* If it didnt work, we are done */ @@ -968,8 +973,67 @@ insertCreator(nitf_DLL* dso, * * No more talking to the DSOs directly */ -NITFPROT(nitf_TREHandler*) -nitf_PluginRegistry_retrieveTREHandler(nitf_PluginRegistry* reg, +static const nitf_TREPreloaded* findPreloadedTRE(const char* keyName) +{ + extern const nitf_TREPreloaded preloadedTREs[]; + for (size_t i = 0;; i++) + { + const char* pKeyName = preloadedTREs[i].name; + if (pKeyName == NULL) // end of list + { + return NULL; + } + if (strcmp(keyName, pKeyName) == 0) + { + return &(preloadedTREs[i]); + } + } +} + +/* + * Initialize a DSO. The init hook is retrieved and called once + * when the DSO is loaded + */ +static const char** preload_doInit(NITF_PLUGIN_INIT_FUNCTION init, const char* prefix, nitf_Error* error) +{ + /* Else, call it */ + const char** ident = (*init)(error); + if (!ident) + { + nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "The plugin [%s] is not retrievable", prefix); + return NULL; + } + return ident; +} + +static NRT_BOOL preloadTRE(const char* keyName, nitf_Error* error) +{ + const char** ident; + nitf_PluginRegistry* reg = nitf_PluginRegistry_getInstance(error); + + /* Construct the DLL object */ + nitf_DLL* dll = nitf_DLL_construct(error); + if (!dll) + { + return NITF_FAILURE; + } + dll->lib = NULL; // not a real DLL + dll->dsoMain = NULL; // filled in after successful findPreloadedTRE() + + const nitf_TREPreloaded* plugin = findPreloadedTRE(keyName); + if (plugin == NULL) + { + return NITF_FAILURE; + } + dll->dsoMain = (NRT_DLL_FUNCTION_PTR)plugin->handler; + + /* Now init the plugin!!! */ + ident = preload_doInit(plugin->init, keyName, error); + return insertPlugin_("Successfully pre-loaded plugin: [%s] at [%p]\n", reg, ident, dll, error); +} + +static nitf_TREHandler* +nitf_PluginRegistry_retrieveTREHandler_(nitf_PluginRegistry* reg, const char* treIdent, int* hadError, nitf_Error* error) @@ -1005,6 +1069,45 @@ nitf_PluginRegistry_retrieveTREHandler(nitf_PluginRegistry* reg, return theHandler; } +static nitf_TREHandler* retrievePreloadedTREHandler(nitf_PluginRegistry* reg, const char* treIdent, + int* hadError, nitf_Error* error) +{ + if (!preloadTRE(treIdent, error)) + { + *hadError = 1; + return NULL; + } + + // Successfully preloaded the TRE, it should now be in the hash table. + return nitf_PluginRegistry_retrieveTREHandler_(reg, treIdent, hadError, error); +} + +NITFPROT(nitf_TREHandler*) +nitf_PluginRegistry_retrieveTREHandler(nitf_PluginRegistry* reg, + const char* treIdent, + int* hadError, + nitf_Error* error) +{ + nitf_TREHandler* handler = nitf_PluginRegistry_retrieveTREHandler_(reg, treIdent, hadError, error); + + if (*hadError) + { + *hadError = 0; + return retrievePreloadedTREHandler(reg, treIdent, hadError, error); + } + + // Normally, a NULL handler is **not** an error. + if (handler == NULL) + { + int bad = 0; + nitf_TREHandler* preloadedHandler = retrievePreloadedTREHandler(reg, treIdent, &bad, error); + if (!bad) + return preloadedHandler; + } + + return handler; +} + NITFPROT(nitf_CompressionInterface*) nitf_PluginRegistry_retrieveCompInterface(const char* comp, nitf_Error* error) { diff --git a/modules/c/nitf/source/TREs.c b/modules/c/nitf/source/TREs.c new file mode 100644 index 000000000..8cedb44e5 --- /dev/null +++ b/modules/c/nitf/source/TREs.c @@ -0,0 +1,67 @@ +/* ========================================================================= + * This file is part of NITRO + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * 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 . + * + */ + +#undef NITF_PLUGIN_FUNCTION_EXPORT +#define NITF_PLUGIN_FUNCTION_EXPORT(retval_) static retval_ + +#include "nitf/TRE.h" +#include "nitf/PluginIdentifier.h" + +#if _MSC_VER +#pragma warning(disable: 4464) // relative include path contains '..' +#endif + +#include "../shared/ACCHZB.c" +#include "../shared/ACCPOB.c" +#include "../shared/ACFTA.c" +#include "../shared/AIMIDB.c" +#include "../shared/CSCRNA.c" +#include "../shared/CSEXRB.c" +#include "../shared/ENGRDA.c" +#include "../shared/HISTOA.c" +#include "../shared/JITCID.c" +#include "../shared/PTPRAA.c" +#include "../shared/RPFHDR.c" + +#include "../shared/TEST_DES.c" + +#define NITF_preload_TRE(Tre_) { #Tre_, Tre_##_init, Tre_##_handler } + +extern const nitf_TREPreloaded preloadedTREs[]; +const nitf_TREPreloaded preloadedTREs[] = { +/* + NITF_preload_TRE(ACCHZB), + NITF_preload_TRE(ACCPOB), + NITF_preload_TRE(ACFTA), + NITF_preload_TRE(AIMIDB), + NITF_preload_TRE(CSCRNA), + NITF_preload_TRE(CSEXRB), + //NITF_preload_TRE(ENGRDA), + NITF_preload_TRE(HISTOA), + NITF_preload_TRE(JITCID), + NITF_preload_TRE(PTPRAA), + NITF_preload_TRE(RPFHDR), + + NITF_preload_TRE(TEST_DES), +*/ + { NULL, NULL, NULL } +}; diff --git a/modules/c/nrt/include/nrt/DLL.h b/modules/c/nrt/include/nrt/DLL.h index 9705b8a54..dbdb2127f 100644 --- a/modules/c/nrt/include/nrt/DLL.h +++ b/modules/c/nrt/include/nrt/DLL.h @@ -51,7 +51,8 @@ typedef struct _NRT_DLL { char *libname; /* The name of the library */ - NRT_NATIVE_DLL lib; /* A handle to the library */ + NRT_NATIVE_DLL lib; /* A handle to the library, or NULL for "preloaded" TREs */ + NRT_DLL_FUNCTION_PTR dsoMain; /* If 'lib' is NULL, the main() function */ } nrt_DLL; NRT_CXX_GUARD diff --git a/modules/c/nrt/source/DLLUnix.c b/modules/c/nrt/source/DLLUnix.c index 1cd147e76..fb68470cc 100644 --- a/modules/c/nrt/source/DLLUnix.c +++ b/modules/c/nrt/source/DLLUnix.c @@ -39,6 +39,7 @@ NRTAPI(nrt_DLL *) nrt_DLL_construct(nrt_Error * error) } dll->libname = NULL; dll->lib = NULL; + dll->dsoMain = NULL; return dll; } @@ -84,6 +85,7 @@ NRTAPI(NRT_BOOL) nrt_DLL_load(nrt_DLL * dll, const char *libname, return NRT_FAILURE; } + dll->dsoMain = NULL; return NRT_SUCCESS; } @@ -120,7 +122,16 @@ NRTAPI(NRT_DLL_FUNCTION_PTR) nrt_DLL_retrieve(nrt_DLL * dll, NRT_ERR_RETRIEVING_DLL_HOOK); } return ptr; + } + // This might be a "preloaded" TRE + if (dll->dsoMain) + { + const char* underscore = strchr(function, '_'); + if ((underscore != NULL) && strcmp(underscore, "_handler") == 0) + { + return dll->dsoMain; + } } /* You shouldnt be calling it if it didnt load */ diff --git a/modules/c/nrt/source/DLLWin32.c b/modules/c/nrt/source/DLLWin32.c index b6c7138c0..d5a59e621 100644 --- a/modules/c/nrt/source/DLLWin32.c +++ b/modules/c/nrt/source/DLLWin32.c @@ -37,6 +37,7 @@ NRTAPI(nrt_DLL *) nrt_DLL_construct(nrt_Error * error) { dll->libname = NULL; dll->lib = NULL; + dll->dsoMain = NULL; } return dll; } @@ -62,7 +63,7 @@ NRTAPI(void) nrt_DLL_destruct(nrt_DLL ** dll) NRTAPI(NRT_BOOL) nrt_DLL_isValid(nrt_DLL * dll) { - return (dll->lib != (NRT_NATIVE_DLL) NULL); + return (dll->lib != NULL) && (dll->dsoMain == NULL); } NRTAPI(NRT_BOOL) nrt_DLL_load(nrt_DLL * dll, const char *libname, @@ -87,6 +88,7 @@ NRTAPI(NRT_BOOL) nrt_DLL_load(nrt_DLL * dll, const char *libname, dll->libname = NULL; return NRT_FAILURE; } + dll->dsoMain = NULL; return NRT_SUCCESS; } @@ -132,6 +134,16 @@ NRTAPI(NRT_DLL_FUNCTION_PTR) nrt_DLL_retrieve(nrt_DLL * dll, return ptr; } + // This might be a "preloaded" TRE + if (dll->dsoMain) + { + const char* underscore = strchr(function, '_'); + if ((underscore != NULL) && strcmp(underscore, "_handler") == 0) + { + return dll->dsoMain; + } + } + nrt_Error_initf(error, NRT_CTXT, NRT_ERR_UNINITIALIZED_DLL_READ, "Failed to retrieve function [%s] -- DLL appears to be uninitialized", function); diff --git a/nitro.sln b/nitro.sln index d32ec9368..56cfb2e04 100644 --- a/nitro.sln +++ b/nitro.sln @@ -22,8 +22,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "modules\c++\nit EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ACCPOB", "modules\c\nitf\ACCPOB.vcxproj", "{730B1E6E-2469-4F9E-B093-D0C6262453C9}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ACCHZB", "modules\c\nitf\ACCHZB.vcxproj", "{53F9F908-C678-4DEE-9309-E71C1D03A45F}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ACFTA", "modules\c\nitf\ACFTA.vcxproj", "{51D7B426-899E-428D-9F69-5DDAC9E403FB}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AIMIDB", "modules\c\nitf\AIMIDB.vcxproj", "{12AA0752-4EE3-4E0A-85AF-0E5DEADBF343}" @@ -36,14 +34,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CSCRNA", "modules\c\nitf\CS EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RPFHDR", "modules\c\nitf\RPFHDR.vcxproj", "{CF5B4F02-364D-4117-9FB9-6C9C7938E412}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "show_nitf++", "modules\c++\nitf\apps\show_nitf++\show_nitf++.vcxproj", "{839FF52C-57D1-45B6-81FD-5C7D72523EE5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTPRAA", "modules\c\nitf\PTPRAA.vcxproj", "{2BAAACA9-A5A4-412C-AE52-B16C2D107F55}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HISTOA", "modules\c\nitf\HISTOA.vcxproj", "{D749AA73-4C9A-473D-96BB-070A6D9CAA54}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ENGRDA", "modules\c\nitf\ENGRDA.vcxproj", "{53F9F908-C678-4DEE-9309-E71C1E03A45F}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "J2KCompress", "modules\c\j2k\J2KCompress.vcxproj", "{A676EDF3-F231-47C8-A6E6-0FE50B50B71B}" @@ -65,6 +59,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda- EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{8ACE478C-8F6F-4D42-9B43-7D75882D4BE1}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ACCHZB", "modules\c\nitf\ACCHZB.vcxproj", "{53F9F908-C678-4DEE-9309-E71C1D03A45F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HISTOA", "modules\c\nitf\HISTOA.vcxproj", "{D749AA73-4C9A-473D-96BB-070A6D9CAA54}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -83,10 +83,6 @@ Global {730B1E6E-2469-4F9E-B093-D0C6262453C9}.Debug|x64.Build.0 = Debug|x64 {730B1E6E-2469-4F9E-B093-D0C6262453C9}.Release|x64.ActiveCfg = Release|x64 {730B1E6E-2469-4F9E-B093-D0C6262453C9}.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 - {53F9F908-C678-4DEE-9309-E71C1D03A45F}.Release|x64.Build.0 = Release|x64 {51D7B426-899E-428D-9F69-5DDAC9E403FB}.Debug|x64.ActiveCfg = Debug|x64 {51D7B426-899E-428D-9F69-5DDAC9E403FB}.Debug|x64.Build.0 = Debug|x64 {51D7B426-899E-428D-9F69-5DDAC9E403FB}.Release|x64.ActiveCfg = Release|x64 @@ -107,10 +103,6 @@ Global {CF5B4F02-364D-4117-9FB9-6C9C7938E412}.Debug|x64.Build.0 = Debug|x64 {CF5B4F02-364D-4117-9FB9-6C9C7938E412}.Release|x64.ActiveCfg = Release|x64 {CF5B4F02-364D-4117-9FB9-6C9C7938E412}.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 {839FF52C-57D1-45B6-81FD-5C7D72523EE5}.Debug|x64.ActiveCfg = Debug|x64 {839FF52C-57D1-45B6-81FD-5C7D72523EE5}.Debug|x64.Build.0 = Debug|x64 {839FF52C-57D1-45B6-81FD-5C7D72523EE5}.Release|x64.ActiveCfg = Release|x64 @@ -119,10 +111,6 @@ Global {2BAAACA9-A5A4-412C-AE52-B16C2D107F55}.Debug|x64.Build.0 = Debug|x64 {2BAAACA9-A5A4-412C-AE52-B16C2D107F55}.Release|x64.ActiveCfg = Release|x64 {2BAAACA9-A5A4-412C-AE52-B16C2D107F55}.Release|x64.Build.0 = Release|x64 - {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Debug|x64.ActiveCfg = Debug|x64 - {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Debug|x64.Build.0 = Debug|x64 - {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Release|x64.ActiveCfg = Release|x64 - {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Release|x64.Build.0 = Release|x64 {53F9F908-C678-4DEE-9309-E71C1E03A45F}.Debug|x64.ActiveCfg = Debug|x64 {53F9F908-C678-4DEE-9309-E71C1E03A45F}.Debug|x64.Build.0 = Debug|x64 {53F9F908-C678-4DEE-9309-E71C1E03A45F}.Release|x64.ActiveCfg = Release|x64 @@ -147,27 +135,39 @@ 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 + {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 + {53F9F908-C678-4DEE-9309-E71C1D03A45F}.Release|x64.Build.0 = Release|x64 + {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Debug|x64.ActiveCfg = Debug|x64 + {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Debug|x64.Build.0 = Debug|x64 + {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.Release|x64.ActiveCfg = Release|x64 + {D749AA73-4C9A-473D-96BB-070A6D9CAA54}.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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {730B1E6E-2469-4F9E-B093-D0C6262453C9} = {27A2685A-E869-42A2-956D-92994F60C536} - {53F9F908-C678-4DEE-9309-E71C1D03A45F} = {27A2685A-E869-42A2-956D-92994F60C536} {51D7B426-899E-428D-9F69-5DDAC9E403FB} = {27A2685A-E869-42A2-956D-92994F60C536} {12AA0752-4EE3-4E0A-85AF-0E5DEADBF343} = {27A2685A-E869-42A2-956D-92994F60C536} {D1D7FCD3-6130-4504-9DA0-9D80506BE55E} = {27A2685A-E869-42A2-956D-92994F60C536} {023DE06D-3967-4406-B1B8-032118BB2552} = {27A2685A-E869-42A2-956D-92994F60C536} {CF5B4F02-364D-4117-9FB9-6C9C7938E412} = {27A2685A-E869-42A2-956D-92994F60C536} - {78849481-D356-4CC7-B182-31C21F857ED1} = {27A2685A-E869-42A2-956D-92994F60C536} {2BAAACA9-A5A4-412C-AE52-B16C2D107F55} = {27A2685A-E869-42A2-956D-92994F60C536} - {D749AA73-4C9A-473D-96BB-070A6D9CAA54} = {27A2685A-E869-42A2-956D-92994F60C536} {53F9F908-C678-4DEE-9309-E71C1E03A45F} = {27A2685A-E869-42A2-956D-92994F60C536} {A676EDF3-F231-47C8-A6E6-0FE50B50B71B} = {27A2685A-E869-42A2-956D-92994F60C536} {C787537A-0CAC-4D6D-A6D6-A66765A06753} = {27A2685A-E869-42A2-956D-92994F60C536} {A45CB073-25A7-411D-A7E7-589BCC8AF547} = {5C5727E7-0CFF-42B4-8F5A-D31B3BC81F21} {0A9BDA26-092F-4A2C-BBEF-00C64BF0C65E} = {27A2685A-E869-42A2-956D-92994F60C536} {9997E895-5161-4DDF-8F3F-099894CB2F21} = {7D26D571-0014-4C50-BF86-612E743E64B6} + {53F9F908-C678-4DEE-9309-E71C1D03A45F} = {27A2685A-E869-42A2-956D-92994F60C536} + {D749AA73-4C9A-473D-96BB-070A6D9CAA54} = {27A2685A-E869-42A2-956D-92994F60C536} + {78849481-D356-4CC7-B182-31C21F857ED1} = {27A2685A-E869-42A2-956D-92994F60C536} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2D7AC542-BBB6-4BAC-8BF1-7E76C714BBA4}