From 4346b6a906cd27eb7bc028211db1a235c877fed1 Mon Sep 17 00:00:00 2001 From: Jonathan Hollocombe Date: Wed, 6 Dec 2023 11:46:14 +0000 Subject: [PATCH] Moving all core plugins to use new plugin base --- source/plugins/bytes/bytesPlugin.cpp | 4 +- source/plugins/hdf5/hdf5plugin.cpp | 4 +- source/plugins/help/help_plugin.cpp | 20 +- source/plugins/keyvalue/help.txt | 7 + source/plugins/keyvalue/keyvaluePlugin.cpp | 283 +---- source/plugins/template/help.txt | 5 + source/plugins/template/templatePlugin.cpp | 16 +- source/plugins/testplugin/CMakeLists.txt | 2 +- source/plugins/testplugin/help.txt | 47 + source/plugins/testplugin/testplugin.cpp | 651 +++------- source/plugins/testplugin/testplugin.h | 21 +- source/plugins/uda/uda_plugin.cpp | 307 ++--- source/plugins/uda_plugin_base.cpp | 29 +- source/plugins/uda_plugin_base.hpp | 35 +- source/plugins/viewport/viewport.cpp | 1272 ++++++++------------ source/plugins/viewport/viewport.h | 13 - 16 files changed, 945 insertions(+), 1771 deletions(-) create mode 100644 source/plugins/keyvalue/help.txt create mode 100644 source/plugins/template/help.txt create mode 100644 source/plugins/testplugin/help.txt diff --git a/source/plugins/bytes/bytesPlugin.cpp b/source/plugins/bytes/bytesPlugin.cpp index 32c8115a7..970750e3b 100644 --- a/source/plugins/bytes/bytesPlugin.cpp +++ b/source/plugins/bytes/bytesPlugin.cpp @@ -12,8 +12,8 @@ class BytesPlugin : public UDAPluginBase { public: BytesPlugin(); int read(IDAM_PLUGIN_INTERFACE* plugin_interface); - int init(IDAM_PLUGIN_INTERFACE* plugin_interface) override { return 0; } - int reset() override { return 0; } + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} }; BytesPlugin::BytesPlugin() diff --git a/source/plugins/hdf5/hdf5plugin.cpp b/source/plugins/hdf5/hdf5plugin.cpp index 71c442e73..2be8044a4 100644 --- a/source/plugins/hdf5/hdf5plugin.cpp +++ b/source/plugins/hdf5/hdf5plugin.cpp @@ -16,8 +16,8 @@ class HDF5Plugin : public UDAPluginBase { { return setReturnDataString(plugin_interface->data_block, "foo!", nullptr); } - int init(IDAM_PLUGIN_INTERFACE* plugin_interface) override { return 0; } - int reset() override { return 0; } + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} }; HDF5Plugin::HDF5Plugin() diff --git a/source/plugins/help/help_plugin.cpp b/source/plugins/help/help_plugin.cpp index 285788692..73826708a 100755 --- a/source/plugins/help/help_plugin.cpp +++ b/source/plugins/help/help_plugin.cpp @@ -13,8 +13,8 @@ class HelpPlugin : public UDAPluginBase { HelpPlugin(); int ping(IDAM_PLUGIN_INTERFACE* plugin_interface); int services(IDAM_PLUGIN_INTERFACE* plugin_interface); - int init(IDAM_PLUGIN_INTERFACE* plugin_interface) override { return 0; } - int reset() override { return 0; } + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} }; HelpPlugin::HelpPlugin() @@ -35,7 +35,7 @@ int helpPlugin(IDAM_PLUGIN_INTERFACE* plugin_interface) return plugin.call(plugin_interface); } -int HelpPlugin::ping(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) +int HelpPlugin::ping(IDAM_PLUGIN_INTERFACE* plugin_interface) { //---------------------------------------------------------------------------------------- @@ -72,20 +72,20 @@ int HelpPlugin::ping(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) defineField(&field, "microseconds", "Server inter-second time in microseconds", &offset, SCALARUINT); addCompoundField(&usertype, field); - USERDEFINEDTYPELIST* userdefinedtypelist = idam_plugin_interface->userdefinedtypelist; + USERDEFINEDTYPELIST* userdefinedtypelist = plugin_interface->userdefinedtypelist; addUserDefinedType(userdefinedtypelist, usertype); // assign the returned data structure auto data = (HELP_PING*)malloc(sizeof(HELP_PING)); - addMalloc(idam_plugin_interface->logmalloclist, (void*)data, 1, sizeof(HELP_PING), "HELP_PING"); // Register + addMalloc(plugin_interface->logmalloclist, (void*)data, 1, sizeof(HELP_PING), "HELP_PING"); // Register data->seconds = (unsigned int)serverTime.tv_sec; data->microseconds = (unsigned int)serverTime.tv_usec; // return to the client - DATA_BLOCK* data_block = idam_plugin_interface->data_block; + DATA_BLOCK* data_block = plugin_interface->data_block; initDataBlock(data_block); data_block->data_type = UDA_TYPE_COMPOUND; @@ -104,7 +104,7 @@ int HelpPlugin::ping(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) return 0; } -int HelpPlugin::services(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) +int HelpPlugin::services(IDAM_PLUGIN_INTERFACE* plugin_interface) { //====================================================================================== // Plugin functionality @@ -119,9 +119,9 @@ int HelpPlugin::services(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) // Total Number of registered plugins available - const ENVIRONMENT* environment = idam_plugin_interface->environment; + const ENVIRONMENT* environment = plugin_interface->environment; - const PLUGINLIST* pluginList = idam_plugin_interface->pluginList; + const PLUGINLIST* pluginList = plugin_interface->pluginList; count = 0; for (int i = 0; i < pluginList->count; i++) { @@ -264,5 +264,5 @@ int HelpPlugin::services(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) doc += "\n\n"; - return setReturnDataString(idam_plugin_interface->data_block, doc.c_str(), "Description of UDA data access services"); + return setReturnDataString(plugin_interface->data_block, doc.c_str(), "Description of UDA data access services"); } diff --git a/source/plugins/keyvalue/help.txt b/source/plugins/keyvalue/help.txt new file mode 100644 index 000000000..ff6204f98 --- /dev/null +++ b/source/plugins/keyvalue/help.txt @@ -0,0 +1,7 @@ +KEYVALUE: Plugin to allow for reading and writing data to a LevelDB key-value store + +Functions: + +read(key) Read the data from the store for the given key +write(key, value) Write the given data to the store with the given key +delete(key) Delete the key from the store diff --git a/source/plugins/keyvalue/keyvaluePlugin.cpp b/source/plugins/keyvalue/keyvaluePlugin.cpp index e690ec959..ed5951480 100755 --- a/source/plugins/keyvalue/keyvaluePlugin.cpp +++ b/source/plugins/keyvalue/keyvaluePlugin.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include #include #include @@ -10,260 +13,92 @@ namespace uda { namespace keyvalue { -class Plugin { +class Plugin : public UDAPluginBase { public: - Plugin() = default; - - int help(IDAM_PLUGIN_INTERFACE* plugin_interface); - int version(IDAM_PLUGIN_INTERFACE* plugin_interface); - int build_date(IDAM_PLUGIN_INTERFACE* plugin_interface); - int default_method(IDAM_PLUGIN_INTERFACE* plugin_interface); - int max_interface_version(IDAM_PLUGIN_INTERFACE* plugin_interface); + Plugin(); int write(IDAM_PLUGIN_INTERFACE* plugin_interface); int read(IDAM_PLUGIN_INTERFACE* plugin_interface); int del(IDAM_PLUGIN_INTERFACE* plugin_interface); - - int init(IDAM_PLUGIN_INTERFACE* plugin_interface); - void reset(IDAM_PLUGIN_INTERFACE* plugin_interface); + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override; + void reset() override; private: - bool initialised_ = false; leveldb_readoptions_t* roptions_ = nullptr; leveldb_writeoptions_t* woptions_ = nullptr; leveldb_options_t* options_ = nullptr; leveldb_t* db_ = nullptr; }; -} -} - -int keyValue(IDAM_PLUGIN_INTERFACE* plugin_interface) +Plugin::Plugin() + : UDAPluginBase( + "KEYVALUE", + 1, + "read", + boost::filesystem::path(__FILE__).parent_path().append("help.txt").string() +) { - if (plugin_interface->interfaceVersion > THISPLUGIN_MAX_INTERFACE_VERSION) { - RAISE_PLUGIN_ERROR("Plugin Interface Version Unknown to this plugin: Unable to execute the request!"); - } - - static uda::keyvalue::Plugin plugin{}; - - if (plugin.init(plugin_interface) != 0) { - RAISE_PLUGIN_ERROR("Plugin initialisation failed."); - } - - plugin_interface->pluginVersion = THISPLUGIN_VERSION; - - REQUEST_BLOCK* request_block = plugin_interface->request_block; - - int rc = 0; - - if (STR_IEQUALS(request_block->function, "help")) { - rc = plugin.help(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "version")) { - rc = plugin.version(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "builddate")) { - rc = plugin.build_date(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "defaultmethod")) { - rc = plugin.default_method(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "maxinterfaceversion")) { - rc = plugin.max_interface_version(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "write")) { - rc = plugin.write(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "read")) { - rc = plugin.read(plugin_interface); - } else if (STR_IEQUALS(request_block->function, "delete")) { - rc = plugin.del(plugin_interface); - } else { - RAISE_PLUGIN_ERROR("Unknown function requested!"); - } - - return rc; + register_method("write", static_cast(&Plugin::write)); + register_method("read", static_cast(&Plugin::read)); + register_method("delete", static_cast(&Plugin::del)); } -int uda::keyvalue::Plugin::init(IDAM_PLUGIN_INTERFACE* plugin_interface) -{ -#if defined(UDA_VERSION) && UDA_VERSION_MAJOR > 3 - initPlugin(plugin_interface); -#endif - - REQUEST_BLOCK* request_block = plugin_interface->request_block; - - if (!initialised_ - || !strcasecmp(request_block->function, "init") || !strcasecmp(request_block->function, "initialise")) { - - options_ = leveldb_options_create(); - leveldb_options_set_create_if_missing(options_, 1); - - char* err = nullptr; - db_ = leveldb_open(options_, "idam_ks", &err); - if (err != nullptr) { - RAISE_PLUGIN_ERROR(err); - } - - woptions_ = leveldb_writeoptions_create(); - roptions_ = leveldb_readoptions_create(); - - initialised_ = true; - } - - return 0; } - -void uda::keyvalue::Plugin::reset(IDAM_PLUGIN_INTERFACE* plugin_interface) -{ - REQUEST_BLOCK* request_block = plugin_interface->request_block; - - if (plugin_interface->housekeeping || !strcasecmp(request_block->function, "reset")) { - if (!initialised_) return; - - leveldb_close(db_); - db_ = nullptr; - - leveldb_writeoptions_destroy(woptions_); - woptions_ = nullptr; - - leveldb_readoptions_destroy(roptions_); - roptions_ = nullptr; - - leveldb_options_destroy(options_); - options_ = nullptr; - - initialised_ = false; - } } -// Help: A Description of library functionality -int uda::keyvalue::Plugin::help(IDAM_PLUGIN_INTERFACE* plugin_interface) +int keyValue(IDAM_PLUGIN_INTERFACE* plugin_interface) { - DATA_BLOCK* data_block = plugin_interface->data_block; - - char* p = (char*)malloc(sizeof(char) * 2 * 1024); - - strcpy(p, "\ntemplatePlugin: Add Functions Names, Syntax, and Descriptions\n\n"); - - initDataBlock(data_block); - - data_block->rank = 1; - data_block->dims = (DIMS*)malloc(data_block->rank * sizeof(DIMS)); - - for (unsigned int i = 0; i < data_block->rank; i++) { - initDimBlock(&data_block->dims[i]); - } - - data_block->data_type = UDA_TYPE_STRING; - strcpy(data_block->data_desc, "templatePlugin: help = description of this plugin"); - - data_block->data = (char*)p; - - data_block->dims[0].data_type = UDA_TYPE_UNSIGNED_INT; - data_block->dims[0].dim_n = strlen(p) + 1; - data_block->dims[0].compressed = 1; - data_block->dims[0].dim0 = 0.0; - data_block->dims[0].diff = 1.0; - data_block->dims[0].method = 0; - - data_block->data_n = data_block->dims[0].dim_n; - - strcpy(data_block->data_label, ""); - strcpy(data_block->data_units, ""); - - return 0; + static uda::keyvalue::Plugin plugin = {}; + return plugin.call(plugin_interface); } -int uda::keyvalue::Plugin::version(IDAM_PLUGIN_INTERFACE* plugin_interface) +void uda::keyvalue::Plugin::init(IDAM_PLUGIN_INTERFACE* plugin_interface) { - DATA_BLOCK* data_block = plugin_interface->data_block; - - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_INT; - data_block->rank = 0; - data_block->data_n = 1; - int* data = (int*)malloc(sizeof(int)); - data[0] = THISPLUGIN_VERSION; - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin version number"); - strcpy(data_block->data_label, "version"); - strcpy(data_block->data_units, ""); + options_ = leveldb_options_create(); + leveldb_options_set_create_if_missing(options_, 1); - return 0; -} - -// Plugin Build Date -int uda::keyvalue::Plugin::build_date(IDAM_PLUGIN_INTERFACE* plugin_interface) -{ - DATA_BLOCK* data_block = plugin_interface->data_block; - - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_STRING; - data_block->rank = 0; - data_block->data_n = strlen(__DATE__) + 1; - char* data = (char*)malloc(data_block->data_n * sizeof(char)); - strcpy(data, __DATE__); - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin build date"); - strcpy(data_block->data_label, "date"); - strcpy(data_block->data_units, ""); + char* err = nullptr; + db_ = leveldb_open(options_, "idam_ks", &err); + if (err != nullptr) { + error(err); + } - return 0; + woptions_ = leveldb_writeoptions_create(); + roptions_ = leveldb_readoptions_create(); } -// Plugin Default Method -int uda::keyvalue::Plugin::default_method(IDAM_PLUGIN_INTERFACE* plugin_interface) +void uda::keyvalue::Plugin::reset() { - DATA_BLOCK* data_block = plugin_interface->data_block; - - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_STRING; - data_block->rank = 0; - data_block->data_n = strlen(THISPLUGIN_DEFAULT_METHOD) + 1; - char* data = (char*)malloc(data_block->data_n * sizeof(char)); - strcpy(data, THISPLUGIN_DEFAULT_METHOD); - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin default method"); - strcpy(data_block->data_label, "method"); - strcpy(data_block->data_units, ""); + leveldb_close(db_); + db_ = nullptr; - return 0; -} + leveldb_writeoptions_destroy(woptions_); + woptions_ = nullptr; -// Plugin Maximum Interface Version -int uda::keyvalue::Plugin::max_interface_version(IDAM_PLUGIN_INTERFACE* plugin_interface) -{ - DATA_BLOCK* data_block = plugin_interface->data_block; - - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_INT; - data_block->rank = 0; - data_block->data_n = 1; - int* data = (int*)malloc(sizeof(int)); - data[0] = THISPLUGIN_MAX_INTERFACE_VERSION; - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Maximum Interface Version"); - strcpy(data_block->data_label, "version"); - strcpy(data_block->data_units, ""); + leveldb_readoptions_destroy(roptions_); + roptions_ = nullptr; - return 0; + leveldb_options_destroy(options_); + options_ = nullptr; } int uda::keyvalue::Plugin::write(IDAM_PLUGIN_INTERFACE* plugin_interface) { - const char* key = nullptr; - const char* value = nullptr; - - FIND_REQUIRED_STRING_VALUE(plugin_interface->request_block->nameValueList, key); - FIND_REQUIRED_STRING_VALUE(plugin_interface->request_block->nameValueList, value); + auto key = find_required_arg(plugin_interface, "key"); + auto value = find_required_arg(plugin_interface, "value"); char* env = getenv("UDA_PLUGIN_KEYVALUE_STORE"); if (env == nullptr) { - RAISE_PLUGIN_ERROR("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); + error("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); } if (STR_EQUALS(env, "LEVELDB")) { - UDA_LOG(UDA_LOG_DEBUG, "Writing key %s to LevelDB keystore", key); + debug("Writing key {} to LevelDB keystore", key); } else { - RAISE_PLUGIN_ERROR("Unknown keyvalue store requested"); + error("Unknown keyvalue store requested"); } char* err = nullptr; - leveldb_put(db_, woptions_, key, strlen(key), value, strlen(value), &err); + leveldb_put(db_, woptions_, key.c_str(), key.size(), value.c_str(), value.size(), &err); if (err != nullptr) { RAISE_PLUGIN_ERROR_EX(err, { leveldb_free(err); }); @@ -274,25 +109,23 @@ int uda::keyvalue::Plugin::write(IDAM_PLUGIN_INTERFACE* plugin_interface) int uda::keyvalue::Plugin::read(IDAM_PLUGIN_INTERFACE* plugin_interface) { - const char* key = nullptr; - - FIND_REQUIRED_STRING_VALUE(plugin_interface->request_block->nameValueList, key); + auto key = find_required_arg(plugin_interface, "key"); char* env = getenv("UDA_PLUGIN_KEYVALUE_STORE"); if (env == nullptr) { - RAISE_PLUGIN_ERROR("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); + error("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); } if (STR_EQUALS(env, "LEVELDB")) { - UDA_LOG(UDA_LOG_DEBUG, "Writing key %s to LevelDB keystore", key); + debug("Writing key {} to LevelDB keystore", key); } else { - RAISE_PLUGIN_ERROR("Unknown keyvalue store requested"); + error("Unknown keyvalue store requested"); } char* err = nullptr; size_t value_len; - char* value = leveldb_get(db_, roptions_, key, strlen(key), &value_len, &err); + char* value = leveldb_get(db_, roptions_, key.c_str(), key.size(), &value_len, &err); if (err != nullptr) { RAISE_PLUGIN_ERROR_EX(err, { leveldb_free(err); }); @@ -306,27 +139,27 @@ int uda::keyvalue::Plugin::read(IDAM_PLUGIN_INTERFACE* plugin_interface) int uda::keyvalue::Plugin::del(IDAM_PLUGIN_INTERFACE* plugin_interface) { - const char* key = nullptr; - - FIND_REQUIRED_STRING_VALUE(plugin_interface->request_block->nameValueList, key); + auto key = find_required_arg(plugin_interface, "key"); char* env = getenv("UDA_PLUGIN_KEYVALUE_STORE"); if (env == nullptr) { - RAISE_PLUGIN_ERROR("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); + error("Environmental variable IDAM_PLUGIN_KEYVALUE_STORE not found"); } if (STR_EQUALS(env, "LEVELDB")) { - UDA_LOG(UDA_LOG_DEBUG, "Writing key %s to LevelDB keystore", key); + debug("Writing key {} to LevelDB keystore", key); } else { - RAISE_PLUGIN_ERROR("Unknown keyvalue store requested"); + error("Unknown keyvalue store requested"); } char* err = nullptr; - leveldb_delete(db_, woptions_, key, strlen(key), &err); + leveldb_delete(db_, woptions_, key.c_str(), key.size(), &err); if (err != nullptr) { - RAISE_PLUGIN_ERROR_EX(err, { leveldb_free(err); }); + std::string message = err; + leveldb_free(err); + error(message); } return 0; diff --git a/source/plugins/template/help.txt b/source/plugins/template/help.txt new file mode 100644 index 000000000..652e51dd0 --- /dev/null +++ b/source/plugins/template/help.txt @@ -0,0 +1,5 @@ +TEMPLATE: Plugin that can be used as the template for new plugins + +Functions: + +function() Example of custom plugin function diff --git a/source/plugins/template/templatePlugin.cpp b/source/plugins/template/templatePlugin.cpp index 4846a3b0f..64f4e3ee0 100755 --- a/source/plugins/template/templatePlugin.cpp +++ b/source/plugins/template/templatePlugin.cpp @@ -30,15 +30,15 @@ class TemplatePlugin : public UDAPluginBase { public: TemplatePlugin(); int function(IDAM_PLUGIN_INTERFACE* plugin_interface); - int init(IDAM_PLUGIN_INTERFACE* plugin_interface) override { return 0; } - int reset() override { return 0; } + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} }; TemplatePlugin::TemplatePlugin() : UDAPluginBase( "TEMPLATE", 1, - "read", + "function", boost::filesystem::path(__FILE__).parent_path().append("help.txt").string() ) { @@ -76,13 +76,9 @@ int TemplatePlugin::function(IDAM_PLUGIN_INTERFACE* plugin_interface) auto array = find_required_array_arg(plugin_interface, "array"); auto optional = find_arg(plugin_interface, "optional"); - std::string result = std::string("Passed args: required=") + required - + ", array=[" + to_string(array) + "]"; - if (optional) { - result += ", optional=" + std::to_string(*optional) + ")"; - } else { - result += ", optional=)"; - } + std::string optional_str = optional ? std::to_string(*optional) : ""; + std::string result = fmt::format("Passed args: required={}, array=[{}], optional={}", + required, to_string(array), optional_str); setReturnDataString(data_block, result.c_str(), "result of TemplatePlugin::function"); diff --git a/source/plugins/testplugin/CMakeLists.txt b/source/plugins/testplugin/CMakeLists.txt index 8effe9975..5522ef222 100755 --- a/source/plugins/testplugin/CMakeLists.txt +++ b/source/plugins/testplugin/CMakeLists.txt @@ -24,7 +24,7 @@ include( plugins ) uda_plugin( NAME TESTPLUGIN - ENTRY_FUNC testplugin + ENTRY_FUNC testPlugin DESCRIPTION "Generate Test Data" EXAMPLE "TESTPLUGIN::test1()" LIBNAME testplugin_plugin diff --git a/source/plugins/testplugin/help.txt b/source/plugins/testplugin/help.txt new file mode 100644 index 000000000..c35eb369a --- /dev/null +++ b/source/plugins/testplugin/help.txt @@ -0,0 +1,47 @@ +TESTPLUGIN: Plugin which generates test data that is used in UDA tests + +test0-test9: String passing tests + test0: single string as a char array + test1: single string + test2: multiple strings as a 2D array of chars + test3: array of strings + test4: data structure with a fixed length single string + test5: data structure with a fixed length multiple string + test6: data structure with an arbitrary length single string + test7: data structure with a fixed number of arbitrary length strings + test8: data structure with an arbitrary number of arbitrary length strings\n + test9: array of data structures with a variety of string types\n + test9A: array of data structures with a variety of string types and single sub structure\n + +test10-test18: Integer passing tests + test10: single integer + test11: fixed number (rank 1 array) of integers + test12: arbitrary number (rank 1 array) of integers + test13: fixed length rank 2 array of integers + test14: arbitrary length rank 2 array of integers + test15: data structure with a single integer + test16: data structure with a fixed number of integers + test17: data structure with a arbitrary number of integers + test18: array of data structures with a variety of integer types\n + +test20-test28: Short Integer passing tests + test20: single integer + test21: fixed number (rank 1 array) of integers + test22: arbitrary number (rank 1 array) of integers + test23: fixed length rank 2 array of integers + test24: arbitrary length rank 2 array of integers + test25: data structure with a single integer + test26: data structure with a fixed number of integers + test27: data structure with a arbitrary number of integers + test28: array of data structures with a variety of integer types\n + +test30-test32: double passing tests + test30: pair of doubles (Coordinate) + +test40-test40: put data block receiving tests +test50: Passing parameters into plugins via the source argument +test60-62: ENUMLIST structures + +plugin: test calling other plugins + +error: Error reporting and server termination tests; \ No newline at end of file diff --git a/source/plugins/testplugin/testplugin.cpp b/source/plugins/testplugin/testplugin.cpp index eb158a289..7e778e045 100755 --- a/source/plugins/testplugin/testplugin.cpp +++ b/source/plugins/testplugin/testplugin.cpp @@ -1,32 +1,10 @@ -/*--------------------------------------------------------------- -* Test UDA Plugin: Test regular and structured data passing middleware -* -* Input Arguments: IDAM_PLUGIN_INTERFACE *plugin_interface -* -* Returns: testplugin 0 if read was successful -* otherwise a Error Code is returned -* DATA_BLOCK Structure with Data from the File -* -* Calls freeDataBlock to free Heap memory if an Error Occurs -* -* Notes: All memory required to hold data is allocated dynamically -* in heap storage. Pointers to these areas of memory are held -* by the passed DATA_BLOCK structure. Local memory allocations -* are freed on exit. However, the blocks reserved for data are -* not and MUST BE FREED by the calling routine. -* -*---------------------------------------------------------------------------------------------------------------*/ - #include "testplugin.h" #include #include #include -#ifdef __GNUC__ -# include -#endif - +#include #include #include #include @@ -34,7 +12,9 @@ #include #include #include + #include +#include #include "teststructs.h" @@ -44,323 +24,160 @@ #ifdef TESTUDT # include -#endif // TESTUDT - -static int do_help(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test0(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test2(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test4(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test5(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test6(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test7(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test8(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test9(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test9A(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test10(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test11(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test12(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test13(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test14(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test15(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test16(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test18(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test19(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test20(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test21(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test22(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test23(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test24(IDAM_PLUGIN_INTERFACE* plugin_interface); +# include "udtc.h" +# include -static int do_test25(IDAM_PLUGIN_INTERFACE* plugin_interface); +typedef int bool; +int g_IP_Version = AF_INET; // IPv4 family of addresses +int g_Socket_Type = SOCK_STREAM; // use reliable transport layer protocol with Aknowledgements (default TCP) -static int do_test26(IDAM_PLUGIN_INTERFACE* plugin_interface); +char g_Localhost[] = "192.168.16.88"; //"192.168.16.125"; //"127.0.0.1"; // "192.168.16.88"; // Client IP address (*** passed as a parameter) +int g_Server_Port = 50000; // port number (*** passed as a parameter) -static int do_test27(IDAM_PLUGIN_INTERFACE* plugin_interface); +int g_TotalNum = 1000000; // Test data -static int do_test28(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test30(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test31(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test32(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test33(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test34(IDAM_PLUGIN_INTERFACE* plugin_interface); +int tcp_connect(SYSSOCKET *ssock, int port); +int c_connect(UDTSOCKET *usock, int port); +int createUDTSocket(int *usock, int port, int rendezvous); +int createTCPSocket(SYSSOCKET *ssock, int port, bool rendezvous); +#endif +class TestPlugin : public UDAPluginBase { +public: + TestPlugin(); + int test0(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test2(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test4(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test5(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test6(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test7(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test8(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test9(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test9A(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test10(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test11(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test12(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test13(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test14(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test15(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test16(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test18(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test19(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test20(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test21(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test22(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test23(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test24(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test25(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test26(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test27(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test28(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test30(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test31(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test32(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test33(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test34(IDAM_PLUGIN_INTERFACE* plugin_interface); #ifdef PUTDATAENABLED -static int do_test40(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test40(IDAM_PLUGIN_INTERFACE* plugin_interface); #endif // PUTDATAENABLED - -static int do_test50(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test60(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test61(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_test62(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_plugin(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_errortest(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_scalartest(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_array1dtest(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_call_plugin_test(IDAM_PLUGIN_INTERFACE* plugin_interface); -static int do_call_plugin_test_index(IDAM_PLUGIN_INTERFACE* plugin_interface); -static int do_call_plugin_test_slice(IDAM_PLUGIN_INTERFACE* plugin_interface); -static int do_call_plugin_test_stride(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_emptytest(IDAM_PLUGIN_INTERFACE* plugin_interface); - + int test50(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test60(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test61(IDAM_PLUGIN_INTERFACE* plugin_interface); + int test62(IDAM_PLUGIN_INTERFACE* plugin_interface); + int plugin(IDAM_PLUGIN_INTERFACE* plugin_interface); + int errortest(IDAM_PLUGIN_INTERFACE* plugin_interface); + int scalartest(IDAM_PLUGIN_INTERFACE* plugin_interface); + int array1dtest(IDAM_PLUGIN_INTERFACE* plugin_interface); + int call_plugin_test(IDAM_PLUGIN_INTERFACE* plugin_interface); + int call_plugin_test_index(IDAM_PLUGIN_INTERFACE* plugin_interface); + int call_plugin_test_slice(IDAM_PLUGIN_INTERFACE* plugin_interface); + int call_plugin_test_stride(IDAM_PLUGIN_INTERFACE* plugin_interface); + int emptytest(IDAM_PLUGIN_INTERFACE* plugin_interface); #ifdef CAPNP_ENABLED -static int do_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_nested_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_long_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); - -static int do_large_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); + int capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); + int nested_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); + int long_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); + int large_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface); #endif // CAPNP_ENABLED - #ifdef TESTUDT -static int do_testudt(IDAM_PLUGIN_INTERFACE* plugin_interface); + int testudt(IDAM_PLUGIN_INTERFACE* plugin_interface); #endif // TESTUDT -extern int testplugin(IDAM_PLUGIN_INTERFACE* plugin_interface) + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} +}; + +TestPlugin::TestPlugin() + : UDAPluginBase( + "TESTPLUGIN", + 1, + "test0", + boost::filesystem::path(__FILE__).parent_path().append("help.txt").string() +) { - int err = 0; - static short init = 0; - - //---------------------------------------------------------------------------------------- - // Standard v1 Plugin Interface - - REQUEST_DATA* request; - - unsigned short housekeeping; - - if (plugin_interface->interfaceVersion >= 1) { - plugin_interface->pluginVersion = 1; - request = plugin_interface->request_data; - housekeeping = plugin_interface->housekeeping; - } else { - RAISE_PLUGIN_ERROR("Plugin Interface Version is Not Known: Unable to execute the request!"); - } - - UDA_LOG(UDA_LOG_DEBUG, "Interface exchanged on entry\n"); - - //---------------------------------------------------------------------------------------- - // Heap Housekeeping - - // Plugin must maintain a list of open file handles and sockets: loop over and close all files and sockets - // Plugin must maintain a list of plugin functions called: loop over and reset state and free heap. - // Plugin must maintain a list of calls to other plugins: loop over and call each plugin with the housekeeping request - // Plugin must destroy lists at end of housekeeping - - if (housekeeping || STR_IEQUALS(request->function, "reset")) { - if (!init) return 0; // Not previously initialised: Nothing to do! - init = 0; - UDA_LOG(UDA_LOG_DEBUG, "reset function executed\n"); - return 0; - } - - //---------------------------------------------------------------------------------------- - // Initialise - - if (!init || STR_IEQUALS(request->function, "init") - || STR_IEQUALS(request->function, "initialise")) { - init = 1; - UDA_LOG(UDA_LOG_DEBUG, "plugin initialised\n"); - if (STR_IEQUALS(request->function, "init") - || STR_IEQUALS(request->function, "initialise")) { - return 0; - } - } - - if (!STR_IEQUALS(request->function, "test50") - && plugin_interface->userdefinedtypelist == nullptr) { - RAISE_PLUGIN_ERROR("Unable to define Data Structures - nullptr list!"); - } - - UDA_LOG(UDA_LOG_DEBUG, "entering init_structure_definitions\n"); - - init_structure_definitions(plugin_interface); - - UDA_LOG(UDA_LOG_DEBUG, "return from init_structure_definitions\n"); - - //---------------------------------------------------------------------------------------- - // Plugin Functions - //---------------------------------------------------------------------------------------- - - if (STR_IEQUALS(request->function, "help")) { - err = do_help(plugin_interface); - } else if (STR_IEQUALS(request->function, "test0") - || STR_IEQUALS(request->function, "test1")) { - // Single String - not a Structure - // test0: passed as a char/byte array - // test1: passed as type STRING - err = do_test0(plugin_interface); - } else if (STR_IEQUALS(request->function, "test2") - || STR_IEQUALS(request->function, "test3")) { - // Array of Strings - not a Structure - // test2: as a rank 2 char/byte array - // test3: as an array of type STRING - err = do_test2(plugin_interface); - } else if (STR_IEQUALS(request->function, "test4")) { // Simple Structure - err = do_test4(plugin_interface); - } else if (STR_IEQUALS(request->function, "test5")) { // Simple Structure with String Array - err = do_test5(plugin_interface); - } else if (STR_IEQUALS(request->function, "test6")) { // Simple Structure with String Array - err = do_test6(plugin_interface); - } else if (STR_IEQUALS(request->function, "test7")) { // Simple Structure with String Array - err = do_test7(plugin_interface); - } else if (STR_IEQUALS(request->function, "test8")) { // Simple Structure with String Array - err = do_test8(plugin_interface); - } else if (STR_IEQUALS(request->function, "test9")) { // Array of Structures with various String types - err = do_test9(plugin_interface); - } else if (STR_IEQUALS(request->function, "test9A")) { // Array of Structures with string sub structures - err = do_test9A(plugin_interface); - } else - - //========================================================================================================= - // Integer Tests - - if (STR_IEQUALS(request->function, "test10")) { // Single Integer - err = do_test10(plugin_interface); - } else if (STR_IEQUALS(request->function, "test11")) { // Simple Structure - err = do_test11(plugin_interface); - } else if (STR_IEQUALS(request->function, "test12")) { // Simple Structure - err = do_test12(plugin_interface); - } else if (STR_IEQUALS(request->function, "test13")) { // Simple Structure - err = do_test13(plugin_interface); - } else if (STR_IEQUALS(request->function, "test14")) { // Simple Structure - err = do_test14(plugin_interface); - } else if (STR_IEQUALS(request->function, "test15")) { // Simple Structure - err = do_test15(plugin_interface); - } else if (STR_IEQUALS(request->function, "test16")) { // Simple Structure - err = do_test16(plugin_interface); - } else if (STR_IEQUALS(request->function, "test18")) { // array of multi-typed Structures - err = do_test18(plugin_interface); - } else if (STR_IEQUALS(request->function, "test19")) { // array of multi-typed Structures - err = do_test19(plugin_interface); - } else - - //========================================================================================================= - // Short Integer Tests - - if (STR_IEQUALS(request->function, "test20")) { // Single Short Integer - err = do_test20(plugin_interface); - } else if (STR_IEQUALS(request->function, "test21")) { // Simple Structure - err = do_test21(plugin_interface); - } else if (STR_IEQUALS(request->function, "test22")) { // Simple Structure - err = do_test22(plugin_interface); - } else if (STR_IEQUALS(request->function, "test23")) { // Simple Structure - err = do_test23(plugin_interface); - } else if (STR_IEQUALS(request->function, "test24")) { // Simple Structure - err = do_test24(plugin_interface); - } else if (STR_IEQUALS(request->function, "test25")) { // Simple Structure - err = do_test25(plugin_interface); - } else if (STR_IEQUALS(request->function, "test26")) { // Simple Structure - err = do_test26(plugin_interface); - } else if (STR_IEQUALS(request->function, "test27")) { // Simple Structure - err = do_test27(plugin_interface); - } else if (STR_IEQUALS(request->function, "test28")) { // Simple Structure - err = do_test28(plugin_interface); - } else - - //===================================================================================================== - // Doubles - - if (STR_IEQUALS(request->function, "test30")) { // Simple Structure - err = do_test30(plugin_interface); - } else if (STR_IEQUALS(request->function, "test31")) { // Rank 2 Array of Structures - err = do_test31(plugin_interface); - } else if (STR_IEQUALS(request->function, "test32")) { // Compound Structure - err = do_test32(plugin_interface); - } else if (STR_IEQUALS(request->function, "test33")) { // Compound Structure - err = do_test33(plugin_interface); - } else if (STR_IEQUALS(request->function, "test34")) { // Compound Structure - err = do_test34(plugin_interface); + register_method("test0", static_cast(&TestPlugin::test0)); + register_method("test2", static_cast(&TestPlugin::test2)); + register_method("test4", static_cast(&TestPlugin::test4)); + register_method("test5", static_cast(&TestPlugin::test5)); + register_method("test6", static_cast(&TestPlugin::test6)); + register_method("test7", static_cast(&TestPlugin::test7)); + register_method("test8", static_cast(&TestPlugin::test8)); + register_method("test9", static_cast(&TestPlugin::test9)); + register_method("test9A", static_cast(&TestPlugin::test9A)); + register_method("test10", static_cast(&TestPlugin::test10)); + register_method("test11", static_cast(&TestPlugin::test11)); + register_method("test12", static_cast(&TestPlugin::test12)); + register_method("test13", static_cast(&TestPlugin::test13)); + register_method("test14", static_cast(&TestPlugin::test14)); + register_method("test15", static_cast(&TestPlugin::test15)); + register_method("test16", static_cast(&TestPlugin::test16)); + register_method("test18", static_cast(&TestPlugin::test18)); + register_method("test19", static_cast(&TestPlugin::test19)); + register_method("test20", static_cast(&TestPlugin::test20)); + register_method("test21", static_cast(&TestPlugin::test21)); + register_method("test22", static_cast(&TestPlugin::test22)); + register_method("test23", static_cast(&TestPlugin::test23)); + register_method("test24", static_cast(&TestPlugin::test24)); + register_method("test25", static_cast(&TestPlugin::test25)); + register_method("test26", static_cast(&TestPlugin::test26)); + register_method("test27", static_cast(&TestPlugin::test27)); + register_method("test28", static_cast(&TestPlugin::test28)); + register_method("test30", static_cast(&TestPlugin::test30)); + register_method("test31", static_cast(&TestPlugin::test31)); + register_method("test32", static_cast(&TestPlugin::test32)); + register_method("test33", static_cast(&TestPlugin::test33)); + register_method("test34", static_cast(&TestPlugin::test34)); #ifdef PUTDATAENABLED - } else if (STR_IEQUALS(request_block->function, "test40")) { - err = do_test40(plugin_interface); -#endif - - //===================================================================================================== - // Misc - - } else if (STR_IEQUALS(request->function, "plugin")) { - err = do_plugin(plugin_interface); - } else if (STR_IEQUALS(request->function, "errortest")) { - err = do_errortest(plugin_interface); - } else if (STR_IEQUALS(request->function, "scalartest")) { - err = do_scalartest(plugin_interface); - } else if (STR_IEQUALS(request->function, "array1dtest")) { - err = do_array1dtest(plugin_interface); - } else if (STR_IEQUALS(request->function, "call_plugin_test")) { - err = do_call_plugin_test(plugin_interface); - } else if (STR_IEQUALS(request->function, "call_plugin_test_index")) { - err = do_call_plugin_test_index(plugin_interface); - } else if (STR_IEQUALS(request->function, "call_plugin_test_slice")) { - err = do_call_plugin_test_slice(plugin_interface); - } else if (STR_IEQUALS(request->function, "call_plugin_test_stride")) { - err = do_call_plugin_test_stride(plugin_interface); - } else if (STR_IEQUALS(request->function, "emptytest")) { - err = do_emptytest(plugin_interface); -#ifdef TESTUDT - } else if (STR_IEQUALS(request_block->function, "test40")) { - err = do_testudt(plugin_interface); -#endif - } else if (STR_IEQUALS(request->function, "test50")) { - err = do_test50(plugin_interface); - } else if (STR_IEQUALS(request->function, "test60")) { // ENUM Type Data tests - err = do_test60(plugin_interface); - } else if (STR_IEQUALS(request->function, "test61")) { - err = do_test61(plugin_interface); - } else if (STR_IEQUALS(request->function, "test62")) { - err = do_test62(plugin_interface); + register_method("test40", static_cast(&TestPlugin::test40)); +#endif // PUTDATAENABLED + register_method("test50", static_cast(&TestPlugin::test50)); + register_method("test60", static_cast(&TestPlugin::test60)); + register_method("test61", static_cast(&TestPlugin::test61)); + register_method("test62", static_cast(&TestPlugin::test62)); + register_method("plugin", static_cast(&TestPlugin::plugin)); + register_method("errortest", static_cast(&TestPlugin::errortest)); + register_method("scalartest", static_cast(&TestPlugin::scalartest)); + register_method("array1dtest", static_cast(&TestPlugin::array1dtest)); + register_method("call_plugin_test", static_cast(&TestPlugin::call_plugin_test)); + register_method("call_plugin_test_index", static_cast(&TestPlugin::call_plugin_test_index)); + register_method("call_plugin_test_slice", static_cast(&TestPlugin::call_plugin_test_slice)); + register_method("call_plugin_test_stride", static_cast(&TestPlugin::call_plugin_test_stride)); + register_method("emptytest", static_cast(&TestPlugin::emptytest)); #ifdef CAPNP_ENABLED - } else if (STR_IEQUALS(request->function, "capnp")) { - err = do_capnp_test(plugin_interface); - } else if (STR_IEQUALS(request->function, "capnp_nested")) { - err = do_nested_capnp_test(plugin_interface); - } else if (STR_IEQUALS(request->function, "capnp_long")) { - err = do_long_capnp_test(plugin_interface); - } else if (STR_IEQUALS(request->function, "capnp_large")) { - err = do_large_capnp_test(plugin_interface); + register_method("capnp_test", static_cast(&TestPlugin::capnp_test)); + register_method("nested_capnp_test", static_cast(&TestPlugin::nested_capnp_test)); + register_method("long_capnp_test", static_cast(&TestPlugin::long_capnp_test)); + register_method("large_capnp_test", static_cast(&TestPlugin::large_capnp_test)); #endif // CAPNP_ENABLED - } else { - err = 999; - addIdamError(UDA_CODE_ERROR_TYPE, "testplugin", err, "Unknown function requested!"); - } +#ifdef TESTUDT + register_method("testudt", static_cast(&TestPlugin::testudt)); +#endif // TESTUDT +} - return err; +extern int testPlugin(IDAM_PLUGIN_INTERFACE* plugin_interface) +{ + static TestPlugin plugin = {}; + return plugin.call(plugin_interface); } void testError1() @@ -377,93 +194,7 @@ void testError2() addIdamError(UDA_CODE_ERROR_TYPE, "testplugin", err, "Test #2 of Error State Management"); } -static int do_help(IDAM_PLUGIN_INTERFACE* plugin_interface) -{ - DATA_BLOCK* data_block = plugin_interface->data_block; - - UDA_LOG(UDA_LOG_DEBUG, "help function called\n"); - - const char* help = "\nTestplugin: Functions Names and Test Descriptions/n/n" - "test0-test9: String passing tests\n" - "\ttest0: single string as a char array\n" - "\ttest1: single string\n" - "\ttest2: multiple strings as a 2D array of chars\n" - "\ttest3: array of strings\n" - "\ttest4: data structure with a fixed length single string\n" - "\ttest5: data structure with a fixed length multiple string\n" - "\ttest6: data structure with an arbitrary length single string\n" - "\ttest7: data structure with a fixed number of arbitrary length strings\n" - "\ttest8: data structure with an arbitrary number of arbitrary length strings\n\n" - "\ttest9: array of data structures with a variety of string types\n\n" - "\ttest9A: array of data structures with a variety of string types and single sub structure\n\n" - - "***test10-test18: Integer passing tests\n" - "\ttest10: single integer\n" - "\ttest11: fixed number (rank 1 array) of integers\n" - "\ttest12: arbitrary number (rank 1 array) of integers\n" - "\ttest13: fixed length rank 2 array of integers\n" - "\ttest14: arbitrary length rank 2 array of integers\n" - "\ttest15: data structure with a single integer\n" - "\ttest16: data structure with a fixed number of integers\n" - "\ttest17: data structure with a arbitrary number of integers\n" - "\ttest18: array of data structures with a variety of integer types\n\n" - - "***test20-test28: Short Integer passing tests\n" - "\ttest20: single integer\n" - "\ttest21: fixed number (rank 1 array) of integers\n" - "\ttest22: arbitrary number (rank 1 array) of integers\n" - "\ttest23: fixed length rank 2 array of integers\n" - "\ttest24: arbitrary length rank 2 array of integers\n" - "\ttest25: data structure with a single integer\n" - "\ttest26: data structure with a fixed number of integers\n" - "\ttest27: data structure with a arbitrary number of integers\n" - "\ttest28: array of data structures with a variety of integer types\n\n" - - "***test30-test32: double passing tests\n" - "\ttest30: pair of doubles (Coordinate)\n" - - "***test40-test40: put data block receiving tests\n" - - "\ttest50: Passing parameters into plugins via the source argument\n" - - "\ttest60-62: ENUMLIST structures\n\n" - - "plugin: test calling other plugins\n" - - "error: Error reporting and server termination tests\n"; - - initDataBlock(data_block); - - data_block->rank = 1; - data_block->dims = (DIMS*)malloc(data_block->rank * sizeof(DIMS)); - - for (unsigned int i = 0; i < data_block->rank; i++) { - initDimBlock(&data_block->dims[i]); - } - - data_block->data_type = UDA_TYPE_STRING; - strcpy(data_block->data_desc, "testplugins: help = description of this plugin"); - - data_block->data = strdup(help); - - data_block->dims[0].data_type = UDA_TYPE_UNSIGNED_INT; - data_block->dims[0].dim_n = (int)strlen(help) + 1; - data_block->dims[0].compressed = 1; - data_block->dims[0].dim0 = 0.0; - data_block->dims[0].diff = 1.0; - data_block->dims[0].method = 0; - - data_block->data_n = data_block->dims[0].dim_n; - - strcpy(data_block->data_label, ""); - strcpy(data_block->data_units, ""); - - UDA_LOG(UDA_LOG_DEBUG, "help function completed\n"); - - return 0; -} - -static int do_test0(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test0(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; REQUEST_DATA* request = plugin_interface->request_data; @@ -504,7 +235,7 @@ static int do_test0(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test2(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test2(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; REQUEST_DATA* request = plugin_interface->request_data; @@ -608,7 +339,7 @@ static int do_test2(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test4(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test4(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -680,7 +411,7 @@ static int do_test4(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test5(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test5(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -755,7 +486,7 @@ static int do_test5(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test6(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test6(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -828,7 +559,7 @@ static int do_test6(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test7(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test7(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -912,7 +643,7 @@ static int do_test7(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test8(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test8(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -997,7 +728,7 @@ static int do_test8(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test9(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test9(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1074,7 +805,7 @@ static int do_test9(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test9A(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test9A(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1181,7 +912,7 @@ static int do_test9A(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test10(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test10(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1204,7 +935,7 @@ static int do_test10(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test11(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test11(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1275,7 +1006,7 @@ static int do_test11(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test12(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test12(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1348,7 +1079,7 @@ static int do_test12(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test13(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test13(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1425,7 +1156,7 @@ static int do_test13(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test14(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test14(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1500,7 +1231,7 @@ static int do_test14(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test15(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test15(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1577,7 +1308,7 @@ static int do_test15(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test16(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test16(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1661,7 +1392,7 @@ static int do_test16(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test18(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test18(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1749,7 +1480,7 @@ static int do_test18(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test19(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test19(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1900,7 +1631,7 @@ static int do_test19(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test20(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test20(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1923,7 +1654,7 @@ static int do_test20(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test21(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test21(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -1994,7 +1725,7 @@ static int do_test21(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test22(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test22(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2067,7 +1798,7 @@ static int do_test22(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test23(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test23(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2144,7 +1875,7 @@ static int do_test23(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test24(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test24(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2219,7 +1950,7 @@ static int do_test24(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test25(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test25(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2296,7 +2027,7 @@ static int do_test25(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test26(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test26(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2381,7 +2112,7 @@ static int do_test26(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test27(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test27(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2480,7 +2211,7 @@ static int do_test27(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test28(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test28(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2584,7 +2315,7 @@ static int do_test28(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test30(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test30(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2649,7 +2380,7 @@ static int do_test30(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test31(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test31(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2729,7 +2460,7 @@ static int do_test31(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test32(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test32(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2846,7 +2577,7 @@ static int do_test32(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test33(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test33(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -2970,7 +2701,7 @@ static int do_test33(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test34(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test34(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -3119,7 +2850,7 @@ static int do_test34(IDAM_PLUGIN_INTERFACE* plugin_interface) // Echo passed data back as an array of structures // The library won't build if the server version is not OK for this functionality // If the client cannot pass putdata blocks then no data will appear here to process. -static int do_test40(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test40(IDAM_PLUGIN_INTERFACE* plugin_interface) { typedef struct Test40 { unsigned int dataCount; @@ -3271,7 +3002,7 @@ static int do_test40(IDAM_PLUGIN_INTERFACE* plugin_interface) // Shot number passed via request_block->exp_number // Placeholder values passed via request_block->tpass -static int do_test50(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test50(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; REQUEST_DATA* request = plugin_interface->request_data; @@ -3334,7 +3065,7 @@ typedef struct EnumList60 int* arraydata_shape; } ENUMLIST60; -static int do_test60(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test60(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto enumlist = (ENUMLIST60*)malloc(sizeof(ENUMLIST60)); strcpy(enumlist->name, "TEST60 ENUM of type unsigned short"); @@ -3528,7 +3259,7 @@ static int do_test60(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test61(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test61(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto enumlist = (ENUMLIST60*)malloc(sizeof(ENUMLIST60)); strcpy(enumlist->name, "TEST61 ENUM of type unsigned long long"); @@ -3698,7 +3429,7 @@ static int do_test61(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -static int do_test62(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::test62(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto* enumlist = (ENUMLIST*)malloc(sizeof(ENUMLIST)); strcpy(enumlist->name, "TEST62 ENUM of type unsigned long long"); @@ -3772,7 +3503,7 @@ static int do_test62(IDAM_PLUGIN_INTERFACE* plugin_interface) // If the housekeeping action is requested, this must be also applied to all plugins called. // A list must be maintained to register these plugin calls to manage housekeeping. // Calls to plugins must also respect access policy and user authentication policy -static int do_plugin(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::plugin(IDAM_PLUGIN_INTERFACE* plugin_interface) { REQUEST_DATA* request = plugin_interface->request_data; @@ -3836,7 +3567,7 @@ static int do_plugin(IDAM_PLUGIN_INTERFACE* plugin_interface) // To maintain consistency with existing legacy code, use a local structure with a global scope (plugin library only) // A final necessary step is to concatenate this local structure with the server structure before returning. // When testing the plugin, errors are doubled (tripled!) up as both stacks are the same. -static int do_errortest(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::errortest(IDAM_PLUGIN_INTERFACE* plugin_interface) { int err = 0; int test = 0; @@ -3870,7 +3601,7 @@ static int do_errortest(IDAM_PLUGIN_INTERFACE* plugin_interface) UDA_THROW_ERROR(9990 + test, "Test of Error State Management"); } -static int do_scalartest(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::scalartest(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -3885,7 +3616,7 @@ static int do_scalartest(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -int do_array1dtest(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::array1dtest(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; @@ -3912,35 +3643,35 @@ int do_array1dtest(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -int do_emptytest(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::emptytest(IDAM_PLUGIN_INTERFACE* plugin_interface) { DATA_BLOCK* data_block = plugin_interface->data_block; initDataBlock(data_block); return 0; } -int do_call_plugin_test(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::call_plugin_test(IDAM_PLUGIN_INTERFACE* plugin_interface) { return callPlugin(plugin_interface->pluginList, "TESTPLUGIN::array1dtest()", plugin_interface); } -int do_call_plugin_test_index(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::call_plugin_test_index(IDAM_PLUGIN_INTERFACE* plugin_interface) { return callPlugin(plugin_interface->pluginList, "TESTPLUGIN::array1dtest()[25]", plugin_interface); } -int do_call_plugin_test_slice(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::call_plugin_test_slice(IDAM_PLUGIN_INTERFACE* plugin_interface) { return callPlugin(plugin_interface->pluginList, "TESTPLUGIN::array1dtest()[10:20]", plugin_interface); } -int do_call_plugin_test_stride(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::call_plugin_test_stride(IDAM_PLUGIN_INTERFACE* plugin_interface) { return callPlugin(plugin_interface->pluginList, "TESTPLUGIN::array1dtest()[::2]", plugin_interface); } #ifdef CAPNP_ENABLED -int do_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto tree = uda_capnp_new_tree(); auto root = uda_capnp_get_root(tree); @@ -3983,7 +3714,7 @@ int do_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -int do_nested_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::nested_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto tree = uda_capnp_new_tree(); auto root = uda_capnp_get_root(tree); @@ -4039,7 +3770,7 @@ int do_nested_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -int do_long_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::long_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto tree = uda_capnp_new_tree(); auto root = uda_capnp_get_root(tree); @@ -4078,7 +3809,7 @@ int do_long_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } -int do_large_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::large_capnp_test(IDAM_PLUGIN_INTERFACE* plugin_interface) { auto tree = uda_capnp_new_tree(); auto root = uda_capnp_get_root(tree); @@ -4269,7 +4000,7 @@ int tcp_connect(SYSSOCKET* ssock, int port) // UDP has better performance but data packets may get lost - it is not reliable // UDT is an application level protocol, based on UDP, that is reliable and has the performance of UDP // The IDAM server acts as a UDT client and the IDAM client acts as the UDT server! -static int do_testudt(IDAM_PLUGIN_INTERFACE* plugin_interface) +int TestPlugin::testudt(IDAM_PLUGIN_INTERFACE* plugin_interface) { // Start a mini server loop and create a separate communiation channel with the client bye-passing the TCP socket diff --git a/source/plugins/testplugin/testplugin.h b/source/plugins/testplugin/testplugin.h index 4f8051074..82a836709 100755 --- a/source/plugins/testplugin/testplugin.h +++ b/source/plugins/testplugin/testplugin.h @@ -8,26 +8,7 @@ extern "C" { #endif -#ifdef TESTUDT - #include "udtc.h" - #include - - typedef int bool; - int g_IP_Version = AF_INET; // IPv4 family of addresses - int g_Socket_Type = SOCK_STREAM; // use reliable transport layer protocol with Aknowledgements (default TCP) - - char g_Localhost[] = "192.168.16.88"; //"192.168.16.125"; //"127.0.0.1"; // "192.168.16.88"; // Client IP address (*** passed as a parameter) - int g_Server_Port = 50000; // port number (*** passed as a parameter) - - int g_TotalNum = 1000000; // Test data - -LIBRARY_API int tcp_connect(SYSSOCKET *ssock, int port); -LIBRARY_API int c_connect(UDTSOCKET *usock, int port); -LIBRARY_API int createUDTSocket(int *usock, int port, int rendezvous); -LIBRARY_API int createTCPSocket(SYSSOCKET *ssock, int port, bool rendezvous); -#endif - -int testplugin(IDAM_PLUGIN_INTERFACE *idam_plugin_interface); +int testPlugin(IDAM_PLUGIN_INTERFACE *idam_plugin_interface); #ifdef __cplusplus } diff --git a/source/plugins/uda/uda_plugin.cpp b/source/plugins/uda/uda_plugin.cpp index 30b4ec7ca..d6500fc5e 100755 --- a/source/plugins/uda/uda_plugin.cpp +++ b/source/plugins/uda/uda_plugin.cpp @@ -8,173 +8,52 @@ #include #include #include +#include #include -#include - -#if !defined(__GNUC__) -# define strcasecmp _stricmp -#endif - -static int do_help(IDAM_PLUGIN_INTERFACE* idam_plugin_interface); - -static int do_version(IDAM_PLUGIN_INTERFACE* idam_plugin_interface); - -static int do_builddate(IDAM_PLUGIN_INTERFACE* idam_plugin_interface); - -static int do_defaultmethod(IDAM_PLUGIN_INTERFACE* idam_plugin_interface); - -static int do_maxinterfaceversion(IDAM_PLUGIN_INTERFACE* idam_plugin_interface); - -static int do_get(IDAM_PLUGIN_INTERFACE* idam_plugin_interface, char* oldServerHost, int* oldPort); - -extern int UDAPlugin(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) -{ - int err = 0; - - static short init = 0; - static char oldServerHost[STRING_LENGTH] = ""; - static int oldPort = 0; - - //---------------------------------------------------------------------------------------- - // Standard v1 Plugin Interface - - unsigned short housekeeping; - - if (idam_plugin_interface->interfaceVersion > THISPLUGIN_MAX_INTERFACE_VERSION) { - UDA_LOG(UDA_LOG_ERROR, "Plugin Interface Version Unknown to this plugin: Unable to execute the request!\n"); - UDA_THROW_ERROR(999, "Plugin Interface Version Unknown to this plugin: Unable to execute the request!"); - } - - idam_plugin_interface->pluginVersion = THISPLUGIN_VERSION; - - housekeeping = idam_plugin_interface->housekeeping; - - REQUEST_DATA* request = idam_plugin_interface->request_data; - - if (housekeeping || STR_IEQUALS(request->function, "reset")) { - - if (!init) return 0; // Not previously initialised: Nothing to do! - - // Resetting all UDA client properties - - resetIdamProperties(udaClientFlags()); - udaFreeAll(); - - putIdamServerHost(oldServerHost); // Original Host - putIdamServerPort(oldPort); // Original Port - // Free Heap & reset counters - - init = 0; - - return 0; - } - - //---------------------------------------------------------------------------------------- - // Initialise - - if (!init || STR_IEQUALS(request->function, "create") || STR_IEQUALS(request->function, "initialise")) { - - // Default Server Host and Port - - strcpy(oldServerHost, getIdamServerHost()); // Current Host - oldPort = getIdamServerPort(); // Current Port - - // Resetting all UDA client properties - - resetIdamProperties(udaClientFlags()); +#include +#include - // Hand over Server IO File Handles to UDA Client library +namespace uda::plugins::uda { - UDA_LOG(UDA_LOG_DEBUG, "Handing over Server File Handles to UDA Client\n"); +class Plugin : public UDAPluginBase { +public: + Plugin(); - init = 1; - if (STR_IEQUALS(request->function, "create") || STR_IEQUALS(request->function, "initialise")) { - return 0; - } - } + int get(IDAM_PLUGIN_INTERFACE *plugin_interface); - //---------------------------------------------------------------------------------------- - // Plugin Functions - //---------------------------------------------------------------------------------------- - - if (STR_IEQUALS(request->function, "help")) { - err = do_help(idam_plugin_interface); - } else if (STR_IEQUALS(request->function, "version")) { - err = do_version(idam_plugin_interface); - } else if (STR_IEQUALS(request->function, "builddate")) { - err = do_builddate(idam_plugin_interface); - } else if (STR_IEQUALS(request->function, "defaultmethod")) { - err = do_defaultmethod(idam_plugin_interface); - } else if (STR_IEQUALS(request->function, "maxinterfaceversion")) { - err = do_maxinterfaceversion(idam_plugin_interface); - } else if (STR_IEQUALS(request->function, "get")) { - err = do_get(idam_plugin_interface, oldServerHost, &oldPort); - } else { - UDA_THROW_ERROR(999, "Unknown function requested!"); + void init(IDAM_PLUGIN_INTERFACE *plugin_interface) override { + old_host_ = getIdamServerHost(); + old_port_ = getIdamServerPort(); } - //-------------------------------------------------------------------------------------- - // Housekeeping - - return err; -} - -/** - * Help: A Description of library functionality - * @param idam_plugin_interface - * @return - */ -int do_help(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) -{ - const char* help = "\nUDA: Add Functions Names, Syntax, and Descriptions\n\n"; - const char* desc = "UDA: help = description of this plugin"; - - return setReturnDataString(idam_plugin_interface->data_block, help, desc); -} + void reset() override {} -/** - * Plugin version - * @param idam_plugin_interface - * @return - */ -int do_version(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) -{ - return setReturnDataIntScalar(idam_plugin_interface->data_block, THISPLUGIN_VERSION, "Plugin version number"); -} +private: + std::string old_host_; + int old_port_; +}; -/** - * Plugin Build Date - * @param idam_plugin_interface - * @return - */ -int do_builddate(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) +Plugin::Plugin() + : UDAPluginBase( + "UDA", + 1, + "get", + boost::filesystem::path(__FILE__).parent_path().append("help.txt").string() +) { - return setReturnDataString(idam_plugin_interface->data_block, __DATE__, "Plugin build date"); + register_method("get", static_cast(&Plugin::get)); } -/** - * Plugin Default Method - * @param idam_plugin_interface - * @return - */ -int do_defaultmethod(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) -{ - return setReturnDataString(idam_plugin_interface->data_block, THISPLUGIN_DEFAULT_METHOD, "Plugin default method"); -} +} // namespace uda::plugins::uda -/** - * Plugin Maximum Interface Version - * @param idam_plugin_interface - * @return - */ -int do_maxinterfaceversion(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) +extern int UDAPlugin(IDAM_PLUGIN_INTERFACE* plugin_interface) { - return setReturnDataIntScalar(idam_plugin_interface->data_block, THISPLUGIN_MAX_INTERFACE_VERSION, - "Maximum Interface Version"); + static uda::plugins::uda::Plugin plugin = {}; + return plugin.call(plugin_interface); } -static int do_get(IDAM_PLUGIN_INTERFACE* idam_plugin_interface, char* oldServerHost, int* oldPort) +int uda::plugins::uda::Plugin::get(IDAM_PLUGIN_INTERFACE* plugin_interface) { int err = 0; @@ -273,9 +152,9 @@ Notes: there are three pathways depending on the request pattern int pathway = 0; - DATA_SOURCE* data_source = idam_plugin_interface->data_source; - SIGNAL_DESC* signal_desc = idam_plugin_interface->signal_desc; - REQUEST_DATA* request = idam_plugin_interface->request_data; + DATA_SOURCE* data_source = plugin_interface->data_source; + SIGNAL_DESC* signal_desc = plugin_interface->signal_desc; + REQUEST_DATA* request = plugin_interface->request_data; if (data_source->source_id > 0 && signal_desc->signal_desc_id > 0) { pathway = 1; @@ -287,8 +166,7 @@ Notes: there are three pathways depending on the request pattern // Source URL may be an nullptr string pathway = 4; } else { - UDA_LOG(UDA_LOG_ERROR, "Execution pathway not recognised: Unable to execute the request!\n"); - UDA_THROW_ERROR(999, "Execution pathway not recognised: Unable to execute the request!"); + error("Execution pathway not recognised: Unable to execute the request!"); } //---------------------------------------------------------------------- @@ -308,7 +186,7 @@ Notes: there are three pathways depending on the request pattern // Set Properties - CLIENT_BLOCK* client_block = idam_plugin_interface->client_block; + CLIENT_BLOCK* client_block = plugin_interface->client_block; auto client_flags = udaClientFlags(); if (client_block->get_nodimdata) setIdamProperty("get_nodimdata", client_flags); @@ -369,35 +247,34 @@ Notes: there are three pathways depending on the request pattern if (p != nullptr) { p[0] = '\0'; - if (strcasecmp(oldServerHost, data_source->server) != 0) { - strcpy(oldServerHost, data_source->server); + if (strcasecmp(old_host_.c_str(), data_source->server) != 0) { + old_host_ = data_source->server; putIdamServerHost(data_source->server); } if (IsNumber(&p[1])) { newPort = atoi(&p[1]); - if (newPort != *oldPort) { + if (newPort != old_port_) { putIdamServerPort(newPort); - *oldPort = newPort; + old_port_ = newPort; } } else { - UDA_THROW_ERROR(999, - "The Server Port must be an Integer Number passed using the formats 'server:port' or 'server port'"); + error("The Server Port must be an Integer Number passed using the formats 'server:port' or 'server port'"); } } else { - if (strcasecmp(oldServerHost, data_source->server) != 0) { - strcpy(oldServerHost, data_source->server); + if (strcasecmp(old_host_.c_str(), data_source->server) != 0) { + old_host_ = data_source->server; putIdamServerHost(data_source->server); } } } else { - UDA_THROW_ERROR(999, "No Server has been specified!"); + error("No Server has been specified!"); } - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Host for Idam Plugin %s\n", data_source->server); - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Port for Idam Plugin %d\n", newPort); - UDA_LOG(UDA_LOG_DEBUG, "Calling idamGetAPI API (Database based Request)\n"); - UDA_LOG(UDA_LOG_DEBUG, "Signal: %s\n", signal.c_str()); - UDA_LOG(UDA_LOG_DEBUG, "Source: %s\n", source.c_str()); + debug("UDA Server Host for UDA Plugin {}\n", data_source->server); + debug("UDA Server Port for UDA Plugin {}\n", newPort); + debug("Calling idamGetAPI API (Database based Request)\n"); + debug("Signal: {}\n", signal.c_str()); + debug("Source: {}\n", source.c_str()); handle = idamGetAPI(signal.c_str(), source.c_str()); @@ -417,8 +294,7 @@ Notes: there are three pathways depending on the request pattern p[0] = '\0'; // Break the String (work) strcpy(source, p + 1); // Extract the Source URL Argument } else { - UDA_THROW_ERROR(999, - "The Remote Server Data Source specified does not comply with the naming model: serverHost:port/sourceURL"); + error("The Remote Server Data Source specified does not comply with the naming model: serverHost:port/sourceURL"); } } else { if ((p = strchr(request->server, '/')) != nullptr) { @@ -426,8 +302,7 @@ Notes: there are three pathways depending on the request pattern p[0] = '\0'; // Break the String (work) strcpy(source, p + 1); // Extract the Source URL Argument } else { - UDA_THROW_ERROR(999, - "The Remote Server Data Source specified does not comply with the naming model: serverHost:port/sourceURL"); + error("The Remote Server Data Source specified does not comply with the naming model: serverHost:port/sourceURL"); } } @@ -445,32 +320,31 @@ Notes: there are three pathways depending on the request pattern if (p != nullptr) { p[0] = '\0'; - if (strcasecmp(oldServerHost, request->server) != 0) { - strcpy(oldServerHost, request->server); + if (strcasecmp(old_host_.c_str(), request->server) != 0) { + old_host_ = request->server; putIdamServerHost(request->server); // different host name? } if (IsNumber(&p[1])) { newPort = atoi(&p[1]); - if (newPort != *oldPort) { + if (newPort != old_port_) { putIdamServerPort(newPort); - *oldPort = newPort; + old_port_ = newPort; } } else { - UDA_THROW_ERROR(999, - "The Server Port must be an Integer Number passed using the format 'server:port' or 'server port'"); + error("The Server Port must be an Integer Number passed using the format 'server:port' or 'server port'"); } } else { - if (strcasecmp(oldServerHost, request->server) != 0) { - strcpy(oldServerHost, request->server); + if (strcasecmp(old_host_.c_str(), request->server) != 0) { + old_host_ = request->server; putIdamServerHost(request->server); } } - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Host for Idam Plugin %s\n", request->server); - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Port for Idam Plugin %d\n", newPort); - UDA_LOG(UDA_LOG_DEBUG, "Calling idamGetAPI API (Device redirect or server protocol based Request)\n"); - UDA_LOG(UDA_LOG_DEBUG, "Signal: %s\n", request->signal); - UDA_LOG(UDA_LOG_DEBUG, "Source: %s\n", source); + debug("UDA Server Host for UDA Plugin {}\n", request->server); + debug("UDA Server Port for UDA Plugin {}\n", newPort); + debug("Calling idamGetAPI API (Device redirect or server protocol based Request)\n"); + debug("Signal: {}\n", request->signal); + debug("Source: {}\n", source); handle = idamGetAPI(request->signal, source); @@ -492,29 +366,29 @@ Notes: there are three pathways depending on the request pattern // Set host and port - if (isHost && strcasecmp(oldServerHost, host) != 0) { - strcpy(oldServerHost, host); + if (isHost && strcasecmp(old_host_.c_str(), host) != 0) { + old_host_ = host; putIdamServerHost(host); } - if (isPort && *oldPort != newPort) { - *oldPort = newPort; + if (isPort && old_port_ != newPort) { + old_port_ = newPort; putIdamServerPort(newPort); } - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Host for Idam Plugin %s\n", host); - UDA_LOG(UDA_LOG_DEBUG, "Idam Server Port for Idam Plugin %d\n", newPort); - UDA_LOG(UDA_LOG_DEBUG, "Calling idamGetAPI API (plugin library method based Request)\n"); + debug("UDA Server Host for UDA Plugin {}\n", host); + debug("UDA Server Port for UDA Plugin {}\n", newPort); + debug("Calling idamGetAPI API (plugin library method based Request)\n"); if (isSignal && isSource) { - UDA_LOG(UDA_LOG_DEBUG, "Signal: %s\n", signal); - UDA_LOG(UDA_LOG_DEBUG, "idamAPIPlugin; Source: %s\n", source); + debug("Signal: {}\n", signal); + debug("idamAPIPlugin; Source: {}\n", source); handle = idamGetAPI(signal, source); } else if (isSignal) { - UDA_LOG(UDA_LOG_DEBUG, "Signal: %s\n", signal); - UDA_LOG(UDA_LOG_DEBUG, "idamAPIPlugin; Source: %s\n", request->source); + debug("Signal: {}\n", signal); + debug("idamAPIPlugin; Source: {}\n", request->source); handle = idamGetAPI(signal, request->source); } else { - UDA_THROW_ERROR(999, "A data object (signal) has not been specified!"); + error("A data object (signal) has not been specified!"); } } else if (pathway == 4) { @@ -542,34 +416,33 @@ Notes: there are three pathways depending on the request pattern if (p != nullptr) { // look for a port number in the server name p[0] = '\0'; // Split - if (strcasecmp(oldServerHost, request->server) != 0) { // Different Hosts? - strcpy(oldServerHost, request->server); // Preserve + if (strcasecmp(old_host_.c_str(), request->server) != 0) { // Different Hosts? + old_host_ = request->server; putIdamServerHost(request->server); // Change to a different host name } if (IsNumber(&p[1])) { newPort = atoi(&p[1]); - if (newPort != *oldPort) { + if (newPort != old_port_) { // Different Ports? putIdamServerPort(newPort); - *oldPort = newPort; + old_port_ = newPort; } } else { - UDA_THROW_ERROR(999, - "The Server Port must be an Integer Number passed using the format 'server:port' or 'server port'"); + error("The Server Port must be an Integer Number passed using the format 'server:port' or 'server port'"); } } else { // No port number passed - if (strcasecmp(oldServerHost, request->server) != 0) { // Different Hosts? - strcpy(oldServerHost, request->server); + if (strcasecmp(old_host_.c_str(), request->server) != 0) { // Different Hosts? + old_host_ = request->server; putIdamServerHost(request->server); } } - UDA_LOG(UDA_LOG_DEBUG, "UDA Server Host for UDA Plugin %s\n", request->server); - UDA_LOG(UDA_LOG_DEBUG, "UDA Server Port for UDA Plugin %d\n", newPort); - UDA_LOG(UDA_LOG_DEBUG, "Calling idamGetAPI API (Server protocol based Request)\n"); - UDA_LOG(UDA_LOG_DEBUG, "Signal: %s\n", request->signal); - UDA_LOG(UDA_LOG_DEBUG, "Source: %s\n", source); + debug("UDA Server Host for UDA Plugin {}\n", request->server); + debug("UDA Server Port for UDA Plugin {}\n", newPort); + debug("Calling idamGetAPI API (Server protocol based Request)\n"); + debug("Signal: {}\n", request->signal); + debug("Source: {}\n", source); handle = idamGetAPI(request->signal, source); } @@ -580,13 +453,13 @@ Notes: there are three pathways depending on the request pattern //---------------------------------------------------------------------- // Test for Errors: Close Socket and Free heap - UDA_LOG(UDA_LOG_DEBUG, "Returned from idamGetAPI API: handle = %d, error code = %d\n", handle, + debug("Returned from idamGetAPI API: handle = {}, error code = {}\n", handle, getIdamErrorCode(handle)); if (handle < 0) { - UDA_THROW_ERROR(abs(handle), getIdamServerErrorStackRecordMsg(0)); + error(getIdamServerErrorStackRecordMsg(0)); } else if ((err = getIdamErrorCode(handle)) != 0) { - UDA_THROW_ERROR(err, getIdamErrorMsg(handle)); + error(getIdamErrorMsg(handle)); } //---------------------------------------------------------------------- @@ -600,7 +473,7 @@ Notes: there are three pathways depending on the request pattern // Check the originals have no XML action definitions before replacement // Why should a plugin have this concern? - DATA_BLOCK* data_block = idam_plugin_interface->data_block; + DATA_BLOCK* data_block = plugin_interface->data_block; if (getIdamClientVersion() >= 7) { // This should contain everything! @@ -668,7 +541,7 @@ Notes: there are three pathways depending on the request pattern *signal_desc = *(data_block->signal_desc); } - UDA_LOG(UDA_LOG_DEBUG, "Exit\n"); + debug("Exit\n"); //---------------------------------------------------------------------- // If the Data are Hierarchical, then necessary to forward the xdr file diff --git a/source/plugins/uda_plugin_base.cpp b/source/plugins/uda_plugin_base.cpp index 3aeff15ed..a32d6a9e8 100644 --- a/source/plugins/uda_plugin_base.cpp +++ b/source/plugins/uda_plugin_base.cpp @@ -53,28 +53,22 @@ std::string UDAPluginBase::get_function(IDAM_PLUGIN_INTERFACE* plugin_interface) return boost::to_lower_copy(request->function); } -int UDAPluginBase::do_init(IDAM_PLUGIN_INTERFACE* plugin_interface) { +void UDAPluginBase::do_init(IDAM_PLUGIN_INTERFACE* plugin_interface) { std::string function = get_function(plugin_interface); if (!init_ || (function == "init" || function == "initialise")) { - int rc = init(plugin_interface); - if (rc == 0) { - init_ = true; - } - return rc; + init(plugin_interface); + init_ = true; } - return 0; } -int UDAPluginBase::do_reset() { +void UDAPluginBase::do_reset() { if (!init_) { // Not previously initialised: Nothing to do! - return 0; + return; } reset(); init_ = false; - - return 0; } int UDAPluginBase::help(IDAM_PLUGIN_INTERFACE *plugin_interface) { @@ -87,7 +81,7 @@ int UDAPluginBase::help(IDAM_PLUGIN_INTERFACE *plugin_interface) { auto path = boost::filesystem::path(help_file_); if (!boost::filesystem::exists(path)) { - auto help = (boost::format("help file %1% does not exist") % path).str(); + auto help = fmt::format("help file {} does not exist", path.string()); return setReturnDataString(plugin_interface->data_block, help.c_str(), desc.c_str()); } @@ -123,11 +117,8 @@ void UDAPluginBase::register_function(const std::string &name, plugin_function_t function_map_[name] = plugin_function; } -void UDAPluginBase::debug(const std::string& message) { - UDA_LOG(UDA_LOG_DEBUG, "%s", message.c_str()); +bool UDAPluginBase::has_arg(IDAM_PLUGIN_INTERFACE* plugin_interface, const std::string& name) +{ + const char* str; + return findStringValue(&plugin_interface->request_data->nameValueList, &str, name.c_str()); } - -void UDAPluginBase::error(const std::string &message) { - UDA_LOG(UDA_LOG_ERROR, "%s", message.c_str()); - throw std::runtime_error{ message.c_str() }; -} \ No newline at end of file diff --git a/source/plugins/uda_plugin_base.hpp b/source/plugins/uda_plugin_base.hpp index ffbe53f97..9511821d8 100644 --- a/source/plugins/uda_plugin_base.hpp +++ b/source/plugins/uda_plugin_base.hpp @@ -9,8 +9,9 @@ #include #include -#include +#include #include +#include #include #include "udaPlugin.h" @@ -45,15 +46,29 @@ class UDAPluginBase { register_method("maxinterfaceversion", &UDAPluginBase::max_interface_version); } - virtual int init(IDAM_PLUGIN_INTERFACE* plugin_interface) = 0; - virtual int reset() = 0; + virtual void init(IDAM_PLUGIN_INTERFACE* plugin_interface) = 0; + virtual void reset() = 0; LIBRARY_API void register_method(const std::string& name, plugin_member_type plugin_method); LIBRARY_API void register_function(const std::string& name, plugin_function_type plugin_function); // Helper methods - LIBRARY_API void debug(const std::string& message); - LIBRARY_API void error(const std::string& message); + template + void debug(const std::string& message, Args... args) + { + auto msg = fmt::format(message, args...); + UDA_LOG(UDA_LOG_DEBUG, "%s", msg.c_str()); + } + + template + void error(const std::string& message, Args... args) + { + auto msg = fmt::format(message, args...); + UDA_LOG(UDA_LOG_ERROR, "%s", msg.c_str()); + throw std::runtime_error{ msg.c_str() }; + } + + LIBRARY_API bool has_arg(IDAM_PLUGIN_INTERFACE* plugin_interface, const std::string& name); template boost::optional find_arg(IDAM_PLUGIN_INTERFACE* plugin_interface, const std::string& name, bool required=false) @@ -66,8 +81,7 @@ class UDAPluginBase { ss >> value; return value; } else if (required) { - auto message = (boost::format("Required argument '%1%' not given") % name).str(); - error(message); + error("Required argument '{}' not given", name); } return {}; } @@ -95,8 +109,7 @@ class UDAPluginBase { values.push_back(n); } } else if (required) { - auto message = (boost::format("Required argument '%1%' not given") % name).str(); - error(message); + error("Required argument '{}' not given", name); } return {}; } @@ -116,8 +129,8 @@ class UDAPluginBase { LIBRARY_API int max_interface_version(IDAM_PLUGIN_INTERFACE* plugin_interface); private: - int do_init(IDAM_PLUGIN_INTERFACE* plugin_interface); - int do_reset(); + void do_init(IDAM_PLUGIN_INTERFACE* plugin_interface); + void do_reset(); static std::string get_function(IDAM_PLUGIN_INTERFACE* plugin_interface); bool init_; diff --git a/source/plugins/viewport/viewport.cpp b/source/plugins/viewport/viewport.cpp index b52302a5b..ae8034e60 100755 --- a/source/plugins/viewport/viewport.cpp +++ b/source/plugins/viewport/viewport.cpp @@ -2,7 +2,7 @@ * v1 IDAM Plugin viewPort: re-bin data to visualise with a rectangular viewport defined by horizonal * and vertical pixel ranges * -* Input Arguments: IDAM_PLUGIN_INTERFACE *idam_plugin_interface +* Input Arguments: IDAM_PLUGIN_INTERFACE *plugin_interface * * Returns: 0 if the plugin functionality was successful * otherwise a Error Code is returned @@ -18,910 +18,620 @@ # include #endif +#include #include #include #include #include -#include #include -static int handleCount = 0; -static int handles[MAXHANDLES]; -static char signals[MAXHANDLES][MAXMETA]; -static char sources[MAXHANDLES][STRING_LENGTH]; - -int whichHandle(char* signal, char* source) +#include +#include + +struct CacheEntry { + int handle; + std::string signal; + std::string source; +}; + +class ViewportPlugin : public UDAPluginBase { +public: + ViewportPlugin(); + int get(IDAM_PLUGIN_INTERFACE* plugin_interface); + void init(IDAM_PLUGIN_INTERFACE* plugin_interface) override {} + void reset() override {} + +private: + std::vector cache_; + int find_handle(const std::string& signal, const std::string& source); +}; + +ViewportPlugin::ViewportPlugin() + : UDAPluginBase( + "VIEWPORT", + 1, + "function", + boost::filesystem::path(__FILE__).parent_path().append("help.txt").string() +) { - for (int i = 0; i < handleCount; i++) - if (STR_IEQUALS(signals[i], signal) && STR_IEQUALS(sources[i], source)) { - return handles[i]; - } - return -1; // Not found + register_method("get", static_cast(&ViewportPlugin::get)); } +std::vector getBins(float* coords, int count, int pixel_width, float minValue, float maxValue, int** column); +void reduceOrderedData(float* values, int* count, float* startValue, float* endValue, float* coords, float* min, + float* max); +void getVerticalPixelValues(float* values, int count, int pixel_height, float* startValue, float* endValue, + float** verticalPixelValues, float* delta); -extern int viewport(IDAM_PLUGIN_INTERFACE* idam_plugin_interface) -{ - int err = 0; - char* p; - - static short init = 0; +char* memdup(const void* mem, size_t size) { + char* out = (char*)malloc(size); - //---------------------------------------------------------------------------------------- - // Standard v1 Plugin Interface + if(out != nullptr) { + memcpy(out, mem, size); + } - unsigned short housekeeping; + return out; +} - if (idam_plugin_interface->interfaceVersion > THISPLUGIN_MAX_INTERFACE_VERSION) { - RAISE_PLUGIN_ERROR("Plugin Interface Version Unknown to this plugin: Unable to execute the request!"); +int ViewportPlugin::find_handle(const std::string& signal, const std::string& source) +{ + for (const auto& entry : cache_) { + if (entry.signal == signal && entry.source == source) { + return entry.handle; + } } + return -1; +} - idam_plugin_interface->pluginVersion = THISPLUGIN_VERSION; - - DATA_BLOCK* data_block = idam_plugin_interface->data_block; - REQUEST_DATA* request = idam_plugin_interface->request_data; - - housekeeping = idam_plugin_interface->housekeeping; - - //---------------------------------------------------------------------------------------- - // Context relevent Name-Value pairs and keywords - - bool isStartValueX = false; - bool isEndValueX = false; - bool isStartValueY = false; - bool isEndValueY = false; - bool isPixelHeight = false; - bool isPixelWidth = false; - int pixelHeight = 0; - int pixelWidth = 0; - bool isClearCache = false; - bool isMean = false; - bool isMode = false; - bool isMedian = false; - bool isTest = false; - bool isRange = true; - - int test = 0; - char* signal = nullptr; - char* source = nullptr; - float startValueX = 0.0; - float endValueX = 0.0; - float startValueY = 0.0; - float endValueY = 0.0; - - { - for (int i = 0; i < request->nameValueList.pairCount; i++) { - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "signal")) { - signal = request->nameValueList.nameValue[i].value; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "source")) { - source = request->nameValueList.nameValue[i].value; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "startValueX")) { - isStartValueX = true; - startValueX = (float)atof(request->nameValueList.nameValue[i].value); - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "endValueX")) { - isEndValueX = true; - endValueX = (float)atof(request->nameValueList.nameValue[i].value); - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "startValueY")) { - isStartValueY = true; - startValueY = (float)atof(request->nameValueList.nameValue[i].value); - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "endValueY")) { - isEndValueY = true; - endValueY = (float)atof(request->nameValueList.nameValue[i].value); - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "pixelHeight")) { - isPixelHeight = true; - pixelHeight = atoi(request->nameValueList.nameValue[i].value); - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "pixelWidth")) { - isPixelWidth = true; - pixelWidth = atoi(request->nameValueList.nameValue[i].value); - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "clearCache")) { - isClearCache = true; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "test")) { - isTest = true; - test = atoi(request->nameValueList.nameValue[i].value); - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "mean")) { - isMean = true; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "mode")) { - isMode = true; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "median")) { - isMedian = true; - continue; - } - if (STR_IEQUALS(request->nameValueList.nameValue[i].name, "range")) { - isRange = true; - continue; - } +extern int viewport(IDAM_PLUGIN_INTERFACE* plugin_interface) +{ + static ViewportPlugin plugin = {}; + return plugin.call(plugin_interface); +} + +int ViewportPlugin::get(IDAM_PLUGIN_INTERFACE* plugin_interface) +{ + // Context based Tests: required - pixel_width, pixel_height, Signal, Source + + // Access data if the signal/source data are not cached + + std::string signal = find_required_arg(plugin_interface, "signal"); + std::string source = find_required_arg(plugin_interface, "source"); + auto test = find_arg(plugin_interface, "test"); + auto pixel_width = find_arg(plugin_interface, "pixel_width"); + auto pixel_height = find_arg(plugin_interface, "pixel_height"); + auto start_x = find_arg(plugin_interface, "start_x"); + auto end_x = find_arg(plugin_interface, "end_x"); + auto start_y = find_arg(plugin_interface, "start_y"); + auto end_y = find_arg(plugin_interface, "end_y"); + auto range = find_arg(plugin_interface, "range"); + auto mean = has_arg(plugin_interface, "mean"); + auto median = has_arg(plugin_interface, "mean"); + auto mode = has_arg(plugin_interface, "mean"); + + int handle = find_handle(signal, source); + + if (handle < 0) { + + if ((handle = idamGetAPI(signal.c_str(), source.c_str())) < 0 || getIdamErrorCode(handle) != 0) { + error(getIdamErrorMsg(handle)); } - } - //---------------------------------------------------------------------------------------- - // Heap Housekeeping + cache_.emplace_back(CacheEntry{handle, signal, source}); + } - // Plugin must maintain a list of open file handles and sockets: loop over and close all files and sockets - // Plugin must maintain a list of plugin functions called: loop over and reset state and free heap. - // Plugin must maintain a list of calls to other plugins: loop over and call each plugin with the housekeeping request - // Plugin must destroy lists at end of housekeeping + // Get the data rank and data shape, the data and the coordinates - // A plugin only has a single instance on a server. For multiple instances, multiple servers are needed. - // Plugins can maintain state so recursive calls (on the same server) must respect this. - // If the housekeeping action is requested, this must be also applied to all plugins called. - // A list must be maintained to register these plugin calls to manage housekeeping. - // Calls to plugins must also respect access policy and user authentication policy + int rank = getIdamRank(handle); + int order = getIdamOrder(handle); - if (housekeeping || STR_IEQUALS(request->function, "reset")) { + if (rank == 1) { + int count = getIdamDataNum(handle); - if (!init) return 0; // Not previously initialised: Nothing to do! + std::vector values(static_cast(count)); + std::vector coords(static_cast(count)); - // Free Heap & reset counters - - for (int i = 0; i < handleCount; i++) { - udaFree(handles[i]); - handles[i] = -1; - } + getIdamFloatData(handle, values.data()); + getIdamFloatDimData(handle, 0, coords.data()); - init = 0; - handleCount = 0; + if (test) { + debug( "Running Viewport Test {}\n", *test); - return 0; - } + switch (*test) { + case 1: { // Do nothing + break; + } + case 2: { // 100 values mapped to 100 pixels: each pixel column has a single data value + pixel_width = 100; + break; + } + case 3: { // 100 values mapped to 100 pixels: each pixel column has a single data value + pixel_height = 100; + break; + } + case 4: { // 100 values mapped to 100 pixels: each pixel column has a single data value + pixel_height = 100; + pixel_width = 100; + break; + } - if (STR_IEQUALS(request->function, "clearCache") || isClearCache) { + case 5: { // 100 values mapped to 100 pixels: each pixel column has a single data value + count = 101; + for (int i = 0; i < count; i++) { + values[i] = (float)i + 1; + coords[i] = (float)i + 1; + } + pixel_height = 100; + pixel_width = 100; + break; + } - // Free Cached data if requested or filled - - for (int i = 0; i < handleCount; i++) { - udaFree(handles[i]); - handles[i] = -1; + case 6: { // 50 values mapped to 100 pixels: alternate pixels have no data! + count = 201; + for (int i = 0; i < count; i++) { + values[i] = (float)i + 1; + coords[i] = (float)i + 1; + } + start_x = 151.0; + pixel_height = 100; + pixel_width = 100; + break; + } + case 7: { // 50 values mapped to 100 pixels: alternate pixels have no data! + count = 201; + for (int i = 0; i < count; i++) { + values[i] = (float)i + 1; + coords[i] = (float)i + 1; + } + start_y = 151.0; + pixel_height = 100; + pixel_width = 100; + break; + } + } } - handleCount = 0; + // Map data to the viewport - return 0; - } + // Real-world coordinate Width Scenarios + // 1> no start or end value set + // 2> start value set + // 3> end value set + // 4> start and end value set - if (handleCount == MAXHANDLES) { - // Free some Cached data if cache is full - for (int i = 0; i < FREEHANDLEBLOCK; i++) { - udaFree(handles[i]); - handles[i] = handles[i + FREEHANDLEBLOCK]; - strcpy(signals[i], signals[i + FREEHANDLEBLOCK]); - strcpy(sources[i], sources[i + FREEHANDLEBLOCK]); - } + // Issues + // 1> Insufficient data to fill some pixels + // 2> requested range lies outside the data's range - handleCount = handleCount - FREEHANDLEBLOCK; - return 0; - } + // Reduce data to fit the value ranges specified + // Assume X data (coordinates) are ordered in increasing value - //---------------------------------------------------------------------------------------- - // Initialise + float max_y = values[0]; + float min_y = values[0]; + float max_x = coords[count - 1]; + float min_x = values[0]; - if (!init || STR_IEQUALS(request->function, "init") - || STR_IEQUALS(request->function, "initialise")) { + // Reduce the ordered X data's width - // Free Heap Cache & reset counters - for (int i = 0; i < handleCount; i++) { - udaFree(handles[i]); - handles[i] = -1; + if (!start_x && !end_x) { + reduceOrderedData(values.data(), &count, nullptr, nullptr, coords.data(), &min_x, &max_x); } - - handleCount = 0; - - init = 1; - if (STR_IEQUALS(request->function, "init") || STR_IEQUALS(request->function, "initialise")) { - return 0; + if (!start_x && end_x) { + reduceOrderedData(values.data(), &count, nullptr, &*end_x, coords.data(), &min_x, &max_x); + } + if (start_x && !end_x) { + reduceOrderedData(values.data(), &count, &*start_x, nullptr, coords.data(), &min_x, &max_x); + } + if (start_x && end_x) { + reduceOrderedData(values.data(), &count, &*start_x, &*end_x, coords.data(), &min_x, &max_x); } - } - - //---------------------------------------------------------------------------------------- - // Plugin Functions - //---------------------------------------------------------------------------------------- - do { + // Range of Y data - // Help: A Description of library functionality + if (!start_y) { + min_y = FLT_MAX; + for (int j = 0; j < count; j++) { + if (values[j] < min_y) min_y = values[j]; + } + } else { + min_y = *start_y; + } - if (STR_IEQUALS(request->function, "help")) { + if (!end_y) { + max_y = -FLT_MAX; + for (int j = 0; j < count; j++) { + if (values[j] > max_y) max_y = values[j]; + } + } else { + max_y = *end_y; + } - p = (char*)malloc(sizeof(char) * 2 * 1024); + // Reduce unordered Y data: remove points outside the range - strcpy(p, "\nviewport: Add Functions Names, Syntax, and Descriptions\n\n"); + if (start_y || end_y) { + int new_count = 0; + int* remove = (int*)malloc(count * sizeof(int)); + for (int j = 0; j < count; j++) { + if (values[j] < min_y || values[j] > max_y) { + remove[j] = 1; + } else { + remove[j] = 0; + new_count++; + } + } - initDataBlock(data_block); + if (new_count < count) { + int id = 0; - data_block->rank = 1; - data_block->dims = (DIMS*)malloc(data_block->rank * sizeof(DIMS)); - for (unsigned int i = 0; i < data_block->rank; i++) { - initDimBlock(&data_block->dims[i]); - } + std::vector new_values(static_cast(new_count)); + std::vector new_coords(static_cast(new_count)); - data_block->data_type = UDA_TYPE_STRING; - strcpy(data_block->data_desc, "viewport: help = description of this plugin"); - - data_block->data = (char*)p; - - data_block->dims[0].data_type = UDA_TYPE_UNSIGNED_INT; - data_block->dims[0].dim_n = strlen(p) + 1; - data_block->dims[0].compressed = 1; - data_block->dims[0].dim0 = 0.0; - data_block->dims[0].diff = 1.0; - data_block->dims[0].method = 0; - - data_block->data_n = data_block->dims[0].dim_n; - - strcpy(data_block->data_label, ""); - strcpy(data_block->data_units, ""); - - break; - } else - - //---------------------------------------------------------------------------------------- - // Standard methods: version, builddate, defaultmethod, maxinterfaceversion - - if (STR_IEQUALS(request->function, "version")) { - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_INT; - data_block->rank = 0; - data_block->data_n = 1; - int* data = (int*)malloc(sizeof(int)); - data[0] = THISPLUGIN_VERSION; - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin version number"); - strcpy(data_block->data_label, "version"); - strcpy(data_block->data_units, ""); - break; - } else - - // Plugin Build Date - - if (STR_IEQUALS(request->function, "builddate")) { - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_STRING; - data_block->rank = 0; - data_block->data_n = strlen(__DATE__) + 1; - char* data = (char*)malloc(data_block->data_n * sizeof(char)); - strcpy(data, __DATE__); - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin build date"); - strcpy(data_block->data_label, "date"); - strcpy(data_block->data_units, ""); - break; - } else - - // Plugin Default Method - - if (STR_IEQUALS(request->function, "defaultmethod")) { - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_STRING; - data_block->rank = 0; - data_block->data_n = strlen(THISPLUGIN_DEFAULT_METHOD) + 1; - char* data = (char*)malloc(data_block->data_n * sizeof(char)); - strcpy(data, THISPLUGIN_DEFAULT_METHOD); - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Plugin default method"); - strcpy(data_block->data_label, "method"); - strcpy(data_block->data_units, ""); - break; - } else - - // Plugin Maximum Interface Version - - if (STR_IEQUALS(request->function, "maxinterfaceversion")) { - initDataBlock(data_block); - data_block->data_type = UDA_TYPE_INT; - data_block->rank = 0; - data_block->data_n = 1; - int* data = (int*)malloc(sizeof(int)); - data[0] = THISPLUGIN_MAX_INTERFACE_VERSION; - data_block->data = (char*)data; - strcpy(data_block->data_desc, "Maximum Interface Version"); - strcpy(data_block->data_label, "version"); - strcpy(data_block->data_units, ""); - break; - } else - - - //---------------------------------------------------------------------------------------- - // Get data and map to the specified viewport - // Viewport Resolution Aggregation - - // Real world coordinates: startValueX, endValueX, startValueY, endValueY - // Device coordinates (relative) pixelWidth, pixelHeight - - if (STR_IEQUALS(request->function, "get")) { - - // Context based Tests: required - pixelWidth, pixelHeight, Signal, Source - - // Access data if the signal/source data are not cached - - int handle = whichHandle(signal, source); - - if (handle < 0) { - - if ((handle = idamGetAPI(signal, source)) < 0 || getIdamErrorCode(handle) != 0) { - err = 999; - addIdamError(UDA_CODE_ERROR_TYPE, "viewPort", err, (char*)getIdamErrorMsg(handle)); - break; + for (int j = 0; j < count; j++) { + if (!remove[j]) { + new_values[id] = values[j]; + new_coords[id++] = coords[j]; + } } - handles[handleCount] = handle; - strcpy(signals[handleCount], signal); - strcpy(sources[handleCount], source); - handleCount++; + count = new_count; + + values = new_values; + coords = new_coords; } - // Get the data rank and data shape, the data and the coordinates + free(remove); + } - int rank = getIdamRank(handle); - int order = getIdamOrder(handle); + // Reduce data to fix the device coordinates (relative pixels) - if (rank == 1) { - int count = getIdamDataNum(handle); + // Coordinate index range of each horizontal pixel column + // Each pixel has data points - auto values = (float*)malloc(count * sizeof(float)); - auto coords = (float*)malloc(count * sizeof(float)); + std::vector data; + std::vector err_hi; + std::vector err_lo; - getIdamFloatData(handle, values); - getIdamFloatDimData(handle, 0, coords); + int pixelWidth2 = 0; + std::vector horizontal_pixel_values; - if (isTest) { - UDA_LOG(UDA_LOG_DEBUG, "Running Viewport Test %d\n", test); + if (pixel_width && pixel_height) { + // Map to pixels if the device coordinate viewport is defined - switch (test) { - case 1: { // Do nothing - break; - } - case 2: { // 100 values mapped to 100 pixels: each pixel column has a single data value - isPixelWidth = true; - pixelWidth = 100; - break; - } - case 3: { // 100 values mapped to 100 pixels: each pixel column has a single data value - isPixelHeight = true; - pixelHeight = 100; - break; - } - case 4: { // 100 values mapped to 100 pixels: each pixel column has a single data value - isPixelHeight = true; - isPixelWidth = true; - pixelHeight = 100; - pixelWidth = 100; - break; - } + debug("Viewport: Mapping data to device pixel coordinate range (width, height) = {}, {}\n", + *pixel_width, *pixel_height); - case 5: { // 100 values mapped to 100 pixels: each pixel column has a single data value - count = 101; - for (int i = 0; i < count; i++) { - values[i] = (float)i + 1; - coords[i] = (float)i + 1; - } - isPixelHeight = true; - isPixelWidth = true; - pixelHeight = 100; - pixelWidth = 100; - break; - } + int* column = nullptr; - case 6: { // 50 values mapped to 100 pixels: alternate pixels have no data! - count = 201; - for (int i = 0; i < count; i++) { - values[i] = (float)i + 1; - coords[i] = (float)i + 1; - } - isStartValueX = true; - startValueX = 151.0; - isPixelHeight = true; - isPixelWidth = true; - pixelHeight = 100; - pixelWidth = 100; - break; - } - case 7: { // 50 values mapped to 100 pixels: alternate pixels have no data! - count = 201; - for (int i = 0; i < count; i++) { - values[i] = (float)i + 1; - coords[i] = (float)i + 1; - } - isStartValueX = true; - startValueY = 151.0; - isPixelHeight = true; - isPixelWidth = true; - pixelHeight = 100; - pixelWidth = 100; - break; - } - } - } + // Assign coordinates to pixel columns - // Map data to the viewport + horizontal_pixel_values = getBins(coords.data(), count, *pixel_width, (double)min_x, (double)max_x, &column); - // Real-world coordinate Width Scenarios - // 1> no start or end value set - // 2> start value set - // 3> end value set - // 4> start and end value set + // Frequency distribution of pixel hits along each vertical pixel column - // Issues - // 1> Insufficient data to fill some pixels - // 2> requested range lies outside the data's range + data.resize(*pixel_width); + err_hi.resize(*pixel_width); + err_lo.resize(*pixel_width); + int* good = (int*)malloc(*pixel_width * sizeof(int)); - // Reduce data to fit the value ranges specified - // Assume X data (coordinates) are ordered in increasing value + float* verticalPixelValues = nullptr; // Value at the pixel center + float delta; - float maxValueY = values[0]; - float minValueY = values[0]; - float maxValueX = coords[count - 1]; - float minValueX = values[0]; + getVerticalPixelValues(values.data(), count, *pixel_height, &min_y, &max_y, &verticalPixelValues, + &delta); - // Reduce the ordered X data's width + auto verticalPixelBoundaries = (float*)malloc((*pixel_height + 2) * sizeof(float)); + verticalPixelBoundaries[0] = min_y; - if (!isStartValueX && !isEndValueX) { - reduceOrderedData(coords, &count, nullptr, nullptr, values, &minValueX, &maxValueX); - } - if (!isStartValueX && isEndValueX) { - reduceOrderedData(coords, &count, nullptr, &endValueX, values, &minValueX, &maxValueX); - } - if (isStartValueX && !isEndValueX) { - reduceOrderedData(coords, &count, &startValueX, nullptr, values, &minValueX, &maxValueX); - } - if (isStartValueX && isEndValueX) { - reduceOrderedData(coords, &count, &startValueX, &endValueX, values, &minValueX, &maxValueX); - } + for (int i = 1; i < *pixel_height + 2; i++) { + // Lower boundary of pixel cell + verticalPixelBoundaries[i] = verticalPixelBoundaries[i - 1] + delta; + } - // Range of Y data + // frequency distribution of values within each pixel column - if (!isStartValueY) { - minValueY = FLT_MAX; - for (int j = 0; j < count; j++) { - if (values[j] < minValueY) minValueY = values[j]; - } - } else { - minValueY = startValueY; - } + int* row = (int*)malloc(count * sizeof(int)); + int* fctot = (int*)malloc(*pixel_width * sizeof(int)); + int* frtot = (int*)malloc(*pixel_height * sizeof(int)); + int** freq = (int**)malloc(*pixel_width * sizeof(int*)); - if (!isEndValueY) { - maxValueY = -FLT_MAX; - for (int j = 0; j < count; j++) { - if (values[j] > maxValueY) maxValueY = values[j]; - } - } else { - maxValueY = endValueY; + for (int i = 0; i < *pixel_width; i++) { + fctot[i] = 0; + freq[i] = (int*)malloc(*pixel_height * sizeof(int)); + for (int j = 0; j < pixel_height; j++) { + freq[i][j] = 0; } + } - // Reduce unordered Y data: remove points outside the range - - if (isStartValueY || isEndValueY) { - int newCount = 0; - int* remove = (int*)malloc(count * sizeof(int)); - for (int j = 0; j < count; j++) { - if (values[j] < minValueY || values[j] > maxValueY) { - remove[j] = 1; - } else { - remove[j] = 0; - newCount++; - } - } - - if (newCount < count) { - int id = 0; - auto newValues = (float*)malloc(newCount * sizeof(float)); - auto newCoords = (float*)malloc(newCount * sizeof(float)); + for (int i = 0; i < count; i++) { + fctot[column[i]]++; // total counts + } - for (int j = 0; j < count; j++) { - if (!remove[j]) { - newValues[id] = values[j]; - newCoords[id++] = coords[j]; - } - } + int colCount = 0; + for (int i = 0; i < *pixel_width; i++) { + colCount = colCount + fctot[i]; + } - count = newCount; - free(values); - free(coords); + debug( "Column Totals: {}\n", colCount); + for (int i = 0; i < *pixel_width; i++) { + debug( "[{}] {}\n", i, fctot[i]); + } - values = newValues; - coords = newCoords; + // Which pixel row bin do each un-ordered data point fall into? + for (int j = 0; j < count; j++) { + row[j] = -1; + for (int i = 0; i < *pixel_height + 1; i++) { // Search within pixel boundaries + if (values[j] >= verticalPixelBoundaries[i] && values[j] < verticalPixelBoundaries[i + 1]) { + row[j] = i; + break; } - - free(remove); + } + if (row[j] > *pixel_height - 1) { + row[j] = *pixel_height - 1; } - // Reduce data to fix the device coordinates (relative pixels) - - // Coordinate index range of each horizontal pixel column - // Each pixel has data points - - float* data = nullptr; - float* errhi = nullptr; - float* errlo = nullptr; - int pixelWidth2 = 0; - float* horizontalPixelValues = nullptr; // Value at the pixel center + if (column[j] >= 0 && row[j] >= 0) { + freq[column[j]][row[j]]++; // build frequency distribution + } + } - if (isPixelWidth && isPixelHeight) { - // Map to pixels if the device coordinate viewport is defined + for (int i = 0; i < *pixel_height; i++) { + frtot[i] = 0; + } - UDA_LOG(UDA_LOG_DEBUG, - "Viewport: Mapping data to device pixel coordinate range (width, height) = %d, %d\n", - pixelWidth, pixelHeight); + for (int i = 0; i < count; i++) { + frtot[row[i]]++; // total counts + } - int* column = nullptr; + int rowCount = 0; + for (int i = 0; i < *pixel_height; i++) { + rowCount = rowCount + frtot[i]; + } - // Assign coordinates to pixel columns + debug( "Row Totals: {}\n", rowCount); + for (int i = 0; i < *pixel_height; i++) { + debug( "[{}] {}\n", i, frtot[i]); + } - getBins(coords, count, pixelWidth, (double)minValueX, (double)maxValueX, &column, - &horizontalPixelValues); + free(column); + free(row); + free(fctot); + free(frtot); - // Frequency distribution of pixel hits along each vertical pixel column + // Build return values - data = (float*)malloc(pixelWidth * sizeof(float)); - errhi = (float*)malloc(pixelWidth * sizeof(float)); - errlo = (float*)malloc(pixelWidth * sizeof(float)); + int good_count = 0; + pixelWidth2 = *pixel_width; + int* integral = (int*)malloc(*pixel_height * sizeof(int)); - int* good = (int*)malloc(pixelWidth * sizeof(int)); + for (int i = 0; i < pixel_width; i++) { - float* verticalPixelValues = nullptr; // Value at the pixel center - float delta; + // which value to return? + // mean, median or mode? + // with/without errors - standard deviation, asymmetric? + // 2D pixel map with colour for frequency - limited pallet? 1 byte == 256 colours - getVerticalPixelValues(values, count, pixelHeight, &minValueY, &maxValueY, &verticalPixelValues, - &delta); + good[i] = 0; + data[i] = 0.0; + err_lo[i] = 0.0; + err_hi[i] = 0.0; + int meanCount = 0; - auto verticalPixelBoundaries = (float*)malloc((pixelHeight + 2) * sizeof(float)); - verticalPixelBoundaries[0] = minValueY; - - for (int i = 1; i < pixelHeight + 2; i++) { - // Lower boundary of pixel cell - verticalPixelBoundaries[i] = verticalPixelBoundaries[i - 1] + delta; + if (range && mean) { + if (i == 0) { + debug( "Mean returned\n"); } - - // frequency distribution of values within each pixel column - - int* row = (int*)malloc(count * sizeof(int)); - int* fctot = (int*)malloc(pixelWidth * sizeof(int)); - int* frtot = (int*)malloc(pixelHeight * sizeof(int)); - int** freq = (int**)malloc(pixelWidth * sizeof(int*)); - - for (int i = 0; i < pixelWidth; i++) { - fctot[i] = 0; - freq[i] = (int*)malloc(pixelHeight * sizeof(int)); - for (int j = 0; j < pixelHeight; j++) { - freq[i][j] = 0; + for (int j = 0; j < pixel_height; j++) { + if (freq[i][j] > 0) { + data[i] = data[i] + (float)freq[i][j] * verticalPixelValues[j]; + meanCount = meanCount + freq[i][j]; } } - - for (int i = 0; i < count; i++) { - fctot[column[i]]++; // total counts - } - - int colCount = 0; - for (int i = 0; i < pixelWidth; i++) { - colCount = colCount + fctot[i]; - } - - UDA_LOG(UDA_LOG_DEBUG, "Column Totals: %d\n", colCount); - for (int i = 0; i < pixelWidth; i++) { - UDA_LOG(UDA_LOG_DEBUG, "[%d] %d\n", i, fctot[i]); + if (meanCount > 0) { + data[i] = data[i] / (float)meanCount; + good[i] = 1; + good_count++; } - // Which pixel row bin do each un-ordered data point fall into? - - for (int j = 0; j < count; j++) { - row[j] = -1; - for (int i = 0; i < pixelHeight + 1; i++) { // Search within pixel boundaries - if (values[j] >= verticalPixelBoundaries[i] && values[j] < verticalPixelBoundaries[i + 1]) { - row[j] = i; - break; - } + } else if (!range && mode) { + debug( "Mode returned\n"); + int fmax = 0; + int fmaxID = -1; + for (int j = 0; j < pixel_height; j++) { + if (freq[i][j] > fmax) { // First mode found if multi-modal + fmaxID = j; + fmax = freq[i][j]; } - if (row[j] > pixelHeight - 1) row[j] = pixelHeight - 1; - - if (column[j] >= 0 && row[j] >= 0) freq[column[j]][row[j]]++; // build frequency distribution - } - - for (int i = 0; i < pixelHeight; i++) { - frtot[i] = 0; } - - for (int i = 0; i < count; i++) { - frtot[row[i]]++; // total counts + if (fmaxID >= 0) { + data[i] = verticalPixelValues[fmaxID]; + good[i] = 1; + good_count++; } - - int rowCount = 0; - for (int i = 0; i < pixelHeight; i++) { - rowCount = rowCount + frtot[i]; + } else if (!range && median) { + if (i == 0) { + debug( "Median returned\n"); } + integral[0] = freq[i][0]; - UDA_LOG(UDA_LOG_DEBUG, "Row Totals: %d\n", rowCount); - for (int i = 0; i < pixelHeight; i++) { - UDA_LOG(UDA_LOG_DEBUG, "[%d] %d\n", i, frtot[i]); + for (int j = 1; j < *pixel_height; j++) { + integral[j] = integral[j - 1] + freq[i][j]; } - free(column); - free(row); - free(fctot); - free(frtot); - - // Build return values - - int goodCount = 0; - pixelWidth2 = pixelWidth; - int* integral = (int*)malloc(pixelHeight * sizeof(int)); - - for (int i = 0; i < pixelWidth; i++) { - - // which value to return? - // mean, median or mode? - // with/without errors - standard deviation, asymmetric? - // 2D pixel map with colour for frequency - limited pallet? 1 byte == 256 colours - - good[i] = 0; - data[i] = 0.0; - errlo[i] = 0.0; - errhi[i] = 0.0; - int meanCount = 0; - - if (!isRange && isMean) { - if (i == 0) { - UDA_LOG(UDA_LOG_DEBUG, "Mean returned\n"); - } - for (int j = 0; j < pixelHeight; j++) { - if (freq[i][j] > 0) { - data[i] = data[i] + (float)freq[i][j] * verticalPixelValues[j]; - meanCount = meanCount + freq[i][j]; - } - } - if (meanCount > 0) { - data[i] = data[i] / (float)meanCount; - good[i] = 1; - goodCount++; - } - - } else if (!isRange && isMode) { - UDA_LOG(UDA_LOG_DEBUG, "Mode returned\n"); - int fmax = 0; - int fmaxID = -1; - for (int j = 0; j < pixelHeight; j++) { - if (freq[i][j] > fmax) { // First mode found if multi-modal - fmaxID = j; - fmax = freq[i][j]; + int target = integral[*pixel_height - 1] / 2; + + for (int j = 0; j < *pixel_height; j++) { + if (integral[j] >= target) { + if (1 && (j > 0 && integral[j - 1] > 0 && integral[j] != target)) { + float dx = (float)(integral[j] - integral[j - 1]); + if (dx != 0.0) { + float m = (verticalPixelValues[j] - verticalPixelValues[j - 1]) / dx; + data[i] = m * (target - integral[j]) + + verticalPixelValues[j]; // Linear Interpolate + } else { + data[i] = verticalPixelValues[j]; } - } - if (fmaxID >= 0) { - data[i] = verticalPixelValues[fmaxID]; - good[i] = 1; - goodCount++; - } - } else if (!isRange && isMedian) { - if (i == 0) { - UDA_LOG(UDA_LOG_DEBUG, "Median returned\n"); - } - integral[0] = freq[i][0]; - for (int j = 1; j < pixelHeight; j++) { - integral[j] = integral[j - 1] + freq[i][j]; - } - - int target = integral[pixelHeight - 1] / 2; - - for (int j = 0; j < pixelHeight; j++) { - if (integral[j] >= target) { - if (1 && (j > 0 && integral[j - 1] > 0 && integral[j] != target)) { - float dx = (float)(integral[j] - integral[j - 1]); - if (dx != 0.0) { - float m = (verticalPixelValues[j] - verticalPixelValues[j - 1]) / dx; - data[i] = m * (target - integral[j]) + - verticalPixelValues[j]; // Linear Interpolate - } else { - data[i] = verticalPixelValues[j]; - } - - } else { - if (j > 0 && integral[j - 1] > 0 && - (target - integral[j - 1]) <= (integral[j] - target)) { - data[i] = verticalPixelValues[j - 1]; - } else { - data[i] = verticalPixelValues[j]; - } - } - good[i] = 1; - goodCount++; - - break; + } else { + if (j > 0 && integral[j - 1] > 0 && + (target - integral[j - 1]) <= (integral[j] - target)) { + data[i] = verticalPixelValues[j - 1]; + } else { + data[i] = verticalPixelValues[j]; } } - } - - // Range of data values - Above and below the mean/mode/median value - - errhi[i] = 0.0; - errlo[i] = 0.0; - - for (int j = 0; j < pixelHeight; j++) { - if (freq[i][j] > 0) { - errlo[i] = verticalPixelValues[j]; // lowest value - break; - } - } - - for (int j = pixelHeight - 1; j >= 0; j--) { - if (freq[i][j] > 0) { - errhi[i] = verticalPixelValues[j]; // highest value - break; - } - } + good[i] = 1; + good_count++; - if (isRange) { - if (i == 0) { - UDA_LOG(UDA_LOG_DEBUG, "Range returned\n"); - } - data[i] = 0.5 * (errlo[i] + errhi[i]); - goodCount++; + break; } + } + } - free(freq[i]); - - if (i == 0) { - UDA_LOG(UDA_LOG_DEBUG, "&data = %p\n", data); - } - UDA_LOG(UDA_LOG_DEBUG, "[%d] %f %f %f %f\n", i, data[i], errlo[i], errhi[i], - horizontalPixelValues[i]); + // Range of data values - Above and below the mean/mode/median value - } // end of loop over pixelWidth + err_hi[i] = 0.0; + err_lo[i] = 0.0; - UDA_LOG(UDA_LOG_DEBUG, "goodCount = %d\n", goodCount); - UDA_LOG(UDA_LOG_DEBUG, "pixelWidth = %d\n", pixelWidth); - UDA_LOG(UDA_LOG_DEBUG, "&data = %p\n", data); - for (int i = 0; i < pixelWidth2; i++) { - UDA_LOG(UDA_LOG_DEBUG, "[%d] %f %f %f %f\n", i, data[i], errlo[i], errhi[i], - horizontalPixelValues[i]); - } - // Free allocated heap - - free(values); - free(coords); - free(freq); - free(verticalPixelValues); - free(verticalPixelBoundaries); - free(integral); - - // data, errhi, errlo, horizontalPixelValues heap freed once the server transmits the data - // heap within the idam layer is freed on reset or clearCache or if the cache fills - - // Remove pixel columns without data - - if (goodCount < pixelWidth) { - UDA_LOG(UDA_LOG_DEBUG, "Removing pixel columns without data [%d, %d]\n", goodCount, pixelWidth); - auto newData = (float*)malloc(goodCount * sizeof(float)); - auto newErrhi = (float*)malloc(goodCount * sizeof(float)); - auto newErrlo = (float*)malloc(goodCount * sizeof(float)); - auto pixelValues = (float*)malloc(goodCount * sizeof(float)); - int ID = 0; - for (int i = 0; i < pixelWidth; i++) { - if (good[i]) { - newData[ID] = data[i]; - newErrhi[ID] = errlo[i]; - newErrlo[ID] = errhi[i]; - pixelValues[ID] = horizontalPixelValues[i]; - ID++; - } - } - free(good); - - free(data); - free(errlo); - free(errhi); - free(horizontalPixelValues); - - data = newData; - errlo = newErrlo; - errhi = newErrhi; - horizontalPixelValues = pixelValues; - pixelWidth2 = goodCount; + for (int j = 0; j < *pixel_height; j++) { + if (freq[i][j] > 0) { + err_lo[i] = verticalPixelValues[j]; // lowest value + break; } - } else { // Device pixel coordinate range not set - data = values; - horizontalPixelValues = coords; - pixelWidth2 = count; } - // Return viewport data - - initDataBlock(data_block); - - data_block->rank = 1; - data_block->dims = (DIMS*)malloc(data_block->rank * sizeof(DIMS)); - for (unsigned int i = 0; i < data_block->rank; i++) { - initDimBlock(&data_block->dims[i]); + for (int j = *pixel_height - 1; j >= 0; j--) { + if (freq[i][j] > 0) { + err_hi[i] = verticalPixelValues[j]; // highest value + break; + } } - data_block->data_n = pixelWidth2; - data_block->data_type = UDA_TYPE_FLOAT; - strcpy(data_block->data_desc, getIdamDataDesc(handle)); - strcpy(data_block->data_label, getIdamDataLabel(handle)); - strcpy(data_block->data_units, getIdamDataUnits(handle)); + if (range) { + if (i == 0) { + debug( "Range returned\n"); + } + data[i] = 0.5 * (err_lo[i] + err_hi[i]); + good_count++; + } - data_block->dims[0].dim = (char*)horizontalPixelValues; + free(freq[i]); - data_block->dims[0].data_type = UDA_TYPE_FLOAT; - data_block->dims[0].dim_n = pixelWidth2; - data_block->dims[0].compressed = 0; - strcpy(data_block->dims[0].dim_label, getIdamDimLabel(handle, 0)); - strcpy(data_block->dims[0].dim_units, getIdamDimUnits(handle, 0)); + debug( "[{}] {} {} {} {}\n", i, data[i], err_lo[i], err_hi[i], + horizontal_pixel_values[i]); - data_block->data = (char*)data; + } // end of loop over pixel_width - if (errhi != nullptr && errlo != nullptr) { - if (!isRange) { - data_block->errasymmetry = 1; - data_block->errlo = (char*)errlo; - } else { - free(errlo); + debug( "good_count = {}\n", good_count); + debug( "pixel_width = {}\n", *pixel_width); + for (int i = 0; i < pixelWidth2; i++) { + debug( "[{}] {} {} {} {}\n", i, data[i], err_lo[i], err_hi[i], + horizontal_pixel_values[i]); + } + // Free allocated heap + + free(freq); + free(verticalPixelValues); + free(verticalPixelBoundaries); + free(integral); + + // data, err_hi, err_lo, horizontal_pixel_values heap freed once the server transmits the data + // heap within the idam layer is freed on reset or clearCache or if the cache fills + + // Remove pixel columns without data + + if (good_count < pixel_width) { + debug( "Removing pixel columns without data [{}, {}]\n", good_count, *pixel_width); + + std::vector new_data(static_cast(good_count)); + std::vector new_err_hi(static_cast(good_count)); + std::vector new_err_lo(static_cast(good_count)); + std::vector pixel_values(static_cast(good_count)); + + int ID = 0; + for (int i = 0; i < pixel_width; i++) { + if (good[i]) { + new_data[ID] = data[i]; + new_err_hi[ID] = err_lo[i]; + new_err_lo[ID] = err_hi[i]; + pixel_values[ID] = horizontal_pixel_values[i]; + ID++; } - data_block->errhi = (char*)errhi; - data_block->error_type = UDA_TYPE_FLOAT; } + free(good); + + data = new_data; + err_lo = new_err_lo; + err_hi = new_err_hi; + horizontal_pixel_values = pixel_values; + pixelWidth2 = good_count; + } + } else { // Device pixel coordinate range not set + data = values; + horizontal_pixel_values = coords; + pixelWidth2 = count; + } - data_block->order = order; + // Return viewport data + DATA_BLOCK* data_block = plugin_interface->data_block; + initDataBlock(data_block); - } else { - err = 999; - addIdamError(UDA_CODE_ERROR_TYPE, "viewPort", err, "A viewport for rank > 1 data has not been implemented!"); - break; - } + data_block->rank = 1; + data_block->dims = (DIMS*)malloc(data_block->rank * sizeof(DIMS)); + for (unsigned int i = 0; i < data_block->rank; i++) { + initDimBlock(&data_block->dims[i]); + } - break; - } else { + data_block->data_n = pixelWidth2; + data_block->data_type = UDA_TYPE_FLOAT; + strcpy(data_block->data_desc, getIdamDataDesc(handle)); + strcpy(data_block->data_label, getIdamDataLabel(handle)); + strcpy(data_block->data_units, getIdamDataUnits(handle)); - //====================================================================================== - // Error ... + data_block->dims[0].dim = memdup(horizontal_pixel_values.data(), horizontal_pixel_values.size()); - err = 999; - addIdamError(UDA_CODE_ERROR_TYPE, "viewport", err, "Unknown function requested!"); - break; + data_block->dims[0].data_type = UDA_TYPE_FLOAT; + data_block->dims[0].dim_n = pixelWidth2; + data_block->dims[0].compressed = 0; + strcpy(data_block->dims[0].dim_label, getIdamDimLabel(handle, 0)); + strcpy(data_block->dims[0].dim_units, getIdamDimUnits(handle, 0)); + + data_block->data = memdup(data.data(), data.size()); + + if (!range) { + data_block->errasymmetry = 1; + data_block->errlo = memdup(err_lo.data(), err_lo.size()); } + data_block->errhi = memdup(err_hi.data(), err_hi.size()); + data_block->error_type = UDA_TYPE_FLOAT; - } while (0); + data_block->order = order; + } else { + error("A viewport for rank > 1 data has not been implemented!"); + } - return err; + return 0; } - -void getBins(float* coords, int count, int pixelWidth, float minValue, float maxValue, int** column, - float** pixelValues) +std::vector getBins(float* coords, int count, int pixel_width, float minValue, float maxValue, int** column) { int start; int* bin = (int*)malloc(count * sizeof(int)); - float* pixValues = (float*)malloc((pixelWidth + 2) * sizeof(float)); // Include an extra point + + std::vector pix_values(static_cast(pixel_width + 2)); // Value width of each pixel - float delta = (maxValue - minValue) / (float)pixelWidth; + float delta = (maxValue - minValue) / (float)pixel_width; - // lower pixel boundary value (pixelWidth + 1 boundaries + extra point) + // lower pixel boundary value (pixel_width + 1 boundaries + extra point) - pixValues[0] = minValue; - for (int i = 1; i < pixelWidth + 2; i++) { - pixValues[i] = pixValues[i - 1] + delta; + pix_values[0] = minValue; + for (int i = 1; i < pixel_width + 2; i++) { + pix_values[i] = pix_values[i - 1] + delta; } // Which pixel column bin do each data point fall into? @@ -929,31 +639,31 @@ void getBins(float* coords, int count, int pixelWidth, float minValue, float max start = 0; for (int j = 0; j < count; j++) { bin[j] = -1; - for (int i = start; i < pixelWidth + 1; i++) { // Search within pixel boundaries - if (coords[j] >= pixValues[i] && coords[j] < pixValues[i + 1]) { + for (int i = start; i < pixel_width + 1; i++) { // Search within pixel boundaries + if (coords[j] >= pix_values[i] && coords[j] < pix_values[i + 1]) { bin[j] = i; start = i; break; } } - if (bin[j] > pixelWidth - 1) bin[j] = pixelWidth - 1; + if (bin[j] > pixel_width - 1) bin[j] = pixel_width - 1; } // mid pixel value: the range of data is mapped to these pixels - pixValues[0] = minValue + 0.5 * delta; - for (int i = 1; i < pixelWidth; i++) pixValues[i] = pixValues[i - 1] + delta; + pix_values[0] = minValue + 0.5 * delta; + for (int i = 1; i < pixel_width; i++) pix_values[i] = pix_values[i - 1] + delta; *column = bin; - *pixelValues = pixValues; + return pix_values; } // Mid-Pixel value -void getVerticalPixelValues(float* values, int count, int pixelHeight, float* startValue, float* endValue, +void getVerticalPixelValues(float* values, int count, int pixel_height, float* startValue, float* endValue, float** verticalPixelValues, float* delta) { - auto v = (float*)malloc(pixelHeight * sizeof(float)); + auto v = (float*)malloc(pixel_height * sizeof(float)); float maxValue = values[0], minValue = values[0]; if (startValue == nullptr) { @@ -972,9 +682,9 @@ void getVerticalPixelValues(float* values, int count, int pixelHeight, float* st maxValue = *endValue; } - *delta = (maxValue - minValue) / (float)pixelHeight; + *delta = (maxValue - minValue) / (float)pixel_height; v[0] = minValue + 0.5 * (*delta); - for (int i = 1; i < pixelHeight; i++) { + for (int i = 1; i < pixel_height; i++) { v[i] = v[i - 1] + *delta; } *verticalPixelValues = v; @@ -982,15 +692,15 @@ void getVerticalPixelValues(float* values, int count, int pixelHeight, float* st // Assume data are arranged in no particular value order -void getBinIds(float* values, int count, int pixelHeight, float* pixelValues, int** freq) +void getBinIds(float* values, int count, int pixel_height, float* pixel_values, int** freq) { - auto f = (int*)malloc(pixelHeight * sizeof(int)); - for (int i = 0; i < pixelHeight; i++) { + auto f = (int*)malloc(pixel_height * sizeof(int)); + for (int i = 0; i < pixel_height; i++) { f[i] = 0; } for (int i = 0; i < count; i++) { - for (int j = 0; j < pixelHeight; j++) { - if (values[i] >= pixelValues[j] && values[i] <= pixelValues[j]) f[j]++; + for (int j = 0; j < pixel_height; j++) { + if (values[i] >= pixel_values[j] && values[i] <= pixel_values[j]) f[j]++; } } *freq = f; diff --git a/source/plugins/viewport/viewport.h b/source/plugins/viewport/viewport.h index 5c6b2e45a..f3de6c74c 100755 --- a/source/plugins/viewport/viewport.h +++ b/source/plugins/viewport/viewport.h @@ -18,19 +18,6 @@ extern "C" { int viewport(IDAM_PLUGIN_INTERFACE * idam_plugin_interface); -LIBRARY_API void getVerticalPixelValues(float * values, int count, int pixelHeight, float * startValue, float * endValue, - float ** verticalPixelValues, float * delta); - -LIBRARY_API void getBins(float * coords, int count, int pixelWidth, float minValue, float maxValue, int ** column, - float ** pixelValues); - -LIBRARY_API void reduceOrderedData(float * values, int * count, float * startValue, float * endValue, float * coords, float * min, - float * max); - -LIBRARY_API void getBinIds(float * values, int count, int pixelHeight, float * pixelValues, int ** freq); - -LIBRARY_API int whichHandle(char * signal, char * source); - #ifdef __cplusplus } #endif