llsaleinfo.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

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