Remove dynamic exceptions
[anna.git] / include / anna / diameter / codec / Avp.hpp
index bdf2227..331551b 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not Nothingness Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// http://redmine.teslayout.com/projects/anna-suite
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     *  Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: eduardo.ramos.testillano@gmail.com
-//          cisco.tierra@gmail.com
+// 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_Avp_hpp
@@ -42,6 +14,7 @@
 #include <anna/config/defines.hpp>
 #include <anna/diameter/defines.hpp>
 #include <anna/diameter/codec/basetypes/basetypes.hpp>
+#include <anna/diameter/codec/functions.hpp>
 #include <anna/diameter/stack/Avp.hpp>
 
 #include <anna/core/RuntimeException.hpp>
@@ -198,42 +171,42 @@ class Avp {
   //  of your class.
 
   // Common (also for Message class)
-  static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) throw();
-  static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) throw() {
+  static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) ;
+  static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) {
     return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
   }
-  static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
-  static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
-  static void fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) throw();
-  static bool validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const std::string & parentDescription, Message *answer) throw(anna::RuntimeException); // validates mandatory/fixed and cardinality
-  static const Avp* getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) throw(anna::RuntimeException);
-  static int countAvp(const avp_container &avps, AvpId id) throw();
-  static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
-  static int countChilds(const avp_container &avps) throw();
-  static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) throw() {
+  static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) ;
+  static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) ;
+  static void fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) ;
+  static bool validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false); // validates mandatory/fixed and cardinality
+  static const Avp* getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) noexcept(false);
+  static int countAvp(const avp_container &avps, AvpId id) ;
+  static const Avp* firstAvp(const avp_container &avps, AvpId id) ;
+  static int countChilds(const avp_container &avps) ;
+  static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) {
     if(!avp) return -1;
 
     avps[insertionPositionForChilds++] = avp;
     return insertionPositionForChilds;
   }
-  static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) throw();
-  const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
-  const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
+  static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) ;
+  const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false);
+  const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false);
 
   // Own
-  avp_iterator avp_begin() throw() { return a_avps.begin(); }
-  avp_iterator avp_end() throw() { return a_avps.end(); }
-  static Avp* avp(avp_iterator ii) throw() { return ii->second; }
-  const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
-  const_avp_iterator avp_end() const throw() { return a_avps.end(); }
-  static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
+  avp_iterator avp_begin() { return a_avps.begin(); }
+  avp_iterator avp_end() { return a_avps.end(); }
+  static Avp* avp(avp_iterator ii) { return ii->second; }
+  const_avp_iterator avp_begin() const { return a_avps.begin(); }
+  const_avp_iterator avp_end() const { return a_avps.end(); }
+  static const Avp* avp(const_avp_iterator ii) { return ii->second; }
 
   // Internal
-  bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
-  int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
-  bool hasChildren() throw() { return a_avps.size() != 0; }
+  bool flagsOK() const ; // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
+  int addChild(Avp *avp) noexcept(false) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
+  bool hasChildren() { return a_avps.size() != 0; }
 
-  static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) throw() { return true; }
+  static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) { return true; }
 
 
   /**
@@ -242,17 +215,17 @@ class Avp {
      This is useful to give flexibility to the application during message construction before encoding or representing the data.
      Is not recommended to fix a recently decoded message because possible validation problems will be hidden.
   */
-  void fix() throw();
+  void fix() ;
 
   /**
      Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
 
-     @param parentDescription Parent description. Internally used for alarms and tracing
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer could be modified with any validation problem during requests validation
 
      @return Boolean indicating validation result
   */
-  bool valid(const std::string & parentDescription, Message *answer) const throw(anna::RuntimeException);
+  bool valid(const anna::diameter::codec::parent_t & parent, Message *answer) const noexcept(false);
 
   /**
      Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
@@ -260,9 +233,10 @@ class Avp {
      depending on validation depth (codec::Engine::ValidationDepth).
 
      @param db Buffer data block processed
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer built for request decoding/validation
   */
-  void decode(const anna::DataBlock &db, Message *answer) throw(anna::RuntimeException);
+  void decode(const anna::DataBlock &db, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false);
 
 
   /////////////////////////////////////////////
