lltemplatemessagereader.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 #include "lltemplatemessagereader.h"
00034 
00035 #include "llfasttimer.h"
00036 #include "llmessagebuilder.h"
00037 #include "llmessagetemplate.h"
00038 #include "llquaternion.h"
00039 #include "message.h"
00040 #include "u64.h"
00041 #include "v3dmath.h"
00042 #include "v3math.h"
00043 #include "v4math.h"
00044 
00045 LLTemplateMessageReader::LLTemplateMessageReader(message_template_number_map_t&
00046                                                                                                  number_template_map) :
00047         mReceiveSize(0),
00048         mCurrentRMessageTemplate(NULL),
00049         mCurrentRMessageData(NULL),
00050         mMessageNumbers(number_template_map)
00051 {
00052 }
00053 
00054 //virtual 
00055 LLTemplateMessageReader::~LLTemplateMessageReader()
00056 {
00057         delete mCurrentRMessageData;
00058         mCurrentRMessageData = NULL;
00059 }
00060 
00061 //virtual
00062 void LLTemplateMessageReader::clearMessage()
00063 {
00064         mReceiveSize = -1;
00065         mCurrentRMessageTemplate = NULL;
00066         delete mCurrentRMessageData;
00067         mCurrentRMessageData = NULL;
00068 }
00069 
00070 void LLTemplateMessageReader::getData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size)
00071 {
00072         // is there a message ready to go?
00073         if (mReceiveSize == -1)
00074         {
00075                 llerrs << "No message waiting for decode 2!" << llendl;
00076                 return;
00077         }
00078 
00079         if (!mCurrentRMessageData)
00080         {
00081                 llerrs << "Invalid mCurrentMessageData in getData!" << llendl;
00082                 return;
00083         }
00084 
00085         char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash.  The bnamep is never derefference
00086         char *vnamep = (char *)varname; 
00087 
00088         LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
00089 
00090         if (iter == mCurrentRMessageData->mMemberBlocks.end())
00091         {
00092                 llerrs << "Block " << blockname << " #" << blocknum
00093                         << " not in message " << mCurrentRMessageData->mName << llendl;
00094                 return;
00095         }
00096 
00097         LLMsgBlkData *msg_block_data = iter->second;
00098         LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
00099 
00100         if (!vardata.getName())
00101         {
00102                 llerrs << "Variable "<< vnamep << " not in message "
00103                         << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
00104                 return;
00105         }
00106 
00107         if (size && size != vardata.getSize())
00108         {
00109                 llerrs << "Msg " << mCurrentRMessageData->mName 
00110                         << " variable " << vnamep
00111                         << " is size " << vardata.getSize()
00112                         << " but copying into buffer of size " << size
00113                         << llendl;
00114                 return;
00115         }
00116 
00117 
00118         const S32 vardata_size = vardata.getSize();
00119         if( max_size >= vardata_size )
00120         {   
00121                 switch( vardata_size )
00122                 { 
00123                 case 1:
00124                         *((U8*)datap) = *((U8*)vardata.getData());
00125                         break;
00126                 case 2:
00127                         *((U16*)datap) = *((U16*)vardata.getData());
00128                         break;
00129                 case 4:
00130                         *((U32*)datap) = *((U32*)vardata.getData());
00131                         break;
00132                 case 8:
00133                         ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
00134                         ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
00135                         break;
00136                 default:
00137                         memcpy(datap, vardata.getData(), vardata_size);
00138                         break;
00139                 }
00140         }
00141         else
00142         {
00143                 llwarns << "Msg " << mCurrentRMessageData->mName 
00144                         << " variable " << vnamep
00145                         << " is size " << vardata.getSize()
00146                         << " but truncated to max size of " << max_size
00147                         << llendl;
00148 
00149                 memcpy(datap, vardata.getData(), max_size);
00150         }
00151 }
00152 
00153 S32 LLTemplateMessageReader::getNumberOfBlocks(const char *blockname)
00154 {
00155         // is there a message ready to go?
00156         if (mReceiveSize == -1)
00157         {
00158                 llerrs << "No message waiting for decode 3!" << llendl;
00159                 return -1;
00160         }
00161 
00162         if (!mCurrentRMessageData)
00163         {
00164                 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
00165                 return -1;
00166         }
00167 
00168         char *bnamep = (char *)blockname; 
00169 
00170         LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
00171         
00172         if (iter == mCurrentRMessageData->mMemberBlocks.end())
00173         {
00174 //              sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName);
00175 //              llerrs << errmsg << llendl;
00176 //              return -1;
00177                 return 0;
00178         }
00179 
00180         return (iter->second)->mBlockNumber;
00181 }
00182 
00183 S32 LLTemplateMessageReader::getSize(const char *blockname, const char *varname)
00184 {
00185         // is there a message ready to go?
00186         if (mReceiveSize == -1)
00187         {
00188                 llerrs << "No message waiting for decode 4!" << llendl;
00189                 return -1;
00190         }
00191 
00192         if (!mCurrentRMessageData)
00193         {
00194                 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
00195                 return -1;
00196         }
00197 
00198         char *bnamep = (char *)blockname; 
00199 
00200         LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
00201         
00202         if (iter == mCurrentRMessageData->mMemberBlocks.end())
00203         {
00204                 llerrs << "Block " << bnamep << " not in message "
00205                         << mCurrentRMessageData->mName << llendl;
00206                 return -1;
00207         }
00208 
00209         char *vnamep = (char *)varname; 
00210 
00211         LLMsgBlkData* msg_data = iter->second;
00212         LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
00213         
00214         if (!vardata.getName())
00215         {
00216                 llerrs << "Variable " << varname << " not in message "
00217                         << mCurrentRMessageData->mName << " block " << bnamep << llendl;
00218                 return -1;
00219         }
00220 
00221         if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
00222         {
00223                 llerrs << "Block " << bnamep << " isn't type MBT_SINGLE,"
00224                         " use getSize with blocknum argument!" << llendl;
00225                 return -1;
00226         }
00227 
00228         return vardata.getSize();
00229 }
00230 
00231 S32 LLTemplateMessageReader::getSize(const char *blockname, S32 blocknum, const char *varname)
00232 {
00233         // is there a message ready to go?
00234         if (mReceiveSize == -1)
00235         {
00236                 llerrs << "No message waiting for decode 5!" << llendl;
00237                 return -1;
00238         }
00239 
00240         if (!mCurrentRMessageData)
00241         {
00242                 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
00243                 return -1;
00244         }
00245 
00246         char *bnamep = (char *)blockname + blocknum; 
00247         char *vnamep = (char *)varname; 
00248 
00249         LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
00250         
00251         if (iter == mCurrentRMessageData->mMemberBlocks.end())
00252         {
00253                 llerrs << "Block " << bnamep << " not in message "
00254                         << mCurrentRMessageData->mName << llendl;
00255                 return -1;
00256         }
00257 
00258         LLMsgBlkData* msg_data = iter->second;
00259         LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
00260         
00261         if (!vardata.getName())
00262         {
00263                 llerrs << "Variable " << vnamep << " not in message "
00264                         <<  mCurrentRMessageData->mName << " block " << bnamep << llendl;
00265                 return -1;
00266         }
00267 
00268         return vardata.getSize();
00269 }
00270 
00271 void LLTemplateMessageReader::getBinaryData(const char *blockname, 
00272                                                                                         const char *varname, void *datap, 
00273                                                                                         S32 size, S32 blocknum, 
00274                                                                                         S32 max_size)
00275 {
00276         getData(blockname, varname, datap, size, blocknum, max_size);
00277 }
00278 
00279 void LLTemplateMessageReader::getS8(const char *block, const char *var, 
00280                                                                                 S8 &u, S32 blocknum)
00281 {
00282         getData(block, var, &u, sizeof(S8), blocknum);
00283 }
00284 
00285 void LLTemplateMessageReader::getU8(const char *block, const char *var, 
00286                                                                                 U8 &u, S32 blocknum)
00287 {
00288         getData(block, var, &u, sizeof(U8), blocknum);
00289 }
00290 
00291 void LLTemplateMessageReader::getBOOL(const char *block, const char *var, 
00292                                                                                   BOOL &b, S32 blocknum )
00293 {
00294         U8 value;
00295         getData(block, var, &value, sizeof(U8), blocknum);
00296         b = (BOOL) value;
00297 }
00298 
00299 void LLTemplateMessageReader::getS16(const char *block, const char *var, 
00300                                                                                  S16 &d, S32 blocknum)
00301 {
00302         getData(block, var, &d, sizeof(S16), blocknum);
00303 }
00304 
00305 void LLTemplateMessageReader::getU16(const char *block, const char *var, 
00306                                                                                  U16 &d, S32 blocknum)
00307 {
00308         getData(block, var, &d, sizeof(U16), blocknum);
00309 }
00310 
00311 void LLTemplateMessageReader::getS32(const char *block, const char *var, 
00312                                                                                  S32 &d, S32 blocknum)
00313 {
00314         getData(block, var, &d, sizeof(S32), blocknum);
00315 }
00316 
00317 void LLTemplateMessageReader::getU32(const char *block, const char *var, 
00318                                                                          U32 &d, S32 blocknum)
00319 {
00320         getData(block, var, &d, sizeof(U32), blocknum);
00321 }
00322 
00323 void LLTemplateMessageReader::getU64(const char *block, const char *var, 
00324                                                                          U64 &d, S32 blocknum)
00325 {
00326         getData(block, var, &d, sizeof(U64), blocknum);
00327 }
00328 
00329 void LLTemplateMessageReader::getF32(const char *block, const char *var, 
00330                                                                          F32 &d, S32 blocknum)
00331 {
00332         getData(block, var, &d, sizeof(F32), blocknum);
00333 
00334         if( !llfinite( d ) )
00335         {
00336                 llwarns << "non-finite in getF32Fast " << block << " " << var 
00337                                 << llendl;
00338                 d = 0;
00339         }
00340 }
00341 
00342 void LLTemplateMessageReader::getF64(const char *block, const char *var, 
00343                                                                          F64 &d, S32 blocknum)
00344 {
00345         getData(block, var, &d, sizeof(F64), blocknum);
00346 
00347         if( !llfinite( d ) )
00348         {
00349                 llwarns << "non-finite in getF64Fast " << block << " " << var 
00350                                 << llendl;
00351                 d = 0;
00352         }
00353 }
00354 
00355 void LLTemplateMessageReader::getVector3(const char *block, const char *var, 
00356                                                                                  LLVector3 &v, S32 blocknum )
00357 {
00358         getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
00359 
00360         if( !v.isFinite() )
00361         {
00362                 llwarns << "non-finite in getVector3Fast " << block << " " 
00363                                 << var << llendl;
00364                 v.zeroVec();
00365         }
00366 }
00367 
00368 void LLTemplateMessageReader::getVector4(const char *block, const char *var, 
00369                                                                                  LLVector4 &v, S32 blocknum)
00370 {
00371         getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
00372 
00373         if( !v.isFinite() )
00374         {
00375                 llwarns << "non-finite in getVector4Fast " << block << " " 
00376                                 << var << llendl;
00377                 v.zeroVec();
00378         }
00379 }
00380 
00381 void LLTemplateMessageReader::getVector3d(const char *block, const char *var, 
00382                                                                                   LLVector3d &v, S32 blocknum )
00383 {
00384         getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum);
00385 
00386         if( !v.isFinite() )
00387         {
00388                 llwarns << "non-finite in getVector3dFast " << block << " " 
00389                                 << var << llendl;
00390                 v.zeroVec();
00391         }
00392 
00393 }
00394 
00395 void LLTemplateMessageReader::getQuat(const char *block, const char *var, 
00396                                                                           LLQuaternion &q, S32 blocknum)
00397 {
00398         LLVector3 vec;
00399         getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum);
00400         if( vec.isFinite() )
00401         {
00402                 q.unpackFromVector3( vec );
00403         }
00404         else
00405         {
00406                 llwarns << "non-finite in getQuatFast " << block << " " << var 
00407                                 << llendl;
00408                 q.loadIdentity();
00409         }
00410 }
00411 
00412 void LLTemplateMessageReader::getUUID(const char *block, const char *var, 
00413                                                                           LLUUID &u, S32 blocknum)
00414 {
00415         getData(block, var, &u.mData[0], sizeof(u.mData), blocknum);
00416 }
00417 
00418 inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
00419 {
00420         getData(block, var, &u, sizeof(U32), blocknum);
00421 }
00422 
00423 inline void LLTemplateMessageReader::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum)
00424 {
00425         getData(block, var, &u, sizeof(U16), blocknum);
00426         u = ntohs(u);
00427 }
00428 
00429 inline void LLTemplateMessageReader::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
00430 {
00431         s[0] = '\0';
00432         getData(block, var, s, 0, blocknum, buffer_size);
00433         s[buffer_size - 1] = '\0';
00434 }
00435 
00436 //virtual 
00437 S32 LLTemplateMessageReader::getMessageSize() const
00438 {
00439         return mReceiveSize;
00440 }
00441 
00442 // Returns template for the message contained in buffer
00443 BOOL LLTemplateMessageReader::decodeTemplate(  
00444                 const U8* buffer, S32 buffer_size,  // inputs
00445                 LLMessageTemplate** msg_template ) // outputs
00446 {
00447         const U8* header = buffer + LL_PACKET_ID_SIZE;
00448 
00449         // is there a message ready to go?
00450         if (buffer_size <= 0)
00451         {
00452                 llwarns << "No message waiting for decode!" << llendl;
00453                 return(FALSE);
00454         }
00455 
00456         U32 num = 0;
00457 
00458         if (header[0] != 255)
00459         {
00460                 // high frequency message
00461                 num = header[0];
00462         }
00463         else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
00464         {
00465                 // medium frequency message
00466                 num = (255 << 8) | header[1];
00467         }
00468         else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
00469         {
00470                 // low frequency message
00471                 U16     message_id_U16 = 0;
00472                 // I think this check busts the message system.
00473                 // it appears that if there is a NULL in the message #, it won't copy it....
00474                 // what was the goal?
00475                 //if(header[2])
00476                 memcpy(&message_id_U16, &header[2], 2);
00477 
00478                 // dependant on endian-ness:
00479                 //              U32     temp = (255 << 24) | (255 << 16) | header[2];
00480 
00481                 // independant of endian-ness:
00482                 message_id_U16 = ntohs(message_id_U16);
00483                 num = 0xFFFF0000 | message_id_U16;
00484         }
00485         else // bogus packet received (too short)
00486         {
00487                 llwarns << "Packet with unusable length received (too short): "
00488                                 << buffer_size << llendl;
00489                 return(FALSE);
00490         }
00491 
00492         LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
00493         if (temp)
00494         {
00495                 *msg_template = temp;
00496         }
00497         else
00498         {
00499                 llwarns << "Message #" << std::hex << num << std::dec
00500                         << " received but not registered!" << llendl;
00501                 gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
00502                 return(FALSE);
00503         }
00504 
00505         return(TRUE);
00506 }
00507 
00508 void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted )
00509 {
00510         // we've run off the end of the packet!
00511         llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
00512 //                      << " with id " << mCurrentRecvPacketID 
00513                         << " from " << host
00514                         << " trying to read " << wanted
00515                         << " bytes at position " << where
00516                         << " going past packet end at " << mReceiveSize
00517                         << llendl;
00518         if(gMessageSystem->mVerboseLog)
00519         {
00520                 llinfos << "MSG: -> " << host << "\tREAD PAST END:\t"
00521 //                              << mCurrentRecvPacketID << " "
00522                                 << getMessageName() << llendl;
00523         }
00524         gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
00525 }
00526 
00527 // decode a given message
00528 BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
00529 {
00530         llassert( mReceiveSize >= 0 );
00531         llassert( mCurrentRMessageTemplate);
00532         llassert( !mCurrentRMessageData );
00533         delete mCurrentRMessageData; // just to make sure
00534 
00535         // The offset tells us how may bytes to skip after the end of the
00536         // message name.
00537         U8 offset = buffer[PHL_OFFSET];
00538         S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset;
00539 
00540         // create base working data set
00541         mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
00542         
00543         // loop through the template building the data structure as we go
00544         LLMessageTemplate::message_block_map_t::const_iterator iter;
00545         for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
00546                 iter != mCurrentRMessageTemplate->mMemberBlocks.end();
00547                 ++iter)
00548         {
00549                 LLMessageBlock* mbci = *iter;
00550                 U8      repeat_number;
00551                 S32     i;
00552 
00553                 // how many of this block?
00554 
00555                 if (mbci->mType == MBT_SINGLE)
00556                 {
00557                         // just one
00558                         repeat_number = 1;
00559                 }
00560                 else if (mbci->mType == MBT_MULTIPLE)
00561                 {
00562                         // a known number
00563                         repeat_number = mbci->mNumber;
00564                 }
00565                 else if (mbci->mType == MBT_VARIABLE)
00566                 {
00567                         // need to read the number from the message
00568                         // repeat number is a single byte
00569                         if (decode_pos >= mReceiveSize)
00570                         {
00571                                 logRanOffEndOfPacket(sender, decode_pos, 1);
00572 
00573                                 // default to 0 repeats
00574                                 repeat_number = 0;
00575                         }
00576                         else
00577                         {
00578                                 repeat_number = buffer[decode_pos];
00579                                 decode_pos++;
00580                         }
00581                 }
00582                 else
00583                 {
00584                         llerrs << "Unknown block type" << llendl;
00585                         return FALSE;
00586                 }
00587 
00588                 LLMsgBlkData* cur_data_block = NULL;
00589 
00590                 // now loop through the block
00591                 for (i = 0; i < repeat_number; i++)
00592                 {
00593                         if (i)
00594                         {
00595                                 // build new name to prevent collisions
00596                                 // TODO: This should really change to a vector
00597                                 cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
00598                                 cur_data_block->mName = mbci->mName + i;
00599                         }
00600                         else
00601                         {
00602                                 cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
00603                         }
00604 
00605                         // add the block to the message
00606                         mCurrentRMessageData->addBlock(cur_data_block);
00607 
00608                         // now read the variables
00609                         for (LLMessageBlock::message_variable_map_t::const_iterator iter = 
00610                                          mbci->mMemberVariables.begin();
00611                                  iter != mbci->mMemberVariables.end(); iter++)
00612                         {
00613                                 const LLMessageVariable& mvci = **iter;
00614 
00615                                 // ok, build out the variables
00616                                 // add variable block
00617                                 cur_data_block->addVariable(mvci.getName(), mvci.getType());
00618 
00619                                 // what type of variable?
00620                                 if (mvci.getType() == MVT_VARIABLE)
00621                                 {
00622                                         // variable, get the number of bytes to read from the template
00623                                         S32 data_size = mvci.getSize();
00624                                         U8 tsizeb = 0;
00625                                         U16 tsizeh = 0;
00626                                         U32 tsize = 0;
00627 
00628                                         if ((decode_pos + data_size) > mReceiveSize)
00629                                         {
00630                                                 logRanOffEndOfPacket(sender, decode_pos, data_size);
00631 
00632                                                 // default to 0 length variable blocks
00633                                                 tsize = 0;
00634                                         }
00635                                         else
00636                                         {
00637                                                 switch(data_size)
00638                                                 {
00639                                                 case 1:
00640                                                         htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
00641                                                         tsize = tsizeb;
00642                                                         break;
00643                                                 case 2:
00644                                                         htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
00645                                                         tsize = tsizeh;
00646                                                         break;
00647                                                 case 4:
00648                                                         htonmemcpy(&tsize, &buffer[decode_pos], MVT_U32, 4);
00649                                                         break;
00650                                                 default:
00651                                                         llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
00652                                                         break;
00653                                                 }
00654                                         }
00655                                         decode_pos += data_size;
00656 
00657                                         cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
00658                                         decode_pos += tsize;
00659                                 }
00660                                 else
00661                                 {
00662                                         // fixed!
00663                                         // so, copy data pointer and set data size to fixed size
00664                                         if ((decode_pos + mvci.getSize()) > mReceiveSize)
00665                                         {
00666                                                 logRanOffEndOfPacket(sender, decode_pos, mvci.getSize());
00667 
00668                                                 // default to 0s.
00669                                                 U32 size = mvci.getSize();
00670                                                 std::vector<U8> data(size);
00671                                                 memset(&(data[0]), 0, size);
00672                                                 cur_data_block->addData(mvci.getName(), &(data[0]), 
00673                                                                                                 size, mvci.getType());
00674                                         }
00675                                         else
00676                                         {
00677                                                 cur_data_block->addData(mvci.getName(), 
00678                                                                                                 &buffer[decode_pos], 
00679                                                                                                 mvci.getSize(), 
00680                                                                                                 mvci.getType());
00681                                         }
00682                                         decode_pos += mvci.getSize();
00683                                 }
00684                         }
00685                 }
00686         }
00687 
00688         if (mCurrentRMessageData->mMemberBlocks.empty()
00689                 && !mCurrentRMessageTemplate->mMemberBlocks.empty())
00690         {
00691                 lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
00692                 return FALSE;
00693         }
00694 
00695         {
00696                 static LLTimer decode_timer;
00697 
00698                 if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
00699                 {
00700                         decode_timer.reset();
00701                 }
00702 
00703                 {
00704                         LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
00705                         if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
00706                         {
00707                                 llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
00708                         }
00709                 }
00710 
00711                 if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
00712                 {
00713                         F32 decode_time = decode_timer.getElapsedTimeF32();
00714 
00715                         if (gMessageSystem->getTimingCallback())
00716                         {
00717                                 (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName,
00718                                                                 decode_time,
00719                                                                 gMessageSystem->getTimingCallbackData());
00720                         }
00721 
00722                         if (LLMessageReader::getTimeDecodes())
00723                         {
00724                                 mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
00725 
00726                                 mCurrentRMessageTemplate->mTotalDecoded++;
00727                                 mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
00728 
00729                                 if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
00730                                 {
00731                                         mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
00732                                 }
00733 
00734 
00735                                 if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
00736                                 {
00737                                         lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
00738                                                 mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
00739                                                 (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
00740                                 }
00741                         }
00742                 }
00743         }
00744         return TRUE;
00745 }
00746 
00747 BOOL LLTemplateMessageReader::validateMessage(const U8* buffer, 
00748                                                                                           S32 buffer_size, 
00749                                                                                           const LLHost& sender)
00750 {
00751         mReceiveSize = buffer_size;
00752         BOOL result = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate );
00753         if(result)
00754         {
00755                 mCurrentRMessageTemplate->mReceiveCount++;
00756                 //lldebugs << "MessageRecvd:" 
00757                 //                                               << mCurrentRMessageTemplate->mName 
00758                 //                                               << " from " << sender << llendl;
00759         }
00760         return result;
00761 }
00762 
00763 BOOL LLTemplateMessageReader::readMessage(const U8* buffer, 
00764                                                                                   const LLHost& sender)
00765 {
00766         return decodeData(buffer, sender);
00767 }
00768 
00769 //virtual 
00770 const char* LLTemplateMessageReader::getMessageName() const
00771 {
00772         if (!mCurrentRMessageTemplate)
00773         {
00774                 llwarns << "no mCurrentRMessageTemplate" << llendl;
00775                 return "";
00776         }
00777         return mCurrentRMessageTemplate->mName;
00778 }
00779 
00780 //virtual 
00781 bool LLTemplateMessageReader::isTrusted() const
00782 {
00783         return mCurrentRMessageTemplate->getTrust() == MT_TRUST;
00784 }
00785 
00786 //virtual 
00787 bool LLTemplateMessageReader::isBanned(bool trustedSource) const
00788 {
00789         return mCurrentRMessageTemplate->isBanned(trustedSource);
00790 }
00791 
00792 //virtual 
00793 void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const
00794 {
00795         if(NULL == mCurrentRMessageTemplate)
00796     {
00797         return;
00798     }
00799         builder.copyFromMessageData(*mCurrentRMessageData);
00800 }

Generated on Fri May 16 08:32:30 2008 for SecondLife by  doxygen 1.5.5