New feature to allow to register components with different names for same class:...
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Sun, 7 Jun 2015 21:42:40 +0000 (23:42 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Sun, 7 Jun 2015 22:04:43 +0000 (00:04 +0200)
26 files changed:
example/diameter/batchConverter/main.cpp
example/diameter/launcher/Launcher.cpp
example/diameter/launcher/Launcher.hpp
example/diameter/launcher/MyDiameterEngine.hpp
example/diameter/launcher/MyDiameterEntity.hpp
example/diameter/launcher/MyLocalServer.cpp
example/diameter/launcher/MyLocalServer.hpp
example/diameter/launcher/ProgrammedAnswers.cpp
example/diameter/launcher/ProgrammedAnswers.hpp
include/anna/app/functions.hpp
include/anna/core/functions.hpp
include/anna/core/util/Configuration.hpp
include/anna/dbms.mysql/Database.hpp
include/anna/diameter.comm/Engine.hpp
include/anna/diameter/codec/Avp.hpp
include/anna/diameter/codec/Engine.hpp
include/anna/diameter/codec/EngineImpl.hpp
include/anna/diameter/codec/Message.hpp
include/anna/diameter/codec/tme/Engine.hpp
source/app/Application.cpp
source/diameter.comm/Engine.cpp
source/diameter/codec/Avp.cpp
source/diameter/codec/EngineImpl.cpp
source/diameter/codec/Message.cpp
source/diameter/codec/tme/Avp.cpp
source/diameter/codec/tme/Message.cpp

index 3e92f5c..7232973 100644 (file)
@@ -122,7 +122,7 @@ int main(int argc, char **argv) {
   bool processHex = xmlOnly ? false:true;
   Logger::setLevel(debug ? Logger::Debug:Logger::Warning);
   Logger::initialize(execBN.c_str(), new TraceWriter(filetrace.c_str(), 2048000));
-  G_codecEngine = new anna::diameter::codec::Engine();
+  G_codecEngine = new anna::diameter::codec::Engine("MyCodecEngine");
   G_codecMsg = G_codecEngine->createMessage();
   anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate();
 
index f377e91..239095f 100644 (file)
@@ -22,7 +22,7 @@
 
 #define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.tasks.input"
 #define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.tasks.output"
-
+#define DIAMETER_CODEC_ENGINE_NAME_PREFIX "MyCodecEngine"
 
 Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "1.1"), a_communicator(NULL) {
   a_myDiameterEngine = new MyDiameterEngine();
@@ -320,6 +320,7 @@ void Launcher::startDiameterServer(int diameterServerSessions) throw(anna::Runti
   //ServerSocket *createServerSocket(const std::string & addr, int port = Session::DefaultPort, int maxConnections = -1, int category = 1, const std::string & description = "")
   a_diameterLocalServer = (MyLocalServer*)(a_myDiameterEngine->createLocalServer(address, port, diameterServerSessions));
   a_diameterLocalServer->setDescription("Launcher diameter local server");
+  a_diameterLocalServer->setProgrammedAnswersCodecEngine(getCodecEngine());
   int allowedInactivityTime = 90000; // ms
 
   if(cl.exists("allowedInactivityTime")) allowedInactivityTime = cl.getIntegerValue("allowedInactivityTime");
@@ -395,7 +396,7 @@ throw(anna::RuntimeException) {
   }
 
   // Stack:
-  anna::diameter::codec::Engine *codecEngine = new anna::diameter::codec::Engine();
+  a_codecEngine = new anna::diameter::codec::Engine(DIAMETER_CODEC_ENGINE_NAME_PREFIX);
   anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate();
   anna::diameter::stack::Dictionary * d = stackEngine.createDictionary(0 /* stack id; its value don't mind, is not used (ADL is monostack) */);
   // Analyze comma-separated list:
@@ -416,8 +417,8 @@ throw(anna::RuntimeException) {
     }
   }
 
-  codecEngine->setDictionary(d);
-  LOGDEBUG(anna::Logger::debug(codecEngine->asString(), ANNA_FILE_LOCATION));
+  getCodecEngine()->setDictionary(d);
+  LOGDEBUG(anna::Logger::debug(getCodecEngine()->asString(), ANNA_FILE_LOCATION));
 
   if(lst.size() > 1) {
     std::string all_in_one = "./dictionary-all-in-one.xml";
@@ -563,8 +564,8 @@ throw(anna::RuntimeException) {
   // Integration (validation 'Complete' for receiving messages) and debugging (validation also before encoding: 'Always').
   // If missing 'integrationAndDebugging', default behaviour at engine is: mode 'AfterDecoding', depth 'FirstError':
   if(cl.exists("integrationAndDebugging")) {
-    codecEngine->setValidationMode(anna::diameter::codec::Engine::ValidationMode::Always);
-    codecEngine->setValidationDepth(anna::diameter::codec::Engine::ValidationDepth::Complete);
+    getCodecEngine()->setValidationMode(anna::diameter::codec::Engine::ValidationMode::Always);
+    getCodecEngine()->setValidationDepth(anna::diameter::codec::Engine::ValidationDepth::Complete);
   }
 
   // Fix mode
@@ -576,10 +577,10 @@ throw(anna::RuntimeException) {
     else if (fixMode == "Always") fm = anna::diameter::codec::Engine::FixMode::Always;
     else if (fixMode == "Never") fm = anna::diameter::codec::Engine::FixMode::Never;
     else LOGINFORMATION(anna::Logger::information("Unreconized command-line fix mode. Assumed default 'BeforeEncoding'", ANNA_FILE_LOCATION));
-    codecEngine->setFixMode(fm);
+    getCodecEngine()->setFixMode(fm);
   }
 
-  codecEngine->ignoreFlagsOnValidation(cl.exists("ignoreFlags"));
+  getCodecEngine()->ignoreFlagsOnValidation(cl.exists("ignoreFlags"));
 
   // Diameter Server:
   if(cl.exists("diameterServer"))
@@ -636,6 +637,7 @@ throw(anna::RuntimeException) {
       a_entity = (MyDiameterEntity*)(a_myDiameterEngine->createEntity(servers, "Launcher diameter entity"));
       a_entity->setClassCodeTimeout(anna::diameter::comm::ClassCode::Bind, ceaTimeout);
       a_entity->setClassCodeTimeout(anna::diameter::comm::ClassCode::ApplicationMessage, answersTimeout);
+      a_entity->setProgrammedAnswersCodecEngine(getCodecEngine());
       a_entity->bind();
     }
   }
@@ -1554,8 +1556,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     } else if (param1 == "dump") {
       localServer->getReactingAnswers()->dump();
     } else {
-      anna::diameter::codec::Engine *engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION);
-      anna::diameter::codec::Message *message = engine->createMessage(param1);
+      anna::diameter::codec::Message *message = getCodecEngine()->createMessage(param1);
       LOGDEBUG
       (
         anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION);
@@ -1587,8 +1588,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     } else if (param1 == "dump") {
       entity->getReactingAnswers()->dump();
     } else {
-      anna::diameter::codec::Engine *engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION);
-      anna::diameter::codec::Message *message = engine->createMessage(param1);
+      anna::diameter::codec::Message *message = getCodecEngine()->createMessage(param1);
       LOGDEBUG
       (
         anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION);
@@ -1724,7 +1724,7 @@ throw() {
   result->createAttribute("StartTime", a_start_time.asString());
   result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
   // Diameter:
-  (anna::functions::component <anna::diameter::codec::Engine> (ANNA_FILE_LOCATION))->asXML(result);
+  getCodecEngine()->asXML(result);
   // OAM:
   anna::diameter::comm::OamModule::instantiate().asXML(result);
   anna::diameter::comm::ApplicationMessageOamModule::instantiate().asXML(result);
index d550ceb..25f20c8 100644 (file)
@@ -42,6 +42,7 @@ class Launcher : public anna::comm::Application {
   MyCommunicator *a_communicator;
   MyDiameterEngine *a_myDiameterEngine;
   MyDiameterEntity *a_entity;
+  anna::diameter::codec::Engine *a_codecEngine;
   std::string a_logFile, a_burstLogFile;
   std::ofstream a_burstLogStream;
   bool a_splitLog, a_detailedLog, a_dumpLog;
@@ -75,6 +76,7 @@ class Launcher : public anna::comm::Application {
 public:
   Launcher();
 
+  anna::diameter::codec::Engine *getCodecEngine() const throw() { return a_codecEngine; }
   MyCommunicator *getCommunicator() throw() { return a_communicator; }
   MyDiameterEngine* getMyDiameterEngine() const throw() { return (a_myDiameterEngine); }
   void baseProtocolSetupAsClient(void) throw(anna::RuntimeException);
index 8491fd9..4606edc 100644 (file)
@@ -20,8 +20,7 @@
 class MyDiameterEngine : public anna::diameter::comm::Engine {
 public:
 
-  static const char* getClassName() throw() { return "launcher::MyDiameterEngine"; }
-  MyDiameterEngine() {;}
+  MyDiameterEngine(const char *className = "MyDiameterEngine") : Engine(className) {;}
 
 // Default implementation is enough
 //   void readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw() {;} // DPA is not replied
index fe23cfa..654a640 100644 (file)
 // Process
 #include "ProgrammedAnswers.hpp"
 
+namespace anna {
+  namespace diameter {
+    namespace codec {
+      class Engine;
+    }
+  }
+}
 
 class MyDiameterEntity : public anna::diameter::comm::Entity {
 
@@ -29,6 +36,7 @@ class MyDiameterEntity : public anna::diameter::comm::Entity {
 public:
 
   ProgrammedAnswers a_reactingAnswers;
+  void setProgrammedAnswersCodecEngine(anna::diameter::codec::Engine *codecEngine) throw() { a_reactingAnswers.setCodecEngine(codecEngine); }
   ProgrammedAnswers *getReactingAnswers() throw() { return (ProgrammedAnswers *)&a_reactingAnswers; }
 };
 
index 7db0d87..9346c5d 100644 (file)
@@ -90,7 +90,7 @@ throw(anna::RuntimeException) {
     } else return; // nothing done
   }
 
-  anna::diameter::codec::Engine *codecEngine = (anna::functions::component <anna::diameter::codec::Engine> (ANNA_FILE_LOCATION));
+  anna::diameter::codec::Engine *codecEngine = my_app.getCodecEngine();
   anna::diameter::codec::Engine::ValidationMode::_v backupVM = codecEngine->getValidationMode();
 
   if(!analysisOK)
index 65b74e2..a7c139a 100644 (file)
 // Process
 #include "ProgrammedAnswers.hpp"
 
+namespace anna {
+  namespace diameter {
+    namespace codec {
+      class Engine;
+    }
+  }
+}
 
 class MyLocalServer : public anna::diameter::comm::LocalServer {
 
@@ -26,6 +33,7 @@ class MyLocalServer : public anna::diameter::comm::LocalServer {
 public:
 
   ProgrammedAnswers a_reactingAnswers;
+  void setProgrammedAnswersCodecEngine(anna::diameter::codec::Engine *codecEngine) throw() { a_reactingAnswers.setCodecEngine(codecEngine); }
   ProgrammedAnswers *getReactingAnswers() throw() { return (ProgrammedAnswers *)&a_reactingAnswers; }
 };
 
index 5f6dd4f..f617282 100644 (file)
@@ -19,8 +19,7 @@
 
 void ProgrammedAnswers::clear () throw() {
   for (reacting_answers_const_iterator it = a_deques.begin(); it != a_deques.end(); it++) {
-       anna::diameter::codec::Engine *engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION);
-       engine->releaseMessage(*(it->second->begin()));
+       a_codecEngine->releaseMessage(*(it->second->begin()));
        delete(it->second);
   }
   a_deques.clear();
@@ -70,12 +69,11 @@ void ProgrammedAnswers::nextMessage(int code) throw() { //pops the deque and rel
   reacting_answers_const_iterator it = a_deques.find(code);
   if (it != a_deques.end()) {
        if (!it->second->empty()) {
-         anna::diameter::codec::Engine *engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION);
          if (a_rotate) {
                addMessage(code, *(it->second->begin()));
          }
          else {
-               engine->releaseMessage(*(it->second->begin()));
+               a_codecEngine->releaseMessage(*(it->second->begin()));
          }
          it->second->pop_front();
        }
@@ -89,6 +87,8 @@ std::string ProgrammedAnswers::asString(const char *queueName) const throw() {
   aux += "', Rotation ";
   aux += a_rotate ? "enabled":"disabled";
   result += anna::functions::highlightJustify(aux);
+  result += "Codec engine: ";
+  result += a_codecEngine->getClassName();
   if(a_deques.size() != 0) {
        for(reacting_answers_const_iterator it = a_deques.begin(); it != a_deques.end(); it++) {
          if (it->second->size() != 0) {
index 00b9d4d..a7cd897 100644 (file)
@@ -18,6 +18,7 @@ namespace anna {
   namespace diameter {
     namespace codec {
       class Message;
+      class Engine;
     }
   }
 }
@@ -34,11 +35,13 @@ typedef std::map < int /* message code */, codec_messages_deque* >::const_iterat
 
   reacting_answers_container a_deques;
   bool a_rotate;
+  anna::diameter::codec::Engine *a_codecEngine;
 
   public:
     ProgrammedAnswers() { a_rotate = false; }
     ~ProgrammedAnswers() { clear(); }
 
+    void setCodecEngine(anna::diameter::codec::Engine *codecEngine) throw() { a_codecEngine = codecEngine; }
     bool rotate() const throw() { return a_rotate; }
     void rotate(bool r) throw() { a_rotate = r; }
 
index 9998558..c078917 100644 (file)
@@ -28,36 +28,19 @@ struct functions : public anna::functions {
   */
   static Application& getApp() throw(RuntimeException);
 
-  /**
-     Patron para obtener facilmente la instancia de un determinado componente.
-     Estos dos parametros suelen ser sustituidos por la macro C <b>FILE_LOCATION</b>.
-
-     \param fromFile Fichero desde el que se invoca a este metodo
-     \param fromLine Numero de linea desde el que se invoca a este metodo.
-
-     \return La instancia del componente de la clase recibida como parametro.
-     \warning La clase T de implementar un metodo de la forma:
-     \code
-         static const char* getClassName () throw ();
-     \endcode
-     \see Component
-  */
-  template <typename T> static T* component(const char* fromFile, const int fromLine)
-  throw(anna::RuntimeException) {
-    return component<T> (T::getClassName(), fromFile, fromLine);
-  }
 
   /**
-     Patron para obtener facilmente la instancia de un determinado componente.
-     Estos dos parametros suelen ser sustituidos por la macro C <b>FILE_LOCATION</b>.
-     \param className Nombre del componente buscado.
-     \param fromFile Fichero desde el que se invoca a este metodo
-     \param fromLine Numero de linea desde el que se invoca a este metodo.
+     Pattern to obtain a multi named application component instance easily.
+     Parameters are usually replaced by the macro C <b>FILE_LOCATION</b>.
+
+     \param className Application component class name
+     \param fromFile File which called the method
+     \param fromLine Line number within the file from where the method is called.
 
-     \return La instancia del componente de la clase recibida como parametro.
+     \return Application component instance for the class provided at the pattern
      \see Component
   */
-  template <typename T> static T* component(const char* className, const char* fromFile, const int fromLine)
+  template <typename T> static T* componentByName(const char *className, const char* fromFile, const int fromLine)
   throw(anna::RuntimeException) {
     T* result = static_cast <T*>(functions::getApp().find(className));
 
@@ -71,6 +54,25 @@ struct functions : public anna::functions {
   }
 };
 
+  /**
+     Pattern to obtain a single named application component instance easily.
+     Parameters are usually replaced by the macro C <b>FILE_LOCATION</b>.
+
+     \param fromFile File which called the method
+     \param fromLine Line number within the file from where the method is called.
+
+     \return Application component instance for the class provided at the pattern
+     \warning T class must implement a method in the form:
+     \code
+         static const char* getClassName () throw ();
+     \endcode
+     \see Component
+  */
+  template <typename T> static T* component(const char* fromFile, const int fromLine)
+  throw(RuntimeException) {
+    return functions::componentByName<T> (T::getClassName(), fromFile, fromLine);
+  }
+
 }
 }
 
index b2a24ab..0ceb358 100644 (file)
@@ -620,34 +620,50 @@ struct functions {
   //////////////////////////////////////////////////////////////////////////////////////////////////
 
   /**
-     Pattern to obtain a component instance easily.
+     Pattern to obtain a multi named component instance easily.
      Parameters are usually replaced by the macro C <b>FILE_LOCATION</b>.
 
+     \param className Component class name
      \param fromFile File which called the method
      \param fromLine Line number within the file from where the method is called.
 
      \return Component instance for the class provided at the pattern
-     \warning The class T must define:
-     \code
-         static const char* getClassName () throw ();
-     \endcode
      \see Component
   */
-  template <typename T> static T* component(const char* fromFile, const int fromLine)
+  template <typename T> static T* componentByName(const char *className, const char* fromFile, const int fromLine)
   throw(RuntimeException) {
     ComponentManager &cm = ComponentManager::instantiate();
-    const char *className = T::getClassName();
     T* result = static_cast <T*>(cm.find(className));
 
     if(result == NULL) {
       std::string msg(className);
-      msg += " | Componente no registrado";
+      msg += " | Unregistered component";
       throw RuntimeException(msg, fromFile, fromLine);
     }
 
     return result;
   }
 
+  /**
+     Pattern to obtain a single named component instance easily.
+     Parameters are usually replaced by the macro C <b>FILE_LOCATION</b>.
+
+     \param fromFile File which called the method
+     \param fromLine Line number within the file from where the method is called.
+
+     \return Component instance for the class provided at the pattern
+     \warning T class must implement a method in the form:
+     \code
+         static const char* getClassName () throw ();
+     \endcode
+     \see Component
+  */
+  template <typename T> static T* component(const char* fromFile, const int fromLine)
+  throw(RuntimeException) {
+    return functions::componentByName<T> (T::getClassName(), fromFile, fromLine);
+  }
+
+
   /**
    * Gets exclusive hash for string provided on integer range
    *
index 8e05069..1e1cb7c 100644 (file)
@@ -28,12 +28,6 @@ class Configuration {
 public:
   static const char* defaultSection;
 
-  /**
-     Constructor.
-     \param className Nombre de la clase usado para registrar en la lista de componentes.
-  */
-  Configuration(const char* className) {;}
-
   /**
      Constructor.
   */
index b152492..b9ad79e 100644 (file)
@@ -56,7 +56,7 @@ public:
      \return La cadena por la que podemos buscar el componente.
      \see Application::find
   */
-  static const char* getClassName() { return "dbms::mysql::Database"; }
+  static const char* getClassName() { return "anna::dbms::mysql::Database"; }
 
 private:
   char* a_host;
index 1c1a12e..d1c276e 100644 (file)
@@ -94,12 +94,6 @@ class LocalServer;
 class Engine : public anna::app::Component {
 public:
 
-  /**
-     Logical name for this anna::app::Component.
-     \return Logical name for this anna::app::Component.
-  */
-  static const char* getClassName() throw() { return "anna::diameter::comm::Engine"; }
-
   /**
      Diameter application node realm name (used to be the site domain name).
 
@@ -619,8 +613,9 @@ public:
 protected:
   /**
      Constructor.
+     @param className Component class name
   */
-  Engine();
+  Engine(const char *className);
 
 
   // INTERNAL CREATORS AND CLOSE METHODS
index 40a75dd..6deb5d7 100644 (file)
@@ -383,6 +383,10 @@ public:
   Avp(AvpId id);
 
 
+  /** Sets the codec engine */
+  void setEngine(Engine *engine) throw() { a_engine = engine; }
+
+
   // Length references
   static const int HeaderLengthVactive;
   static const int HeaderLengthVinactive;
index 4485319..1f106c6 100644 (file)
@@ -43,9 +43,11 @@ class Engine : public EngineImpl {
 
 public:
 
-  static const char* getClassName() throw() { return "anna::diameter::codec::Engine"; }
-
-  Engine() : EngineImpl(getClassName()) {;}
+  /**
+     Constructor
+     @param className Logical name for the class.
+  */
+  Engine(const char *className) : EngineImpl(className) {;}
 
   void releaseAvp(Avp* avp) throw() {
     if(avp == NULL) return;
index e282724..753d15e 100644 (file)
@@ -114,8 +114,7 @@ class Avp;
  *
  *     class MyEngine : public EngineImpl {
  *     public:
- *        Engine (getClassName()) {;}
- *        static const char* getClassName() throw() { return "<full-naming path>::MyEngine"; }
+ *        MyEngine (const char *className = "MyEngine") : Engine(className) {;}
  *
  *     private:
  *        anna::Recycler<MyAvp> a_avps;
index fd44c42..133c4af 100644 (file)
@@ -173,6 +173,10 @@ public:
   Message(CommandId id);
 
 
+  /** Sets the codec engine */
+  void setEngine(Engine *engine) throw() { a_engine = engine; }
+
+
   // Length references
   static const int HeaderLength;
 
index f726c39..92fbc31 100644 (file)
@@ -45,9 +45,11 @@ class Engine : public EngineImpl {
 
 public:
 
-  static const char* getClassName() throw() { return "anna::diameter::codec::tme::Engine"; }
-
-  Engine() : EngineImpl(getClassName()) {;}
+  /**
+     Constructor
+     @param className Logical name for the class.
+  */
+  Engine(const char *className = "anna::diameter::codec::tme::Engine") : EngineImpl(className) {;}
 
   void releaseAvp(anna::diameter::codec::Avp* avp) throw() {
     if(avp == NULL) return;
index 003f7ed..d4a9570 100644 (file)
@@ -82,7 +82,6 @@ app::Application::Application(const char* shortName, const char* title, const ch
 app::Component* app::Application::find(const char* className)
 throw() {
   Component* component;
-
   for(iterator ii = begin(), maxii = end(); ii != maxii; ii ++) {
     component = Application::component(ii);
 
index fa13a37..53de6ac 100644 (file)
@@ -37,8 +37,8 @@ using namespace std;
 using namespace anna::diameter::comm;
 
 
-Engine::Engine() :
-  anna::app::Component(getClassName()),
+Engine::Engine(const char *className) :
+  anna::app::Component(className),
   a_autoBind(true),
   a_availableForEntities(false),
   a_availableForLocalServers(false),
index 26df741..bb65e38 100644 (file)
@@ -81,7 +81,10 @@ Avp::~Avp() {
 //------------------------------------------------------------- Avp::getEngine()
 //------------------------------------------------------------------------------
 Engine * Avp::getEngine() const throw(anna::RuntimeException) {
-  return a_engine ? a_engine : (a_engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION));
+  if(!a_engine)
+    throw anna::RuntimeException("Invalid codec engine reference (NULL)", ANNA_FILE_LOCATION);
+
+  return a_engine;
 }
 
 
@@ -89,7 +92,6 @@ Engine * Avp::getEngine() const throw(anna::RuntimeException) {
 //------------------------------------------------------------ Avp::initialize()
 //------------------------------------------------------------------------------
 void Avp::initialize() throw() {
-  a_engine = NULL;
   a_id = helpers::AVPID__AVP; // (0,0)
   a_flags = 0x00;
   a_insertionPositionForChilds = 0;
index d9a6146..5d24eb9 100644 (file)
@@ -144,6 +144,9 @@ Avp* EngineImpl::createAvp(const AvpId *id) throw(anna::RuntimeException) {
   if((result = allocateAvp()) == NULL)
     throw anna::RuntimeException("diameter::codec::EngineImpl::allocateAvp returns NULL", ANNA_FILE_LOCATION);
 
+  // Sets engine
+  result->setEngine((Engine*)this);
+
   //result->clear(); better clear this at releaseAvp(), see class-help implementation example
   if(id) result->setId(*id);
 
@@ -161,6 +164,9 @@ Message* EngineImpl::createMessage(const CommandId *id) throw(anna::RuntimeExcep
   if((result = allocateMessage()) == NULL)
     throw anna::RuntimeException("diameter::codec::EngineImpl::allocateMessage returns NULL", ANNA_FILE_LOCATION);
 
+  // Sets engine
+  result->setEngine((Engine*)this);
+
   //result->clear(); better clear this at releaseMessage(), see class-help implementation example
   if(id) result->setId(*id);
 
index 5f21bb2..51a5218 100644 (file)
@@ -82,7 +82,11 @@ Message::~Message() {
 //--------------------------------------------------------- Message::getEngine()
 //------------------------------------------------------------------------------
 Engine * Message::getEngine() const throw(anna::RuntimeException) {
-  return a_engine ? a_engine : (a_engine = anna::functions::component <Engine> (ANNA_FILE_LOCATION));
+  if(!a_engine)
+    throw anna::RuntimeException("Invalid codec engine reference (NULL)", ANNA_FILE_LOCATION);
+
+  return a_engine;
+
 }
 
 
@@ -90,7 +94,6 @@ Engine * Message::getEngine() const throw(anna::RuntimeException) {
 //-------------------------------------------------------- Message::initialize()
 //------------------------------------------------------------------------------
 void Message::initialize() throw() {
-  a_engine = NULL;
   a_version = 1;
   a_id = CommandId(0, false);
   a_flags = 0x00;
index a503516..f105670 100644 (file)
@@ -50,7 +50,10 @@ Avp::~Avp() {
 //------------------------------------------------------------- Avp::getEngine()
 //------------------------------------------------------------------------------
 anna::diameter::codec::Engine * Avp::getEngine() const throw(anna::RuntimeException) {
-  return a_engine ? a_engine : (a_engine = (anna::diameter::codec::Engine *)anna::functions::component <Engine> (ANNA_FILE_LOCATION));
+  if(!a_engine)
+    throw anna::RuntimeException("Invalid codec engine reference (NULL)", ANNA_FILE_LOCATION);
+
+  return a_engine;
 }
 
 
index e704d4f..190a281 100644 (file)
@@ -19,7 +19,10 @@ using namespace anna::diameter::codec::tme;
 //--------------------------------------------------------- Message::getEngine()
 //------------------------------------------------------------------------------
 anna::diameter::codec::Engine * Message::getEngine() const throw(anna::RuntimeException) {
-  return a_engine ? a_engine : (a_engine = (anna::diameter::codec::Engine*)anna::functions::component <Engine> (ANNA_FILE_LOCATION));
+  if(!a_engine)
+    throw anna::RuntimeException("Invalid codec engine reference (NULL)", ANNA_FILE_LOCATION);
+
+  return a_engine;
 }