]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
pluginlib: Add command context switcher.
authorRadosław Korzeniewski <radekk@inteos.pl>
Wed, 23 Dec 2020 13:14:40 +0000 (14:14 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:00 +0000 (09:03 +0100)
bacula/src/plugins/fd/pluginlib/commctx.h [new file with mode: 0644]
bacula/src/plugins/fd/pluginlib/commctx_test.cpp [new file with mode: 0644]

diff --git a/bacula/src/plugins/fd/pluginlib/commctx.h b/bacula/src/plugins/fd/pluginlib/commctx.h
new file mode 100644 (file)
index 0000000..1a5ec3b
--- /dev/null
@@ -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<typename T>
+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<CMD> _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<typename T>
+T * COMMCTX<T>::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<typename T>
+bool COMMCTX<T>::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<typename T>
+void COMMCTX<T>::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 (file)
index 0000000..4f91dc7
--- /dev/null
@@ -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<testctx> 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();
+}