llmessagetemplate.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLMESSAGETEMPLATE_H
00033 #define LL_LLMESSAGETEMPLATE_H
00034 
00035 #include "lldarray.h"
00036 #include "message.h" // TODO: babbage: Remove...
00037 #include "llmsgvariabletype.h"
00038 #include "llstl.h"
00039 #include <list>
00040 #include <algorithm>
00041 #include <functional>
00042 
00043 class LLMsgVarData
00044 {
00045 public:
00046         LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8)
00047         {
00048         }
00049 
00050         LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type)
00051         {
00052                 mName = (char *)name; 
00053         }
00054 
00055         ~LLMsgVarData() 
00056         {
00057                 // copy constructor just copies the mData pointer, so only delete mData explicitly
00058         }
00059         
00060         void deleteData() 
00061         {
00062                 delete[] mData;
00063                 mData = NULL;
00064         }
00065         
00066         void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1);
00067 
00068         char *getName() const   { return mName; }
00069         S32 getSize() const             { return mSize; }
00070         void *getData()                 { return (void*)mData; }
00071         const void *getData() const { return (const void*)mData; }
00072         S32 getDataSize() const { return mDataSize; }
00073         EMsgVariableType getType() const        { return mType; }
00074 
00075 protected:
00076         char                            *mName;
00077         S32                                     mSize;
00078         S32                                     mDataSize;
00079 
00080         U8                                      *mData;
00081         EMsgVariableType        mType;
00082 };
00083 
00084 class LLMsgBlkData
00085 {
00086 public:
00087         LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1) 
00088         { 
00089                 mName = (char *)name; 
00090         }
00091 
00092         ~LLMsgBlkData()
00093         {
00094                 for (msg_var_data_map_t::iterator iter = mMemberVarData.begin();
00095                          iter != mMemberVarData.end(); iter++)
00096                 {
00097                         iter->deleteData();
00098                 }
00099         }
00100 
00101         void addVariable(const char *name, EMsgVariableType type)
00102         {
00103                 LLMsgVarData tmp(name,type);
00104                 mMemberVarData[name] = tmp;
00105         }
00106 
00107         void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1)
00108         {
00109                 LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist
00110                 temp->addData(data, size, type, data_size);
00111         }
00112 
00113         S32                                                                     mOffset;
00114         S32                                                                     mBlockNumber;
00115         typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t;
00116         msg_var_data_map_t                                      mMemberVarData;
00117         char                                                            *mName;
00118         S32                                                                     mTotalSize;
00119 };
00120 
00121 class LLMsgData
00122 {
00123 public:
00124         LLMsgData(const char *name) : mTotalSize(-1) 
00125         { 
00126                 mName = (char *)name; 
00127         }
00128         ~LLMsgData()
00129         {
00130                 for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
00131         }
00132 
00133         void addBlock(LLMsgBlkData *blockp)
00134         {
00135                 mMemberBlocks[blockp->mName] = blockp;
00136         }
00137 
00138         void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1);
00139 
00140 public:
00141         S32                                                                     mOffset;
00142         typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t;
00143         msg_blk_data_map_t                                      mMemberBlocks;
00144         char                                                            *mName;
00145         S32                                                                     mTotalSize;
00146 };
00147 
00148 // LLMessage* classes store the template of messages
00149 class LLMessageVariable
00150 {
00151 public:
00152         LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1)
00153         {
00154         }
00155 
00156         LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1)
00157         {
00158                 mName = name;
00159         }
00160 
00161         LLMessageVariable(const char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size) 
00162         {
00163                 mName = gMessageStringTable.getString(name); 
00164         }
00165         
00166         ~LLMessageVariable() {}
00167 
00168         friend std::ostream&     operator<<(std::ostream& s, LLMessageVariable &msg);
00169 
00170         EMsgVariableType getType() const                                { return mType; }
00171         S32     getSize() const                                                         { return mSize; }
00172         char *getName() const                                                   { return mName; }
00173 protected:
00174         char                            *mName;
00175         EMsgVariableType        mType;
00176         S32                                     mSize;
00177 };
00178 
00179 
00180 typedef enum e_message_block_type
00181 {
00182         MBT_NULL,
00183         MBT_SINGLE,
00184         MBT_MULTIPLE,
00185         MBT_VARIABLE,
00186         MBT_EOF
00187 } EMsgBlockType;
00188 
00189 class LLMessageBlock
00190 {
00191 public:
00192         LLMessageBlock(const char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0) 
00193         { 
00194                 mName = gMessageStringTable.getString(name);
00195         }
00196 
00197         ~LLMessageBlock()
00198         {
00199                 for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePointer());
00200         }
00201 
00202         void addVariable(char *name, const EMsgVariableType type, const S32 size)
00203         {
00204                 LLMessageVariable** varp = &mMemberVariables[name];
00205                 if (*varp != NULL)
00206                 {
00207                         llerrs << name << " has already been used as a variable name!" << llendl;
00208                 }
00209                 *varp = new LLMessageVariable(name, type, size);
00210                 if (((*varp)->getType() != MVT_VARIABLE)
00211                         &&(mTotalSize != -1))
00212                 {
00213                         mTotalSize += (*varp)->getSize();
00214                 }
00215                 else
00216                 {
00217                         mTotalSize = -1;
00218                 }
00219         }
00220 
00221         EMsgVariableType getVariableType(char *name)
00222         {
00223                 return (mMemberVariables[name])->getType();
00224         }
00225 
00226         S32 getVariableSize(char *name)
00227         {
00228                 return (mMemberVariables[name])->getSize();
00229         }
00230 
00231         const LLMessageVariable* getVariable(char* name) const
00232         {
00233                 message_variable_map_t::const_iterator iter = mMemberVariables.find(name);
00234                 return iter != mMemberVariables.end()? *iter : NULL;
00235         }
00236 
00237         friend std::ostream&     operator<<(std::ostream& s, LLMessageBlock &msg);
00238 
00239         typedef LLDynamicArrayIndexed<LLMessageVariable*, const char *, 8> message_variable_map_t;
00240         message_variable_map_t                                  mMemberVariables;
00241         char                                                                    *mName;
00242         EMsgBlockType                                                   mType;
00243         S32                                                                             mNumber;
00244         S32                                                                             mTotalSize;
00245 };
00246 
00247 
00248 enum EMsgFrequency
00249 {
00250         MFT_NULL        = 0,  // value is size of message number in bytes
00251         MFT_HIGH        = 1,
00252         MFT_MEDIUM      = 2,
00253         MFT_LOW         = 4
00254 };
00255 
00256 typedef enum e_message_trust
00257 {
00258         MT_TRUST,
00259         MT_NOTRUST
00260 } EMsgTrust;
00261 
00262 enum EMsgEncoding
00263 {
00264         ME_UNENCODED,
00265         ME_ZEROCODED
00266 };
00267 
00268 enum EMsgDeprecation
00269 {
00270         MD_NOTDEPRECATED,
00271         MD_UDPDEPRECATED,
00272         MD_DEPRECATED
00273 };
00274 
00275 class LLMessageTemplateHandlerEntry
00276 {
00277 public:
00278         LLMessageTemplateHandlerEntry(message_handler_func_t handler, void **userdata = NULL) :
00279                 mHandlerFunc(handler), mUserData(userdata) {}
00280 
00281         void call(LLMessageSystem *msgsystem) const { mHandlerFunc(msgsystem, mUserData); }
00282 
00283         bool operator==(const LLMessageTemplateHandlerEntry&a) { return mHandlerFunc == a.mHandlerFunc; }
00284 private:
00285         // message handler function (this is set by each application)
00286         message_handler_func_t mHandlerFunc;
00287         void **mUserData;       
00288 };
00289 
00290 class callHandler : public std::unary_function<LLMessageTemplateHandlerEntry, void>
00291 {
00292 public:
00293         callHandler(LLMessageSystem *msg) : mMsg(msg) {}
00294         void operator()(const LLMessageTemplateHandlerEntry& a) const { a.call(mMsg); }
00295 private:
00296         LLMessageSystem *mMsg;
00297 };
00298 
00299 class LLMessageTemplate
00300 {
00301 public:
00302         LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq)
00303                 : 
00304                 //mMemberBlocks(),
00305                 mName(NULL),
00306                 mFrequency(freq),
00307                 mTrust(MT_NOTRUST),
00308                 mEncoding(ME_ZEROCODED),
00309                 mDeprecation(MD_NOTDEPRECATED),
00310                 mMessageNumber(message_number),
00311                 mTotalSize(0), 
00312                 mReceiveCount(0),
00313                 mReceiveBytes(0),
00314                 mReceiveInvalid(0),
00315                 mDecodeTimeThisFrame(0.f),
00316                 mTotalDecoded(0),
00317                 mTotalDecodeTime(0.f),
00318                 mMaxDecodeTimePerMsg(0.f),
00319                 mBanFromTrusted(false),
00320                 mBanFromUntrusted(false)
00321         { 
00322                 mName = gMessageStringTable.getString(name);
00323         }
00324 
00325         ~LLMessageTemplate()
00326         {
00327                 for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer());
00328 }
00329 
00330         void addBlock(LLMessageBlock *blockp)
00331         {
00332                 LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName];
00333                 if (*member_blockp != NULL)
00334                 {
00335                         llerrs << "Block " << blockp->mName
00336                                 << "has already been used as a block name!" << llendl;
00337                 }
00338                 *member_blockp = blockp;
00339                 if (  (mTotalSize != -1)
00340                         &&(blockp->mTotalSize != -1)
00341                         &&(  (blockp->mType == MBT_SINGLE)
00342                            ||(blockp->mType == MBT_MULTIPLE)))
00343                 {
00344                         mTotalSize += blockp->mNumber*blockp->mTotalSize;
00345                 }
00346                 else
00347                 {
00348                         mTotalSize = -1;
00349                 }
00350         }
00351 
00352         LLMessageBlock *getBlock(char *name)
00353         {
00354                 return mMemberBlocks[name];
00355         }
00356 
00357         // Trusted messages can only be recieved on trusted circuits.
00358         void setTrust(EMsgTrust t)
00359         {
00360                 mTrust = t;
00361         }
00362 
00363         EMsgTrust getTrust(void) const
00364         {
00365                 return mTrust;
00366         }
00367 
00368         // controls for how the message should be encoded
00369         void setEncoding(EMsgEncoding e)
00370         {
00371                 mEncoding = e;
00372         }
00373         EMsgEncoding getEncoding() const
00374         {
00375                 return mEncoding;
00376         }
00377 
00378         void setDeprecation(EMsgDeprecation d)
00379         {
00380                 mDeprecation = d;
00381         }
00382 
00383         EMsgDeprecation getDeprecation() const
00384         {
00385                 return mDeprecation;
00386         }
00387 
00396         void addHandlerFunc(message_handler_func_t handler, void **user_data)   
00397         {
00398                 LLMessageTemplateHandlerEntry h(handler, user_data);
00399 
00400                 if ( std::find(mHandlers.begin(), mHandlers.end(), h ) != mHandlers.end() )
00401                 {
00402                         return;
00403                 }
00404 
00405                 mHandlers.push_back( h );
00406         }
00407 
00416         void setHandlerFunc(message_handler_func_t handler, void **user_data)
00417         {
00418                 if ( !mHandlers.empty() )
00419                 {
00420                         llwarns << "Removing existing handlers for message " << mName << llendl;
00421                 }
00422                 mHandlers.clear();
00423                 addHandlerFunc(handler, user_data);
00424         }
00425 
00433         void delHandlerFunc(message_handler_func_t handler)
00434         {
00435                 mHandlers.remove( LLMessageTemplateHandlerEntry(handler) );
00436         }
00437 
00438         BOOL callHandlerFunc(LLMessageSystem *msgsystem) const
00439         {
00440                 if ( mHandlers.empty() )
00441                 {
00442                         return FALSE;
00443                 }
00444 
00445                 std::for_each(mHandlers.begin(), mHandlers.end(), callHandler(msgsystem));
00446                 return TRUE;
00447         }
00448 
00449         bool isBanned(bool trustedSource) const
00450         {
00451                 return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
00452         }
00453 
00454         friend std::ostream&     operator<<(std::ostream& s, LLMessageTemplate &msg);
00455 
00456         const LLMessageBlock* getBlock(char* name) const
00457         {
00458                 message_block_map_t::const_iterator iter = mMemberBlocks.find(name);
00459                 return iter != mMemberBlocks.end()? *iter : NULL;
00460         }
00461 
00462 public:
00463         typedef LLDynamicArrayIndexed<LLMessageBlock*, char*, 8> message_block_map_t;
00464         message_block_map_t                                             mMemberBlocks;
00465         char                                                                    *mName;
00466         EMsgFrequency                                                   mFrequency;
00467         EMsgTrust                                                               mTrust;
00468         EMsgEncoding                                                    mEncoding;
00469         EMsgDeprecation                                                 mDeprecation;
00470         U32                                                                             mMessageNumber;
00471         S32                                                                             mTotalSize;
00472         U32                                                                             mReceiveCount;          // how many of this template have been received since last reset
00473         U32                                                                             mReceiveBytes;          // How many bytes received
00474         U32                                                                             mReceiveInvalid;        // How many "invalid" packets
00475         F32                                                                             mDecodeTimeThisFrame;   // Total seconds spent decoding this frame
00476         U32                                                                             mTotalDecoded;          // Total messages successfully decoded
00477         F32                                                                             mTotalDecodeTime;       // Total time successfully decoding messages
00478         F32                                                                             mMaxDecodeTimePerMsg;
00479 
00480         bool                                                                    mBanFromTrusted;
00481         bool                                                                    mBanFromUntrusted;
00482 
00483 private:
00484         std::list<LLMessageTemplateHandlerEntry> mHandlers;
00485 };
00486 
00487 #endif // LL_LLMESSAGETEMPLATE_H

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