Add nlohmann/json parser
[anna.git] / include / anna / diameter / codec / Message.hpp
index 69aecf2..41ebe0a 100644 (file)
@@ -180,16 +180,21 @@ public:
   *
   * Once assigned (here or at constructor), this method SHALL NOT be used anymore.
   * Also, the associated dictionary SHOULD NOT BE CHANGED through the engine,
-  * unless you know what are you doing. If you want to reconfigure the engine,
-  * first #clear the message and then you could reuse the same object with
-  * different configurations (execution contexts).
-  *
+  * unless you know what are you doing.
   * Setting a new different engine with different stack, even same engine where the
   * stack has been dynamically changed, could cause a bad behaviour depending on the
   * changes: in general, if the dictionary grows, nothing bad will happen, but if
   * you remove or modified some elements which were processed with a certain format,
   * will be interpreted as 'unknown' with the new dictionary, and then some problems
   * may occur. If you add elements (vendors, avps, messages) is not a problem.
+  *
+  * IMPORTANT NOTES:
+  * 1) if you want to reuse the message, as a recommendation, you should #clear the
+  * message. In that way, next operation will adjust automatically the needed engine.
+  * 2) if you have dedicated message objects for each interface (application id), then
+  * you could set the corresponding engine on constructor (or setEngine), and forget
+  * about #clear. The needed cleanup will be done automatically from decoding and xml
+  * loading procedures, and initialized engine will be kept along message operations.
   */
   void setEngine(Engine *engine) throw();
 
@@ -218,7 +223,8 @@ public:
   /**
   * Destructor
   */
-  ~Message();
+  virtual ~Message();
+
   // Virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class:
   // This destructor is not virtual, then a pointer to base class (even pointing to a children one) will invoke this destructor, not the derived one.
   // My current solution: virtualizing method 'clear'
@@ -232,9 +238,8 @@ public:
      Sets the command identifier and clear the former content.
 
      @param id Command identifier as pair (code,request-indicator).
-     @param _clear Message will be cleared when updating the command identifier (default behaviour).
   */
-  void setId(CommandId id, bool _clear = true) throw(anna::RuntimeException);
+  void setId(CommandId id) throw(anna::RuntimeException);
 
   /**
      Same as #setId but providing dictionary logical name for Avp searched
@@ -317,7 +322,7 @@ public:
 
     a_engine = request.getEngine(); // we know this will be
 
-    setId(CommandId(request.getId().first, !request.getId().second), false /* don't clear */);
+    setId(CommandId(request.getId().first, !request.getId().second));
     setVersion(request.getVersion());
     setApplicationId(request.getApplicationId());
     setHopByHop(request.getHopByHop()); // The same Hop-by-Hop Identifier in the request is used in the answer (RFC 6733 Section 6.2).
@@ -494,14 +499,21 @@ public:
   * Application must clear auxiliary message objects before adding Avps in a new context if the same object is reused.
   * Application don't need to clear a message object before decode operation (decode invokes #clear before any other task).
   * Any reimplementation must first invoke base class method.
+  *
+  * @param resetEngine Sets to NULL the codec engine (true, default) or respect its current value (false). If you are going
+  * to reuse the message instance it is better to clear all the information (default) to manage different stacks, because if
+  * you don't initialize the engine to NULL, the second use of the message will keep the same engine deduced from the first
+  * decoding/loading operation, which could be wrong if the second message belongs to a different application identifier.
   */
-  virtual void clear() throw(anna::RuntimeException);
+  virtual void clear(bool resetEngine = true) throw(anna::RuntimeException);
 
   /**
      Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
      message is valid against all odds then validation will go on). In case that validation is enabled (codec::Engine::ValidationMode) an exception will be launched
      in a moment which depends on validation depth (codec::Engine::ValidationDepth).
 
+     You could decode multiple times over the same object. A basic cleanup is done respecting the codec engine.
+
      @param db buffer data block processed. Before decoding, the whole message instance will be cleared (no need to invoke #clear before #decode).
      @param ptrAnswer Answer set by application (could be empty or not), who is responsible for its memory reservation,
      and automatically built regarding standard. If message analyzed realizes to be an answer, internal reference becomes
@@ -528,19 +540,32 @@ public:
 
   /**
      Interpret xml data in order to dump over the class content.
+     You could apply this multiple times over the same object. A basic cleanup is done respecting the codec engine.
      \param messageNode Message root node obtained from @functions::xmlFileTo
   */
   void fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeException);
 
   /**
    * Interpret a xml file in order to create a diameter message
+   * You could apply this multiple times over the same object. A basic cleanup is done respecting the codec engine.
    *
    * @see functions::messageXmlDocumentFromXmlFile
    * @see fromXML
    *
    * @param xmlPathFile Complete path file to the xml document which represents the diameter message
    */
-  void loadXML(const std::string &xmlPathFile) throw(anna::RuntimeException);
+  void loadXMLFile(const std::string &xmlPathFile) throw(anna::RuntimeException);
+
+  /**
+   * Interpret a xml string in order to create a diameter message
+   * You could apply this multiple times over the same object. A basic cleanup is done respecting the codec engine.
+   *
+   * @see functions::messageXmlDocumentFromXmlString
+   * @see fromXML
+   *
+   * @param xmlString xml representation of the diameter message
+   */
+  void loadXMLString(const std::string &xmlString) throw(anna::RuntimeException);
 
 
   // getters
@@ -734,13 +759,13 @@ public:
      for example, the pattern '<avp name="Framed-IP-Address" hex-data="0a[A-Fa-f0-9][A-Fa-f0-9]0a0a"/>'
      matchs IP addresses for '10.x.10.10' where x = [0..255].
 
-     Note that string pattern could also be generated via #loadXML and then #asXML, that is to say, you
+     Note that string pattern could also be generated via #loadXMLFile/#loadXMLString and then #asXML, thus, you
      could get patterns through xml files which act as conditional triggers over message. In that case,
      it is not possible to specify regular expressions within xml 'hex-data' fields because parser will fail
      during hexadecimal read. Normally only printable 'data' fields are used for matching issues.
 
      For example, imagine a 'pattern.xml' file like:
-     <message version="1" name="Credit-Control-Request" application-id="16777236" hop-by-hop-id="0" end-by-end-id="0">
+     <message version="1" name="Credit-Control-Request" application-id="16777236" hop-by-hop-id="0" end-to-end-id="0">
         <avp name="Subscription-Id">
            <avp name="Subscription-Id-Type" data="0" alias="END_USER_E164"/>
            <avp name="Subscription-Id-Data" data="616[0-9]{6,6}"/>
@@ -750,7 +775,7 @@ public:
      Then you could do:
 
      anna::diameter::codec::Message patternMessage;
-     patternMessage.loadXML("pattern.xml");
+     patternMessage.loadXMLFile("pattern.xml");
      std::string pattern = patternMessage.getAvp("Subscription-Id")->getAvp("Subscription-Id-Type")->asXMLString();
      // Former is '<avp name="Subscription-Id-Data" data="616[0-9]{6,6}"/>'
      bool match = incomingMessage.isLike(pattern);
@@ -783,3 +808,4 @@ public:
 
 
 #endif
+