Annotation of /linden_release/linden/indra/llinventory/llsaleinfo.cpp
Parent Directory
|
Revision Log
Revision 57 - (view) (download)
| 1 : | mjm | 57 | /** |
| 2 : | * @file llsaleinfo.cpp | ||
| 3 : | * @brief | ||
| 4 : | * | ||
| 5 : | * $LicenseInfo:firstyear=2002&license=viewergpl$ | ||
| 6 : | * | ||
| 7 : | * Copyright (c) 2002-2008, 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 http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
| 21 : | * | ||
| 22 : | * By copying, modifying or distributing this software, you acknowledge | ||
| 23 : | * that you have read and understood your obligations described above, | ||
| 24 : | * and agree to abide by those obligations. | ||
| 25 : | * | ||
| 26 : | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
| 27 : | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
| 28 : | * COMPLETENESS OR PERFORMANCE. | ||
| 29 : | * $/LicenseInfo$ | ||
| 30 : | */ | ||
| 31 : | |||
| 32 : | #include <iostream> | ||
| 33 : | #include "linden_common.h" | ||
| 34 : | |||
| 35 : | #include "llsaleinfo.h" | ||
| 36 : | |||
| 37 : | #include "llerror.h" | ||
| 38 : | #include "message.h" | ||
| 39 : | #include "llsdutil.h" | ||
| 40 : | |||
| 41 : | // use this to avoid temporary object creation | ||
| 42 : | const LLSaleInfo LLSaleInfo::DEFAULT; | ||
| 43 : | |||
| 44 : | ///---------------------------------------------------------------------------- | ||
| 45 : | /// Local function declarations, constants, enums, and typedefs | ||
| 46 : | ///---------------------------------------------------------------------------- | ||
| 47 : | |||
| 48 : | const char* FOR_SALE_NAMES[] = | ||
| 49 : | { | ||
| 50 : | "not", | ||
| 51 : | "orig", | ||
| 52 : | "copy", | ||
| 53 : | "cntn" | ||
| 54 : | }; | ||
| 55 : | |||
| 56 : | ///---------------------------------------------------------------------------- | ||
| 57 : | /// Class llsaleinfo | ||
| 58 : | ///---------------------------------------------------------------------------- | ||
| 59 : | |||
| 60 : | // Default constructor | ||
| 61 : | LLSaleInfo::LLSaleInfo() : | ||
| 62 : | mSaleType(LLSaleInfo::FS_NOT), | ||
| 63 : | mSalePrice(DEFAULT_PRICE) | ||
| 64 : | { | ||
| 65 : | } | ||
| 66 : | |||
| 67 : | LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) : | ||
| 68 : | mSaleType(sale_type), | ||
| 69 : | mSalePrice(sale_price) | ||
| 70 : | { | ||
| 71 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 72 : | } | ||
| 73 : | |||
| 74 : | BOOL LLSaleInfo::isForSale() const | ||
| 75 : | { | ||
| 76 : | return (FS_NOT != mSaleType); | ||
| 77 : | } | ||
| 78 : | |||
| 79 : | U32 LLSaleInfo::getCRC32() const | ||
| 80 : | { | ||
| 81 : | U32 rv = (U32)mSalePrice; | ||
| 82 : | rv += (mSaleType * 0x07073096); | ||
| 83 : | return rv; | ||
| 84 : | } | ||
| 85 : | |||
| 86 : | |||
| 87 : | BOOL LLSaleInfo::exportFile(LLFILE* fp) const | ||
| 88 : | { | ||
| 89 : | fprintf(fp, "\tsale_info\t0\n\t{\n"); | ||
| 90 : | fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType)); | ||
| 91 : | fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice); | ||
| 92 : | fprintf(fp,"\t}\n"); | ||
| 93 : | return TRUE; | ||
| 94 : | } | ||
| 95 : | |||
| 96 : | BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const | ||
| 97 : | { | ||
| 98 : | output_stream << "\tsale_info\t0\n\t{\n"; | ||
| 99 : | output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n"; | ||
| 100 : | output_stream << "\t\tsale_price\t" << mSalePrice << "\n"; | ||
| 101 : | output_stream <<"\t}\n"; | ||
| 102 : | return TRUE; | ||
| 103 : | } | ||
| 104 : | |||
| 105 : | LLSD LLSaleInfo::asLLSD() const | ||
| 106 : | { | ||
| 107 : | LLSD sd = LLSD(); | ||
| 108 : | sd["sale_type"] = lookup(mSaleType); | ||
| 109 : | sd["sale_price"] = mSalePrice; | ||
| 110 : | return sd; | ||
| 111 : | } | ||
| 112 : | |||
| 113 : | bool LLSaleInfo::fromLLSD(LLSD& sd, BOOL& has_perm_mask, U32& perm_mask) | ||
| 114 : | { | ||
| 115 : | const char *w; | ||
| 116 : | |||
| 117 : | mSaleType = lookup(sd["sale_type"].asString().c_str()); | ||
| 118 : | mSalePrice = llclamp(sd["sale_price"].asInteger(), 0, S32_MAX); | ||
| 119 : | w = "perm_mask"; | ||
| 120 : | if (sd.has(w)) | ||
| 121 : | { | ||
| 122 : | has_perm_mask = TRUE; | ||
| 123 : | perm_mask = ll_U32_from_sd(sd[w]); | ||
| 124 : | } | ||
| 125 : | return true; | ||
| 126 : | } | ||
| 127 : | |||
| 128 : | LLXMLNode *LLSaleInfo::exportFileXML() const | ||
| 129 : | { | ||
| 130 : | LLXMLNode *ret = new LLXMLNode("sale_info", FALSE); | ||
| 131 : | std::string type_str = ll_safe_string( lookup(mSaleType)); | ||
| 132 : | ret->createChild("type", TRUE)->setStringValue(1, &type_str); | ||
| 133 : | ret->createChild("price", TRUE)->setIntValue(1, &mSalePrice); | ||
| 134 : | return ret; | ||
| 135 : | } | ||
| 136 : | |||
| 137 : | BOOL LLSaleInfo::importXML(LLXMLNode* node) | ||
| 138 : | { | ||
| 139 : | BOOL success = FALSE; | ||
| 140 : | if (node) | ||
| 141 : | { | ||
| 142 : | success = TRUE; | ||
| 143 : | LLXMLNodePtr sub_node; | ||
| 144 : | if (node->getChild("type", sub_node)) | ||
| 145 : | { | ||
| 146 : | mSaleType = lookup(sub_node->getValue().c_str()); | ||
| 147 : | } | ||
| 148 : | if (node->getChild("price", sub_node)) | ||
| 149 : | { | ||
| 150 : | success &= (1 == sub_node->getIntValue(1, &mSalePrice)); | ||
| 151 : | } | ||
| 152 : | if (!success) | ||
| 153 : | { | ||
| 154 : | lldebugs << "LLSaleInfo::importXML() failed for node named '" | ||
| 155 : | << node->getName() << "'" << llendl; | ||
| 156 : | } | ||
| 157 : | } | ||
| 158 : | return success; | ||
| 159 : | } | ||
| 160 : | |||
| 161 : | BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask) | ||
| 162 : | { | ||
| 163 : | has_perm_mask = FALSE; | ||
| 164 : | |||
| 165 : | // *NOTE: Changing the buffer size will require changing the scanf | ||
| 166 : | // calls below. | ||
| 167 : | char buffer[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 168 : | char keyword[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 169 : | char valuestr[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 170 : | BOOL success = TRUE; | ||
| 171 : | |||
| 172 : | keyword[0] = '\0'; | ||
| 173 : | valuestr[0] = '\0'; | ||
| 174 : | while(success && (!feof(fp))) | ||
| 175 : | { | ||
| 176 : | if (fgets(buffer, MAX_STRING, fp) == NULL) | ||
| 177 : | { | ||
| 178 : | buffer[0] = '\0'; | ||
| 179 : | } | ||
| 180 : | |||
| 181 : | sscanf( /* Flawfinder: ignore */ | ||
| 182 : | buffer, | ||
| 183 : | " %254s %254s", | ||
| 184 : | keyword, valuestr); | ||
| 185 : | if(!keyword[0]) | ||
| 186 : | { | ||
| 187 : | continue; | ||
| 188 : | } | ||
| 189 : | if(0 == strcmp("{",keyword)) | ||
| 190 : | { | ||
| 191 : | continue; | ||
| 192 : | } | ||
| 193 : | if(0 == strcmp("}", keyword)) | ||
| 194 : | { | ||
| 195 : | break; | ||
| 196 : | } | ||
| 197 : | else if(0 == strcmp("sale_type", keyword)) | ||
| 198 : | { | ||
| 199 : | mSaleType = lookup(valuestr); | ||
| 200 : | } | ||
| 201 : | else if(0 == strcmp("sale_price", keyword)) | ||
| 202 : | { | ||
| 203 : | sscanf(valuestr, "%d", &mSalePrice); | ||
| 204 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 205 : | } | ||
| 206 : | else if (!strcmp("perm_mask", keyword)) | ||
| 207 : | { | ||
| 208 : | //llinfos << "found deprecated keyword perm_mask" << llendl; | ||
| 209 : | has_perm_mask = TRUE; | ||
| 210 : | sscanf(valuestr, "%x", &perm_mask); | ||
| 211 : | } | ||
| 212 : | else | ||
| 213 : | { | ||
| 214 : | llwarns << "unknown keyword '" << keyword | ||
| 215 : | << "' in sale info import" << llendl; | ||
| 216 : | } | ||
| 217 : | } | ||
| 218 : | return success; | ||
| 219 : | } | ||
| 220 : | |||
| 221 : | BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask) | ||
| 222 : | { | ||
| 223 : | has_perm_mask = FALSE; | ||
| 224 : | |||
| 225 : | // *NOTE: Changing the buffer size will require changing the scanf | ||
| 226 : | // calls below. | ||
| 227 : | char buffer[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 228 : | char keyword[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 229 : | char valuestr[MAX_STRING]; /* Flawfinder: ignore */ | ||
| 230 : | BOOL success = TRUE; | ||
| 231 : | |||
| 232 : | keyword[0] = '\0'; | ||
| 233 : | valuestr[0] = '\0'; | ||
| 234 : | while(success && input_stream.good()) | ||
| 235 : | { | ||
| 236 : | input_stream.getline(buffer, MAX_STRING); | ||
| 237 : | sscanf( /* Flawfinder: ignore */ | ||
| 238 : | buffer, | ||
| 239 : | " %254s %254s", | ||
| 240 : | keyword, valuestr); | ||
| 241 : | if(!keyword[0]) | ||
| 242 : | { | ||
| 243 : | continue; | ||
| 244 : | } | ||
| 245 : | if(0 == strcmp("{",keyword)) | ||
| 246 : | { | ||
| 247 : | continue; | ||
| 248 : | } | ||
| 249 : | if(0 == strcmp("}", keyword)) | ||
| 250 : | { | ||
| 251 : | break; | ||
| 252 : | } | ||
| 253 : | else if(0 == strcmp("sale_type", keyword)) | ||
| 254 : | { | ||
| 255 : | mSaleType = lookup(valuestr); | ||
| 256 : | } | ||
| 257 : | else if(0 == strcmp("sale_price", keyword)) | ||
| 258 : | { | ||
| 259 : | sscanf(valuestr, "%d", &mSalePrice); | ||
| 260 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 261 : | } | ||
| 262 : | else if (!strcmp("perm_mask", keyword)) | ||
| 263 : | { | ||
| 264 : | //llinfos << "found deprecated keyword perm_mask" << llendl; | ||
| 265 : | has_perm_mask = TRUE; | ||
| 266 : | sscanf(valuestr, "%x", &perm_mask); | ||
| 267 : | } | ||
| 268 : | else | ||
| 269 : | { | ||
| 270 : | llwarns << "unknown keyword '" << keyword | ||
| 271 : | << "' in sale info import" << llendl; | ||
| 272 : | } | ||
| 273 : | } | ||
| 274 : | return success; | ||
| 275 : | } | ||
| 276 : | |||
| 277 : | void LLSaleInfo::setSalePrice(S32 price) | ||
| 278 : | { | ||
| 279 : | mSalePrice = price; | ||
| 280 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 281 : | } | ||
| 282 : | |||
| 283 : | LLSD LLSaleInfo::packMessage() const | ||
| 284 : | { | ||
| 285 : | LLSD result; | ||
| 286 : | |||
| 287 : | U8 sale_type = static_cast<U8>(mSaleType); | ||
| 288 : | result["sale-type"] = (U8)sale_type; | ||
| 289 : | result["sale-price"] = (S32)mSalePrice; | ||
| 290 : | //result[_PREHASH_NextOwnerMask] = mNextOwnerPermMask; | ||
| 291 : | return result; | ||
| 292 : | } | ||
| 293 : | |||
| 294 : | void LLSaleInfo::packMessage(LLMessageSystem* msg) const | ||
| 295 : | { | ||
| 296 : | U8 sale_type = static_cast<U8>(mSaleType); | ||
| 297 : | msg->addU8Fast(_PREHASH_SaleType, sale_type); | ||
| 298 : | msg->addS32Fast(_PREHASH_SalePrice, mSalePrice); | ||
| 299 : | //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask); | ||
| 300 : | } | ||
| 301 : | |||
| 302 : | void LLSaleInfo::unpackMessage(LLSD sales) | ||
| 303 : | { | ||
| 304 : | U8 sale_type = (U8)sales["sale-type"].asInteger(); | ||
| 305 : | mSaleType = static_cast<EForSale>(sale_type); | ||
| 306 : | |||
| 307 : | mSalePrice = (S32)sales["sale-price"].asInteger(); | ||
| 308 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 309 : | //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask); | ||
| 310 : | } | ||
| 311 : | |||
| 312 : | void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block) | ||
| 313 : | { | ||
| 314 : | U8 sale_type; | ||
| 315 : | msg->getU8Fast(block, _PREHASH_SaleType, sale_type); | ||
| 316 : | mSaleType = static_cast<EForSale>(sale_type); | ||
| 317 : | msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice); | ||
| 318 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 319 : | //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask); | ||
| 320 : | } | ||
| 321 : | |||
| 322 : | void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block, | ||
| 323 : | S32 block_num) | ||
| 324 : | { | ||
| 325 : | U8 sale_type; | ||
| 326 : | msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num); | ||
| 327 : | mSaleType = static_cast<EForSale>(sale_type); | ||
| 328 : | msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num); | ||
| 329 : | mSalePrice = llclamp(mSalePrice, 0, S32_MAX); | ||
| 330 : | //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask, block_num); | ||
| 331 : | } | ||
| 332 : | |||
| 333 : | LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name) | ||
| 334 : | { | ||
| 335 : | for(S32 i = 0; i < FS_COUNT; i++) | ||
| 336 : | { | ||
| 337 : | if(0 == strcmp(name, FOR_SALE_NAMES[i])) | ||
| 338 : | { | ||
| 339 : | // match | ||
| 340 : | return (EForSale)i; | ||
| 341 : | } | ||
| 342 : | } | ||
| 343 : | return FS_NOT; | ||
| 344 : | } | ||
| 345 : | |||
| 346 : | const char* LLSaleInfo::lookup(EForSale type) | ||
| 347 : | { | ||
| 348 : | if((type >= 0) && (type < FS_COUNT)) | ||
| 349 : | { | ||
| 350 : | return FOR_SALE_NAMES[S32(type)]; | ||
| 351 : | } | ||
| 352 : | else | ||
| 353 : | { | ||
| 354 : | return NULL; | ||
| 355 : | } | ||
| 356 : | } | ||
| 357 : | |||
| 358 : | // Allow accumulation of sale info. The price of each is added, | ||
| 359 : | // conflict in sale type results in FS_NOT, and the permissions are | ||
| 360 : | // tightened. | ||
| 361 : | void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) | ||
| 362 : | { | ||
| 363 : | if(mSaleType != sale_info.mSaleType) | ||
| 364 : | { | ||
| 365 : | mSaleType = FS_NOT; | ||
| 366 : | } | ||
| 367 : | mSalePrice += sale_info.mSalePrice; | ||
| 368 : | //mNextOwnerPermMask &= sale_info.mNextOwnerPermMask; | ||
| 369 : | } | ||
| 370 : | |||
| 371 : | bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const | ||
| 372 : | { | ||
| 373 : | return ( | ||
| 374 : | (mSaleType == rhs.mSaleType) && | ||
| 375 : | (mSalePrice == rhs.mSalePrice) | ||
| 376 : | ); | ||
| 377 : | } | ||
| 378 : | |||
| 379 : | bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const | ||
| 380 : | { | ||
| 381 : | return ( | ||
| 382 : | (mSaleType != rhs.mSaleType) || | ||
| 383 : | (mSalePrice != rhs.mSalePrice) | ||
| 384 : | ); | ||
| 385 : | } | ||
| 386 : | |||
| 387 : | |||
| 388 : | ///---------------------------------------------------------------------------- | ||
| 389 : | /// Local function definitions | ||
| 390 : | ///---------------------------------------------------------------------------- | ||
| 391 : | |||
| 392 : | ///---------------------------------------------------------------------------- | ||
| 393 : | /// exported functions | ||
| 394 : | ///---------------------------------------------------------------------------- | ||
| 395 : | static const std::string ST_TYPE_LABEL("sale_type"); | ||
| 396 : | static const std::string ST_PRICE_LABEL("sale_price"); | ||
| 397 : | |||
| 398 : | LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale) | ||
| 399 : | { | ||
| 400 : | LLSD rv; | ||
| 401 : | const char* type = LLSaleInfo::lookup(sale.getSaleType()); | ||
| 402 : | if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT); | ||
| 403 : | rv[ST_TYPE_LABEL] = type; | ||
| 404 : | rv[ST_PRICE_LABEL] = sale.getSalePrice(); | ||
| 405 : | return rv; | ||
| 406 : | } | ||
| 407 : | |||
| 408 : | LLSaleInfo ll_sale_info_from_sd(const LLSD& sd) | ||
| 409 : | { | ||
| 410 : | LLSaleInfo rv; | ||
| 411 : | rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str())); | ||
| 412 : | rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX)); | ||
| 413 : | return rv; | ||
| 414 : | } |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

