PageRenderTime 32ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/lldispatcher.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 147 lines | 91 code | 13 blank | 43 comment | 12 complexity | de9243eac3ee220c29ddee47211b0740 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lldispatcher.cpp
  3. * @brief Implementation of the dispatcher object.
  4. *
  5. * $LicenseInfo:firstyear=2004&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 "lldispatcher.h"
  28. #include <algorithm>
  29. #include "llstl.h"
  30. #include "message.h"
  31. ///----------------------------------------------------------------------------
  32. /// Class lldispatcher
  33. ///----------------------------------------------------------------------------
  34. LLDispatcher::LLDispatcher()
  35. {
  36. }
  37. LLDispatcher::~LLDispatcher()
  38. {
  39. }
  40. bool LLDispatcher::isHandlerPresent(const key_t& name) const
  41. {
  42. if(mHandlers.find(name) != mHandlers.end())
  43. {
  44. return true;
  45. }
  46. return false;
  47. }
  48. void LLDispatcher::copyAllHandlerNames(keys_t& names) const
  49. {
  50. // copy the names onto the vector we are given
  51. std::transform(
  52. mHandlers.begin(),
  53. mHandlers.end(),
  54. std::back_insert_iterator<keys_t>(names),
  55. llselect1st<dispatch_map_t::value_type>());
  56. }
  57. bool LLDispatcher::dispatch(
  58. const key_t& name,
  59. const LLUUID& invoice,
  60. const sparam_t& strings) const
  61. {
  62. dispatch_map_t::const_iterator it = mHandlers.find(name);
  63. if(it != mHandlers.end())
  64. {
  65. LLDispatchHandler* func = (*it).second;
  66. return (*func)(this, name, invoice, strings);
  67. }
  68. llwarns << "Unable to find handler for Generic message: " << name << llendl;
  69. return false;
  70. }
  71. LLDispatchHandler* LLDispatcher::addHandler(
  72. const key_t& name, LLDispatchHandler* func)
  73. {
  74. dispatch_map_t::iterator it = mHandlers.find(name);
  75. LLDispatchHandler* old_handler = NULL;
  76. if(it != mHandlers.end())
  77. {
  78. old_handler = (*it).second;
  79. mHandlers.erase(it);
  80. }
  81. if(func)
  82. {
  83. // only non-null handlers so that we don't have to worry about
  84. // it later.
  85. mHandlers.insert(dispatch_map_t::value_type(name, func));
  86. }
  87. return old_handler;
  88. }
  89. // static
  90. bool LLDispatcher::unpackMessage(
  91. LLMessageSystem* msg,
  92. LLDispatcher::key_t& method,
  93. LLUUID& invoice,
  94. LLDispatcher::sparam_t& parameters)
  95. {
  96. char buf[MAX_STRING]; /*Flawfinder: ignore*/
  97. msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
  98. msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
  99. S32 size;
  100. S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
  101. for (S32 i = 0; i < count; ++i)
  102. {
  103. // we treat the SParam as binary data (since it might be an
  104. // LLUUID in compressed form which may have embedded \0's,)
  105. size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
  106. if (size >= 0)
  107. {
  108. msg->getBinaryDataFast(
  109. _PREHASH_ParamList, _PREHASH_Parameter,
  110. buf, size, i, MAX_STRING-1);
  111. // If the last byte of the data is 0x0, this is either a normally
  112. // packed string, or a binary packed UUID (which for these messages
  113. // are packed with a 17th byte 0x0). Unpack into a std::string
  114. // without the trailing \0, so "abc\0" becomes std::string("abc", 3)
  115. // which matches const char* "abc".
  116. if (size > 0
  117. && buf[size-1] == 0x0)
  118. {
  119. // special char*/size constructor because UUIDs may have embedded
  120. // 0x0 bytes.
  121. std::string binary_data(buf, size-1);
  122. parameters.push_back(binary_data);
  123. }
  124. else
  125. {
  126. // This is either a NULL string, or a string that was packed
  127. // incorrectly as binary data, without the usual trailing '\0'.
  128. std::string string_data(buf, size);
  129. parameters.push_back(string_data);
  130. }
  131. }
  132. }
  133. return true;
  134. }