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