From: Radosław Korzeniewski Date: Wed, 23 Dec 2020 13:14:40 +0000 (+0100) Subject: pluginlib: Add command context switcher. X-Git-Tag: Release-11.3.2~734 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2b6adcc7311e2b07ed9f7f6bc1777083dbe4a1f;p=thirdparty%2Fbacula.git pluginlib: Add command context switcher. --- diff --git a/bacula/src/plugins/fd/pluginlib/commctx.h b/bacula/src/plugins/fd/pluginlib/commctx.h new file mode 100644 index 000000000..1a5ec3b99 --- /dev/null +++ b/bacula/src/plugins/fd/pluginlib/commctx.h @@ -0,0 +1,138 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2020 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ +/** + * @file commctx.h + * @author Radosław Korzeniewski (radoslaw@korzeniewski.net) + * @brief This is a Bacula plugin command context switcher template. + * @version 1.1.0 + * @date 2020-12-23 + * + * @copyright Copyright (c) 2020 All rights reserved. IP transferred to Bacula Systems according to agreement. + */ + +#ifndef COMMCTX_H +#define COMMCTX_H + +#include "pluginlib.h" +#include "smartalist.h" + + +template +class COMMCTX : public SMARTALLOC +{ + struct CMD : public SMARTALLOC + { + POOL_MEM cmd; + T * ptr; + CMD(const char * command) : cmd(PM_FNAME), ptr(New(T(command))) { pm_strcpy(cmd, command); }; +#if __cplusplus > 201103L + CMD() = delete; + CMD(CMD &) = delete; + CMD(CMD &&) = delete; +#endif + ~CMD() { delete ptr; }; + }; + + /** The command context list for multiple config execution for a single job */ + smart_alist _command_list; + +public: + T * ctx; + + COMMCTX() : ctx(NULL) {}; +#if __cplusplus > 201103L + COMMCTX(COMMCTX &) = delete; + COMMCTX(COMMCTX &&) = delete; + ~COMMCTX() = default; +#else + ~COMMCTX() {}; +#endif + + T * switch_command(const char *command); + bool check_command(const char *command); + void foreach_command(void (*func)(T *, void *), void *param); +}; + + +/** + * @brief Switches current command context to requested. + * + * @tparam T is command context type. + * @param command is command context string to switch into. + * @return T* is command context pointer. + */ +template +T * COMMCTX::switch_command(const char * command) +{ + CMD * cmdctx; + foreach_alist(cmdctx, &_command_list) + { + if (bstrcmp(cmdctx->cmd.c_str(), command)) + { + ctx = cmdctx->ptr; + return ctx; + } + } + + cmdctx = New(CMD(command)); + _command_list.append(cmdctx); + ctx = cmdctx->ptr; + + return ctx; +} + +/** + * @brief Checks if command context is already defined on list. + * + * @tparam T is command context type. + * @param command is command context string to check. + * @return true when command context already exist. + * @return false when command context does not exist yet. + */ +template +bool COMMCTX::check_command(const char *command) +{ + CMD * cmdctx; + foreach_alist(cmdctx, &_command_list) + { + if (bstrcmp(cmdctx->cmd.c_str(), command)) + return true; + } + + return false; +} + +/** + * @brief Iterate on all command context to execute function. + * + * @tparam T is command context type. + * @param param is the execution function param. + */ +template +void COMMCTX::foreach_command(void(*func)(T*, void*), void* param) +{ + CMD * cmdctx; + foreach_alist(cmdctx, &_command_list) + { + ctx = cmdctx->ptr; + func(ctx, param); + } +} + +#endif /* COMMCTX_H */ diff --git a/bacula/src/plugins/fd/pluginlib/commctx_test.cpp b/bacula/src/plugins/fd/pluginlib/commctx_test.cpp new file mode 100644 index 000000000..4f91dc7b0 --- /dev/null +++ b/bacula/src/plugins/fd/pluginlib/commctx_test.cpp @@ -0,0 +1,79 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2020 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ +/** + * @file commctx_test.cpp + * @author Radosław Korzeniewski (radoslaw@korzeniewski.net) + * @brief A Bacula plugin command context switcher template - unittest. + * @version 1.1.0 + * @date 2020-12-23 + * + * @copyright Copyright (c) 2020 All rights reserved. IP transferred to Bacula Systems according to agreement. + */ + +#include "pluginlib.h" +#include "commctx.h" +#include "unittests.h" + +bFuncs *bfuncs; +bInfo *binfo; + +static int referencenumber = 0; + +struct testctx : public SMARTALLOC +{ + const char * cmd; + testctx(const char *command) : cmd(command) { referencenumber++; }; + ~testctx() { referencenumber--; };; +}; + +int main() +{ + Unittests pluglib_test("commctx_test"); + + // Pmsg0(0, "Initialize tests ...\n"); + +#define TEST1 "TEST1" +#define TEST2 "TEST2" + + { + COMMCTX ctx; + + nok(ctx.check_command("TEST1"), "test empty ctx list"); + ok(referencenumber == 0, "check no allocation yet"); + + auto testctx1 = ctx.switch_command(TEST1); + ok(testctx1 != nullptr, "test first command"); + ok(referencenumber == 1, "check allocation"); + + auto testctx2 = ctx.switch_command(TEST2); + ok(testctx2 != nullptr, "test next command"); + ok(referencenumber == 2, "check allocation"); + + auto currentctx = ctx.switch_command(TEST1); + ok(currentctx != nullptr, "test switch command"); + ok(currentctx == testctx1, "test switch command to proper"); + ok(referencenumber == 2, "check allocation"); + + ok(ctx.check_command(TEST2), "test check command"); + } + + ok(referencenumber == 0, "check smart free"); + + return report(); +}