@@ -274,7 +248,7 @@ class Avp {
   * Default implementation supports all anna::diameter formats (including derived ones).
   * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
   */
-  virtual void initializeByFormat() throw() {};
+  virtual void initializeByFormat() {};
 
   /**
   * Gets avp data-part length.
@@ -285,7 +259,7 @@ class Avp {
   *
   * @return Avp data-part size.
   */
-  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw() { return 0; };
+  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const { return 0; };
 
   /**
      Gets data or hexadecimal data depending on avp format, for xml creating
@@ -296,7 +270,7 @@ class Avp {
      \param stackFormat Stack avp format in which data extraction is based.
      \return xml data representation
   */
-  virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw() { return ""; };
+  virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const { return ""; };
 
   /**
      Interpret xml data in order to dump over the class content.
@@ -307,7 +281,7 @@ class Avp {
      \param hexData Avp hex-data attribute
      \param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
+  virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) noexcept(false) {};
 
 
   /**
@@ -318,7 +292,7 @@ class Avp {
      @param dataPart Data-part begin pointer
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException) {};
+  virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const noexcept(false) {};
 
 
   /**
@@ -330,7 +304,7 @@ class Avp {
      @param size Avp data part size
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
+  virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) noexcept(false) {};
 
   /**
      Reserves memory for data part depending on avp format for the identifier provided.
@@ -339,12 +313,12 @@ class Avp {
 
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw() {};
+  virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) {};
 
   /**
   * Clears Avp data-part format containers.
   */
-  virtual void clearByFormat() throw() {};
+  virtual void clearByFormat() {};
 
 
 
@@ -354,17 +328,17 @@ protected:
   mutable Engine *a_engine;
 
   /** Codec Engine getter: avoids have to create base engine when using its child */
-  virtual Engine * getEngine() const throw(anna::RuntimeException);
+  virtual Engine * getEngine() const noexcept(false);
 
   /**
   * Initializes Avp class information.
   */
-  void initialize() throw();
+  void initialize() ;
 
   /**
   * Assert format regarding dictionary
   */
-  void assertFormat(const std::string &name) const throw(anna::RuntimeException);
+  void assertFormat(const std::string &name) const noexcept(false);
 
   /**
   * Gets avp total length based on internal data part and header configuration.
@@ -372,7 +346,7 @@ protected:
   * The only format which always have total length equal to sum of all its parts is Grouped,
   * because of the 4-multiple nature of its data part length.
   */
-  U24 getLength() const throw();
+  U24 getLength() const ;
 
   /**
      Gets data or hexadecimal data depending on avp format, for xml creating
@@ -381,23 +355,7 @@ protected:
      \param stackFormat Stack avp format in which data extraction is based.
      \return xml data representation
   */
-  std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
-
-  /**
-     Interpret xml data in order to dump over the class content.
-
-     \param avpNode Avp root node
-  */
-  void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
-
-
-  /**
-     Encodes buffer with the class content.
-
-  * @param buffer Raw data to be encoded
-  * @param size Size of raw data to be encoded
-  */
-  void code(char* buffer, int &size) const throw(anna::RuntimeException);
+  std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const ;
 
 
   /**
@@ -405,23 +363,45 @@ protected:
 
      @param buffer Avp data part start pointer
      @param size Avp data part size
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer built for request decoding/validation
   */
-  void decodeDataPart(const char * buffer, int size, Message *answer) throw(anna::RuntimeException);
+  void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false);
 
 
 public:
 
   /**
   * Default constructor
+  * @param engine Codec engine used
   */
-  Avp();
+  Avp(Engine *engine = NULL);
 
   /**
   * Identified constructor
   * @param id Avp identifier as pair (code,vendor-id).
+  * @param engine Codec engine used
+  */
+  Avp(AvpId id, Engine *engine = NULL);
+
+
+  /**
+  * Sets the codec engine
+  *
+  * 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 avp and then you could reuse the same object with
+  * different configurations (execution contexts).
+  *
+  * 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.
   */
-  Avp(AvpId id);
+  void setEngine(Engine *engine) ;
 
 
   // Length references
@@ -445,7 +425,7 @@ public:
   /**
   * Destructor
   */
-  ~Avp();
+  virtual ~Avp();
 
 
   // setters
@@ -454,7 +434,7 @@ public:
   * Clears and initializes Avp class information.
   * Application should clear auxiliary avp objects before setting data in a new context.
   */
-  void clear() throw(anna::RuntimeException);
+  void clear() noexcept(false);
 
 
   /**
@@ -465,12 +445,12 @@ public:
 
      @param id Avp identifier as pair (code,vendor-id).
   */
