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(FILE* 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(FILE* 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 void LLSaleInfo::packMessage(LLMessageSystem* msg) const
00284 {
00285 U8 sale_type = static_cast<U8>(mSaleType);
00286 msg->addU8Fast(_PREHASH_SaleType, sale_type);
00287 msg->addS32Fast(_PREHASH_SalePrice, mSalePrice);
00288
00289 }
00290
00291 void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
00292 {
00293 U8 sale_type;
00294 msg->getU8Fast(block, _PREHASH_SaleType, sale_type);
00295 mSaleType = static_cast<EForSale>(sale_type);
00296 msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice);
00297 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00298
00299 }
00300
00301 void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block,
00302 S32 block_num)
00303 {
00304 U8 sale_type;
00305 msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num);
00306 mSaleType = static_cast<EForSale>(sale_type);
00307 msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num);
00308 mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
00309
00310 }
00311
00312 LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name)
00313 {
00314 for(S32 i = 0; i < FS_COUNT; i++)
00315 {
00316 if(0 == strcmp(name, FOR_SALE_NAMES[i]))
00317 {
00318
00319 return (EForSale)i;
00320 }
00321 }
00322 return FS_NOT;
00323 }
00324
00325 const char* LLSaleInfo::lookup(EForSale type)
00326 {
00327 if((type >= 0) && (type < FS_COUNT))
00328 {
00329 return FOR_SALE_NAMES[S32(type)];
00330 }
00331 else
00332 {
00333 return NULL;
00334 }
00335 }
00336
00337
00338
00339
00340 void LLSaleInfo::accumulate(const LLSaleInfo& sale_info)
00341 {
00342 if(mSaleType != sale_info.mSaleType)
00343 {
00344 mSaleType = FS_NOT;
00345 }
00346 mSalePrice += sale_info.mSalePrice;
00347
00348 }
00349
00350 bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const
00351 {
00352 return (
00353 (mSaleType == rhs.mSaleType) &&
00354 (mSalePrice == rhs.mSalePrice)
00355 );
00356 }
00357
00358 bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const
00359 {
00360 return (
00361 (mSaleType != rhs.mSaleType) ||
00362 (mSalePrice != rhs.mSalePrice)
00363 );
00364 }
00365
00366
00370
00374 static const std::string ST_TYPE_LABEL("sale_type");
00375 static const std::string ST_PRICE_LABEL("sale_price");
00376
00377 LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale)
00378 {
00379 LLSD rv;
00380 const char* type = LLSaleInfo::lookup(sale.getSaleType());
00381 if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT);
00382 rv[ST_TYPE_LABEL] = type;
00383 rv[ST_PRICE_LABEL] = sale.getSalePrice();
00384 return rv;
00385 }
00386
00387 LLSaleInfo ll_sale_info_from_sd(const LLSD& sd)
00388 {
00389 LLSaleInfo rv;
00390 rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str()));
00391 rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX));
00392 return rv;
00393 }