PageRenderTime 33ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llui/llsdparam.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 342 lines | 245 code | 53 blank | 44 comment | 25 complexity | 889ff9a1ec025ac350e85efc9384bf3a MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsdparam.cpp
  3. * @brief parameter block abstraction for creating complex objects and
  4. * parsing construction parameters from xml and LLSD
  5. *
  6. * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "linden_common.h"
  28. // Project includes
  29. #include "llsdparam.h"
  30. #include "llsdutil.h"
  31. static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
  32. static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
  33. static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
  34. static const LLSD NO_VALUE_MARKER;
  35. LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion");
  36. //
  37. // LLParamSDParser
  38. //
  39. LLParamSDParser::LLParamSDParser()
  40. : Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
  41. {
  42. using boost::bind;
  43. if (sReadFuncs.empty())
  44. {
  45. registerParserFuncs<LLInitParam::Flag>(readFlag, &LLParamSDParser::writeFlag);
  46. registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
  47. registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
  48. registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
  49. registerParserFuncs<F64>(readF64, &LLParamSDParser::writeTypedValue<F64>);
  50. registerParserFuncs<bool>(readBool, &LLParamSDParser::writeTypedValue<bool>);
  51. registerParserFuncs<std::string>(readString, &LLParamSDParser::writeTypedValue<std::string>);
  52. registerParserFuncs<LLUUID>(readUUID, &LLParamSDParser::writeTypedValue<LLUUID>);
  53. registerParserFuncs<LLDate>(readDate, &LLParamSDParser::writeTypedValue<LLDate>);
  54. registerParserFuncs<LLURI>(readURI, &LLParamSDParser::writeTypedValue<LLURI>);
  55. registerParserFuncs<LLSD>(readSD, &LLParamSDParser::writeTypedValue<LLSD>);
  56. }
  57. }
  58. // special case handling of U32 due to ambiguous LLSD::assign overload
  59. bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
  60. {
  61. LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
  62. if (!sdparser.mWriteRootSD) return false;
  63. parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
  64. LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
  65. sd_to_write.assign((S32)*((const U32*)val_ptr));
  66. return true;
  67. }
  68. bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
  69. {
  70. LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
  71. if (!sdparser.mWriteRootSD) return false;
  72. parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
  73. LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
  74. return true;
  75. }
  76. void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack)
  77. {
  78. mCurReadSD = &sd;
  79. block.submitValue(name_stack, *this);
  80. }
  81. void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
  82. {
  83. mCurReadSD = NULL;
  84. mNameStack.clear();
  85. setParseSilently(silent);
  86. LLParamSDParserUtilities::readSDValues(boost::bind(&LLParamSDParser::submit, this, boost::ref(block), _1, _2), sd, mNameStack);
  87. //readSDValues(sd, block);
  88. }
  89. void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
  90. {
  91. mNameStack.clear();
  92. mWriteRootSD = &sd;
  93. name_stack_t name_stack;
  94. block.serializeBlock(*this, name_stack);
  95. }
  96. /*virtual*/ std::string LLParamSDParser::getCurrentElementName()
  97. {
  98. std::string full_name = "sd";
  99. for (name_stack_t::iterator it = mNameStack.begin();
  100. it != mNameStack.end();
  101. ++it)
  102. {
  103. full_name += llformat("[%s]", it->first.c_str());
  104. }
  105. return full_name;
  106. }
  107. bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
  108. {
  109. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  110. return self.mCurReadSD == &NO_VALUE_MARKER;
  111. }
  112. bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
  113. {
  114. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  115. *((S32*)val_ptr) = self.mCurReadSD->asInteger();
  116. return true;
  117. }
  118. bool LLParamSDParser::readU32(Parser& parser, void* val_ptr)
  119. {
  120. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  121. *((U32*)val_ptr) = self.mCurReadSD->asInteger();
  122. return true;
  123. }
  124. bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
  125. {
  126. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  127. *((F32*)val_ptr) = self.mCurReadSD->asReal();
  128. return true;
  129. }
  130. bool LLParamSDParser::readF64(Parser& parser, void* val_ptr)
  131. {
  132. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  133. *((F64*)val_ptr) = self.mCurReadSD->asReal();
  134. return true;
  135. }
  136. bool LLParamSDParser::readBool(Parser& parser, void* val_ptr)
  137. {
  138. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  139. *((bool*)val_ptr) = self.mCurReadSD->asBoolean();
  140. return true;
  141. }
  142. bool LLParamSDParser::readString(Parser& parser, void* val_ptr)
  143. {
  144. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  145. *((std::string*)val_ptr) = self.mCurReadSD->asString();
  146. return true;
  147. }
  148. bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr)
  149. {
  150. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  151. *((LLUUID*)val_ptr) = self.mCurReadSD->asUUID();
  152. return true;
  153. }
  154. bool LLParamSDParser::readDate(Parser& parser, void* val_ptr)
  155. {
  156. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  157. *((LLDate*)val_ptr) = self.mCurReadSD->asDate();
  158. return true;
  159. }
  160. bool LLParamSDParser::readURI(Parser& parser, void* val_ptr)
  161. {
  162. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  163. *((LLURI*)val_ptr) = self.mCurReadSD->asURI();
  164. return true;
  165. }
  166. bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
  167. {
  168. LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
  169. *((LLSD*)val_ptr) = *self.mCurReadSD;
  170. return true;
  171. }
  172. // static
  173. LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range)
  174. {
  175. LLSD* sd_to_write = &input;
  176. for (LLInitParam::Parser::name_stack_t::iterator it = name_stack_range.first;
  177. it != name_stack_range.second;
  178. ++it)
  179. {
  180. bool new_traversal = it->second;
  181. LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
  182. if (child_sd->isArray())
  183. {
  184. if (new_traversal)
  185. {
  186. // write to new element at end
  187. sd_to_write = &(*child_sd)[child_sd->size()];
  188. }
  189. else
  190. {
  191. // write to last of existing elements, or first element if empty
  192. sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
  193. }
  194. }
  195. else
  196. {
  197. if (new_traversal
  198. && child_sd->isDefined()
  199. && !child_sd->isArray())
  200. {
  201. // copy child contents into first element of an array
  202. LLSD new_array = LLSD::emptyArray();
  203. new_array.append(*child_sd);
  204. // assign array to slot that previously held the single value
  205. *child_sd = new_array;
  206. // return next element in that array
  207. sd_to_write = &((*child_sd)[1]);
  208. }
  209. else
  210. {
  211. sd_to_write = child_sd;
  212. }
  213. }
  214. it->second = false;
  215. }
  216. return *sd_to_write;
  217. }
  218. //static
  219. void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack)
  220. {
  221. if (sd.isMap())
  222. {
  223. for (LLSD::map_const_iterator it = sd.beginMap();
  224. it != sd.endMap();
  225. ++it)
  226. {
  227. stack.push_back(make_pair(it->first, true));
  228. readSDValues(cb, it->second, stack);
  229. stack.pop_back();
  230. }
  231. }
  232. else if (sd.isArray())
  233. {
  234. for (LLSD::array_const_iterator it = sd.beginArray();
  235. it != sd.endArray();
  236. ++it)
  237. {
  238. stack.back().second = true;
  239. readSDValues(cb, *it, stack);
  240. }
  241. }
  242. else if (sd.isUndefined())
  243. {
  244. if (!cb.empty())
  245. {
  246. cb(NO_VALUE_MARKER, stack);
  247. }
  248. }
  249. else
  250. {
  251. if (!cb.empty())
  252. {
  253. cb(sd, stack);
  254. }
  255. }
  256. }
  257. //static
  258. void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd)
  259. {
  260. LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t();
  261. readSDValues(cb, sd, stack);
  262. }
  263. namespace LLInitParam
  264. {
  265. // LLSD specialization
  266. // block param interface
  267. bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
  268. {
  269. LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
  270. LLSD::String string;
  271. if (p.readValue<LLSD::String>(string))
  272. {
  273. sd = string;
  274. return true;
  275. }
  276. return false;
  277. }
  278. //static
  279. void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
  280. {
  281. p.writeValue<LLSD::String>(sd.asString(), name_stack);
  282. }
  283. void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
  284. {
  285. // read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
  286. Parser::name_stack_t stack;
  287. LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
  288. }
  289. }