X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FAvp.cpp;h=89884be105caee03860fcc977c7af538b9b832c9;hb=6a05cda7553cf39d5b14539f9f4b9cf829c156a6;hp=26df7412d200037be9fb3b110b09b46f1ed69cc8;hpb=93366a0bda79e6fd6e7dad6316bfcf8cc82f5731;p=anna.git diff --git a/source/diameter/codec/Avp.cpp b/source/diameter/codec/Avp.cpp index 26df741..89884be 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,12 +74,26 @@ Avp::~Avp() { clear(); } +//------------------------------------------------------------------------------ +//------------------------------------------------------------- Avp::setEngine() +//------------------------------------------------------------------------------ +void Avp::setEngine(Engine *engine) throw() { + 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)); + 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; } @@ -89,7 +101,6 @@ Engine * Avp::getEngine() const throw(anna::RuntimeException) { //------------------------------------------------------------ Avp::initialize() //------------------------------------------------------------------------------ void Avp::initialize() throw() { - a_engine = NULL; a_id = helpers::AVPID__AVP; // (0,0) a_flags = 0x00; a_insertionPositionForChilds = 0; @@ -178,13 +189,24 @@ 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 * result = engine->createAvp(NULL); result->setId(id); addChild(avps, insertionPositionForChilds, result); return result; } +//------------------------------------------------------------------------------ +//---------------------------------------------------------------- Avp::addAvp() +//------------------------------------------------------------------------------ +Avp * Avp::addAvp(Avp * avp) throw(anna::RuntimeException) { + if(!avp) return NULL; + if (avp->getEngine() != getEngine()) return NULL; + addChild(avp); + return avp; +} + + //------------------------------------------------------------------------------ //------------------------------------------------------------- Avp::removeAvp() //------------------------------------------------------------------------------ @@ -665,7 +687,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) { @@ -1225,7 +1247,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 @@ -1503,7 +1535,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);