PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llmessage/llsdmessagebuilder.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 424 lines | 301 code | 73 blank | 50 comment | 17 complexity | 3a49a0504943577fe2b2045e1d97d768 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsdmessagebuilder.cpp
  3. * @brief LLSDMessageBuilder class implementation.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llsdmessagebuilder.h"
  28. #include "llmessagetemplate.h"
  29. #include "llmath.h"
  30. #include "llquaternion.h"
  31. #include "llsdutil.h"
  32. #include "llsdutil_math.h"
  33. #include "llsdserialize.h"
  34. #include "u64.h"
  35. #include "v3dmath.h"
  36. #include "v3math.h"
  37. #include "v4math.h"
  38. LLSDMessageBuilder::LLSDMessageBuilder() :
  39. mCurrentMessage(LLSD::emptyMap()),
  40. mCurrentBlock(NULL),
  41. mCurrentMessageName(""),
  42. mCurrentBlockName(""),
  43. mbSBuilt(FALSE),
  44. mbSClear(TRUE)
  45. {
  46. }
  47. //virtual
  48. LLSDMessageBuilder::~LLSDMessageBuilder()
  49. {
  50. }
  51. // virtual
  52. void LLSDMessageBuilder::newMessage(const char* name)
  53. {
  54. mbSBuilt = FALSE;
  55. mbSClear = FALSE;
  56. mCurrentMessage = LLSD::emptyMap();
  57. mCurrentMessageName = (char*)name;
  58. }
  59. // virtual
  60. void LLSDMessageBuilder::clearMessage()
  61. {
  62. mbSBuilt = FALSE;
  63. mbSClear = TRUE;
  64. mCurrentMessage = LLSD::emptyMap();
  65. mCurrentMessageName = "";
  66. }
  67. // virtual
  68. void LLSDMessageBuilder::nextBlock(const char* blockname)
  69. {
  70. LLSD& block = mCurrentMessage[blockname];
  71. if(block.isUndefined())
  72. {
  73. block[0] = LLSD::emptyMap();
  74. mCurrentBlock = &(block[0]);
  75. }
  76. else if(block.isArray())
  77. {
  78. block[block.size()] = LLSD::emptyMap();
  79. mCurrentBlock = &(block[block.size() - 1]);
  80. }
  81. else
  82. {
  83. llerrs << "existing block not array" << llendl;
  84. }
  85. }
  86. // TODO: Remove this horror...
  87. BOOL LLSDMessageBuilder::removeLastBlock()
  88. {
  89. /* TODO: finish implementing this */
  90. return FALSE;
  91. }
  92. void LLSDMessageBuilder::addBinaryData(
  93. const char* varname,
  94. const void* data,
  95. S32 size)
  96. {
  97. std::vector<U8> v;
  98. v.resize(size);
  99. memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size);
  100. (*mCurrentBlock)[varname] = v;
  101. }
  102. void LLSDMessageBuilder::addS8(const char* varname, S8 v)
  103. {
  104. (*mCurrentBlock)[varname] = v;
  105. }
  106. void LLSDMessageBuilder::addU8(const char* varname, U8 v)
  107. {
  108. (*mCurrentBlock)[varname] = v;
  109. }
  110. void LLSDMessageBuilder::addS16(const char* varname, S16 v)
  111. {
  112. (*mCurrentBlock)[varname] = v;
  113. }
  114. void LLSDMessageBuilder::addU16(const char* varname, U16 v)
  115. {
  116. (*mCurrentBlock)[varname] = v;
  117. }
  118. void LLSDMessageBuilder::addF32(const char* varname, F32 v)
  119. {
  120. (*mCurrentBlock)[varname] = v;
  121. }
  122. void LLSDMessageBuilder::addS32(const char* varname, S32 v)
  123. {
  124. (*mCurrentBlock)[varname] = v;
  125. }
  126. void LLSDMessageBuilder::addU32(const char* varname, U32 v)
  127. {
  128. (*mCurrentBlock)[varname] = ll_sd_from_U32(v);
  129. }
  130. void LLSDMessageBuilder::addU64(const char* varname, U64 v)
  131. {
  132. (*mCurrentBlock)[varname] = ll_sd_from_U64(v);
  133. }
  134. void LLSDMessageBuilder::addF64(const char* varname, F64 v)
  135. {
  136. (*mCurrentBlock)[varname] = v;
  137. }
  138. void LLSDMessageBuilder::addIPAddr(const char* varname, U32 v)
  139. {
  140. (*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v);
  141. }
  142. void LLSDMessageBuilder::addIPPort(const char* varname, U16 v)
  143. {
  144. (*mCurrentBlock)[varname] = v;
  145. }
  146. void LLSDMessageBuilder::addBOOL(const char* varname, BOOL v)
  147. {
  148. (*mCurrentBlock)[varname] = (v == TRUE);
  149. }
  150. void LLSDMessageBuilder::addString(const char* varname, const char* v)
  151. {
  152. if (v)
  153. (*mCurrentBlock)[varname] = v; /* Flawfinder: ignore */
  154. else
  155. (*mCurrentBlock)[varname] = "";
  156. }
  157. void LLSDMessageBuilder::addString(const char* varname, const std::string& v)
  158. {
  159. if (v.size())
  160. (*mCurrentBlock)[varname] = v;
  161. else
  162. (*mCurrentBlock)[varname] = "";
  163. }
  164. void LLSDMessageBuilder::addVector3(const char* varname, const LLVector3& v)
  165. {
  166. (*mCurrentBlock)[varname] = ll_sd_from_vector3(v);
  167. }
  168. void LLSDMessageBuilder::addVector4(const char* varname, const LLVector4& v)
  169. {
  170. (*mCurrentBlock)[varname] = ll_sd_from_vector4(v);
  171. }
  172. void LLSDMessageBuilder::addVector3d(const char* varname, const LLVector3d& v)
  173. {
  174. (*mCurrentBlock)[varname] = ll_sd_from_vector3d(v);
  175. }
  176. void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v)
  177. {
  178. (*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
  179. }
  180. void LLSDMessageBuilder::addUUID(const char* varname, const LLUUID& v)
  181. {
  182. (*mCurrentBlock)[varname] = v;
  183. }
  184. void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
  185. {
  186. }
  187. BOOL LLSDMessageBuilder::isMessageFull(const char* blockname) const
  188. {
  189. return FALSE;
  190. }
  191. U32 LLSDMessageBuilder::buildMessage(U8*, U32, U8)
  192. {
  193. return 0;
  194. }
  195. void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
  196. {
  197. // copy the blocks
  198. // counting variables used to encode multiple block info
  199. S32 block_count = 0;
  200. char* block_name = NULL;
  201. // loop through msg blocks to loop through variables, totalling up size
  202. // data and filling the new (send) message
  203. LLMsgData::msg_blk_data_map_t::const_iterator iter =
  204. data.mMemberBlocks.begin();
  205. LLMsgData::msg_blk_data_map_t::const_iterator end =
  206. data.mMemberBlocks.end();
  207. for(; iter != end; ++iter)
  208. {
  209. const LLMsgBlkData* mbci = iter->second;
  210. if(!mbci) continue;
  211. // do we need to encode a block code?
  212. if (block_count == 0)
  213. {
  214. block_count = mbci->mBlockNumber;
  215. block_name = (char*)mbci->mName;
  216. }
  217. // counting down mutliple blocks
  218. block_count--;
  219. nextBlock(block_name);
  220. // now loop through the variables
  221. LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
  222. LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
  223. for(; dit != dend; ++dit)
  224. {
  225. const LLMsgVarData& mvci = *dit;
  226. const char* varname = mvci.getName();
  227. switch(mvci.getType())
  228. {
  229. case MVT_FIXED:
  230. addBinaryData(varname, mvci.getData(), mvci.getSize());
  231. break;
  232. case MVT_VARIABLE:
  233. {
  234. const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated
  235. if (mvci.getDataSize() == 1 && end == 0)
  236. {
  237. addString(varname, (const char*)mvci.getData());
  238. }
  239. else
  240. {
  241. addBinaryData(varname, mvci.getData(), mvci.getSize());
  242. }
  243. break;
  244. }
  245. case MVT_U8:
  246. addU8(varname, *(U8*)mvci.getData());
  247. break;
  248. case MVT_U16:
  249. addU16(varname, *(U16*)mvci.getData());
  250. break;
  251. case MVT_U32:
  252. addU32(varname, *(U32*)mvci.getData());
  253. break;
  254. case MVT_U64:
  255. addU64(varname, *(U64*)mvci.getData());
  256. break;
  257. case MVT_S8:
  258. addS8(varname, *(S8*)mvci.getData());
  259. break;
  260. case MVT_S16:
  261. addS16(varname, *(S16*)mvci.getData());
  262. break;
  263. case MVT_S32:
  264. addS32(varname, *(S32*)mvci.getData());
  265. break;
  266. // S64 not supported in LLSD so we just truncate it
  267. case MVT_S64:
  268. addS32(varname, *(S64*)mvci.getData());
  269. break;
  270. case MVT_F32:
  271. addF32(varname, *(F32*)mvci.getData());
  272. break;
  273. case MVT_F64:
  274. addF64(varname, *(F64*)mvci.getData());
  275. break;
  276. case MVT_LLVector3:
  277. addVector3(varname, *(LLVector3*)mvci.getData());
  278. break;
  279. case MVT_LLVector3d:
  280. addVector3d(varname, *(LLVector3d*)mvci.getData());
  281. break;
  282. case MVT_LLVector4:
  283. addVector4(varname, *(LLVector4*)mvci.getData());
  284. break;
  285. case MVT_LLQuaternion:
  286. {
  287. LLVector3 v = *(LLVector3*)mvci.getData();
  288. LLQuaternion q;
  289. q.unpackFromVector3(v);
  290. addQuat(varname, q);
  291. break;
  292. }
  293. case MVT_LLUUID:
  294. addUUID(varname, *(LLUUID*)mvci.getData());
  295. break;
  296. case MVT_BOOL:
  297. addBOOL(varname, *(BOOL*)mvci.getData());
  298. break;
  299. case MVT_IP_ADDR:
  300. addIPAddr(varname, *(U32*)mvci.getData());
  301. break;
  302. case MVT_IP_PORT:
  303. addIPPort(varname, *(U16*)mvci.getData());
  304. break;
  305. case MVT_U16Vec3:
  306. //treated as an array of 6 bytes
  307. addBinaryData(varname, mvci.getData(), 6);
  308. break;
  309. case MVT_U16Quat:
  310. //treated as an array of 8 bytes
  311. addBinaryData(varname, mvci.getData(), 8);
  312. break;
  313. case MVT_S16Array:
  314. addBinaryData(varname, mvci.getData(), mvci.getSize());
  315. break;
  316. default:
  317. llwarns << "Unknown type in conversion of message to LLSD" << llendl;
  318. break;
  319. }
  320. }
  321. }
  322. }
  323. //virtual
  324. void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg)
  325. {
  326. mCurrentMessage = msg;
  327. lldebugs << LLSDNotationStreamer(mCurrentMessage) << llendl;
  328. }
  329. const LLSD& LLSDMessageBuilder::getMessage() const
  330. {
  331. return mCurrentMessage;
  332. }
  333. //virtual
  334. void LLSDMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
  335. //virtual
  336. BOOL LLSDMessageBuilder::isBuilt() const {return mbSBuilt;}
  337. //virtual
  338. BOOL LLSDMessageBuilder::isClear() const {return mbSClear;}
  339. //virtual
  340. S32 LLSDMessageBuilder::getMessageSize()
  341. {
  342. // babbage: size is unknown as message stored as LLSD.
  343. // return non-zero if pending data, as send can be skipped for 0 size.
  344. // return 1 to encourage senders checking size against splitting message.
  345. return mCurrentMessage.size()? 1 : 0;
  346. }
  347. //virtual
  348. const char* LLSDMessageBuilder::getMessageName() const
  349. {
  350. return mCurrentMessageName.c_str();
  351. }