Hard refactoring. CodecEngine is associated to a unique stack.
[anna.git] / include / anna / diameter / codec / EngineManager.hpp
diff --git a/include/anna/diameter/codec/EngineManager.hpp b/include/anna/diameter/codec/EngineManager.hpp
new file mode 100644 (file)
index 0000000..268e318
--- /dev/null
@@ -0,0 +1,131 @@
+// ANNA - Anna is Not Nothingness Anymore                                                         //
+//                                                                                                //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
+//                                                                                                //
+// See project site at http://redmine.teslayout.com/projects/anna-suite                           //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef anna_diameter_codec_EngineManager_hpp
+#define anna_diameter_codec_EngineManager_hpp
+
+
+// Project
+#include <anna/core/Singleton.hpp>
+#include <anna/diameter/defines.hpp>
+
+// Standard
+#include <map>
+
+
+namespace anna {
+
+namespace diameter {
+
+namespace codec {
+
+class Engine;
+
+typedef std::map<anna::diameter::ApplicationId, Engine*> appid_codec_engines_t;
+typedef std::map<anna::diameter::ApplicationId, Engine*>::const_iterator appid_codec_engines_it;
+typedef std::map<anna::diameter::ApplicationId, Engine*>::iterator appid_codec_engines_nc_it;
+
+/**
+ * Helper class to centralize application codec engines and ease the automatic codec engine selection from
+ * codec resources (mainly Message class, but also Avp).
+ *
+ * This is useful if you enable the auto selection from messages application id, avoiding to pre-initialize
+ * such codec messages with a specific engine before interpreting the data sources or building.
+ * At multithread application, it is recommended to specialize the message codec for each stack without using
+ * this engine manager.
+ */
+class EngineManager : public anna::Singleton <EngineManager> {
+
+private:
+
+  bool a_autoSelectFromApplicationId;
+  appid_codec_engines_t a_appid_codec_engines;
+
+  // private constructor
+  EngineManager() : a_autoSelectFromApplicationId(true) {};
+
+public:
+
+  /**
+   * First element iterator
+   */
+  appid_codec_engines_it begin() const throw() { return a_appid_codec_engines.begin(); }
+
+  /**
+   * Last element iterator
+   */
+  appid_codec_engines_it end() const throw() { return a_appid_codec_engines.end(); }
+
+  /**
+   * Number of registered engines
+   */
+  int size() const throw() { return a_appid_codec_engines.size(); }
+
+  /**
+   * Registers a new codec engine (externally allocated) associated to an application id.
+   * If the application id exists, the new engine pointer will replace the existing one.
+   *
+   * @param appid Application-Id
+   * @param engine Associated codec engine
+   */
+  void registerCodecEngine(const ApplicationId &appid, Engine* engine) throw();
+
+  /**
+   * Get the associated codec engine for a provided Application-Id.
+   *
+   * @param appid Application-Id
+   *
+   * @return Found codec engine, NULL if not found
+   */
+  Engine *getCodecEngine(const ApplicationId &appid) const throw();
+
+  /**
+   * If only one codec engine is registered (mono-stack application), it will be returned
+   * (NULL in other case). This is because mono-stack applications could merge compatible
+   * stacks into one unique dictionary, using a global value for stack id with no relation
+   * regarding application-id concept.
+   *
+   * @return Unique codec engine, NULL if not unique (empty manager or more than one)
+   */
+  Engine *getMonoStackCodecEngine() const throw() {
+    return ((size() != 1) ? NULL : begin()->second);
+  }
+
+  /**
+   * The user could select the appropriate codec engine depending on the context, but some applications could
+   * consider interesting automatic codec engine selection from managed messages (decoded from any source,
+   * or built from scratch). Then, this engine manager will be used registering all the supported stacks
+   * with their corresponding codec engines, and automatic selection will be done during decoding of any
+   * supported source of data (hexadecimal buffers, xml documents) or build operations.
+   *
+   * If the user pre-initializes the codec engine for a #Message or #Avp element, this selection is ignored
+   * even if enabled: the codec engine only can be established one time, for security reasons.
+   *
+   * @param enable Activates/deactivates the codec engine selection from the Application-Id value. True by default
+   * and applicable when this manager store is not empty.
+   */
+  void selectFromApplicationId (bool enable) throw() { a_autoSelectFromApplicationId = enable; }
+
+  /**
+    Gets the currently configured behaviour regarding codec engine selection.
+
+    @return True if selection is done with the Application-Id (default behaviour). False to disable (the manager
+    could be used for some other things which could be also interesting).
+   */
+  bool selectFromApplicationId (void) throw() { return a_autoSelectFromApplicationId; }
+
+
+  friend class anna::Singleton <EngineManager>;
+};
+
+}
+}
+}
+
+#endif
+