00001
00032 #ifndef LL_LLMESSAGETEMPLATE_H
00033 #define LL_LLMESSAGETEMPLATE_H
00034
00035 #include "lldarray.h"
00036 #include "message.h"
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
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];
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
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,
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
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
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
00358 void setTrust(EMsgTrust t)
00359 {
00360 mTrust = t;
00361 }
00362
00363 EMsgTrust getTrust(void) const
00364 {
00365 return mTrust;
00366 }
00367
00368
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;
00473 U32 mReceiveBytes;
00474 U32 mReceiveInvalid;
00475 F32 mDecodeTimeThisFrame;
00476 U32 mTotalDecoded;
00477 F32 mTotalDecodeTime;
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