00001
00032 #include <iostream>
00033 #include "linden_common.h"
00034
00035 #include "llsaleinfo.h"
00036
00037 #include "llerror.h"
00038 #include "message.h"
00039 #include "llsdutil.h"
00040
00041
00042 const LLSaleInfo LLSaleInfo::DEFAULT;
00043
00047
00048 const char* FOR_SALE_NAMES[] =
00049 {
00050 "not",
00051 "orig",
00052 "copy",
00053 "cntn"
00054 };
00055
00059
00060
00061 LLSaleInfo::LLSaleInfo() :
00062 mSaleType(LLSaleInfo::FS_NOT),
00063 mSalePrice(DEFAULT_PRICE)
00064 {
00065 }
00066
00067 LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) :
00068 mSaleType(sale_type),
00069 mSalePrice(sale_price)
00070 {
00071 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00072 }
00073
00074 BOOL LLSaleInfo::isForSale() const
00075 {
00076 return (FS_NOT != mSaleType);
00077 }
00078
00079 U32 LLSaleInfo::getCRC32() const
00080 {
00081 U32 rv = (U32)mSalePrice;
00082 rv += (mSaleType * 0x07073096);
00083 return rv;
00084 }
00085
00086
00087 BOOL LLSaleInfo::exportFile(LLFILE* fp) const
00088 {
00089 fprintf(fp, "\tsale_info\t0\n\t{\n");
00090 fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
00091 fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
00092 fprintf(fp,"\t}\n");
00093 return TRUE;
00094 }
00095
00096 BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
00097 {
00098 output_stream << "\tsale_info\t0\n\t{\n";
00099 output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";
00100 output_stream << "\t\tsale_price\t" << mSalePrice << "\n";
00101 output_stream <<"\t}\n";
00102 return TRUE;
00103 }
00104
00105 LLSD LLSaleInfo::asLLSD() const
00106 {
00107 LLSD sd = LLSD();
00108 sd["sale_type"] = lookup(mSaleType);
00109 sd["sale_price"] = mSalePrice;
00110 return sd;
00111 }
00112
00113 bool LLSaleInfo::fromLLSD(LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
00114 {
00115 const char *w;
00116
00117 mSaleType = lookup(sd["sale_type"].asString().c_str());
00118 mSalePrice = llclamp(sd["sale_price"].asInteger(), 0, S32_MAX);
00119 w = "perm_mask";
00120 if (sd.has(w))
00121 {
00122 has_perm_mask = TRUE;
00123 perm_mask = ll_U32_from_sd(sd[w]);
00124 }
00125 return true;
00126 }
00127
00128 LLXMLNode *LLSaleInfo::exportFileXML() const
00129 {
00130 LLXMLNode *ret = new LLXMLNode("sale_info", FALSE);
00131 LLString type_str = lookup(mSaleType);
00132 ret->createChild("type", TRUE)->setStringValue(1, &type_str);
00133 ret->createChild("price", TRUE)->setIntValue(1, &mSalePrice);
00134 return ret;
00135 }
00136
00137 BOOL LLSaleInfo::importXML(LLXMLNode* node)
00138 {
00139 BOOL success = FALSE;
00140 if (node)
00141 {
00142 success = TRUE;
00143 LLXMLNodePtr sub_node;
00144 if (node->getChild("type", sub_node))
00145 {
00146 mSaleType = lookup(sub_node->getValue().c_str());
00147 }
00148 if (node->getChild("price", sub_node))
00149 {
00150 success &= (1 == sub_node->getIntValue(1, &mSalePrice));
00151 }
00152 if (!success)
00153 {
00154 lldebugs << "LLSaleInfo::importXML() failed for node named '"
00155 << node->getName() << "'" << llendl;
00156 }
00157 }
00158 return success;
00159 }
00160
00161 BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
00162 {
00163 has_perm_mask = FALSE;
00164
00165
00166
00167 char buffer[MAX_STRING];
00168 char keyword[MAX_STRING];
00169 char valuestr[MAX_STRING];
00170 BOOL success = TRUE;
00171
00172 keyword[0] = '\0';
00173 valuestr[0] = '\0';
00174 while(success && (!feof(fp)))
00175 {
00176 if (fgets(buffer, MAX_STRING, fp) == NULL)
00177 {
00178 buffer[0] = '\0';
00179 }
00180
00181 sscanf(
00182 buffer,
00183 " %254s %254s",
00184 keyword, valuestr);
00185 if(!keyword[0])
00186 {
00187 continue;
00188 }
00189 if(0 == strcmp("{",keyword))
00190 {
00191 continue;
00192 }
00193 if(0 == strcmp("}", keyword))
00194 {
00195 break;
00196 }
00197 else if(0 == strcmp("sale_type", keyword))
00198 {
00199 mSaleType = lookup(valuestr);
00200 }
00201 else if(0 == strcmp("sale_price", keyword))
00202 {
00203 sscanf(valuestr, "%d", &mSalePrice);
00204 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00205 }
00206 else if (!strcmp("perm_mask", keyword))
00207 {
00208
00209 has_perm_mask = TRUE;
00210 sscanf(valuestr, "%x", &perm_mask);
00211 }
00212 else
00213 {
00214 llwarns << "unknown keyword '" << keyword
00215 << "' in sale info import" << llendl;
00216 }
00217 }
00218 return success;
00219 }
00220
00221 BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
00222 {
00223 has_perm_mask = FALSE;
00224
00225
00226
00227 char buffer[MAX_STRING];
00228 char keyword[MAX_STRING];
00229 char valuestr[MAX_STRING];
00230 BOOL success = TRUE;
00231
00232 keyword[0] = '\0';
00233 valuestr[0] = '\0';
00234 while(success && input_stream.good())
00235 {
00236 input_stream.getline(buffer, MAX_STRING);
00237 sscanf(
00238 buffer,
00239 " %254s %254s",
00240 keyword, valuestr);
00241 if(!keyword[0])
00242 {
00243 continue;
00244 }
00245 if(0 == strcmp("{",keyword))
00246 {
00247 continue;
00248 }
00249 if(0 == strcmp("}", keyword))
00250 {
00251 break;
00252 }
00253 else if(0 == strcmp("sale_type", keyword))
00254 {
00255 mSaleType = lookup(valuestr);
00256 }
00257 else if(0 == strcmp("sale_price", keyword))
00258 {
00259 sscanf(valuestr, "%d", &mSalePrice);
00260 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00261 }
00262 else if (!strcmp("perm_mask", keyword))
00263 {
00264
00265 has_perm_mask = TRUE;
00266 sscanf(valuestr, "%x", &perm_mask);
00267 }
00268 else
00269 {
00270 llwarns << "unknown keyword '" << keyword
00271 << "' in sale info import" << llendl;
00272 }
00273 }
00274 return success;
00275 }
00276
00277 void LLSaleInfo::setSalePrice(S32 price)
00278 {
00279 mSalePrice = price;
00280 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00281 }
00282
00283 LLSD LLSaleInfo::packMessage() const
00284 {
00285 LLSD result;
00286
00287 U8 sale_type = static_cast<U8>(mSaleType);
00288 result["sale-type"] = (U8)sale_type;
00289 result["sale-price"] = (S32)mSalePrice;
00290
00291 return result;
00292 }
00293
00294 void LLSaleInfo::packMessage(LLMessageSystem* msg) const
00295 {
00296 U8 sale_type = static_cast<U8>(mSaleType);
00297 msg->addU8Fast(_PREHASH_SaleType, sale_type);
00298 msg->addS32Fast(_PREHASH_SalePrice, mSalePrice);
00299
00300 }
00301
00302 void LLSaleInfo::unpackMessage(LLSD sales)
00303 {
00304 U8 sale_type = (U8)sales["sale-type"].asInteger();
00305 mSaleType = static_cast<EForSale>(sale_type);
00306
00307 mSalePrice = (S32)sales["sale-price"].asInteger();
00308 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00309
00310 }
00311
00312 void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
00313 {
00314 U8 sale_type;
00315 msg->getU8Fast(block, _PREHASH_SaleType, sale_type);
00316 mSaleType = static_cast<EForSale>(sale_type);
00317 msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice);
00318 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00319
00320 }
00321
00322 void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block,
00323 S32 block_num)
00324 {
00325 U8 sale_type;
00326 msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num);
00327 mSaleType = static_cast<EForSale>(sale_type);
00328 msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num);
00329 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00330
00331 }
00332
00333 LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name)
00334 {
00335 for(S32 i = 0; i < FS_COUNT; i++)
00336 {
00337 if(0 == strcmp(name, FOR_SALE_NAMES[i]))
00338 {
00339
00340 return (EForSale)i;
00341 }
00342 }
00343 return FS_NOT;
00344 }
00345
00346 const char* LLSaleInfo::lookup(EForSale type)
00347 {
00348 if((type >= 0) && (type < FS_COUNT))
00349 {
00350 return FOR_SALE_NAMES[S32(type)];
00351 }
00352 else
00353 {
00354 return NULL;
00355 }
00356 }
00357
00358
00359
00360
00361 void LLSaleInfo::accumulate(const LLSaleInfo& sale_info)
00362 {
00363 if(mSaleType != sale_info.mSaleType)
00364 {
00365 mSaleType = FS_NOT;
00366 }
00367 mSalePrice += sale_info.mSalePrice;
00368
00369 }
00370
00371 bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const
00372 {
00373 return (
00374 (mSaleType == rhs.mSaleType) &&
00375 (mSalePrice == rhs.mSalePrice)
00376 );
00377 }
00378
00379 bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const
00380 {
00381 return (
00382 (mSaleType != rhs.mSaleType) ||
00383 (mSalePrice != rhs.mSalePrice)
00384 );
00385 }
00386
00387
00391
00395 static const std::string ST_TYPE_LABEL("sale_type");
00396 static const std::string ST_PRICE_LABEL("sale_price");
00397
00398 LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale)
00399 {
00400 LLSD rv;
00401 const char* type = LLSaleInfo::lookup(sale.getSaleType());
00402 if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT);
00403 rv[ST_TYPE_LABEL] = type;
00404 rv[ST_PRICE_LABEL] = sale.getSalePrice();
00405 return rv;
00406 }
00407
00408 LLSaleInfo ll_sale_info_from_sd(const LLSD& sd)
00409 {
00410 LLSaleInfo rv;
00411 rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str()));
00412 rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX));
00413 return rv;
00414 }