-  void setId(AvpId id) throw(anna::RuntimeException);
+  void setId(AvpId id) noexcept(false);
 
   /**
      Same as #setId but providing dictionary logical name for Avp searched
   */
-  void setId(const char *name) throw(anna::RuntimeException);
+  void setId(const char *name) noexcept(false);
 
   /**
      Sets/unsets M bit activation.
@@ -483,7 +463,7 @@ public:
 
      @param activate Activates/deactivates the bit. True by default.
   */
-  void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
+  void setMandatoryBit(bool activate = true) { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
 
   /**
      Sets/unsets P bit activation.
@@ -492,69 +472,72 @@ public:
 
      @param activate Activates/deactivates the bit. True by default.
   */
-  void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
+  void setEncryptionBit(bool activate = true) { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
 
 
   /**
      Adds an avp child providing its identifier and reserve internal memory it.
-     An exception is launched is the Avp is not a grouped avp.
+     An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
 
      @param id Avp identifier as pair (code,vendor-id).
 
      @return Pointer to the new created avp.
   */
-  Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
+  Avp * addAvp(AvpId id) noexcept(false) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
 
 
   /**
      Same as #addAvp but providing dictionary logical name for Avp searched
   */
-  Avp * addAvp(const char *name) throw(anna::RuntimeException);
-
+  Avp * addAvp(const char *name) noexcept(false);
 
   /**
      Adds an avp child providing a persistent pointer (must be maintained by application).
-     An exception is launched is the Avp is not a grouped avp.
+     An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
+     It is not allowed to add an avp with no codec engine configured, neither if the engine
+     is not the same.
 
      @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
+     Also NULL returned for bad engine configuration.
 
      @return Pointer to the added avp (again).
   */
-  Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
+  Avp * addAvp(Avp * avp) noexcept(false);
+
 
   // Data part access
   /** Access content for OctetString Avp in order to set data part */
-  OctetString *        getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
+  OctetString *        getOctetString() noexcept(false) { assertFormat("OctetString"); return a_OctetString; }
   /** Access content for Integer32 Avp in order to set data part */
-  Integer32 *          getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
+  Integer32 *          getInteger32() noexcept(false) { assertFormat("Integer32"); return a_Integer32; }
   /** Access content for Integer64 Avp in order to set data part */
-  Integer64 *          getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
+  Integer64 *          getInteger64() noexcept(false) { assertFormat("Integer64"); return a_Integer64; }
   /** Access content for Unsigned32 Avp in order to set data part */
-  Unsigned32 *         getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
+  Unsigned32 *         getUnsigned32() noexcept(false) { assertFormat("Unsigned32"); return a_Unsigned32; }
   /** Access content for Unsigned64 Avp in order to set data part */
-  Unsigned64 *         getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
+  Unsigned64 *         getUnsigned64() noexcept(false) { assertFormat("Unsigned64"); return a_Unsigned64; }
   /** Access content for Float32 Avp in order to set data part */
-  Float32 *            getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
+  Float32 *            getFloat32() noexcept(false) { assertFormat("Float32"); return a_Float32; }
   /** Access content for Float64 Avp in order to set data part */
-  Float64 *            getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
+  Float64 *            getFloat64() noexcept(false) { assertFormat("Float64"); return a_Float64; }
   /** Access content for Address Avp in order to set data part */
-  Address *            getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
+  Address *            getAddress() noexcept(false) { assertFormat("Address"); return a_Address; }
   /** Access content for Time Avp in order to set data part */
-  Time *               getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
+  Time *               getTime() noexcept(false) { assertFormat("Time"); return a_Time; }
   /** Access content for UTF8String Avp in order to set data part */
-  UTF8String *         getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
+  UTF8String *         getUTF8String() noexcept(false) { assertFormat("UTF8String"); return a_UTF8String; }
   /** Access content for DiameterIdentity Avp in order to set data part */
-  DiameterIdentity *   getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
+  DiameterIdentity *   getDiameterIdentity() noexcept(false) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
   /** Access content for DiameterURI Avp in order to set data part */
-  DiameterURI *        getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
+  DiameterURI *        getDiameterURI() noexcept(false) { assertFormat("DiameterURI"); return a_DiameterURI; }
   /** Access content for Enumerated Avp in order to set data part */
-  Enumerated *         getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
+  Enumerated *         getEnumerated() noexcept(false) { assertFormat("Enumerated"); return a_Enumerated; }
   /** Access content for IPFilterRule Avp in order to set data part */
-  IPFilterRule *       getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
+  IPFilterRule *       getIPFilterRule() noexcept(false) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
   /** Access content for QoSFilterRule Avp in order to set data part */
-  QoSFilterRule *      getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
+  QoSFilterRule *      getQoSFilterRule() noexcept(false) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
   /** Access content for Unknown Avp in order to set data part */
-  Unknown *            getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
+  Unknown *            getUnknown() noexcept(false) { assertFormat("Unknown"); return a_Unknown; }
 
 
   /**
@@ -566,55 +549,55 @@ public:
 
      @return Returns true if something was removed. False in other cases (including i.e. when this Avp is empty or is not a grouped avp).
   */
-  bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
+  bool removeAvp(AvpId id, int ocurrence = 1) noexcept(false) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
 
 
   /**
      Same as #removeAvp but providing dictionary logical name for Avp searched
   */
-  bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
+  bool removeAvp(const char *name, int ocurrence = 1) noexcept(false);
 
   // getters
 
   /**
      Gets Avp identifier as pair (code, vendor-id).
   */
-  const AvpId & getId() const throw() { return a_id; }
+  const AvpId & getId() const { return a_id; }
 
   /**
      Gets Avp vendor-id.
   */
-  int getVendorId() const throw() { return a_id.second; }
+  int getVendorId() const { return a_id.second; }
 
   /**
      Gets stack avp (dictionary avp reference).
   */
-  const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
+  const anna::diameter::stack::Avp *getStackAvp() const noexcept(false) { return getStackAvp(a_id, getEngine()); }
 
   /** Returns V bit activation state */
-  bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
+  bool vendorBit() const { return ((a_flags & VBitMask) != 0x00); }
 
   /** Returns M bit activation state */
-  bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
+  bool mandatoryBit() const { return ((a_flags & MBitMask) != 0x00); }
 
   /** Returns P bit activation state */
-  bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
+  bool encryptionBit() const { return ((a_flags & PBitMask) != 0x00); }
 
   // Data part access
   /** Access content for OctetString Avp */
-  const OctetString *        getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
+  const OctetString *        getOctetString() const noexcept(false) { assertFormat("OctetString"); return a_OctetString; }
   /** Access content for Integer32 Avp */
-  const Integer32 *          getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
+  const Integer32 *          getInteger32() const noexcept(false) { assertFormat("Integer32"); return a_Integer32; }
   /** Access content for Integer64 Avp */
-  const Integer64 *          getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
+  const Integer64 *          getInteger64() const noexcept(false) { assertFormat("Integer64"); return a_Integer64; }
   /** Access content for Unsigned32 Avp */
-  const Unsigned32 *         getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
+  const Unsigned32 *         getUnsigned32() const noexcept(false) { assertFormat("Unsigned32"); return a_Unsigned32; }
   /** Access content for Unsigned64 Avp */
-  const Unsigned64 *         getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
+  const Unsigned64 *         getUnsigned64() const noexcept(false) { assertFormat("Unsigned64"); return a_Unsigned64; }
   /** Access content for Float32 Avp */
-  const Float32 *            getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
+  const Float32 *            getFloat32() const noexcept(false) { assertFormat("Float32"); return a_Float32; }
   /** Access content for Float64 Avp */
-  const Float64 *            getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
+  const Float64 *            getFloat64() const noexcept(false) { assertFormat("Float64"); return a_Float64; }
 
   /**
      Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
@@ -646,45 +629,76 @@ public:
      If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
      error and must be solved.
   */
-  const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
+  const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const noexcept(false) {
     return _getAvp(id, ocurrence, emode);
   }
 
-  Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
+  Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false) {
     return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
   }
 
   /**
      Same as #getAvp but providing dictionary logical name for Avp searched
   */
-  const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
+  const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const noexcept(false) {
     return _getAvp(name, ocurrence, emode);
   }
 
-  Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
+  Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false) {
     return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
   }
 
 
 
   /** Access content for Address Avp */
