X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FAvp.cpp;h=14d5aa701e00f019470308cbc431f899a82bcf98;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=26df7412d200037be9fb3b110b09b46f1ed69cc8;hpb=93366a0bda79e6fd6e7dad6316bfcf8cc82f5731;p=anna.git diff --git a/source/diameter/codec/Avp.cpp b/source/diameter/codec/Avp.cpp index 26df741..14d5aa7 100644 --- a/source/diameter/codec/Avp.cpp +++ b/source/diameter/codec/Avp.cpp @@ -55,20 +55,18 @@ const U8 Avp::PBitMask(0x20); //------------------------------------------------------------------------------ //------------------------------------------------------------------- Avp::Avp() //------------------------------------------------------------------------------ -Avp::Avp() { +Avp::Avp(Engine *engine) : a_engine(engine) { initialize(); } - //------------------------------------------------------------------------------ //------------------------------------------------------------------- Avp::Avp() //------------------------------------------------------------------------------ -Avp::Avp(AvpId id) { +Avp::Avp(AvpId id, Engine *engine) : a_engine(engine) { initialize(); setId(id); } - //------------------------------------------------------------------------------ //------------------------------------------------------------------ Avp::~Avp() //------------------------------------------------------------------------------ @@ -76,20 +74,33 @@ Avp::~Avp() { clear(); } +//------------------------------------------------------------------------------ +//------------------------------------------------------------- Avp::setEngine() +//------------------------------------------------------------------------------ +void Avp::setEngine(Engine *engine) { + if (a_engine && engine != a_engine) { + LOGWARNING(anna::Logger::warning("Ignored: it is not a good practice to change the codec engine once assigned. Clear the avp first to set the engine again.", ANNA_FILE_LOCATION)); + return; + } + + a_engine = engine; +} //------------------------------------------------------------------------------ //------------------------------------------------------------- Avp::getEngine() //------------------------------------------------------------------------------ -Engine * Avp::getEngine() const throw(anna::RuntimeException) { - return a_engine ? a_engine : (a_engine = anna::functions::component (ANNA_FILE_LOCATION)); +Engine * Avp::getEngine() const noexcept(false) { + if(!a_engine) + throw anna::RuntimeException("Invalid codec engine reference (NULL). Use setEngine() to set the corresponding codec engine", ANNA_FILE_LOCATION); + + return a_engine; } //------------------------------------------------------------------------------ //------------------------------------------------------------ Avp::initialize() //------------------------------------------------------------------------------ -void Avp::initialize() throw() { - a_engine = NULL; +void Avp::initialize() { a_id = helpers::AVPID__AVP; // (0,0) a_flags = 0x00; a_insertionPositionForChilds = 0; @@ -121,7 +132,7 @@ void Avp::initialize() throw() { //------------------------------------------------------------------------------ //----------------------------------------------------------------- Avp::clear() //------------------------------------------------------------------------------ -void Avp::clear() throw(anna::RuntimeException) { +void Avp::clear() noexcept(false) { delete a_OctetString; delete a_Integer32; delete a_Integer64; @@ -156,7 +167,7 @@ void Avp::clear() throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //-------------------------------------------------------------- Avp::avp_find() //------------------------------------------------------------------------------ -avp_iterator Avp::avp_find(avp_container &avps, AvpId id, unsigned int position) throw() { +avp_iterator Avp::avp_find(avp_container &avps, AvpId id, unsigned int position) { int match = 0; Avp *aux; @@ -177,18 +188,29 @@ avp_iterator Avp::avp_find(avp_container &avps, AvpId id, unsigned int position) //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::addAvp() //------------------------------------------------------------------------------ -Avp * Avp::addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw() { - Avp * result = engine->allocateAvp(); +Avp * Avp::addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) { + Avp * result = engine->createAvp(NULL); result->setId(id); addChild(avps, insertionPositionForChilds, result); return result; } +//------------------------------------------------------------------------------ +//---------------------------------------------------------------- Avp::addAvp() +//------------------------------------------------------------------------------ +Avp * Avp::addAvp(Avp * avp) noexcept(false) { + if(!avp) return NULL; + if (avp->getEngine() != getEngine()) return NULL; + addChild(avp); + return avp; +} + + //------------------------------------------------------------------------------ //------------------------------------------------------------- Avp::removeAvp() //------------------------------------------------------------------------------ -bool Avp::removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw() { +bool Avp::removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) { bool removed = false; bool do_remove = true; int position = ocurrence; @@ -241,7 +263,7 @@ bool Avp::removeAvp(avp_container &avps, find_container &finds, AvpId id, int oc //------------------------------------------------------------------------------ //-------------------------------------------------------------- Avp::countAvp() //------------------------------------------------------------------------------ -int Avp::countAvp(const avp_container &avps, AvpId id) throw() { +int Avp::countAvp(const avp_container &avps, AvpId id) { int result = 0; const_avp_iterator it; @@ -254,7 +276,7 @@ int Avp::countAvp(const avp_container &avps, AvpId id) throw() { //------------------------------------------------------------------------------ //-------------------------------------------------------------- Avp::firstAvp() //------------------------------------------------------------------------------ -const Avp* Avp::firstAvp(const avp_container &avps, AvpId id) throw() { +const Avp* Avp::firstAvp(const avp_container &avps, AvpId id) { const_avp_iterator it = avp_find(avps, id, 1); if(it != avps.end()) @@ -267,7 +289,7 @@ const Avp* Avp::firstAvp(const avp_container &avps, AvpId id) throw() { //------------------------------------------------------------------------------ //----------------------------------------------------------- Avp::countChilds() //------------------------------------------------------------------------------ -int Avp::countChilds(const avp_container &avps) throw() { +int Avp::countChilds(const avp_container &avps) { return avps.size(); } @@ -275,7 +297,7 @@ int Avp::countChilds(const avp_container &avps) throw() { //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::getAvp() //------------------------------------------------------------------------------ -const Avp *Avp::getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) throw(anna::RuntimeException) { +const Avp *Avp::getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) noexcept(false) { if(ocurrence == 0) { LOGDEBUG(anna::Logger::debug("Ocurrence number zero has no sense. NULL returned.", ANNA_FILE_LOCATION)); return NULL; @@ -364,7 +386,7 @@ const Avp *Avp::getAvp(const avp_container &avps, find_container &finds, AvpId i //------------------------------------------------------------------------------ //--------------------------------------------------------------- Avp::_getAvp() //------------------------------------------------------------------------------ -const Avp *Avp::_getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException) { +const Avp *Avp::_getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false) { // Dictionary stack avp and format (this): const stack::Avp *stackAvp = getStackAvp(); const stack::Format *stackFormat = stackAvp ? (stackAvp->getFormat()) : NULL /*Unknown*/; @@ -379,7 +401,7 @@ const Avp *Avp::_getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode //------------------------------------------------------------------------------ //---------------------------------------------------------- Avp::assertFormat() //------------------------------------------------------------------------------ -void Avp::assertFormat(const std::string &name) const throw(anna::RuntimeException) { +void Avp::assertFormat(const std::string &name) const noexcept(false) { // Dictionary stack avp and format: const stack::Avp *stackAvp = getStackAvp(); const stack::Format *stackFormat = stackAvp ? (stackAvp->getFormat()) : NULL /*Unknown*/; @@ -401,12 +423,14 @@ void Avp::assertFormat(const std::string &name) const throw(anna::RuntimeExcepti //------------------------------------------------------------------------------ //--------------------------------------------------------------- Avp::flagsOK() //------------------------------------------------------------------------------ -bool Avp::flagsOK() const throw() { +bool Avp::flagsOK() const { // Dictionary stack avp: const stack::Avp *stackAvp = getStackAvp(); if(!stackAvp) { - anna::Logger::error("Impossible to decide if flags are correct because stack avp is not identified. Assume flags ok", ANNA_FILE_LOCATION); + std::string msg = "Impossible to decide if flags are correct because stack avp is not identified. Assume flags ok for Avp "; + msg += anna::diameter::functions::avpIdAsPairString(a_id); + anna::Logger::error(msg, ANNA_FILE_LOCATION); return true; }; @@ -431,7 +455,9 @@ bool Avp::flagsOK() const throw() { // V-bit if((Vnone && Mnone && Pnone && vendorBit()) || (Vmust && !vendorBit()) || (Vmustnot && vendorBit())) { - anna::Logger::error("Vendor Bit (V) incoherence found", ANNA_FILE_LOCATION); + std::string msg = "Vendor Bit (V) incoherence found for Avp "; + msg += stackAvp->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); return false; } @@ -440,19 +466,25 @@ bool Avp::flagsOK() const throw() { // M-bit if((Mmust && !mandatoryBit()) || (Mmustnot && mandatoryBit())) { - anna::Logger::error("Mandatory Bit (M) incoherence found", ANNA_FILE_LOCATION); + std::string msg = "Mandatory Bit (M) incoherence found for Avp "; + msg += stackAvp->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); return false; } // P-bit if((Pmust && !encryptionBit()) || (Pmustnot && encryptionBit())) { - anna::Logger::error("Encryption Bit (P) incoherence found", ANNA_FILE_LOCATION); + std::string msg = "Encryption Bit (P) incoherence found for Avp "; + msg += stackAvp->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); return false; } // Reserved bits if((a_flags & 0x1f) != 0x00) { - anna::Logger::error("Any (or more than one) of the reserved avp flags bit has been activated. Reserved bits must be null", ANNA_FILE_LOCATION); + std::string msg = "Any (or more than one) of the reserved avp flags bit has been activated. Reserved bits must be null. Avp is "; + msg += stackAvp->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); return false; } @@ -463,7 +495,7 @@ bool Avp::flagsOK() const throw() { //------------------------------------------------------------------------------ //----------------------------------------------------------------- Avp::setId() //------------------------------------------------------------------------------ -void Avp::setId(AvpId id) throw(anna::RuntimeException) { +void Avp::setId(AvpId id) noexcept(false) { // Generic AVP assignment has no sense if(id == helpers::AVPID__AVP) return; @@ -525,7 +557,7 @@ void Avp::setId(AvpId id) throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //----------------------------------------------------------------- Avp::setId() //------------------------------------------------------------------------------ -void Avp::setId(const char *name) throw(anna::RuntimeException) { +void Avp::setId(const char *name) noexcept(false) { setId(getEngine()->avpIdForName(name)); } @@ -533,7 +565,7 @@ void Avp::setId(const char *name) throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::addAvp() //------------------------------------------------------------------------------ -Avp * Avp::addAvp(const char *name) throw(anna::RuntimeException) { +Avp * Avp::addAvp(const char *name) noexcept(false) { return addAvp(getEngine()->avpIdForName(name)); } @@ -541,7 +573,7 @@ Avp * Avp::addAvp(const char *name) throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //------------------------------------------------------------- Avp::removeAvp() //------------------------------------------------------------------------------ -bool Avp::removeAvp(const char *name, int ocurrence) throw(anna::RuntimeException) { +bool Avp::removeAvp(const char *name, int ocurrence) noexcept(false) { return removeAvp(getEngine()->avpIdForName(name), ocurrence); } @@ -549,7 +581,7 @@ bool Avp::removeAvp(const char *name, int ocurrence) throw(anna::RuntimeExceptio //------------------------------------------------------------------------------ //--------------------------------------------------------------- Avp::_getAvp() //------------------------------------------------------------------------------ -const Avp *Avp::_getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException) { +const Avp *Avp::_getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false) { return getAvp(getEngine()->avpIdForName(name), ocurrence, emode); } @@ -557,14 +589,14 @@ const Avp *Avp::_getAvp(const char *name, int ocurrence, anna::Exception::Mode:: //------------------------------------------------------------------------------ //-------------------------------------------------------------- Avp::countAvp() //------------------------------------------------------------------------------ -int Avp::countAvp(const char *name) const throw(anna::RuntimeException) { +int Avp::countAvp(const char *name) const noexcept(false) { return countAvp(getEngine()->avpIdForName(name)); } //------------------------------------------------------------------------------ //------------------------------------------------------------- Avp::getLength() //------------------------------------------------------------------------------ -U24 Avp::getLength() const throw() { +U24 Avp::getLength() const { U24 result; // Avp format: const stack::Avp *stackAvp = getStackAvp(); @@ -605,7 +637,7 @@ U24 Avp::getLength() const throw() { //------------------------------------------------------------------------------ //-------------------------------------------- Avp::unknownAvpWithMandatoryBit() //------------------------------------------------------------------------------ -void Avp::unknownAvpWithMandatoryBit() const throw(anna::RuntimeException) { +void Avp::unknownAvpWithMandatoryBit() const noexcept(false) { OamModule &oamModule = OamModule::instantiate(); const char *c_aid = STRING_WITH_QUOTATION_MARKS__C_STR(anna::diameter::functions::avpIdAsPairString(a_id)); oamModule.activateAlarm(OamModule::Alarm::AvpDecode__UnknownAvp__s__WithMandatoryBit, c_aid); @@ -619,7 +651,7 @@ void Avp::unknownAvpWithMandatoryBit() const throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //-------------------------------------------------------- Avp::decodeDataPart() //------------------------------------------------------------------------------ -void Avp::decodeDataPart(const char * buffer, int size, const parent_t & parent, Message *answer) throw(anna::RuntimeException) { +void Avp::decodeDataPart(const char * buffer, int size, const parent_t & parent, Message *answer) noexcept(false) { // OAM OamModule &oamModule = OamModule::instantiate(); // Dictionary stack avp and format: @@ -665,7 +697,7 @@ void Avp::decodeDataPart(const char * buffer, int size, const parent_t & parent, while(avpPos < size) { try { - avp = getEngine()->allocateAvp(); + avp = getEngine()->createAvp(NULL); db.assign(buffer + avpPos, size - avpPos /* is valid to pass total size (indeed i don't know the real avp size) because it will be limited and this has deep copy disabled (no memory is reserved) */); avp -> decode(db, me, answer); } catch(anna::RuntimeException &ex) { @@ -694,7 +726,7 @@ void Avp::decodeDataPart(const char * buffer, int size, const parent_t & parent, //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::decode() //------------------------------------------------------------------------------ -void Avp::decode(const anna::DataBlock &db, const parent_t & parent, Message *answer) throw(anna::RuntimeException) { +void Avp::decode(const anna::DataBlock &db, const parent_t & parent, Message *answer) noexcept(false) { // OAM OamModule &oamModule = OamModule::instantiate(); @@ -803,7 +835,7 @@ void Avp::decode(const anna::DataBlock &db, const parent_t & parent, Message *an //------------------------------------------------------------------------------ //----------------------------------------------------------- Avp::getStackAvp() //------------------------------------------------------------------------------ -const anna::diameter::stack::Avp *Avp::getStackAvp(AvpId id, Engine *engine) throw() { +const anna::diameter::stack::Avp *Avp::getStackAvp(AvpId id, Engine *engine) { const stack::Dictionary * dictionary = engine->getDictionary(); return (dictionary ? (dictionary->getAvp(id)) : NULL); } @@ -812,7 +844,7 @@ const anna::diameter::stack::Avp *Avp::getStackAvp(AvpId id, Engine *engine) thr //------------------------------------------------------------------------------ //------------------------------------------------------------------- Avp::fix() //------------------------------------------------------------------------------ -void Avp::fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) throw() { +void Avp::fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) { // Exit cases if(avps.size() == 0) return; // empty content, nothing to fix @@ -858,7 +890,7 @@ void Avp::fix(avp_container &avps, find_container &finds, int &insertionPosition //------------------------------------------------------------------------------ //------------------------------------------------------------------- Avp::fix() //------------------------------------------------------------------------------ -void Avp::fix() throw() { +void Avp::fix() { // Dictionary stack avp: const stack::Avp *stackAvp = getStackAvp(); const stack::Format *stackFormat = stackAvp ? (stackAvp->getFormat()) : NULL /*Unknown*/; @@ -880,7 +912,7 @@ void Avp::fix() throw() { //------------------------------------------------------------------------------ //------------------------------------------------------------ Avp::validLevel() //------------------------------------------------------------------------------ -bool Avp::validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const parent_t & parent, Message *answer) throw(anna::RuntimeException) { +bool Avp::validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const parent_t & parent, Message *answer) noexcept(false) { bool result = true; // OAM OamModule &oamModule = OamModule::instantiate(); @@ -1053,7 +1085,7 @@ bool Avp::validLevel(const avp_container &avps, anna::diameter::stack::const_avp //------------------------------------------------------------------------------ //----------------------------------------------------------------- Avp::valid() //------------------------------------------------------------------------------ -bool Avp::valid(const parent_t & parent, Message *answer) const throw(anna::RuntimeException) { +bool Avp::valid(const parent_t & parent, Message *answer) const noexcept(false) { // OAM OamModule &oamModule = OamModule::instantiate(); // Dictionary stack avp: @@ -1131,7 +1163,7 @@ bool Avp::valid(const parent_t & parent, Message *answer) const throw(anna::Runt //------------------------------------------------------------------------------ //------------------------------------------------------------------ Avp::code() //------------------------------------------------------------------------------ -void Avp::code(char* buffer, int &size) const throw(anna::RuntimeException) { +void Avp::code(char* buffer, int &size) const noexcept(false) { // Code buffer[0] = (S8)(a_id.first >> 24); buffer[1] = (S8)(a_id.first >> 16); @@ -1210,7 +1242,7 @@ void Avp::code(char* buffer, int &size) const throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //------------------------------------------------------------ Avp::getXMLdata() //------------------------------------------------------------------------------ -std::string Avp::getXMLdata(bool & isHex, const stack::Format *stackFormat) const throw() { +std::string Avp::getXMLdata(bool & isHex, const stack::Format *stackFormat) const { std::string result = ""; isHex = false; // Unknown @@ -1225,7 +1257,17 @@ std::string Avp::getXMLdata(bool & isHex, const stack::Format *stackFormat) cons if(!stackFormat) { isHex = true; - return a_Unknown->asHexString(); // el asHexString del OctetString no puede lanzar una excepcion en realidad + // Tricky situation: if you change the dictionary dynamically, and a previous formatted avp + // becomes unknown (the change consists in remove Avps basically), then this would get a core + // dump: a_Unknown = NULL. We are not going to protect that situation because it represents a + // implementation fault, and there are many points which could have similar bad behaviour + // (those where we access directly the a_Unknown pointer). + // The best way to afford this is ... TODO: + // Freeze dictionary after use from any resource (avp, message), setting a flag which deny + // any modification in such dictionary. The best way to do this is on engine configuration + // for Avp o Message, where we could invoke something like getEngine()->getDictionary()->freeze() + + return a_Unknown->asHexString(); // asHexString for OctetString cannot launch exception } // Special case for Address: could launch exception if not printable @@ -1287,7 +1329,7 @@ std::string Avp::getXMLdata(bool & isHex, const stack::Format *stackFormat) cons //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::decode() //------------------------------------------------------------------------------ -void Avp::decode(const anna::DataBlock &db) throw(anna::RuntimeException) { +void Avp::decode(const anna::DataBlock &db) noexcept(false) { parent_t parent; parent.setMessage(CommandId(0, false), "No-Parent"); decode(db, parent, NULL); @@ -1297,7 +1339,7 @@ void Avp::decode(const anna::DataBlock &db) throw(anna::RuntimeException) { //------------------------------------------------------------------------------ //--------------------------------------------------------------- Avp::fromXML() //------------------------------------------------------------------------------ -void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) { +void Avp::fromXML(const anna::xml::Node* avpNode) noexcept(false) { // const anna::xml::Attribute *name, *code, *vendorCode, *flags, *data, *hexData; name = avpNode->getAttribute("name", false /* no exception */); @@ -1332,20 +1374,28 @@ void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) // Check attributes exclusiveness if(name) { // compact mode - bool allowFlagsField = ( stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::shouldnot + + if(code || vendorCode) { + std::string msg = "Error processing avp getValue(); + msg += "'>: avp attributes <'code' + 'vendorCode'> are not allowed if <'name'> is provided"; + throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); + } + + // flags uncertainty: + bool flagsUncertainty = ( stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getVbit() == anna::diameter::stack::Avp::FlagRule::shouldnot || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getMbit() == anna::diameter::stack::Avp::FlagRule::shouldnot /* umm, perhaps we could omit for bit P, whic is deprecated ... */ /* || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::may || stackAvp->getPbit() == anna::diameter::stack::Avp::FlagRule::shouldnot*/ ); - if(code || (flags && !allowFlagsField) || vendorCode) { - std::string msg = "Error processing avp getValue(); - if (flags) msg += "'>: avp attributes <'code' + 'flags' + 'vendorCode'> are not allowed if <'name'> is provided (also flags is not permitted: no may, no shouldnot)"; - else msg += "'>: avp attributes <'code' + 'vendorCode'> are not allowed if <'name'> is provided"; - throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); + if(flags && !flagsUncertainty) { + std::string msg = "Be careful processing avp getValue(); + msg += "'> together with avp 'flags' attribute, because may/shouldnot uncertainty was not specified"; + LOGINFORMATION(Logger::information(msg, ANNA_FILE_LOCATION)); } setId(stackAvp->getId()); - if (flags && allowFlagsField) { + //if (flags && flagsUncertainty) { + if (flags) { // Flags check int i_aux = flags->getIntegerValue(); @@ -1375,9 +1425,11 @@ void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) int i_aux = code->getIntegerValue(); if(i_aux < 0) { - std::string msg = "Error processing avp getValue(); - msg += "': negative values are not allowed"; - throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); + LOGWARNING( + std::string msg = "Error processing avp getValue(); + msg += "': negative value read from xml"; + anna::Logger::warning(msg, ANNA_FILE_LOCATION); + ); } U24 u_code = i_aux; @@ -1503,7 +1555,7 @@ void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) } try { - avp = getEngine()->allocateAvp(); + avp = getEngine()->createAvp(NULL); avp -> fromXML(*it); } catch(anna::RuntimeException &ex) { getEngine()->releaseAvp(avp); @@ -1547,7 +1599,7 @@ void Avp::fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException) //------------------------------------------------------------------------------ //----------------------------------------------------------------- Avp::asXML() //------------------------------------------------------------------------------ -anna::xml::Node* Avp::asXML(anna::xml::Node* parent) const throw() { +anna::xml::Node* Avp::asXML(anna::xml::Node* parent) const { // anna::xml::Node* result = parent->createChild("avp"); // Dictionary stack avp and format: @@ -1596,16 +1648,24 @@ anna::xml::Node* Avp::asXML(anna::xml::Node* parent) const throw() { //------------------------------------------------------------------------------ //----------------------------------------------------------- Avp::asXMLString() //------------------------------------------------------------------------------ -std::string Avp::asXMLString() const throw() { +std::string Avp::asXMLString(bool normalize) const { anna::xml::Node root("root"); - return anna::xml::Compiler().apply(asXML(&root)); + + anna::xml::Compiler::Mode::_v mode = normalize ? anna::xml::Compiler::Mode::Sort : anna::xml::Compiler::Mode::Visual; + std::string result = anna::xml::Compiler().apply(asXML(&root), mode); + + if (normalize) + result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); + + return result; } //------------------------------------------------------------------------------ //---------------------------------------------------------------- Avp::isLike() //------------------------------------------------------------------------------ -bool Avp::isLike(const std::string &pattern) const throw() { +bool Avp::isLike(const std::string &pattern) const { anna::RegularExpression re(pattern); - return re.isLike(asXMLString()); + return re.isLike(asXMLString(true /* normalize by mean sorting attribute names and removing new lines */)); } +