llsaleinfo.cpp

Go to the documentation of this file.
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 // use this to avoid temporary object creation
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 // Default constructor
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         // *NOTE: Changing the buffer size will require changing the scanf
00166         // calls below.
00167         char buffer[MAX_STRING];        /* Flawfinder: ignore */
00168         char keyword[MAX_STRING];       /* Flawfinder: ignore */
00169         char valuestr[MAX_STRING];      /* Flawfinder: ignore */
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( /* Flawfinder: ignore */
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                         //llinfos << "found deprecated keyword perm_mask" << llendl;
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         // *NOTE: Changing the buffer size will require changing the scanf
00226         // calls below.
00227         char buffer[MAX_STRING];        /* Flawfinder: ignore */
00228         char keyword[MAX_STRING];       /* Flawfinder: ignore */
00229         char valuestr[MAX_STRING];      /* Flawfinder: ignore */
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( /* Flawfinder: ignore */
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                         //llinfos << "found deprecated keyword perm_mask" << llendl;
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         //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask);
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         //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask);
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         //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask, block_num);
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                         // match
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 // Allow accumulation of sale info. The price of each is added,
00338 // conflict in sale type results in FS_NOT, and the permissions are
00339 // tightened.
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         //mNextOwnerPermMask &= sale_info.mNextOwnerPermMask;
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 }

Generated on Thu Jul 1 06:09:05 2010 for Second Life Viewer by  doxygen 1.4.7