Remove dynamic exceptions
[anna.git] / include / anna / diameter / codec / Avp.hpp
index cd6c100..331551b 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not 'N' Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// https://bitbucket.org/testillano/anna
-//
-// 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 Google Inc. 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,8 +14,8 @@
 #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/diameter/helpers/tme/codectypes/codectypes.hpp>
 
 #include <anna/core/RuntimeException.hpp>
 
@@ -70,17 +42,6 @@ namespace anna {
 namespace diameter {
 
 
-namespace helpers {
-namespace tme {
-namespace codectypes {
-class Unsigned16;
-class ISDNNumber;
-class ISDNAddress;
-}
-}
-}
-
-
 namespace stack {
 class Dictionary;
 class Format;
@@ -124,7 +85,6 @@ typedef std::map<find_key, Avp*>::iterator find_iterator;
 
 
 using namespace basetypes;
-using namespace helpers::tme::codectypes;
 
 /**
 * Diameter avp generic container
@@ -201,14 +161,6 @@ class Avp {
   QoSFilterRule *a_QoSFilterRule;
   Unknown *a_Unknown;
 
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  ISDNNumber *a_ISDNNumber;
-  ISDNAddress *a_ISDNAddress;
-  Unsigned16 *a_Unsigned16;
-
-
-
   // Grouped helpers
   find_container a_finds; // fast access for grouped and message first-level avps
 
@@ -219,43 +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
-  void assertFormat(const std::string &name) const throw(anna::RuntimeException);
-  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; }
 
 
   /**
@@ -264,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
@@ -282,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);
 
 
   /////////////////////////////////////////////
@@ -293,80 +245,80 @@ class Avp {
 
   /**
   * Initializes Avp class information.
-  * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+  * 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.
-  * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+  * 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.
   *
   * @param stackFormat Stack avp format in which data extraction is based.
   *
   * @return Avp data-part size.
   */
-  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw();
+  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const { return 0; };
 
   /**
      Gets data or hexadecimal data depending on avp format, for xml creating
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     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.
 
      \param isHex Hexadecimal/Natural data when apply.
      \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();
+  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.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     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.
 
      \param data Avp data attribute
      \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) {};
 
 
   /**
      Encodes buffer with the class content.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     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.
 
      @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) {};
 
 
   /**
      Decodes Avp data part.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     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.
 
      @param buffer Avp data part start pointer
      @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.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     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.
 
      @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() {};
 
 
 
@@ -376,13 +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 noexcept(false);
 
   /**
   * Gets avp total length based on internal data part and header configuration.
@@ -390,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
@@ -399,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 ;
 
 
   /**
@@ -423,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
@@ -463,7 +425,7 @@ public:
   /**
   * Destructor
   */
-  ~Avp();
+  virtual ~Avp();
 
 
   // setters
@@ -472,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);
 
 
   /**
@@ -483,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.
@@ -501,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.
@@ -510,78 +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; }
-
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  /** Access content for ISDNNumber Avp in order to set data part */
-  ISDNNumber *        getISDNNumber() throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
-  /** Access content for ISDNAddress Avp in order to set data part */
-  ISDNAddress *        getISDNAddress() throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
-  /** Access content for Unsigned16 Avp in order to set data part */
-  Unsigned16 *        getUnsigned16() throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
+  Unknown *            getUnknown() noexcept(false) { assertFormat("Unknown"); return a_Unknown; }
 
 
   /**
@@ -593,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:
@@ -673,55 +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; }
 
 
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  /** Access content for ISDNNumber Avp */
-  const ISDNNumber *         getISDNNumber() const throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
-  /** Access content for ISDNAddress Avp */
-  const ISDNAddress *        getISDNAddress() const throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
-  /** Access content for Unsigned16 Avp */
-  const Unsigned16 *        getUnsigned16() const throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
+  /**
+     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
@@ -731,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
@@ -764,12 +764,10 @@ public:
      Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
 
      Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
-     Realy and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
+     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;