llsdmessagebuilder.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /**
  2. * @file llsdmessagebuilder.cpp
  3. * @brief LLSDMessageBuilder class implementation.
  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. #include "linden_common.h"
  33. #include "llsdmessagebuilder.h"
  34. #include "llmessagetemplate.h"
  35. #include "llmath.h"
  36. #include "llquaternion.h"
  37. #include "llsdutil.h"
  38. #include "llsdutil_math.h"
  39. #include "llsdserialize.h"
  40. #include "llvector3d.h"
  41. #include "llvector3.h"
  42. #include "llvector4.h"
  43. LLSDMessageBuilder::LLSDMessageBuilder()
  44. : mCurrentMessage(LLSD::emptyMap()),
  45. mCurrentBlock(NULL),
  46. mSBuilt(false),
  47. mSClear(true)
  48. {
  49. }
  50. //virtual
  51. void LLSDMessageBuilder::newMessage(const char* name)
  52. {
  53. mSBuilt = false;
  54. mSClear = false;
  55. mCurrentMessage = LLSD::emptyMap();
  56. mCurrentMessageName = (char*)name;
  57. }
  58. //virtual
  59. void LLSDMessageBuilder::clearMessage()
  60. {
  61. mSBuilt = false;
  62. mSClear = true;
  63. mCurrentMessage = LLSD::emptyMap();
  64. mCurrentMessageName = "";
  65. }
  66. //virtual
  67. void LLSDMessageBuilder::nextBlock(const char* blockname)
  68. {
  69. LLSD& block = mCurrentMessage[blockname];
  70. if (block.isUndefined())
  71. {
  72. block[0] = LLSD::emptyMap();
  73. mCurrentBlock = &(block[0]);
  74. }
  75. else if (block.isArray())
  76. {
  77. block[block.size()] = LLSD::emptyMap();
  78. mCurrentBlock = &(block[block.size() - 1]);
  79. }
  80. else
  81. {
  82. llerrs << "Existing block is not an array" << llendl;
  83. }
  84. }
  85. void LLSDMessageBuilder::addBinaryData(const char* varname, const void* data,
  86. S32 size)
  87. {
  88. LLSD::Binary v;
  89. v.resize(size);
  90. memcpy(v.data(), reinterpret_cast<const U8*>(data), size);
  91. (*mCurrentBlock)[varname] = v;
  92. }
  93. void LLSDMessageBuilder::addS8(const char* varname, S8 v)
  94. {
  95. (*mCurrentBlock)[varname] = v;
  96. }
  97. void LLSDMessageBuilder::addU8(const char* varname, U8 v)
  98. {
  99. (*mCurrentBlock)[varname] = v;
  100. }
  101. void LLSDMessageBuilder::addS16(const char* varname, S16 v)
  102. {
  103. (*mCurrentBlock)[varname] = v;
  104. }
  105. void LLSDMessageBuilder::addU16(const char* varname, U16 v)
  106. {
  107. (*mCurrentBlock)[varname] = v;
  108. }
  109. void LLSDMessageBuilder::addF32(const char* varname, F32 v)
  110. {
  111. (*mCurrentBlock)[varname] = v;
  112. }
  113. void LLSDMessageBuilder::addS32(const char* varname, S32 v)
  114. {
  115. (*mCurrentBlock)[varname] = v;
  116. }
  117. void LLSDMessageBuilder::addU32(const char* varname, U32 v)
  118. {
  119. (*mCurrentBlock)[varname] = ll_sd_from_U32(v);
  120. }
  121. void LLSDMessageBuilder::addU64(const char* varname, U64 v)
  122. {
  123. (*mCurrentBlock)[varname] = ll_sd_from_U64(v);
  124. }
  125. void LLSDMessageBuilder::addF64(const char* varname, F64 v)
  126. {
  127. (*mCurrentBlock)[varname] = v;
  128. }
  129. void LLSDMessageBuilder::addIPAddr(const char* varname, U32 v)
  130. {
  131. (*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v);
  132. }
  133. void LLSDMessageBuilder::addIPPort(const char* varname, U16 v)
  134. {
  135. (*mCurrentBlock)[varname] = v;
  136. }
  137. void LLSDMessageBuilder::addBool(const char* varname, bool v)
  138. {
  139. (*mCurrentBlock)[varname] = v;
  140. }
  141. void LLSDMessageBuilder::addString(const char* varname, const char* v)
  142. {
  143. if (v)
  144. {
  145. (*mCurrentBlock)[varname] = v;
  146. }
  147. else
  148. {
  149. (*mCurrentBlock)[varname] = "";
  150. }
  151. }
  152. void LLSDMessageBuilder::addString(const char* varname, const std::string& v)
  153. {
  154. if (v.size())
  155. {
  156. (*mCurrentBlock)[varname] = v;
  157. }
  158. else
  159. {
  160. (*mCurrentBlock)[varname] = "";
  161. }
  162. }
  163. void LLSDMessageBuilder::addVector3(const char* varname, const LLVector3& v)
  164. {
  165. (*mCurrentBlock)[varname] = ll_sd_from_vector3(v);
  166. }
  167. void LLSDMessageBuilder::addVector4(const char* varname, const LLVector4& v)
  168. {
  169. (*mCurrentBlock)[varname] = ll_sd_from_vector4(v);
  170. }
  171. void LLSDMessageBuilder::addVector3d(const char* varname, const LLVector3d& v)
  172. {
  173. (*mCurrentBlock)[varname] = ll_sd_from_vector3d(v);
  174. }
  175. void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v)
  176. {
  177. (*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
  178. }
  179. void LLSDMessageBuilder::addUUID(const char* varname, const LLUUID& v)
  180. {
  181. (*mCurrentBlock)[varname] = v;
  182. }
  183. void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
  184. {
  185. // Counting variables used to encode multiple block info
  186. S32 block_count = 0;
  187. char* block_name = NULL;
  188. // Loop through msg blocks to loop through variables, totalling up size
  189. // data and filling the new (send) message
  190. for (LLMsgData::msg_blk_data_map_t::const_iterator
  191. iter = data.mMemberBlocks.begin(),
  192. end = data.mMemberBlocks.end(); iter != end; ++iter)
  193. {
  194. const LLMsgBlkData* mbci = iter->second;
  195. if (!mbci) continue;
  196. // Do we need to encode a block code ?
  197. if (block_count == 0)
  198. {
  199. block_count = mbci->mBlockNumber;
  200. block_name = (char*)mbci->mName;
  201. }
  202. // Counting down mutliple blocks
  203. --block_count;
  204. nextBlock(block_name);
  205. // Now loop through the variables
  206. for (LLMsgBlkData::msg_var_data_map_t::const_iterator
  207. dit = mbci->mMemberVarData.begin(),
  208. dend = mbci->mMemberVarData.end();
  209. dit != dend; ++dit)
  210. {
  211. const LLMsgVarData& mvci = *dit;
  212. const char* varname = mvci.getName();
  213. switch (mvci.getType())
  214. {
  215. case MVT_FIXED:
  216. addBinaryData(varname, mvci.getData(), mvci.getSize());
  217. break;
  218. case MVT_VARIABLE:
  219. {
  220. // Ensure null terminated
  221. const char end = ((const char*)mvci.getData())[mvci.getSize() - 1];
  222. if (mvci.getDataSize() == 1 && end == 0)
  223. {
  224. addString(varname, (const char*)mvci.getData());
  225. }
  226. else
  227. {
  228. addBinaryData(varname, mvci.getData(), mvci.getSize());
  229. }
  230. break;
  231. }
  232. case MVT_U8:
  233. addU8(varname, *(U8*)mvci.getData());
  234. break;
  235. case MVT_U16:
  236. addU16(varname, *(U16*)mvci.getData());
  237. break;
  238. case MVT_U32:
  239. addU32(varname, *(U32*)mvci.getData());
  240. break;
  241. case MVT_U64:
  242. addU64(varname, *(U64*)mvci.getData());
  243. break;
  244. case MVT_S8:
  245. addS8(varname, *(S8*)mvci.getData());
  246. break;
  247. case MVT_S16:
  248. addS16(varname, *(S16*)mvci.getData());
  249. break;
  250. case MVT_S32:
  251. addS32(varname, *(S32*)mvci.getData());
  252. break;
  253. // S64 not supported in LLSD so we just truncate it
  254. case MVT_S64:
  255. addS32(varname, *(S64*)mvci.getData());
  256. break;
  257. case MVT_F32:
  258. addF32(varname, *(F32*)mvci.getData());
  259. break;
  260. case MVT_F64:
  261. addF64(varname, *(F64*)mvci.getData());
  262. break;
  263. case MVT_LLVector3:
  264. addVector3(varname, *(LLVector3*)mvci.getData());
  265. break;
  266. case MVT_LLVector3d:
  267. addVector3d(varname, *(LLVector3d*)mvci.getData());
  268. break;
  269. case MVT_LLVector4:
  270. addVector4(varname, *(LLVector4*)mvci.getData());
  271. break;
  272. case MVT_LLQuaternion:
  273. {
  274. LLVector3 v = *(LLVector3*)mvci.getData();
  275. LLQuaternion q;
  276. q.unpackFromVector3(v);
  277. addQuat(varname, q);
  278. break;
  279. }
  280. case MVT_LLUUID:
  281. addUUID(varname, *(LLUUID*)mvci.getData());
  282. break;
  283. case MVT_BOOL:
  284. addBool(varname, *(bool*)mvci.getData());
  285. break;
  286. case MVT_IP_ADDR:
  287. addIPAddr(varname, *(U32*)mvci.getData());
  288. break;
  289. case MVT_IP_PORT:
  290. addIPPort(varname, *(U16*)mvci.getData());
  291. break;
  292. case MVT_U16Vec3:
  293. // treated as an array of 6 bytes
  294. addBinaryData(varname, mvci.getData(), 6);
  295. break;
  296. case MVT_U16Quat:
  297. // treated as an array of 8 bytes
  298. addBinaryData(varname, mvci.getData(), 8);
  299. break;
  300. case MVT_S16Array:
  301. addBinaryData(varname, mvci.getData(), mvci.getSize());
  302. break;
  303. default:
  304. llwarns << "Unknown type in conversion of message to LLSD"
  305. << llendl;
  306. }
  307. }
  308. }
  309. }
  310. //virtual
  311. void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg)
  312. {
  313. mCurrentMessage = msg;
  314. LL_DEBUGS("Messaging") << LLSDNotationStreamer(mCurrentMessage) << LL_ENDL;
  315. }