X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Fdiameter%2Fcodec%2FAvp.hpp;h=331551bd0c1328c701dba429bece81f30804ef09;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=1e5c529dab88047b4f922f8b81c0268004ec4794;hpb=39033fd99e58e994a5e98c1060dcc79e0d81f9c9;p=anna.git diff --git a/include/anna/diameter/codec/Avp.hpp b/include/anna/diameter/codec/Avp.hpp index 1e5c529..331551b 100644 --- a/include/anna/diameter/codec/Avp.hpp +++ b/include/anna/diameter/codec/Avp.hpp @@ -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 #include #include +#include #include #include @@ -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(_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(_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 @@ -727,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;