-  const Address *            getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
+  const Address *            getAddress() const noexcept(false) { assertFormat("Address"); return a_Address; }
   /** Access content for Time Avp */
-  const Time *               getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
+  const Time *               getTime() const noexcept(false) { assertFormat("Time"); return a_Time; }
   /** Access content for UTF8String Avp */
-  const UTF8String *         getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
+  const UTF8String *         getUTF8String() const noexcept(false) { assertFormat("UTF8String"); return a_UTF8String; }
   /** Access content for DiameterIdentity Avp */
-  const DiameterIdentity *   getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
+  const DiameterIdentity *   getDiameterIdentity() const noexcept(false) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
   /** Access content for DiameterURI Avp */
-  const DiameterURI *        getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
+  const DiameterURI *        getDiameterURI() const noexcept(false) { assertFormat("DiameterURI"); return a_DiameterURI; }
   /** Access content for Enumerated Avp */
-  const Enumerated *         getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
+  const Enumerated *         getEnumerated() const noexcept(false) { assertFormat("Enumerated"); return a_Enumerated; }
   /** Access content for IPFilterRule Avp */
-  const IPFilterRule *       getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
+  const IPFilterRule *       getIPFilterRule() const noexcept(false) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
   /** Access content for QoSFilterRule Avp */
-  const QoSFilterRule *      getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
+  const QoSFilterRule *      getQoSFilterRule() const noexcept(false) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
   /** Access content for Unknown Avp */
