/************************************************************* * @brief Invoke the list of callbacks matching the doctype of the incoming message. * * @param pIncomingMsg The SML message that should be passed to the callbacks. * @returns The response message (or NULL if there is no response from any callback). *************************************************************/ ElementXML* Connection::InvokeCallbacks(ElementXML *pIncomingMsg) { ClearError() ; MessageSML *pIncomingSML = (MessageSML*)pIncomingMsg ; // MessageSML is a soarxml::ElementXML, not sml::ElementXML // Check that we were passed a valid message. if (pIncomingMsg == NULL) { SetError(Error::kInvalidArgument) ; return NULL ; } // Retrieve the type of this message char const* pType = pIncomingSML->GetDocType() ; // Check that this message has a valid doc type (all valid SML do) if (pType == NULL) { SetError(Error::kNoDocType) ; return NULL ; } // Decide if this message is a "call" which requires a "response" bool isIncomingCall = pIncomingSML->IsCall() ; // See if we have a list of callbacks for this type CallbackList* pList = GetCallbackList(pType) ; // Nobody was interested in this type of message, so we're done. if (pList == NULL) { return NULL ; } CallbackListIter iter = pList->begin() ; // Walk the list of callbacks in turn until we reach // the end or one returns a message. while (iter != pList->end()) { Callback* pCallback = *iter ; iter++ ; ElementXML* pResponse = pCallback->Invoke(pIncomingMsg) ; if (pResponse != NULL) { if (isIncomingCall) return pResponse ; // This callback was not for a call and should not return a result. // Delete the result and ignore it. pResponse->ReleaseRefOnHandle() ; pResponse = NULL ; } } // If this is a call, we must respond if (isIncomingCall) SetError(Error::kNoResponseToCall) ; // Nobody returned a response return NULL ; }