lldispatcher.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "lldispatcher.h"
00035 
00036 #include <algorithm>
00037 #include "llstl.h"
00038 #include "message.h"
00039 
00043 
00044 
00045 LLDispatcher::LLDispatcher()
00046 {
00047 }
00048 
00049 LLDispatcher::~LLDispatcher()
00050 {
00051 }
00052 
00053 bool LLDispatcher::isHandlerPresent(const key_t& name) const
00054 {
00055         if(mHandlers.find(name) != mHandlers.end())
00056         {
00057                 return true;
00058         }
00059         return false;
00060 }
00061 
00062 void LLDispatcher::copyAllHandlerNames(keys_t& names) const
00063 {
00064         // copy the names onto the vector we are given
00065         std::transform(
00066                 mHandlers.begin(),
00067                 mHandlers.end(),
00068                 std::back_insert_iterator<keys_t>(names),
00069                 llselect1st<dispatch_map_t::value_type>());
00070 }
00071 
00072 bool LLDispatcher::dispatch(
00073         const key_t& name,
00074         const LLUUID& invoice,
00075         const sparam_t& strings) const
00076 {
00077         dispatch_map_t::const_iterator it = mHandlers.find(name);
00078         if(it != mHandlers.end())
00079         {
00080                 LLDispatchHandler* func = (*it).second;
00081                 return (*func)(this, name, invoice, strings);
00082         }
00083         llwarns << "Unable to find handler for Generic message: " << name << llendl;
00084         return false;
00085 }
00086 
00087 LLDispatchHandler* LLDispatcher::addHandler(
00088         const key_t& name, LLDispatchHandler* func)
00089 {
00090         dispatch_map_t::iterator it = mHandlers.find(name);
00091         LLDispatchHandler* old_handler = NULL;
00092         if(it != mHandlers.end())
00093         {
00094                 old_handler = (*it).second;
00095                 mHandlers.erase(it);
00096         }
00097         if(func)
00098         {
00099                 // only non-null handlers so that we don't have to worry about
00100                 // it later.
00101                 mHandlers.insert(dispatch_map_t::value_type(name, func));
00102         }
00103         return old_handler;
00104 }
00105 
00106 // static
00107 bool LLDispatcher::unpackMessage(
00108                 LLMessageSystem* msg,
00109                 LLDispatcher::key_t& method,
00110                 LLUUID& invoice,
00111                 LLDispatcher::sparam_t& parameters)
00112 {
00113         char buf[MAX_STRING];   /*Flawfinder: ignore*/
00114         msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, MAX_STRING, buf);
00115         method.assign(buf);
00116         msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
00117         S32 size;
00118         S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
00119         for (S32 i = 0; i < count; ++i)
00120         {
00121                 // we treat the SParam as binary data (since it might be an 
00122                 // LLUUID in compressed form which may have embedded \0's,)
00123                 size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
00124                 msg->getBinaryDataFast(
00125                         _PREHASH_ParamList, _PREHASH_Parameter,
00126                         buf, size, i, MAX_STRING-1);
00127 
00128                 // If the last byte of the data is 0x0, this is either a normally
00129                 // packed string, or a binary packed UUID (which for these messages
00130                 // are packed with a 17th byte 0x0).  Unpack into a std::string
00131                 // without the trailing \0, so "abc\0" becomes std::string("abc", 3)
00132                 // which matches const char* "abc".
00133                 if (size > 0
00134                         && buf[size-1] == 0x0)
00135                 {
00136                         // special char*/size constructor because UUIDs may have embedded
00137                         // 0x0 bytes.
00138                         std::string binary_data(buf, size-1);
00139                         parameters.push_back(binary_data);
00140                 }
00141                 else
00142                 {
00143                         // This is either a NULL string, or a string that was packed 
00144                         // incorrectly as binary data, without the usual trailing '\0'.
00145                         std::string string_data(buf, size);
00146                         parameters.push_back(string_data);
00147                 }
00148         }
00149         return true;
00150 }

Generated on Thu Jul 1 06:08:24 2010 for Second Life Viewer by  doxygen 1.4.7