lldispatcher.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * @file lldispatcher.cpp
  3. * @brief Implementation of the dispatcher object.
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2004-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 <algorithm>
  34. #include "lldispatcher.h"
  35. #include "llmessage.h"
  36. bool LLDispatcher::dispatch(const std::string& name, const LLUUID& invoice,
  37. const sparam_t& strings) const
  38. {
  39. dispatch_map_t::const_iterator it = mHandlers.find(name);
  40. if (it != mHandlers.end())
  41. {
  42. LLDispatchHandler* func = it->second;
  43. return (*func)(this, name, invoice, strings);
  44. }
  45. llwarns_once << "Unable to find handler for generic message: " << name
  46. << llendl;
  47. return false;
  48. }
  49. LLDispatchHandler* LLDispatcher::addHandler(const std::string& name,
  50. LLDispatchHandler* func)
  51. {
  52. dispatch_map_t::iterator it = mHandlers.find(name);
  53. LLDispatchHandler* old_handler = NULL;
  54. if (it != mHandlers.end())
  55. {
  56. old_handler = it->second;
  57. mHandlers.erase(it);
  58. }
  59. if (func)
  60. {
  61. // Only non-null handlers so that we don't have to worry about it later
  62. mHandlers.emplace(name, func);
  63. }
  64. return old_handler;
  65. }
  66. //static
  67. bool LLDispatcher::unpackMessage(LLMessageSystem* msg, std::string& method,
  68. LLUUID& invoice, sparam_t& parameters)
  69. {
  70. char buf[MAX_STRING];
  71. msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
  72. msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
  73. S32 size;
  74. S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
  75. for (S32 i = 0; i < count; ++i)
  76. {
  77. // We treat the SParam as binary data (since it might be an LLUUID in
  78. // compressed form which may have embedded \0's,)
  79. size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
  80. if (size >= 0)
  81. {
  82. msg->getBinaryDataFast(_PREHASH_ParamList, _PREHASH_Parameter,
  83. buf, size, i, MAX_STRING-1);
  84. // If the last byte of the data is 0x0, this is either a normally
  85. // packed string, or a binary packed UUID (which for these messages
  86. // are packed with a 17th byte 0x0). Unpack into a std::string
  87. // without the trailing \0, so "abc\0" becomes
  88. // std::string("abc", 3) which matches const char* "abc".
  89. if (size > 0 && buf[size - 1] == 0x0)
  90. {
  91. // Special char*/size constructor because UUIDs may have
  92. // embedded 0x0 bytes.
  93. std::string binary_data(buf, size - 1);
  94. parameters.push_back(binary_data);
  95. }
  96. else
  97. {
  98. // This is either a NULL string, or a string that was packed
  99. // incorrectly as binary data, without the usual trailing '\0'.
  100. std::string string_data(buf, size);
  101. parameters.push_back(string_data);
  102. }
  103. }
  104. }
  105. return true;
  106. }
  107. //static
  108. bool LLDispatcher::unpackLargeMessage(LLMessageSystem* msg,
  109. std::string& method, LLUUID& invoice,
  110. sparam_t& parameters)
  111. {
  112. msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
  113. msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
  114. S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
  115. for (S32 i = 0; i < count; ++i)
  116. {
  117. // This method treats all Parameter List params as strings and unpacks
  118. // them regardless of length. If there is binary data it is the callers
  119. // responsibility to decode it.
  120. std::string param;
  121. msg->getStringFast(_PREHASH_ParamList, _PREHASH_Parameter, param, i);
  122. parameters.push_back(param);
  123. }
  124. return true;
  125. }