llpluginmessage.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**
  2. * @file llpluginmessage.cpp
  3. * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins.
  4. *
  5. * $LicenseInfo:firstyear=2008&license=viewergpl$
  6. *
  7. * Copyright (c) 2008-2009, Linden Research, Inc.
  8. * Copyright (c) 2009-2024, Henri Beauchamp.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "linden_common.h"
  34. #include "llpluginmessage.h"
  35. #include "llsdserialize.h"
  36. #include "llstring.h"
  37. LLPluginMessage::LLPluginMessage(const LLPluginMessage& p)
  38. {
  39. mMessage = p.mMessage;
  40. }
  41. LLPluginMessage::LLPluginMessage(const std::string& message_class,
  42. const std::string& message_name)
  43. {
  44. setMessage(message_class, message_name);
  45. }
  46. // Resets internal state.
  47. void LLPluginMessage::clear()
  48. {
  49. mMessage = LLSD::emptyMap();
  50. mMessage["params"] = LLSD::emptyMap();
  51. }
  52. // Sets the message class and name. Also has the side-effect of clearing any
  53. // key-value pairs in the message.
  54. void LLPluginMessage::setMessage(const std::string& message_class,
  55. const std::string& message_name)
  56. {
  57. clear();
  58. mMessage["class"] = message_class;
  59. mMessage["name"] = message_name;
  60. }
  61. // Sets a key/value pair in the message, where the value is a string.
  62. void LLPluginMessage::setValue(const std::string& key,
  63. const std::string& value)
  64. {
  65. mMessage["params"][key] = value;
  66. }
  67. // Sets a key/value pair in the message, where the value is LLSD.
  68. void LLPluginMessage::setValueLLSD(const std::string& key, const LLSD& value)
  69. {
  70. mMessage["params"][key] = value;
  71. }
  72. // Sets a key/value pair in the message, where the value is LLUUID.
  73. void LLPluginMessage::setValueLLUUID(const std::string& key,
  74. const LLUUID& value)
  75. {
  76. mMessage["params"][key] = value;
  77. }
  78. // Sets a key/value pair in the message, where the value is signed 32 bits.
  79. void LLPluginMessage::setValueS32(const std::string& key, S32 value)
  80. {
  81. mMessage["params"][key] = value;
  82. }
  83. // Sets a key/value pair in the message, where the value is unsigned 32 bits.
  84. // The value is stored as a string beginning with "0x".
  85. void LLPluginMessage::setValueU32(const std::string& key, U32 value)
  86. {
  87. std::stringstream temp;
  88. temp << "0x" << std::hex << value;
  89. setValue(key, temp.str());
  90. }
  91. // Sets a key/value pair in the message, where the value is a bool.
  92. void LLPluginMessage::setValueBoolean(const std::string& key, bool value)
  93. {
  94. mMessage["params"][key] = value;
  95. }
  96. // Sets a key/value pair in the message, where the value is a double.
  97. void LLPluginMessage::setValueReal(const std::string& key, F64 value)
  98. {
  99. mMessage["params"][key] = value;
  100. }
  101. // Sets a key/value pair in the message, where the value is a pointer. The
  102. void LLPluginMessage::setValuePointer(const std::string& key, void* value)
  103. {
  104. std::stringstream temp;
  105. // iostreams should output pointer values in hex with an initial 0x by
  106. // default.
  107. temp << value;
  108. setValue(key, temp.str());
  109. }
  110. // Gets the message class.
  111. std::string LLPluginMessage::getClass() const
  112. {
  113. return mMessage["class"];
  114. }
  115. // Gets the message name.
  116. std::string LLPluginMessage::getName() const
  117. {
  118. return mMessage["name"];
  119. }
  120. // Returns true if the specified key exists in this message (useful for
  121. // optional parameters).
  122. bool LLPluginMessage::hasValue(const std::string& key) const
  123. {
  124. bool result = false;
  125. if (mMessage["params"].has(key))
  126. {
  127. result = true;
  128. }
  129. return result;
  130. }
  131. // Gets the value of a key as a string. If the key does not exist, an empty
  132. // string will be returned.
  133. std::string LLPluginMessage::getValue(const std::string& key) const
  134. {
  135. std::string result;
  136. if (mMessage["params"].has(key))
  137. {
  138. result = mMessage["params"][key].asString();
  139. }
  140. return result;
  141. }
  142. // Gets the value of a key as LLSD. If the key does not exist, a null LLSD
  143. // will be returned.
  144. LLSD LLPluginMessage::getValueLLSD(const std::string& key) const
  145. {
  146. LLSD result;
  147. if (mMessage["params"].has(key))
  148. {
  149. result = mMessage["params"][key];
  150. }
  151. return result;
  152. }
  153. // Gets the value of a key as LLUUID. If the key does not exist, a null LLUUID
  154. // will be returned.
  155. LLUUID LLPluginMessage::getValueLLUUID(const std::string& key) const
  156. {
  157. LLUUID result;
  158. if (mMessage["params"].has(key))
  159. {
  160. result = mMessage["params"][key].asUUID();
  161. }
  162. return result;
  163. }
  164. // Gets the value of a key as signed 32 bits int. If the key does not exist, 0
  165. // will be returned.
  166. S32 LLPluginMessage::getValueS32(const std::string& key) const
  167. {
  168. S32 result = 0;
  169. if (mMessage["params"].has(key))
  170. {
  171. result = mMessage["params"][key].asInteger();
  172. }
  173. return result;
  174. }
  175. // Gets the value of a key as unsigned 32 bits int. If the key does not exist,
  176. // 0 will be returned.
  177. U32 LLPluginMessage::getValueU32(const std::string& key) const
  178. {
  179. U32 result = 0;
  180. if (mMessage["params"].has(key))
  181. {
  182. std::string value = mMessage["params"][key].asString();
  183. result = (U32)strtoul(value.c_str(), NULL, 16);
  184. }
  185. return result;
  186. }
  187. // Gets the value of a key as a bool. If the key does not exist, false will be
  188. // returned.
  189. bool LLPluginMessage::getValueBoolean(const std::string& key) const
  190. {
  191. bool result = false;
  192. if (mMessage["params"].has(key))
  193. {
  194. result = mMessage["params"][key].asBoolean();
  195. }
  196. return result;
  197. }
  198. // Gets the value of a key as a double. If the key does not exist, 0 will be
  199. // returned.
  200. F64 LLPluginMessage::getValueReal(const std::string& key) const
  201. {
  202. F64 result = 0.0f;
  203. if (mMessage["params"].has(key))
  204. {
  205. result = mMessage["params"][key].asReal();
  206. }
  207. return result;
  208. }
  209. // Gets the value of a key as a pointer. If the key does not exist, NULL will
  210. // be returned.
  211. void* LLPluginMessage::getValuePointer(const std::string& key) const
  212. {
  213. void* result = NULL;
  214. if (mMessage["params"].has(key))
  215. {
  216. std::string value = mMessage["params"][key].asString();
  217. result = (void*)llstrtou64(value.c_str(), NULL, 16);
  218. }
  219. return result;
  220. }
  221. // Flattens the message into a string.
  222. std::string LLPluginMessage::generate() const
  223. {
  224. std::ostringstream result;
  225. #if 0 // Pretty XML may be slightly easier to deal with while debugging...
  226. LLSDSerialize::toXML(mMessage, result);
  227. #endif
  228. LLSDSerialize::toPrettyXML(mMessage, result);
  229. return result.str();
  230. }
  231. // Parses an incoming message into component parts. Clears all existing state
  232. // before starting the parse. Returns -1 on failure, otherwise returns the
  233. // number of key/value pairs in the incoming message.
  234. S32 LLPluginMessage::parse(const std::string& message)
  235. {
  236. // Clear any previous state
  237. clear();
  238. std::istringstream input(message);
  239. return LLSDSerialize::fromXML(mMessage, input);
  240. }
  241. // Adds a message listener. TODO:DOC need more info on what uses this. When
  242. // are multiple listeners needed ?
  243. void LLPluginMessageDispatcher::addPluginMessageListener(LLPluginMessageListener* listener)
  244. {
  245. mListeners.insert(listener);
  246. }
  247. // Removes a message listener.
  248. void LLPluginMessageDispatcher::removePluginMessageListener(LLPluginMessageListener* listener)
  249. {
  250. mListeners.erase(listener);
  251. }
  252. // Distribute a message to all message listeners.
  253. void LLPluginMessageDispatcher::dispatchPluginMessage(const LLPluginMessage& message)
  254. {
  255. for (listener_set_t::iterator it = mListeners.begin();
  256. it != mListeners.end(); )
  257. {
  258. LLPluginMessageListener* listener = *it;
  259. listener->receivePluginMessage(message);
  260. // In case something deleted an entry.
  261. it = mListeners.upper_bound(listener);
  262. }
  263. }