00001
00032 #include "linden_common.h"
00033
00034 #include "llinventory.h"
00035
00036 #include "lldbstrings.h"
00037 #include "llxorcipher.h"
00038 #include "llsd.h"
00039 #include "message.h"
00040 #include <boost/tokenizer.hpp>
00041
00042 #include "llsdutil.h"
00043
00047
00048 static const std::string INV_ITEM_ID_LABEL("item_id");
00049 static const std::string INV_FOLDER_ID_LABEL("folder_id");
00050 static const std::string INV_PARENT_ID_LABEL("parent_id");
00051 static const std::string INV_ASSET_TYPE_LABEL("type");
00052 static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
00053 static const std::string INV_INVENTORY_TYPE_LABEL("inv_type");
00054 static const std::string INV_NAME_LABEL("name");
00055 static const std::string INV_DESC_LABEL("desc");
00056 static const std::string INV_PERMISSIONS_LABEL("permissions");
00057 static const std::string INV_ASSET_ID_LABEL("asset_id");
00058 static const std::string INV_SALE_INFO_LABEL("sale_info");
00059 static const std::string INV_FLAGS_LABEL("flags");
00060 static const std::string INV_CREATION_DATE_LABEL("created_at");
00061
00065
00066 const U8 TASK_INVENTORY_ITEM_KEY = 0;
00067 const U8 TASK_INVENTORY_ASSET_KEY = 1;
00068
00069 const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730");
00070
00071
00075
00076 LLInventoryObject::LLInventoryObject(
00077 const LLUUID& uuid,
00078 const LLUUID& parent_uuid,
00079 LLAssetType::EType type,
00080 const LLString& name) :
00081 mUUID(uuid),
00082 mParentUUID(parent_uuid),
00083 mType(type),
00084 mName(name)
00085 {
00086 LLString::replaceNonstandardASCII(mName, ' ');
00087 LLString::replaceChar(mName, '|', ' ');
00088 LLString::trim(mName);
00089 LLString::truncate(mName, DB_INV_ITEM_NAME_STR_LEN);
00090 }
00091
00092 LLInventoryObject::LLInventoryObject() :
00093 mType(LLAssetType::AT_NONE)
00094 {
00095 }
00096
00097 LLInventoryObject::~LLInventoryObject( void )
00098 {
00099 }
00100
00101 void LLInventoryObject::copy(const LLInventoryObject* other)
00102 {
00103 mUUID = other->mUUID;
00104 mParentUUID = other->mParentUUID;
00105 mType = other->mType;
00106 mName = other->mName;
00107 }
00108
00109 const LLUUID& LLInventoryObject::getUUID() const
00110 {
00111 return mUUID;
00112 }
00113
00114 const LLUUID& LLInventoryObject::getParentUUID() const
00115 {
00116 return mParentUUID;
00117 }
00118
00119 const LLString& LLInventoryObject::getName() const
00120 {
00121 return mName;
00122 }
00123
00124 LLAssetType::EType LLInventoryObject::getType() const
00125 {
00126 return mType;
00127 }
00128
00129 void LLInventoryObject::setUUID(const LLUUID& new_uuid)
00130 {
00131 mUUID = new_uuid;
00132 }
00133
00134 void LLInventoryObject::rename(const LLString& n)
00135 {
00136 LLString new_name(n);
00137 LLString::replaceNonstandardASCII(new_name, ' ');
00138 LLString::replaceChar(new_name, '|', ' ');
00139 LLString::trim(new_name);
00140 LLString::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
00141
00142 if( new_name != mName )
00143 {
00144 mName = new_name;
00145 }
00146 }
00147
00148 void LLInventoryObject::setParent(const LLUUID& new_parent)
00149 {
00150 mParentUUID = new_parent;
00151 }
00152
00153 void LLInventoryObject::setType(LLAssetType::EType type)
00154 {
00155 mType = type;
00156 }
00157
00158
00159
00160 BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)
00161 {
00162
00163
00164 char buffer[MAX_STRING];
00165 char keyword[MAX_STRING];
00166 char valuestr[MAX_STRING];
00167
00168 keyword[0] = '\0';
00169 valuestr[0] = '\0';
00170 while(input_stream.good())
00171 {
00172 input_stream.getline(buffer, MAX_STRING);
00173 sscanf(buffer, " %254s %254s", keyword, valuestr);
00174 if(0 == strcmp("{",keyword))
00175 {
00176 continue;
00177 }
00178 if(0 == strcmp("}", keyword))
00179 {
00180 break;
00181 }
00182 else if(0 == strcmp("obj_id", keyword))
00183 {
00184 mUUID.set(valuestr);
00185 }
00186 else if(0 == strcmp("parent_id", keyword))
00187 {
00188 mParentUUID.set(valuestr);
00189 }
00190 else if(0 == strcmp("type", keyword))
00191 {
00192 mType = LLAssetType::lookup(valuestr);
00193 }
00194 else if(0 == strcmp("name", keyword))
00195 {
00196
00197
00198 sscanf(
00199 buffer,
00200 " %254s %254[^|]",
00201 keyword, valuestr);
00202 mName.assign(valuestr);
00203 LLString::replaceNonstandardASCII(mName, ' ');
00204 LLString::replaceChar(mName, '|', ' ');
00205 LLString::trim(mName);
00206 LLString::truncate(mName, DB_INV_ITEM_NAME_STR_LEN);
00207 }
00208 else
00209 {
00210 llwarns << "unknown keyword '" << keyword
00211 << "' in LLInventoryObject::importLegacyStream() for object " << mUUID << llendl;
00212 }
00213 }
00214 return TRUE;
00215 }
00216
00217
00218
00219 BOOL LLInventoryObject::exportFile(FILE* fp, BOOL) const
00220 {
00221 char uuid_str[UUID_STR_LENGTH];
00222 fprintf(fp, "\tinv_object\t0\n\t{\n");
00223 mUUID.toString(uuid_str);
00224 fprintf(fp, "\t\tobj_id\t%s\n", uuid_str);
00225 mParentUUID.toString(uuid_str);
00226 fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00227 fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00228 fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00229 fprintf(fp,"\t}\n");
00230 return TRUE;
00231 }
00232
00233 BOOL LLInventoryObject::exportLegacyStream(std::ostream& output_stream, BOOL) const
00234 {
00235 char uuid_str[UUID_STR_LENGTH];
00236 output_stream << "\tinv_object\t0\n\t{\n";
00237 mUUID.toString(uuid_str);
00238 output_stream << "\t\tobj_id\t" << uuid_str << "\n";
00239 mParentUUID.toString(uuid_str);
00240 output_stream << "\t\tparent_id\t" << uuid_str << "\n";
00241 output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
00242 output_stream << "\t\tname\t" << mName.c_str() << "|\n";
00243 output_stream << "\t}\n";
00244 return TRUE;
00245 }
00246
00247
00248 void LLInventoryObject::removeFromServer()
00249 {
00250
00251 llwarns << "LLInventoryObject::removeFromServer() called. Doesn't do anything." << llendl;
00252 }
00253
00254 void LLInventoryObject::updateParentOnServer(BOOL) const
00255 {
00256
00257 llwarns << "LLInventoryObject::updateParentOnServer() called. Doesn't do anything." << llendl;
00258 }
00259
00260 void LLInventoryObject::updateServer(BOOL) const
00261 {
00262
00263 llwarns << "LLInventoryObject::updateServer() called. Doesn't do anything." << llendl;
00264 }
00265
00266
00270
00271 LLInventoryItem::LLInventoryItem(
00272 const LLUUID& uuid,
00273 const LLUUID& parent_uuid,
00274 const LLPermissions& permissions,
00275 const LLUUID& asset_uuid,
00276 LLAssetType::EType type,
00277 LLInventoryType::EType inv_type,
00278 const LLString& name,
00279 const LLString& desc,
00280 const LLSaleInfo& sale_info,
00281 U32 flags,
00282 S32 creation_date_utc) :
00283 LLInventoryObject(uuid, parent_uuid, type, name),
00284 mPermissions(permissions),
00285 mAssetUUID(asset_uuid),
00286 mDescription(desc),
00287 mSaleInfo(sale_info),
00288 mInventoryType(inv_type),
00289 mFlags(flags),
00290 mCreationDate(creation_date_utc)
00291 {
00292 LLString::replaceNonstandardASCII(mDescription, ' ');
00293 LLString::replaceChar(mDescription, '|', ' ');
00294 }
00295
00296 LLInventoryItem::LLInventoryItem() :
00297 LLInventoryObject(),
00298 mPermissions(),
00299 mAssetUUID(),
00300 mDescription(),
00301 mSaleInfo(),
00302 mInventoryType(LLInventoryType::IT_NONE),
00303 mFlags(0),
00304 mCreationDate(0)
00305 {
00306 }
00307
00308 LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
00309 LLInventoryObject()
00310 {
00311 copy(other);
00312 }
00313
00314 LLInventoryItem::~LLInventoryItem()
00315 {
00316 }
00317
00318
00319 void LLInventoryItem::copy(const LLInventoryItem* other)
00320 {
00321 LLInventoryObject::copy(other);
00322 mPermissions = other->mPermissions;
00323 mAssetUUID = other->mAssetUUID;
00324 mDescription = other->mDescription;
00325 mSaleInfo = other->mSaleInfo;
00326 mInventoryType = other->mInventoryType;
00327 mFlags = other->mFlags;
00328 mCreationDate = other->mCreationDate;
00329 }
00330
00331
00332
00333 void LLInventoryItem::clone(LLPointer<LLInventoryItem>& newitem) const
00334 {
00335 newitem = new LLInventoryItem;
00336 newitem->copy(this);
00337 newitem->mUUID.generate();
00338 }
00339
00340 const LLPermissions& LLInventoryItem::getPermissions() const
00341 {
00342 return mPermissions;
00343 }
00344
00345 const LLUUID& LLInventoryItem::getCreatorUUID() const
00346 {
00347 return mPermissions.getCreator();
00348 }
00349
00350 const LLUUID& LLInventoryItem::getAssetUUID() const
00351 {
00352 return mAssetUUID;
00353 }
00354
00355 void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)
00356 {
00357 mAssetUUID = asset_id;
00358 }
00359
00360
00361 const LLString& LLInventoryItem::getDescription() const
00362 {
00363 return mDescription;
00364 }
00365
00366 S32 LLInventoryItem::getCreationDate() const
00367 {
00368 return mCreationDate;
00369 }
00370
00371 U32 LLInventoryItem::getCRC32() const
00372 {
00373
00374
00375
00376 U32 crc = mUUID.getCRC32();
00377
00378 crc += mParentUUID.getCRC32();
00379
00380 crc += mPermissions.getCRC32();
00381
00382 crc += mAssetUUID.getCRC32();
00383
00384 crc += mType;
00385
00386 crc += mInventoryType;
00387
00388 crc += mFlags;
00389
00390 crc += mSaleInfo.getCRC32();
00391
00392 crc += mCreationDate;
00393
00394 return crc;
00395 }
00396
00397
00398 void LLInventoryItem::setDescription(const LLString& d)
00399 {
00400 LLString new_desc(d);
00401 LLString::replaceNonstandardASCII(new_desc, ' ');
00402 LLString::replaceChar(new_desc, '|', ' ');
00403 if( new_desc != mDescription )
00404 {
00405 mDescription = new_desc;
00406 }
00407 }
00408
00409 void LLInventoryItem::setPermissions(const LLPermissions& perm)
00410 {
00411 mPermissions = perm;
00412 }
00413
00414 void LLInventoryItem::setInventoryType(LLInventoryType::EType inv_type)
00415 {
00416 mInventoryType = inv_type;
00417 }
00418
00419 void LLInventoryItem::setFlags(U32 flags)
00420 {
00421 mFlags = flags;
00422 }
00423
00424 void LLInventoryItem::setCreationDate(S32 creation_date_utc)
00425 {
00426 mCreationDate = creation_date_utc;
00427 }
00428
00429
00430 const LLSaleInfo& LLInventoryItem::getSaleInfo() const
00431 {
00432 return mSaleInfo;
00433 }
00434
00435 void LLInventoryItem::setSaleInfo(const LLSaleInfo& sale_info)
00436 {
00437 mSaleInfo = sale_info;
00438 }
00439
00440 LLInventoryType::EType LLInventoryItem::getInventoryType() const
00441 {
00442 return mInventoryType;
00443 }
00444
00445 U32 LLInventoryItem::getFlags() const
00446 {
00447 return mFlags;
00448 }
00449
00450
00451 void LLInventoryItem::packMessage(LLMessageSystem* msg) const
00452 {
00453 msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00454 msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
00455 mPermissions.packMessage(msg);
00456 msg->addUUIDFast(_PREHASH_AssetID, mAssetUUID);
00457 S8 type = static_cast<S8>(mType);
00458 msg->addS8Fast(_PREHASH_Type, type);
00459 type = static_cast<S8>(mInventoryType);
00460 msg->addS8Fast(_PREHASH_InvType, type);
00461 msg->addU32Fast(_PREHASH_Flags, mFlags);
00462 mSaleInfo.packMessage(msg);
00463 msg->addStringFast(_PREHASH_Name, mName);
00464 msg->addStringFast(_PREHASH_Description, mDescription);
00465 msg->addS32Fast(_PREHASH_CreationDate, mCreationDate);
00466 U32 crc = getCRC32();
00467 msg->addU32Fast(_PREHASH_CRC, crc);
00468 }
00469
00470
00471 BOOL LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
00472 {
00473 msg->getUUIDFast(block, _PREHASH_ItemID, mUUID, block_num);
00474 msg->getUUIDFast(block, _PREHASH_FolderID, mParentUUID, block_num);
00475 mPermissions.unpackMessage(msg, block, block_num);
00476 msg->getUUIDFast(block, _PREHASH_AssetID, mAssetUUID, block_num);
00477
00478 S8 type;
00479 msg->getS8Fast(block, _PREHASH_Type, type, block_num);
00480 mType = static_cast<LLAssetType::EType>(type);
00481 msg->getS8(block, "InvType", type, block_num);
00482 mInventoryType = static_cast<LLInventoryType::EType>(type);
00483
00484 msg->getU32Fast(block, _PREHASH_Flags, mFlags, block_num);
00485
00486 mSaleInfo.unpackMultiMessage(msg, block, block_num);
00487
00488 char name[DB_INV_ITEM_NAME_BUF_SIZE];
00489 msg->getStringFast(block, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name, block_num);
00490 mName.assign(name);
00491 LLString::replaceNonstandardASCII(mName, ' ');
00492
00493 char desc[DB_INV_ITEM_DESC_BUF_SIZE];
00494 msg->getStringFast(block, _PREHASH_Description, DB_INV_ITEM_DESC_BUF_SIZE, desc, block_num);
00495 mDescription.assign(desc);
00496 LLString::replaceNonstandardASCII(mDescription, ' ');
00497
00498 msg->getS32(block, "CreationDate", mCreationDate, block_num);
00499
00500 U32 local_crc = getCRC32();
00501 U32 remote_crc = 0;
00502 msg->getU32(block, "CRC", remote_crc, block_num);
00503
00504 #ifdef CRC_CHECK
00505 if(local_crc == remote_crc)
00506 {
00507 lldebugs << "crc matches" << llendl;
00508 return TRUE;
00509 }
00510 else
00511 {
00512 llwarns << "inventory crc mismatch: local=" << std::hex << local_crc
00513 << " remote=" << remote_crc << std::dec << llendl;
00514 return FALSE;
00515 }
00516 #else
00517 return (local_crc == remote_crc);
00518 #endif
00519 }
00520
00521
00522 BOOL LLInventoryItem::importFile(FILE* fp)
00523 {
00524
00525
00526 char buffer[MAX_STRING];
00527 char keyword[MAX_STRING];
00528 char valuestr[MAX_STRING];
00529 char junk[MAX_STRING];
00530 BOOL success = TRUE;
00531
00532 keyword[0] = '\0';
00533 valuestr[0] = '\0';
00534
00535 mInventoryType = LLInventoryType::IT_NONE;
00536 mAssetUUID.setNull();
00537 while(success && (!feof(fp)))
00538 {
00539 if (fgets(buffer, MAX_STRING, fp) == NULL)
00540 {
00541 buffer[0] = '\0';
00542 }
00543
00544 sscanf(buffer, " %254s %254s", keyword, valuestr);
00545 if(0 == strcmp("{",keyword))
00546 {
00547 continue;
00548 }
00549 if(0 == strcmp("}", keyword))
00550 {
00551 break;
00552 }
00553 else if(0 == strcmp("item_id", keyword))
00554 {
00555 mUUID.set(valuestr);
00556 }
00557 else if(0 == strcmp("parent_id", keyword))
00558 {
00559 mParentUUID.set(valuestr);
00560 }
00561 else if(0 == strcmp("permissions", keyword))
00562 {
00563 success = mPermissions.importFile(fp);
00564 }
00565 else if(0 == strcmp("sale_info", keyword))
00566 {
00567
00568
00569
00570
00571 BOOL has_perm_mask = FALSE;
00572 U32 perm_mask = 0;
00573 success = mSaleInfo.importFile(fp, has_perm_mask, perm_mask);
00574 if(has_perm_mask)
00575 {
00576 if(perm_mask == PERM_NONE)
00577 {
00578 perm_mask = mPermissions.getMaskOwner();
00579 }
00580
00581 if(!(perm_mask & PERM_COPY))
00582 {
00583 perm_mask |= PERM_TRANSFER;
00584 }
00585 mPermissions.setMaskNext(perm_mask);
00586 }
00587 }
00588 else if(0 == strcmp("shadow_id", keyword))
00589 {
00590 mAssetUUID.set(valuestr);
00591 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
00592 cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
00593 }
00594 else if(0 == strcmp("asset_id", keyword))
00595 {
00596 mAssetUUID.set(valuestr);
00597 }
00598 else if(0 == strcmp("type", keyword))
00599 {
00600 mType = LLAssetType::lookup(valuestr);
00601 }
00602 else if(0 == strcmp("inv_type", keyword))
00603 {
00604 mInventoryType = LLInventoryType::lookup(valuestr);
00605 }
00606 else if(0 == strcmp("flags", keyword))
00607 {
00608 sscanf(valuestr, "%x", &mFlags);
00609 }
00610 else if(0 == strcmp("name", keyword))
00611 {
00612
00613
00614 sscanf(
00615 buffer,
00616 " %254s%254[\t]%254[^|]",
00617 keyword, junk, valuestr);
00618
00619
00620 if (valuestr[0] == '|')
00621 {
00622 valuestr[0] = '\000';
00623 }
00624
00625 mName.assign(valuestr);
00626 LLString::replaceNonstandardASCII(mName, ' ');
00627 LLString::replaceChar(mName, '|', ' ');
00628 }
00629 else if(0 == strcmp("desc", keyword))
00630 {
00631
00632
00633 sscanf(
00634 buffer,
00635 " %254s%254[\t]%254[^|]",
00636 keyword, junk, valuestr);
00637
00638 if (valuestr[0] == '|')
00639 {
00640 valuestr[0] = '\000';
00641 }
00642
00643 mDescription.assign(valuestr);
00644 LLString::replaceNonstandardASCII(mDescription, ' ');
00645
00646
00647
00648
00649
00650
00651
00652 }
00653 else if(0 == strcmp("creation_date", keyword))
00654 {
00655 sscanf(valuestr, "%d", &mCreationDate);
00656 }
00657 else
00658 {
00659 llwarns << "unknown keyword '" << keyword
00660 << "' in inventory import of item " << mUUID << llendl;
00661 }
00662 }
00663
00664
00665
00666
00667 if((LLInventoryType::IT_NONE == mInventoryType)
00668 || !inventory_and_asset_types_match(mInventoryType, mType))
00669 {
00670 lldebugs << "Resetting inventory type for " << mUUID << llendl;
00671 mInventoryType = LLInventoryType::defaultForAssetType(mType);
00672 }
00673 return success;
00674 }
00675
00676 BOOL LLInventoryItem::exportFile(FILE* fp, BOOL include_asset_key) const
00677 {
00678 char uuid_str[UUID_STR_LENGTH];
00679 fprintf(fp, "\tinv_item\t0\n\t{\n");
00680 mUUID.toString(uuid_str);
00681 fprintf(fp, "\t\titem_id\t%s\n", uuid_str);
00682 mParentUUID.toString(uuid_str);
00683 fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00684 mPermissions.exportFile(fp);
00685
00686
00687
00688 if(include_asset_key)
00689 {
00690 U32 mask = mPermissions.getMaskBase();
00691 if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
00692 || (mAssetUUID.isNull()))
00693 {
00694 mAssetUUID.toString(uuid_str);
00695 fprintf(fp, "\t\tasset_id\t%s\n", uuid_str);
00696 }
00697 else
00698 {
00699 LLUUID shadow_id(mAssetUUID);
00700 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
00701 cipher.encrypt(shadow_id.mData, UUID_BYTES);
00702 shadow_id.toString(uuid_str);
00703 fprintf(fp, "\t\tshadow_id\t%s\n", uuid_str);
00704 }
00705 }
00706 else
00707 {
00708 LLUUID::null.toString(uuid_str);
00709 fprintf(fp, "\t\tasset_id\t%s\n", uuid_str);
00710 }
00711 fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00712 const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
00713 if(inv_type_str) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str);
00714 fprintf(fp, "\t\tflags\t%08x\n", mFlags);
00715 mSaleInfo.exportFile(fp);
00716 fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00717 fprintf(fp, "\t\tdesc\t%s|\n", mDescription.c_str());
00718 fprintf(fp, "\t\tcreation_date\t%d\n", mCreationDate);
00719 fprintf(fp,"\t}\n");
00720 return TRUE;
00721 }
00722
00723
00724 BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
00725 {
00726
00727
00728 char buffer[MAX_STRING];
00729 char keyword[MAX_STRING];
00730 char valuestr[MAX_STRING];
00731 char junk[MAX_STRING];
00732 BOOL success = TRUE;
00733
00734 keyword[0] = '\0';
00735 valuestr[0] = '\0';
00736
00737 mInventoryType = LLInventoryType::IT_NONE;
00738 mAssetUUID.setNull();
00739 while(success && input_stream.good())
00740 {
00741 input_stream.getline(buffer, MAX_STRING);
00742 sscanf(
00743 buffer,
00744 " %254s %254s",
00745 keyword, valuestr);
00746 if(0 == strcmp("{",keyword))
00747 {
00748 continue;
00749 }
00750 if(0 == strcmp("}", keyword))
00751 {
00752 break;
00753 }
00754 else if(0 == strcmp("item_id", keyword))
00755 {
00756 mUUID.set(valuestr);
00757 }
00758 else if(0 == strcmp("parent_id", keyword))
00759 {
00760 mParentUUID.set(valuestr);
00761 }
00762 else if(0 == strcmp("permissions", keyword))
00763 {
00764 success = mPermissions.importLegacyStream(input_stream);
00765 }
00766 else if(0 == strcmp("sale_info", keyword))
00767 {
00768
00769
00770
00771
00772 BOOL has_perm_mask = FALSE;
00773 U32 perm_mask = 0;
00774 success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask);
00775 if(has_perm_mask)
00776 {
00777 if(perm_mask == PERM_NONE)
00778 {
00779 perm_mask = mPermissions.getMaskOwner();
00780 }
00781
00782 if(!(perm_mask & PERM_COPY))
00783 {
00784 perm_mask |= PERM_TRANSFER;
00785 }
00786 mPermissions.setMaskNext(perm_mask);
00787 }
00788 }
00789 else if(0 == strcmp("shadow_id", keyword))
00790 {
00791 mAssetUUID.set(valuestr);
00792 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
00793 cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
00794 }
00795 else if(0 == strcmp("asset_id", keyword))
00796 {
00797 mAssetUUID.set(valuestr);
00798 }
00799 else if(0 == strcmp("type", keyword))
00800 {
00801 mType = LLAssetType::lookup(valuestr);
00802 }
00803 else if(0 == strcmp("inv_type", keyword))
00804 {
00805 mInventoryType = LLInventoryType::lookup(valuestr);
00806 }
00807 else if(0 == strcmp("flags", keyword))
00808 {
00809 sscanf(valuestr, "%x", &mFlags);
00810 }
00811 else if(0 == strcmp("name", keyword))
00812 {
00813
00814
00815 sscanf(
00816 buffer,
00817 " %254s%254[\t]%254[^|]",
00818 keyword, junk, valuestr);
00819
00820
00821 if (valuestr[0] == '|')
00822 {
00823 valuestr[0] = '\000';
00824 }
00825
00826 mName.assign(valuestr);
00827 LLString::replaceNonstandardASCII(mName, ' ');
00828 LLString::replaceChar(mName, '|', ' ');
00829 }
00830 else if(0 == strcmp("desc", keyword))
00831 {
00832
00833
00834 sscanf(
00835 buffer,
00836 " %254s%254[\t]%254[^|]",
00837 keyword, junk, valuestr);
00838
00839 if (valuestr[0] == '|')
00840 {
00841 valuestr[0] = '\000';
00842 }
00843
00844 mDescription.assign(valuestr);
00845 LLString::replaceNonstandardASCII(mDescription, ' ');
00846
00847
00848
00849
00850
00851
00852
00853 }
00854 else if(0 == strcmp("creation_date", keyword))
00855 {
00856 sscanf(valuestr, "%d", &mCreationDate);
00857 }
00858 else
00859 {
00860 llwarns << "unknown keyword '" << keyword
00861 << "' in inventory import of item " << mUUID << llendl;
00862 }
00863 }
00864
00865
00866
00867
00868 if((LLInventoryType::IT_NONE == mInventoryType)
00869 || !inventory_and_asset_types_match(mInventoryType, mType))
00870 {
00871 lldebugs << "Resetting inventory type for " << mUUID << llendl;
00872 mInventoryType = LLInventoryType::defaultForAssetType(mType);
00873 }
00874 return success;
00875 }
00876
00877 BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key) const
00878 {
00879 char uuid_str[UUID_STR_LENGTH];
00880 output_stream << "\tinv_item\t0\n\t{\n";
00881 mUUID.toString(uuid_str);
00882 output_stream << "\t\titem_id\t" << uuid_str << "\n";
00883 mParentUUID.toString(uuid_str);
00884 output_stream << "\t\tparent_id\t" << uuid_str << "\n";
00885 mPermissions.exportLegacyStream(output_stream);
00886
00887
00888
00889 if(include_asset_key)
00890 {
00891 U32 mask = mPermissions.getMaskBase();
00892 if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
00893 || (mAssetUUID.isNull()))
00894 {
00895 mAssetUUID.toString(uuid_str);
00896 output_stream << "\t\tasset_id\t" << uuid_str << "\n";
00897 }
00898 else
00899 {
00900 LLUUID shadow_id(mAssetUUID);
00901 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
00902 cipher.encrypt(shadow_id.mData, UUID_BYTES);
00903 shadow_id.toString(uuid_str);
00904 output_stream << "\t\tshadow_id\t" << uuid_str << "\n";
00905 }
00906 }
00907 else
00908 {
00909 LLUUID::null.toString(uuid_str);
00910 output_stream << "\t\tasset_id\t" << uuid_str << "\n";
00911 }
00912 output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
00913 const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
00914 if(inv_type_str)
00915 output_stream << "\t\tinv_type\t" << inv_type_str << "\n";
00916 char buffer[32];
00917 snprintf(buffer, sizeof(buffer), "\t\tflags\t%08x\n", mFlags);
00918 output_stream << buffer;
00919 mSaleInfo.exportLegacyStream(output_stream);
00920 output_stream << "\t\tname\t" << mName.c_str() << "|\n";
00921 output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n";
00922 output_stream << "\t\tcreation_date\t" << mCreationDate << "\n";
00923 output_stream << "\t}\n";
00924 return TRUE;
00925 }
00926
00927 LLSD LLInventoryItem::asLLSD() const
00928 {
00929 LLSD sd = LLSD();
00930 sd["item_id"] = mUUID;
00931 sd["parent_id"] = mParentUUID;
00932 sd["permissions"] = ll_create_sd_from_permissions(mPermissions);
00933
00934 U32 mask = mPermissions.getMaskBase();
00935 if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
00936 || (mAssetUUID.isNull()))
00937 {
00938 sd["asset_id"] = mAssetUUID;
00939 }
00940 else
00941 {
00942 LLUUID shadow_id(mAssetUUID);
00943 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
00944 cipher.encrypt(shadow_id.mData, UUID_BYTES);
00945 sd["shadow_id"] = shadow_id;
00946 }
00947 sd["type"] = LLAssetType::lookup(mType);
00948 const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
00949 if(inv_type_str)
00950 {
00951 sd["inv_type"] = inv_type_str;
00952 }
00953 sd["flags"] = ll_sd_from_U32(mFlags);
00954 sd["sale_info"] = mSaleInfo;
00955 sd["name"] = mName;
00956 sd["desc"] = mDescription;
00957 sd["creation_date"] = mCreationDate;
00958
00959 return sd;
00960 }
00961
00962 bool LLInventoryItem::fromLLSD(LLSD& sd)
00963 {
00964 mInventoryType = LLInventoryType::IT_NONE;
00965 mAssetUUID.setNull();
00966 std::string w;
00967
00968 w = INV_ITEM_ID_LABEL;
00969 if (sd.has(w))
00970 {
00971 mUUID = sd[w];
00972 }
00973 w = INV_PARENT_ID_LABEL;
00974 if (sd.has(w))
00975 {
00976 mParentUUID = sd[w];
00977 }
00978 w = INV_PERMISSIONS_LABEL;
00979 if (sd.has(w))
00980 {
00981 mPermissions = ll_permissions_from_sd(sd[w]);
00982 }
00983 w = INV_SALE_INFO_LABEL;
00984 if (sd.has(w))
00985 {
00986
00987
00988
00989
00990 BOOL has_perm_mask = FALSE;
00991 U32 perm_mask = 0;
00992 if (!mSaleInfo.fromLLSD(sd[w], has_perm_mask, perm_mask))
00993 {
00994 goto fail;
00995 }
00996 if (has_perm_mask)
00997 {
00998 if(perm_mask == PERM_NONE)
00999 {
01000 perm_mask = mPermissions.getMaskOwner();
01001 }
01002
01003 if(!(perm_mask & PERM_COPY))
01004 {
01005 perm_mask |= PERM_TRANSFER;
01006 }
01007 mPermissions.setMaskNext(perm_mask);
01008 }
01009 }
01010 w = "shadow_id";
01011 if (sd.has(w))
01012 {
01013 mAssetUUID = sd[w];
01014 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
01015 cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
01016 }
01017 w = INV_ASSET_ID_LABEL;
01018 if (sd.has(w))
01019 {
01020 mAssetUUID = sd[w];
01021 }
01022 w = INV_ASSET_TYPE_LABEL;
01023 if (sd.has(w))
01024 {
01025 mType = LLAssetType::lookup(sd[w].asString().c_str());
01026 }
01027 w = INV_INVENTORY_TYPE_LABEL;
01028 if (sd.has(w))
01029 {
01030 mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());
01031 }
01032 w = INV_FLAGS_LABEL;
01033 if (sd.has(w))
01034 {
01035 mFlags = ll_U32_from_sd(sd[w]);
01036 }
01037 w = INV_NAME_LABEL;
01038 if (sd.has(w))
01039 {
01040 mName = sd[w].asString();
01041 LLString::replaceNonstandardASCII(mName, ' ');
01042 LLString::replaceChar(mName, '|', ' ');
01043 }
01044 w = INV_DESC_LABEL;
01045 if (sd.has(w))
01046 {
01047 mDescription = sd[w].asString();
01048 LLString::replaceNonstandardASCII(mDescription, ' ');
01049 }
01050 w = INV_CREATION_DATE_LABEL;
01051 if (sd.has(w))
01052 {
01053 mCreationDate = sd[w];
01054 }
01055
01056
01057
01058
01059 if((LLInventoryType::IT_NONE == mInventoryType)
01060 || !inventory_and_asset_types_match(mInventoryType, mType))
01061 {
01062 lldebugs << "Resetting inventory type for " << mUUID << llendl;
01063 mInventoryType = LLInventoryType::defaultForAssetType(mType);
01064 }
01065
01066 return true;
01067 fail:
01068 return false;
01069
01070 }
01071
01072 LLXMLNode *LLInventoryItem::exportFileXML(BOOL include_asset_key) const
01073 {
01074 LLMemType m1(LLMemType::MTYPE_INVENTORY);
01075 LLXMLNode *ret = new LLXMLNode("item", FALSE);
01076
01077 ret->createChild("uuid", TRUE)->setUUIDValue(1, &mUUID);
01078 ret->createChild("parent_uuid", TRUE)->setUUIDValue(1, &mParentUUID);
01079
01080 mPermissions.exportFileXML()->setParent(ret);
01081
01082
01083
01084 if(include_asset_key)
01085 {
01086 U32 mask = mPermissions.getMaskBase();
01087 if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
01088 || (mAssetUUID.isNull()))
01089 {
01090 ret->createChild("asset_id", FALSE)->setUUIDValue(1, &mAssetUUID);
01091 }
01092 else
01093 {
01094 LLUUID shadow_id(mAssetUUID);
01095 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
01096 cipher.encrypt(shadow_id.mData, UUID_BYTES);
01097
01098 ret->createChild("shadow_id", FALSE)->setUUIDValue(1, &shadow_id);
01099 }
01100 }
01101
01102 LLString type_str = LLAssetType::lookup(mType);
01103 LLString inv_type_str = LLInventoryType::lookup(mInventoryType);
01104
01105 ret->createChild("asset_type", FALSE)->setStringValue(1, &type_str);
01106 ret->createChild("inventory_type", FALSE)->setStringValue(1, &inv_type_str);
01107 S32 tmp_flags = (S32) mFlags;
01108 ret->createChild("flags", FALSE)->setByteValue(4, (U8*)(&tmp_flags), LLXMLNode::ENCODING_HEX);
01109
01110 mSaleInfo.exportFileXML()->setParent(ret);
01111
01112 LLString temp;
01113 temp.assign(mName);
01114 ret->createChild("name", FALSE)->setStringValue(1, &temp);
01115 temp.assign(mDescription);
01116 ret->createChild("description", FALSE)->setStringValue(1, &temp);
01117 ret->createChild("creation_date", FALSE)->setIntValue(1, &mCreationDate);
01118
01119 return ret;
01120 }
01121
01122 BOOL LLInventoryItem::importXML(LLXMLNode* node)
01123 {
01124 BOOL success = FALSE;
01125 if (node)
01126 {
01127 success = TRUE;
01128 LLXMLNodePtr sub_node;
01129 if (node->getChild("uuid", sub_node))
01130 success = (1 == sub_node->getUUIDValue(1, &mUUID));
01131 if (node->getChild("parent_uuid", sub_node))
01132 success = success && (1 == sub_node->getUUIDValue(1, &mParentUUID));
01133 if (node->getChild("permissions", sub_node))
01134 success = success && mPermissions.importXML(sub_node);
01135 if (node->getChild("asset_id", sub_node))
01136 success = success && (1 == sub_node->getUUIDValue(1, &mAssetUUID));
01137 if (node->getChild("shadow_id", sub_node))
01138 {
01139 success = success && (1 == sub_node->getUUIDValue(1, &mAssetUUID));
01140 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
01141 cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
01142 }
01143 if (node->getChild("asset_type", sub_node))
01144 mType = LLAssetType::lookup(sub_node->getValue().c_str());
01145 if (node->getChild("inventory_type", sub_node))
01146 mInventoryType = LLInventoryType::lookup(sub_node->getValue().c_str());
01147 if (node->getChild("flags", sub_node))
01148 {
01149 S32 tmp_flags = 0;
01150 success = success && (1 == sub_node->getIntValue(1, &tmp_flags));
01151 mFlags = (U32) tmp_flags;
01152 }
01153 if (node->getChild("sale_info", sub_node))
01154 success = success && mSaleInfo.importXML(sub_node);
01155 if (node->getChild("name", sub_node))
01156 mName = sub_node->getValue();
01157 if (node->getChild("description", sub_node))
01158 mDescription = sub_node->getValue();
01159 if (node->getChild("creation_date", sub_node))
01160 success = success && (1 == sub_node->getIntValue(1, &mCreationDate));
01161 if (!success)
01162 {
01163 lldebugs << "LLInventory::importXML() failed for node named '"
01164 << node->getName() << "'" << llendl;
01165 }
01166 }
01167 return success;
01168 }
01169
01170 S32 LLInventoryItem::packBinaryBucket(U8* bin_bucket, LLPermissions* perm_override) const
01171 {
01172
01173 LLPermissions perm;
01174 if (perm_override)
01175 {
01176
01177 perm = *perm_override;
01178 }
01179 else
01180 {
01181
01182 perm = getPermissions();
01183 }
01184
01185
01186 char* buffer = (char*) bin_bucket;
01187 char creator_id_str[UUID_STR_LENGTH];
01188
01189 perm.getCreator().toString(creator_id_str);
01190 char owner_id_str[UUID_STR_LENGTH];
01191 perm.getOwner().toString(owner_id_str);
01192 char last_owner_id_str[UUID_STR_LENGTH];
01193 perm.getLastOwner().toString(last_owner_id_str);
01194 char group_id_str[UUID_STR_LENGTH];
01195 perm.getGroup().toString(group_id_str);
01196 char asset_id_str[UUID_STR_LENGTH];
01197 getAssetUUID().toString(asset_id_str);
01198 S32 size = sprintf(buffer,
01199 "%d|%d|%s|%s|%s|%s|%s|%x|%x|%x|%x|%x|%s|%s|%d|%d|%x",
01200 getType(),
01201 getInventoryType(),
01202 getName().c_str(),
01203 creator_id_str,
01204 owner_id_str,
01205 last_owner_id_str,
01206 group_id_str,
01207 perm.getMaskBase(),
01208 perm.getMaskOwner(),
01209 perm.getMaskGroup(),
01210 perm.getMaskEveryone(),
01211 perm.getMaskNextOwner(),
01212 asset_id_str,
01213 getDescription().c_str(),
01214 getSaleInfo().getSaleType(),
01215 getSaleInfo().getSalePrice(),
01216 getFlags()) + 1;
01217
01218 return size;
01219 }
01220
01221 void LLInventoryItem::unpackBinaryBucket(U8* bin_bucket, S32 bin_bucket_size)
01222 {
01223
01224 if (bin_bucket_size <= 1) return;
01225
01226
01227 char* item_buffer = new char[bin_bucket_size+1];
01228 if ((item_buffer != NULL) && (bin_bucket != NULL))
01229 {
01230 memcpy(item_buffer, bin_bucket, bin_bucket_size);
01231 }
01232 else
01233 {
01234 llerrs << "unpackBinaryBucket failed. item_buffer or bin_bucket is Null." << llendl;
01235 delete[] item_buffer;
01236 return;
01237 }
01238 item_buffer[bin_bucket_size] = '\0';
01239 std::string str(item_buffer);
01240
01241 lldebugs << "item buffer: " << item_buffer << llendl;
01242 delete[] item_buffer;
01243
01244
01245 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
01246 boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
01247 tokenizer tokens(str, sep);
01248 tokenizer::iterator iter = tokens.begin();
01249
01250
01251 LLUUID item_id;
01252 item_id.generate();
01253 setUUID(item_id);
01254
01255 LLAssetType::EType type;
01256 type = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
01257 setType( type );
01258
01259 LLInventoryType::EType inv_type;
01260 inv_type = (LLInventoryType::EType)(atoi((*(iter++)).c_str()));
01261 setInventoryType( inv_type );
01262
01263 LLString name((*(iter++)).c_str());
01264 rename( name );
01265
01266 LLUUID creator_id((*(iter++)).c_str());
01267 LLUUID owner_id((*(iter++)).c_str());
01268 LLUUID last_owner_id((*(iter++)).c_str());
01269 LLUUID group_id((*(iter++)).c_str());
01270 PermissionMask mask_base = strtoul((*(iter++)).c_str(), NULL, 16);
01271 PermissionMask mask_owner = strtoul((*(iter++)).c_str(), NULL, 16);
01272 PermissionMask mask_group = strtoul((*(iter++)).c_str(), NULL, 16);
01273 PermissionMask mask_every = strtoul((*(iter++)).c_str(), NULL, 16);
01274 PermissionMask mask_next = strtoul((*(iter++)).c_str(), NULL, 16);
01275 LLPermissions perm;
01276 perm.init(creator_id, owner_id, last_owner_id, group_id);
01277 perm.initMasks(mask_base, mask_owner, mask_group, mask_every, mask_next);
01278 setPermissions(perm);
01279
01280
01281 LLUUID asset_id((*(iter++)).c_str());
01282 setAssetUUID(asset_id);
01283
01284 LLString desc((*(iter++)).c_str());
01285 setDescription(desc);
01286
01287 LLSaleInfo::EForSale sale_type;
01288 sale_type = (LLSaleInfo::EForSale)(atoi((*(iter++)).c_str()));
01289 S32 price = atoi((*(iter++)).c_str());
01290 LLSaleInfo sale_info(sale_type, price);
01291 setSaleInfo(sale_info);
01292
01293 U32 flags = strtoul((*(iter++)).c_str(), NULL, 16);
01294 setFlags(flags);
01295
01296 time_t now = time(NULL);
01297 setCreationDate(now);
01298 }
01299
01300
01301 BOOL item_dictionary_sort( LLInventoryItem* a, LLInventoryItem* b )
01302 {
01303 return (LLString::compareDict( a->getName().c_str(), b->getName().c_str() ) < 0);
01304 }
01305
01306
01307 BOOL item_date_sort( LLInventoryItem* a, LLInventoryItem* b )
01308 {
01309 return a->getCreationDate() < b->getCreationDate();
01310 }
01311
01312
01316
01317 LLInventoryCategory::LLInventoryCategory(
01318 const LLUUID& uuid,
01319 const LLUUID& parent_uuid,
01320 LLAssetType::EType preferred_type,
01321 const LLString& name) :
01322 LLInventoryObject(uuid, parent_uuid, LLAssetType::AT_CATEGORY, name),
01323 mPreferredType(preferred_type)
01324 {
01325 }
01326
01327 LLInventoryCategory::LLInventoryCategory() :
01328 mPreferredType(LLAssetType::AT_NONE)
01329 {
01330 mType = LLAssetType::AT_CATEGORY;
01331 }
01332
01333 LLInventoryCategory::LLInventoryCategory(const LLInventoryCategory* other) :
01334 LLInventoryObject()
01335 {
01336 copy(other);
01337 }
01338
01339 LLInventoryCategory::~LLInventoryCategory()
01340 {
01341 }
01342
01343
01344 void LLInventoryCategory::copy(const LLInventoryCategory* other)
01345 {
01346 LLInventoryObject::copy(other);
01347 mPreferredType = other->mPreferredType;
01348 }
01349
01350 LLAssetType::EType LLInventoryCategory::getPreferredType() const
01351 {
01352 return mPreferredType;
01353 }
01354
01355 void LLInventoryCategory::setPreferredType(LLAssetType::EType type)
01356 {
01357 mPreferredType = type;
01358 }
01359
01360
01361 void LLInventoryCategory::packMessage(LLMessageSystem* msg) const
01362 {
01363 msg->addUUIDFast(_PREHASH_FolderID, mUUID);
01364 msg->addUUIDFast(_PREHASH_ParentID, mParentUUID);
01365 S8 type = static_cast<S8>(mPreferredType);
01366 msg->addS8Fast(_PREHASH_Type, type);
01367 msg->addStringFast(_PREHASH_Name, mName);
01368 }
01369
01370
01371 void LLInventoryCategory::unpackMessage(LLMessageSystem* msg,
01372 const char* block,
01373 S32 block_num)
01374 {
01375 msg->getUUIDFast(block, _PREHASH_FolderID, mUUID, block_num);
01376 msg->getUUIDFast(block, _PREHASH_ParentID, mParentUUID, block_num);
01377 S8 type;
01378 msg->getS8Fast(block, _PREHASH_Type, type, block_num);
01379 mPreferredType = static_cast<LLAssetType::EType>(type);
01380 char name[DB_INV_ITEM_NAME_BUF_SIZE];
01381 msg->getStringFast(block, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name, block_num);
01382 mName.assign(name);
01383 LLString::replaceNonstandardASCII(mName, ' ');
01384 }
01385
01386
01387 BOOL LLInventoryCategory::importFile(FILE* fp)
01388 {
01389
01390
01391 char buffer[MAX_STRING];
01392 char keyword[MAX_STRING];
01393 char valuestr[MAX_STRING];
01394
01395 keyword[0] = '\0';
01396 valuestr[0] = '\0';
01397 while(!feof(fp))
01398 {
01399 if (fgets(buffer, MAX_STRING, fp) == NULL)
01400 {
01401 buffer[0] = '\0';
01402 }
01403
01404 sscanf(
01405 buffer,
01406 " %254s %254s",
01407 keyword, valuestr);
01408 if(0 == strcmp("{",keyword))
01409 {
01410 continue;
01411 }
01412 if(0 == strcmp("}", keyword))
01413 {
01414 break;
01415 }
01416 else if(0 == strcmp("cat_id", keyword))
01417 {
01418 mUUID.set(valuestr);
01419 }
01420 else if(0 == strcmp("parent_id", keyword))
01421 {
01422 mParentUUID.set(valuestr);
01423 }
01424 else if(0 == strcmp("type", keyword))
01425 {
01426 mType = LLAssetType::lookup(valuestr);
01427 }
01428 else if(0 == strcmp("pref_type", keyword))
01429 {
01430 mPreferredType = LLAssetType::lookup(valuestr);
01431 }
01432 else if(0 == strcmp("name", keyword))
01433 {
01434
01435
01436 sscanf(
01437 buffer,
01438 " %254s %254[^|]",
01439 keyword, valuestr);
01440 mName.assign(valuestr);
01441 LLString::replaceNonstandardASCII(mName, ' ');
01442 LLString::replaceChar(mName, '|', ' ');
01443 }
01444 else
01445 {
01446 llwarns << "unknown keyword '" << keyword
01447 << "' in inventory import category " << mUUID << llendl;
01448 }
01449 }
01450 return TRUE;
01451 }
01452
01453 BOOL LLInventoryCategory::exportFile(FILE* fp, BOOL) const
01454 {
01455 char uuid_str[UUID_STR_LENGTH];
01456 fprintf(fp, "\tinv_category\t0\n\t{\n");
01457 mUUID.toString(uuid_str);
01458 fprintf(fp, "\t\tcat_id\t%s\n", uuid_str);
01459 mParentUUID.toString(uuid_str);
01460 fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
01461 fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
01462 fprintf(fp, "\t\tpref_type\t%s\n", LLAssetType::lookup(mPreferredType));
01463 fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
01464 fprintf(fp,"\t}\n");
01465 return TRUE;
01466 }
01467
01468
01469
01470 BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
01471 {
01472
01473
01474 char buffer[MAX_STRING];
01475 char keyword[MAX_STRING];
01476 char valuestr[MAX_STRING];
01477
01478 keyword[0] = '\0';
01479 valuestr[0] = '\0';
01480 while(input_stream.good())
01481 {
01482 input_stream.getline(buffer, MAX_STRING);
01483 sscanf(
01484 buffer,
01485 " %254s %254s",
01486 keyword, valuestr);
01487 if(0 == strcmp("{",keyword))
01488 {
01489 continue;
01490 }
01491 if(0 == strcmp("}", keyword))
01492 {
01493 break;
01494 }
01495 else if(0 == strcmp("cat_id", keyword))
01496 {
01497 mUUID.set(valuestr);
01498 }
01499 else if(0 == strcmp("parent_id", keyword))
01500 {
01501 mParentUUID.set(valuestr);
01502 }
01503 else if(0 == strcmp("type", keyword))
01504 {
01505 mType = LLAssetType::lookup(valuestr);
01506 }
01507 else if(0 == strcmp("pref_type", keyword))
01508 {
01509 mPreferredType = LLAssetType::lookup(valuestr);
01510 }
01511 else if(0 == strcmp("name", keyword))
01512 {
01513
01514
01515 sscanf(
01516 buffer,
01517 " %254s %254[^|]",
01518 keyword, valuestr);
01519 mName.assign(valuestr);
01520 LLString::replaceNonstandardASCII(mName, ' ');
01521 LLString::replaceChar(mName, '|', ' ');
01522 }
01523 else
01524 {
01525 llwarns << "unknown keyword '" << keyword
01526 << "' in inventory import category " << mUUID << llendl;
01527 }
01528 }
01529 return TRUE;
01530 }
01531
01532 BOOL LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, BOOL) const
01533 {
01534 char uuid_str[UUID_STR_LENGTH];
01535 output_stream << "\tinv_category\t0\n\t{\n";
01536 mUUID.toString(uuid_str);
01537 output_stream << "\t\tcat_id\t" << uuid_str << "\n";
01538 mParentUUID.toString(uuid_str);
01539 output_stream << "\t\tparent_id\t" << uuid_str << "\n";
01540 output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
01541 output_stream << "\t\tpref_type\t" << LLAssetType::lookup(mPreferredType) << "\n";
01542 output_stream << "\t\tname\t" << mName.c_str() << "|\n";
01543 output_stream << "\t}\n";
01544 return TRUE;
01545 }
01546
01550
01551 LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)
01552 {
01553 LLSD rv;
01554 if(item.isNull()) return rv;
01555 if (item->getType() == LLAssetType::AT_NONE)
01556 {
01557 llwarns << "ll_create_sd_from_inventory_item() for item with AT_NONE"
01558 << llendl;
01559 return rv;
01560 }
01561 rv[INV_ITEM_ID_LABEL] = item->getUUID();
01562 rv[INV_PARENT_ID_LABEL] = item->getParentUUID();
01563 rv[INV_NAME_LABEL] = item->getName();
01564 rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(item->getType());
01565 rv[INV_ASSET_ID_LABEL] = item->getAssetUUID();
01566 rv[INV_DESC_LABEL] = item->getDescription();
01567 rv[INV_SALE_INFO_LABEL] = ll_create_sd_from_sale_info(item->getSaleInfo());
01568 rv[INV_PERMISSIONS_LABEL] =
01569 ll_create_sd_from_permissions(item->getPermissions());
01570 rv[INV_INVENTORY_TYPE_LABEL] =
01571 LLInventoryType::lookup(item->getInventoryType());
01572 rv[INV_FLAGS_LABEL] = (S32)item->getFlags();
01573 rv[INV_CREATION_DATE_LABEL] = item->getCreationDate();
01574 return rv;
01575 }
01576
01577 LLPointer<LLInventoryItem> ll_create_item_from_sd(const LLSD& sd_item)
01578 {
01579 LLPointer<LLInventoryItem> rv = new LLInventoryItem;
01580 rv->setUUID(sd_item[INV_ITEM_ID_LABEL].asUUID());
01581 rv->setParent(sd_item[INV_PARENT_ID_LABEL].asUUID());
01582 rv->rename(sd_item[INV_NAME_LABEL].asString());
01583 rv->setType(
01584 LLAssetType::lookup(sd_item[INV_ASSET_TYPE_LABEL].asString().c_str()));
01585 if (sd_item.has("shadow_id"))
01586 {
01587 LLUUID asset_id = sd_item["shadow_id"];
01588 LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
01589 cipher.decrypt(asset_id.mData, UUID_BYTES);
01590 rv->setAssetUUID(asset_id);
01591 }
01592 if (sd_item.has(INV_ASSET_ID_LABEL))
01593 {
01594 rv->setAssetUUID(sd_item[INV_ASSET_ID_LABEL].asUUID());
01595 }
01596 rv->setDescription(sd_item[INV_DESC_LABEL].asString());
01597 rv->setSaleInfo(ll_sale_info_from_sd(sd_item[INV_SALE_INFO_LABEL]));
01598 rv->setPermissions(ll_permissions_from_sd(sd_item[INV_PERMISSIONS_LABEL]));
01599 rv->setInventoryType(
01600 LLInventoryType::lookup(
01601 sd_item[INV_INVENTORY_TYPE_LABEL].asString().c_str()));
01602 rv->setFlags((U32)(sd_item[INV_FLAGS_LABEL].asInteger()));
01603 rv->setCreationDate(sd_item[INV_CREATION_DATE_LABEL].asInteger());
01604 return rv;
01605 }
01606
01607 LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat)
01608 {
01609 LLSD rv;
01610 if(cat.isNull()) return rv;
01611 if (cat->getType() == LLAssetType::AT_NONE)
01612 {
01613 llwarns << "ll_create_sd_from_inventory_category() for cat with AT_NONE"
01614 << llendl;
01615 return rv;
01616 }
01617 rv[INV_FOLDER_ID_LABEL] = cat->getUUID();
01618 rv[INV_PARENT_ID_LABEL] = cat->getParentUUID();
01619 rv[INV_NAME_LABEL] = cat->getName();
01620 rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(cat->getType());
01621 if(LLAssetType::AT_NONE != cat->getPreferredType())
01622 {
01623 rv[INV_PREFERRED_TYPE_LABEL] =
01624 LLAssetType::lookup(cat->getPreferredType());
01625 }
01626 return rv;
01627 }
01628
01629 LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat)
01630 {
01631 LLPointer<LLInventoryCategory> rv = new LLInventoryCategory;
01632 rv->setUUID(sd_cat[INV_FOLDER_ID_LABEL].asUUID());
01633 rv->setParent(sd_cat[INV_PARENT_ID_LABEL].asUUID());
01634 rv->rename(sd_cat[INV_NAME_LABEL].asString());
01635 rv->setType(
01636 LLAssetType::lookup(sd_cat[INV_ASSET_TYPE_LABEL].asString().c_str()));
01637 rv->setPreferredType(
01638 LLAssetType::lookup(
01639 sd_cat[INV_PREFERRED_TYPE_LABEL].asString().c_str()));
01640 return rv;
01641 }