PageRenderTime 162ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llinventory/llsaleinfo.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 388 lines | 287 code | 44 blank | 57 comment | 47 complexity | 27936088022041fd5f6c419b9f2705d7 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsaleinfo.cpp
  3. * @brief
  4. *
  5. * $LicenseInfo:firstyear=2002&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 <iostream>
  27. #include "linden_common.h"
  28. #include "llsaleinfo.h"
  29. #include "llerror.h"
  30. #include "message.h"
  31. #include "llsdutil.h"
  32. // use this to avoid temporary object creation
  33. const LLSaleInfo LLSaleInfo::DEFAULT;
  34. ///----------------------------------------------------------------------------
  35. /// Local function declarations, constants, enums, and typedefs
  36. ///----------------------------------------------------------------------------
  37. const char* FOR_SALE_NAMES[] =
  38. {
  39. "not",
  40. "orig",
  41. "copy",
  42. "cntn"
  43. };
  44. ///----------------------------------------------------------------------------
  45. /// Class llsaleinfo
  46. ///----------------------------------------------------------------------------
  47. // Default constructor
  48. LLSaleInfo::LLSaleInfo() :
  49. mSaleType(LLSaleInfo::FS_NOT),
  50. mSalePrice(DEFAULT_PRICE)
  51. {
  52. }
  53. LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) :
  54. mSaleType(sale_type),
  55. mSalePrice(sale_price)
  56. {
  57. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  58. }
  59. BOOL LLSaleInfo::isForSale() const
  60. {
  61. return (FS_NOT != mSaleType);
  62. }
  63. U32 LLSaleInfo::getCRC32() const
  64. {
  65. U32 rv = (U32)mSalePrice;
  66. rv += (mSaleType * 0x07073096);
  67. return rv;
  68. }
  69. BOOL LLSaleInfo::exportFile(LLFILE* fp) const
  70. {
  71. fprintf(fp, "\tsale_info\t0\n\t{\n");
  72. fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
  73. fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
  74. fprintf(fp,"\t}\n");
  75. return TRUE;
  76. }
  77. BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
  78. {
  79. output_stream << "\tsale_info\t0\n\t{\n";
  80. output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";
  81. output_stream << "\t\tsale_price\t" << mSalePrice << "\n";
  82. output_stream <<"\t}\n";
  83. return TRUE;
  84. }
  85. LLSD LLSaleInfo::asLLSD() const
  86. {
  87. LLSD sd = LLSD();
  88. sd["sale_type"] = lookup(mSaleType);
  89. sd["sale_price"] = mSalePrice;
  90. return sd;
  91. }
  92. bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
  93. {
  94. const char *w;
  95. if (sd["sale_type"].isString())
  96. {
  97. mSaleType = lookup(sd["sale_type"].asString().c_str());
  98. }
  99. else if(sd["sale_type"].isInteger())
  100. {
  101. S8 type = (U8)sd["sale_type"].asInteger();
  102. mSaleType = static_cast<LLSaleInfo::EForSale>(type);
  103. }
  104. mSalePrice = llclamp(sd["sale_price"].asInteger(), 0, S32_MAX);
  105. w = "perm_mask";
  106. if (sd.has(w))
  107. {
  108. has_perm_mask = TRUE;
  109. perm_mask = ll_U32_from_sd(sd[w]);
  110. }
  111. return true;
  112. }
  113. // Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
  114. // because I can't find any non-test code references to it. 2009-05-04 JC
  115. BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
  116. {
  117. has_perm_mask = FALSE;
  118. // *NOTE: Changing the buffer size will require changing the scanf
  119. // calls below.
  120. char buffer[MAX_STRING]; /* Flawfinder: ignore */
  121. char keyword[MAX_STRING]; /* Flawfinder: ignore */
  122. char valuestr[MAX_STRING]; /* Flawfinder: ignore */
  123. BOOL success = TRUE;
  124. keyword[0] = '\0';
  125. valuestr[0] = '\0';
  126. while(success && (!feof(fp)))
  127. {
  128. if (fgets(buffer, MAX_STRING, fp) == NULL)
  129. {
  130. buffer[0] = '\0';
  131. }
  132. sscanf( /* Flawfinder: ignore */
  133. buffer,
  134. " %254s %254s",
  135. keyword, valuestr);
  136. if(!keyword[0])
  137. {
  138. continue;
  139. }
  140. if(0 == strcmp("{",keyword))
  141. {
  142. continue;
  143. }
  144. if(0 == strcmp("}", keyword))
  145. {
  146. break;
  147. }
  148. else if(0 == strcmp("sale_type", keyword))
  149. {
  150. mSaleType = lookup(valuestr);
  151. }
  152. else if(0 == strcmp("sale_price", keyword))
  153. {
  154. sscanf(valuestr, "%d", &mSalePrice);
  155. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  156. }
  157. else if (!strcmp("perm_mask", keyword))
  158. {
  159. //llinfos << "found deprecated keyword perm_mask" << llendl;
  160. has_perm_mask = TRUE;
  161. sscanf(valuestr, "%x", &perm_mask);
  162. }
  163. else
  164. {
  165. llwarns << "unknown keyword '" << keyword
  166. << "' in sale info import" << llendl;
  167. }
  168. }
  169. return success;
  170. }
  171. BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
  172. {
  173. has_perm_mask = FALSE;
  174. // *NOTE: Changing the buffer size will require changing the scanf
  175. // calls below.
  176. char buffer[MAX_STRING]; /* Flawfinder: ignore */
  177. char keyword[MAX_STRING]; /* Flawfinder: ignore */
  178. char valuestr[MAX_STRING]; /* Flawfinder: ignore */
  179. BOOL success = TRUE;
  180. keyword[0] = '\0';
  181. valuestr[0] = '\0';
  182. while(success && input_stream.good())
  183. {
  184. input_stream.getline(buffer, MAX_STRING);
  185. sscanf( /* Flawfinder: ignore */
  186. buffer,
  187. " %254s %254s",
  188. keyword, valuestr);
  189. if(!keyword[0])
  190. {
  191. continue;
  192. }
  193. if(0 == strcmp("{",keyword))
  194. {
  195. continue;
  196. }
  197. if(0 == strcmp("}", keyword))
  198. {
  199. break;
  200. }
  201. else if(0 == strcmp("sale_type", keyword))
  202. {
  203. mSaleType = lookup(valuestr);
  204. }
  205. else if(0 == strcmp("sale_price", keyword))
  206. {
  207. sscanf(valuestr, "%d", &mSalePrice);
  208. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  209. }
  210. else if (!strcmp("perm_mask", keyword))
  211. {
  212. //llinfos << "found deprecated keyword perm_mask" << llendl;
  213. has_perm_mask = TRUE;
  214. sscanf(valuestr, "%x", &perm_mask);
  215. }
  216. else
  217. {
  218. llwarns << "unknown keyword '" << keyword
  219. << "' in sale info import" << llendl;
  220. }
  221. }
  222. return success;
  223. }
  224. void LLSaleInfo::setSalePrice(S32 price)
  225. {
  226. mSalePrice = price;
  227. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  228. }
  229. LLSD LLSaleInfo::packMessage() const
  230. {
  231. LLSD result;
  232. U8 sale_type = static_cast<U8>(mSaleType);
  233. result["sale-type"] = (U8)sale_type;
  234. result["sale-price"] = (S32)mSalePrice;
  235. //result[_PREHASH_NextOwnerMask] = mNextOwnerPermMask;
  236. return result;
  237. }
  238. void LLSaleInfo::packMessage(LLMessageSystem* msg) const
  239. {
  240. U8 sale_type = static_cast<U8>(mSaleType);
  241. msg->addU8Fast(_PREHASH_SaleType, sale_type);
  242. msg->addS32Fast(_PREHASH_SalePrice, mSalePrice);
  243. //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask);
  244. }
  245. void LLSaleInfo::unpackMessage(LLSD sales)
  246. {
  247. U8 sale_type = (U8)sales["sale-type"].asInteger();
  248. mSaleType = static_cast<EForSale>(sale_type);
  249. mSalePrice = (S32)sales["sale-price"].asInteger();
  250. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  251. //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask);
  252. }
  253. void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
  254. {
  255. U8 sale_type;
  256. msg->getU8Fast(block, _PREHASH_SaleType, sale_type);
  257. mSaleType = static_cast<EForSale>(sale_type);
  258. msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice);
  259. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  260. //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask);
  261. }
  262. void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block,
  263. S32 block_num)
  264. {
  265. U8 sale_type;
  266. msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num);
  267. mSaleType = static_cast<EForSale>(sale_type);
  268. msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num);
  269. mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
  270. //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask, block_num);
  271. }
  272. LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name)
  273. {
  274. for(S32 i = 0; i < FS_COUNT; i++)
  275. {
  276. if(0 == strcmp(name, FOR_SALE_NAMES[i]))
  277. {
  278. // match
  279. return (EForSale)i;
  280. }
  281. }
  282. return FS_NOT;
  283. }
  284. const char* LLSaleInfo::lookup(EForSale type)
  285. {
  286. if((type >= 0) && (type < FS_COUNT))
  287. {
  288. return FOR_SALE_NAMES[S32(type)];
  289. }
  290. else
  291. {
  292. return NULL;
  293. }
  294. }
  295. // Allow accumulation of sale info. The price of each is added,
  296. // conflict in sale type results in FS_NOT, and the permissions are
  297. // tightened.
  298. void LLSaleInfo::accumulate(const LLSaleInfo& sale_info)
  299. {
  300. if(mSaleType != sale_info.mSaleType)
  301. {
  302. mSaleType = FS_NOT;
  303. }
  304. mSalePrice += sale_info.mSalePrice;
  305. //mNextOwnerPermMask &= sale_info.mNextOwnerPermMask;
  306. }
  307. bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const
  308. {
  309. return (
  310. (mSaleType == rhs.mSaleType) &&
  311. (mSalePrice == rhs.mSalePrice)
  312. );
  313. }
  314. bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const
  315. {
  316. return (
  317. (mSaleType != rhs.mSaleType) ||
  318. (mSalePrice != rhs.mSalePrice)
  319. );
  320. }
  321. ///----------------------------------------------------------------------------
  322. /// Local function definitions
  323. ///----------------------------------------------------------------------------
  324. ///----------------------------------------------------------------------------
  325. /// exported functions
  326. ///----------------------------------------------------------------------------
  327. static const std::string ST_TYPE_LABEL("sale_type");
  328. static const std::string ST_PRICE_LABEL("sale_price");
  329. LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale)
  330. {
  331. LLSD rv;
  332. const char* type = LLSaleInfo::lookup(sale.getSaleType());
  333. if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT);
  334. rv[ST_TYPE_LABEL] = type;
  335. rv[ST_PRICE_LABEL] = sale.getSalePrice();
  336. return rv;
  337. }
  338. LLSaleInfo ll_sale_info_from_sd(const LLSD& sd)
  339. {
  340. LLSaleInfo rv;
  341. rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str()));
  342. rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX));
  343. return rv;
  344. }