-  const Unknown *            getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
+  const Unknown *            getUnknown() const noexcept(false) { assertFormat("Unknown"); return a_Unknown; }
+
+
+  /**
+     Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
+     avp is valid against all odds then validation will go on). In case that validation is enabled (codec::Engine::ValidationMode) an exception will be launched
+     depending on validation depth (codec::Engine::ValidationDepth).
+
+     Useful as serialization procedure with #code
+
+     @param db Buffer data block processed
+  */
+  void decode(const anna::DataBlock &db) noexcept(false);
+
+
+  /**
+     Interpret xml data in order to dump over the class content.
+
+     \param avpNode Avp root node
+  */
+  void fromXML(const anna::xml::Node* avpNode) noexcept(false);
+
+
+  /**
+    Encodes buffer with the class content. This method is internally used to encode diameter messages, but is declared as public, to allow
+    its use as serialization procedure. Then, it's assumed that this Avp is valid (validation shall be applied as part of a whole diameter
+    message but nothing will be verified now).
+
+  * @param buffer Raw data to be encoded (shall be externally allocated)
+  * @param size Size of raw data to be encoded
+  */
+  void code(char* buffer, int &size) const noexcept(false);
 
 
   // Helpers
@@ -694,32 +708,55 @@ public:
      \param parent Parent XML node on which hold this instance information.
      \return XML document with relevant information for this instance.
   */
-  anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+  anna::xml::Node* asXML(anna::xml::Node* parent) const ;
 
   /**
      Class xml string representation
+     @param normalize Optional normalization which sorts attribute names and removes
+     newlines in the xml representation in order to ease regexp matching.
+
      \return XML string representation with relevant information for this instance.
   */
-  std::string asXMLString() const throw();
+  std::string asXMLString(bool normalize = false) const ;
+
+  /**
+     Comparison operator by mean serialization
+
+     @param a1 Instance 1 for Avp class
+     @param a2 Instance 2 for Avp class
+
+     @return Comparison result
+  */
+  friend bool operator == (const Avp & a1, const Avp & a2) { return (a1.asXMLString() == a2.asXMLString()); }
+
+  /**
+     Match a regular expression (string pattern) regarding xml string serialization for this avp.
+     This works same as #Message::isLike
+
+     @param pattern Pattern to match
+
+     \return Returns the match result
+  */
+  bool isLike(const std::string &pattern) const ;
 
   /**
      Counts the number of ocurrences of Avps (first level) with the identifier provided
 
      @param id Avp identifier (pair code + vendor-id).
   */
-  int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
+  int countAvp(AvpId id) const noexcept(false) { assertFormat("Grouped"); return countAvp(a_avps, id); }
 
   /**
      Same as #countAvp but providing dictionary logical name for Avp searched
   */
-  int countAvp(const char *name) const throw(anna::RuntimeException);
+  int countAvp(const char *name) const noexcept(false);
 
   /**
      Counts the number of children within a grouped avp
 
      @param id Avp identifier (pair code + vendor-id).
   */
-  int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
+  int countChilds() const noexcept(false) { assertFormat("Grouped"); return countChilds(a_avps); }
 
   /**
      The 'M' Bit, known as the Mandatory bit, indicates whether support of the AVP is required. If an AVP with the 'M' bit set is received by
@@ -729,10 +766,8 @@ public:
      Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
      Relay and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
      these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
-
-     @param answer Answer built for request decoding/validation
   */
-  virtual void unknownAvpWithMandatoryBit(Message *answer) const throw(anna::RuntimeException);
+  virtual void unknownAvpWithMandatoryBit() const noexcept(false);
 
 
   friend class Message;