llmessagetemplate.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /**
  2. * @file llmessagetemplate.h
  3. * @brief Declaration of the message template classes.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewergpl$
  6. *
  7. * Copyright (c) 2007-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLMESSAGETEMPLATE_H
  33. #define LL_LLMESSAGETEMPLATE_H
  34. #include <map>
  35. #include <string>
  36. #include <vector>
  37. #include "llerror.h"
  38. #include "llpreprocessor.h"
  39. #include "llstl.h"
  40. #include "llmessage.h"
  41. template <typename Type, typename Key, int BlockSize = 32>
  42. class LLIndexedVector
  43. {
  44. public:
  45. typedef typename std::vector<Type>::iterator iterator;
  46. typedef typename std::vector<Type>::const_iterator const_iterator;
  47. typedef typename std::vector<Type>::reverse_iterator reverse_iterator;
  48. typedef typename std::vector<Type>::const_reverse_iterator const_reverse_iterator;
  49. typedef typename std::vector<Type>::size_type size_type;
  50. protected:
  51. std::vector<Type> mVector;
  52. std::map<Key, U32> mIndexMap;
  53. public:
  54. LL_INLINE LLIndexedVector() { mVector.reserve(BlockSize); }
  55. LL_INLINE iterator begin() { return mVector.begin(); }
  56. LL_INLINE const_iterator begin() const { return mVector.begin(); }
  57. LL_INLINE iterator end() { return mVector.end(); }
  58. LL_INLINE const_iterator end() const { return mVector.end(); }
  59. LL_INLINE reverse_iterator rbegin() { return mVector.rbegin(); }
  60. LL_INLINE const_reverse_iterator rbegin() const { return mVector.rbegin(); }
  61. LL_INLINE reverse_iterator rend() { return mVector.rend(); }
  62. LL_INLINE const_reverse_iterator rend() const { return mVector.rend(); }
  63. LL_INLINE void clear() { mVector.clear(); mIndexMap.clear(); }
  64. LL_INLINE bool empty() const { return mVector.empty(); }
  65. LL_INLINE size_type size() const { return mVector.size(); }
  66. Type& operator[](const Key& k)
  67. {
  68. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  69. if (iter == mIndexMap.end())
  70. {
  71. U32 n = mVector.size();
  72. mIndexMap[k] = n;
  73. mVector.push_back(Type());
  74. llassert(mVector.size() == mIndexMap.size());
  75. return mVector[n];
  76. }
  77. else
  78. {
  79. return mVector[iter->second];
  80. }
  81. }
  82. const_iterator find(const Key& k) const
  83. {
  84. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  85. if (iter == mIndexMap.end())
  86. {
  87. return mVector.end();
  88. }
  89. else
  90. {
  91. return mVector.begin() + iter->second;
  92. }
  93. }
  94. };
  95. class LLMsgVarData
  96. {
  97. protected:
  98. LOG_CLASS(LLMsgVarData);
  99. public:
  100. LLMsgVarData()
  101. : mName(NULL),
  102. mSize(-1),
  103. mDataSize(-1),
  104. mData(NULL),
  105. mType(MVT_U8)
  106. {
  107. }
  108. LLMsgVarData(const char* name, EMsgVariableType type)
  109. : mSize(-1),
  110. mDataSize(-1),
  111. mData(NULL),
  112. mType(type)
  113. {
  114. mName = (char*)name;
  115. }
  116. ~LLMsgVarData()
  117. {
  118. // copy constructor just copies the mData pointer, so only delete mData
  119. // explicitly
  120. }
  121. void deleteData()
  122. {
  123. delete[] mData;
  124. mData = NULL;
  125. }
  126. void addData(const void* indata, S32 size, EMsgVariableType type,
  127. S32 data_size = -1);
  128. LL_INLINE char* getName() const { return mName; }
  129. LL_INLINE S32 getSize() const { return mSize; }
  130. LL_INLINE void* getData() { return (void*)mData; }
  131. LL_INLINE const void* getData() const { return (const void*)mData; }
  132. LL_INLINE S32 getDataSize() const { return mDataSize; }
  133. LL_INLINE EMsgVariableType getType() const { return mType; }
  134. static std::string variableTypeToString(EMsgVariableType type);
  135. protected:
  136. char* mName;
  137. S32 mSize;
  138. S32 mDataSize;
  139. U8* mData;
  140. EMsgVariableType mType;
  141. };
  142. class LLMsgBlkData
  143. {
  144. public:
  145. LLMsgBlkData(const char* name, S32 blocknum)
  146. : mBlockNumber(blocknum),
  147. mTotalSize(-1)
  148. {
  149. mName = (char*)name;
  150. }
  151. ~LLMsgBlkData()
  152. {
  153. for (msg_var_data_map_t::iterator iter = mMemberVarData.begin(),
  154. end = mMemberVarData.end();
  155. iter != end; ++iter)
  156. {
  157. iter->deleteData();
  158. }
  159. }
  160. void addVariable(const char* name, EMsgVariableType type)
  161. {
  162. LLMsgVarData tmp(name,type);
  163. mMemberVarData[name] = tmp;
  164. }
  165. void addData(char* name, const void* data, S32 size, EMsgVariableType type,
  166. S32 data_size = -1)
  167. {
  168. // creates a new entry if one doesn't exist:
  169. LLMsgVarData* temp = &mMemberVarData[name];
  170. temp->addData(data, size, type, data_size);
  171. }
  172. public:
  173. S32 mBlockNumber;
  174. typedef LLIndexedVector<LLMsgVarData, const char*, 8> msg_var_data_map_t;
  175. msg_var_data_map_t mMemberVarData;
  176. char* mName;
  177. S32 mTotalSize;
  178. };
  179. class LLMsgData
  180. {
  181. public:
  182. LLMsgData(const char* name)
  183. : mTotalSize(-1)
  184. {
  185. mName = (char*)name;
  186. }
  187. ~LLMsgData()
  188. {
  189. for_each(mMemberBlocks.begin(), mMemberBlocks.end(),
  190. DeletePairedPointer());
  191. mMemberBlocks.clear();
  192. }
  193. LL_INLINE void addBlock(LLMsgBlkData* blockp)
  194. {
  195. mMemberBlocks[blockp->mName] = blockp;
  196. }
  197. void addDataFast(char* blockname, char* varname, const void* data,
  198. S32 size, EMsgVariableType type, S32 data_size = -1);
  199. public:
  200. typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t;
  201. msg_blk_data_map_t mMemberBlocks;
  202. char* mName;
  203. S32 mTotalSize;
  204. };
  205. // LLMessage* classes store the template of messages
  206. class LLMessageVariable
  207. {
  208. public:
  209. LLMessageVariable()
  210. : mName(NULL),
  211. mType(MVT_NULL),
  212. mSize(-1)
  213. {
  214. }
  215. LLMessageVariable(char* name)
  216. : mType(MVT_NULL),
  217. mSize(-1)
  218. {
  219. mName = name;
  220. }
  221. LLMessageVariable(const char* name, EMsgVariableType type, S32 size)
  222. : mType(type),
  223. mSize(size)
  224. {
  225. mName = gMessageStringTable.getString(name);
  226. }
  227. ~LLMessageVariable() {}
  228. friend std::ostream& operator<<(std::ostream& s, LLMessageVariable& msg);
  229. LL_INLINE EMsgVariableType getType() const { return mType; }
  230. LL_INLINE S32 getSize() const { return mSize; }
  231. LL_INLINE char* getName() const { return mName; }
  232. protected:
  233. char* mName;
  234. EMsgVariableType mType;
  235. S32 mSize;
  236. };
  237. typedef enum e_message_block_type
  238. {
  239. MBT_NULL,
  240. MBT_SINGLE,
  241. MBT_MULTIPLE,
  242. MBT_VARIABLE,
  243. MBT_EOF
  244. } EMsgBlockType;
  245. class LLMessageBlock
  246. {
  247. public:
  248. LLMessageBlock(const char* name, EMsgBlockType type, S32 number = 1)
  249. : mType(type),
  250. mNumber(number),
  251. mTotalSize(0)
  252. {
  253. mName = gMessageStringTable.getString(name);
  254. }
  255. ~LLMessageBlock()
  256. {
  257. for_each(mMemberVariables.begin(), mMemberVariables.end(),
  258. DeletePointer());
  259. mMemberVariables.clear();
  260. }
  261. void addVariable(char* name, EMsgVariableType type, S32 size)
  262. {
  263. LLMessageVariable** varp = &mMemberVariables[name];
  264. if (*varp != NULL)
  265. {
  266. llerrs << name << " has already been used as a variable name !"
  267. << llendl;
  268. }
  269. *varp = new LLMessageVariable(name, type, size);
  270. if ((*varp)->getType() != MVT_VARIABLE && mTotalSize != -1)
  271. {
  272. mTotalSize += (*varp)->getSize();
  273. }
  274. else
  275. {
  276. mTotalSize = -1;
  277. }
  278. }
  279. LL_INLINE EMsgVariableType getVariableType(char* name)
  280. {
  281. return (mMemberVariables[name])->getType();
  282. }
  283. LL_INLINE S32 getVariableSize(char* name)
  284. {
  285. return (mMemberVariables[name])->getSize();
  286. }
  287. LL_INLINE const LLMessageVariable* getVariable(char* name) const
  288. {
  289. message_variable_map_t::const_iterator iter = mMemberVariables.find(name);
  290. return iter != mMemberVariables.end() ? *iter : NULL;
  291. }
  292. friend std::ostream& operator<<(std::ostream& s, LLMessageBlock& msg);
  293. public:
  294. typedef LLIndexedVector<LLMessageVariable*, const char*, 8> message_variable_map_t;
  295. message_variable_map_t mMemberVariables;
  296. char* mName;
  297. EMsgBlockType mType;
  298. S32 mNumber;
  299. S32 mTotalSize;
  300. };
  301. enum EMsgFrequency
  302. {
  303. MFT_NULL = 0, // value is size of message number in bytes
  304. MFT_HIGH = 1,
  305. MFT_MEDIUM = 2,
  306. MFT_LOW = 4
  307. };
  308. typedef enum e_message_trust
  309. {
  310. MT_TRUST,
  311. MT_NOTRUST
  312. } EMsgTrust;
  313. enum EMsgEncoding
  314. {
  315. ME_UNENCODED,
  316. ME_ZEROCODED
  317. };
  318. enum EMsgDeprecation
  319. {
  320. MD_NOTDEPRECATED,
  321. MD_UDPDEPRECATED,
  322. MD_UDPBLACKLISTED,
  323. MD_DEPRECATED
  324. };
  325. class LLMessageTemplate
  326. {
  327. protected:
  328. LOG_CLASS(LLMessageTemplate);
  329. public:
  330. LLMessageTemplate(const char* name, U32 message_number, EMsgFrequency freq)
  331. : //mMemberBlocks(),
  332. mName(NULL),
  333. mFrequency(freq),
  334. mTrust(MT_NOTRUST),
  335. mEncoding(ME_ZEROCODED),
  336. mDeprecation(MD_NOTDEPRECATED),
  337. mMessageNumber(message_number),
  338. mTotalSize(0),
  339. mReceiveCount(0),
  340. mReceiveBytes(0),
  341. mReceiveInvalid(0),
  342. mDecodeTimeThisFrame(0.f),
  343. mTotalDecoded(0),
  344. mTotalDecodeTime(0.f),
  345. mMaxDecodeTimePerMsg(0.f),
  346. mBanFromTrusted(false),
  347. mBanFromUntrusted(false),
  348. mHandlerFunc(NULL),
  349. mUserData(NULL)
  350. {
  351. mName = gMessageStringTable.getString(name);
  352. }
  353. ~LLMessageTemplate()
  354. {
  355. for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer());
  356. mMemberBlocks.clear();
  357. }
  358. void addBlock(LLMessageBlock* blockp)
  359. {
  360. LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName];
  361. if (*member_blockp != NULL)
  362. {
  363. llerrs << "Block " << blockp->mName
  364. << "has already been used as a block name!" << llendl;
  365. }
  366. *member_blockp = blockp;
  367. if (mTotalSize != -1 && blockp->mTotalSize != -1 &&
  368. (blockp->mType == MBT_SINGLE || blockp->mType == MBT_MULTIPLE))
  369. {
  370. mTotalSize += blockp->mNumber * blockp->mTotalSize;
  371. }
  372. else
  373. {
  374. mTotalSize = -1;
  375. }
  376. }
  377. LL_INLINE LLMessageBlock* getBlock(char* name)
  378. {
  379. return mMemberBlocks[name];
  380. }
  381. // Trusted messages can only be received on trusted circuits.
  382. LL_INLINE void setTrust(EMsgTrust t)
  383. {
  384. mTrust = t;
  385. }
  386. LL_INLINE EMsgTrust getTrust() const
  387. {
  388. return mTrust;
  389. }
  390. // controls for how the message should be encoded
  391. LL_INLINE void setEncoding(EMsgEncoding e)
  392. {
  393. mEncoding = e;
  394. }
  395. LL_INLINE EMsgEncoding getEncoding() const
  396. {
  397. return mEncoding;
  398. }
  399. LL_INLINE void setDeprecation(EMsgDeprecation d)
  400. {
  401. mDeprecation = d;
  402. }
  403. EMsgDeprecation getDeprecation() const
  404. {
  405. return mDeprecation;
  406. }
  407. LL_INLINE void setHandlerFunc(void (*handler_func)(LLMessageSystem*,
  408. void**),
  409. void** user_data)
  410. {
  411. mHandlerFunc = handler_func;
  412. mUserData = user_data;
  413. }
  414. LL_INLINE bool callHandlerFunc(LLMessageSystem* msgsystem) const
  415. {
  416. if (mHandlerFunc)
  417. {
  418. mHandlerFunc(msgsystem, mUserData);
  419. return true;
  420. }
  421. return false;
  422. }
  423. LL_INLINE bool isUdpBanned() const
  424. {
  425. return mDeprecation == MD_UDPBLACKLISTED;
  426. }
  427. void banUdp();
  428. LL_INLINE bool isBanned(bool trustedSource) const
  429. {
  430. return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
  431. }
  432. friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate& msg);
  433. LL_INLINE const LLMessageBlock* getBlock(char* name) const
  434. {
  435. message_block_map_t::const_iterator iter = mMemberBlocks.find(name);
  436. return iter != mMemberBlocks.end() ? *iter : NULL;
  437. }
  438. public:
  439. typedef LLIndexedVector<LLMessageBlock*, char*, 8> message_block_map_t;
  440. message_block_map_t mMemberBlocks;
  441. char* mName;
  442. EMsgFrequency mFrequency;
  443. EMsgTrust mTrust;
  444. EMsgEncoding mEncoding;
  445. EMsgDeprecation mDeprecation;
  446. U32 mMessageNumber;
  447. S32 mTotalSize;
  448. // how many of this template have been received since last reset:
  449. U32 mReceiveCount;
  450. U32 mReceiveBytes; // How many bytes received
  451. U32 mReceiveInvalid; // How many "invalid" packets
  452. F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame
  453. U32 mTotalDecoded; // Total messages successfully decoded
  454. F32 mTotalDecodeTime; // Total time successfully decoding messages
  455. F32 mMaxDecodeTimePerMsg;
  456. bool mBanFromTrusted;
  457. bool mBanFromUntrusted;
  458. private:
  459. // message handler function (this is set by each application)
  460. void (*mHandlerFunc)(LLMessageSystem* msgsystem, void** user_data);
  461. void** mUserData;
  462. };
  463. #endif // LL_LLMESSAGETEMPLATE_H