aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs/llvfs.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llvfs/llvfs.cpp
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to '')
-rw-r--r--linden/indra/llvfs/llvfs.cpp177
1 files changed, 118 insertions, 59 deletions
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp
index bb211df..88476eb 100644
--- a/linden/indra/llvfs/llvfs.cpp
+++ b/linden/indra/llvfs/llvfs.cpp
@@ -63,12 +63,11 @@ public:
63 mLength = size; 63 mLength = size;
64 } 64 }
65 65
66 static BOOL insertFirstLL(LLVFSBlock *first, LLVFSBlock *second) 66 static bool locationSortPredicate(
67 const LLVFSBlock* lhs,
68 const LLVFSBlock* rhs)
67 { 69 {
68 return first->mLocation != second->mLocation 70 return lhs->mLocation < rhs->mLocation;
69 ? first->mLocation < second->mLocation
70 : first->mLength < second->mLength;
71
72 } 71 }
73 72
74public: 73public:
@@ -129,7 +128,7 @@ public:
129 } 128 }
130 129
131 #ifdef LL_LITTLE_ENDIAN 130 #ifdef LL_LITTLE_ENDIAN
132 inline void swizzleCopy(void *dst, void *src, int size) { memcpy(dst, src, size); } 131 inline void swizzleCopy(void *dst, void *src, int size) { memcpy(dst, src, size); /* Flawfinder: ignore */}
133 132
134 #else 133 #else
135 134
@@ -156,7 +155,7 @@ public:
156 else 155 else
157 { 156 {
158 // Perhaps this should assert... 157 // Perhaps this should assert...
159 memcpy(dst, src, size); 158 memcpy(dst, src, size); /* Flawfinder: ignore */
160 } 159 }
161 } 160 }
162 161
@@ -170,7 +169,7 @@ public:
170 buffer +=4; 169 buffer +=4;
171 swizzleCopy(buffer, &mAccessTime, 4); 170 swizzleCopy(buffer, &mAccessTime, 4);
172 buffer +=4; 171 buffer +=4;
173 memcpy(buffer, &mFileID.mData, 16); 172 memcpy(buffer, &mFileID.mData, 16); /* Flawfinder: ignore */
174 buffer += 16; 173 buffer += 16;
175 S16 temp_type = mFileType; 174 S16 temp_type = mFileType;
176 swizzleCopy(buffer, &temp_type, 2); 175 swizzleCopy(buffer, &temp_type, 2);
@@ -239,10 +238,15 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
239 } 238 }
240 mValid = VFSVALID_OK; 239 mValid = VFSVALID_OK;
241 mReadOnly = read_only; 240 mReadOnly = read_only;
242 mIndexFilename = new char[strlen(index_filename) + 1]; 241 mIndexFilename = new char[strlen(index_filename) + 1]; /* Flawfinder: ignore */
243 mDataFilename = new char[strlen(data_filename) + 1]; 242 mDataFilename = new char[strlen(data_filename) + 1]; /* Flawfinder: ignore */
244 strcpy(mIndexFilename, index_filename); 243 if (mIndexFilename == NULL || mDataFilename == NULL)
245 strcpy(mDataFilename, data_filename); 244 {
245 llerrs << "Memory Allocation Failure" << llendl;
246 return;
247 }
248 strcpy(mIndexFilename, index_filename); /* Flawfinder: ignore */
249 strcpy(mDataFilename, data_filename); /* Flawfinder: ignore */
246 250
247 const char *file_mode = mReadOnly ? "rb" : "r+b"; 251 const char *file_mode = mReadOnly ? "rb" : "r+b";
248 252
@@ -266,13 +270,23 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
266 { 270 {
267 llwarns << "Can't open VFS data file " << mDataFilename << " attempting to use alternate" << llendl; 271 llwarns << "Can't open VFS data file " << mDataFilename << " attempting to use alternate" << llendl;
268 272
269 char *temp_index = new char[strlen(mIndexFilename) + 10]; 273 char *temp_index = new char[strlen(mIndexFilename) + 10]; /* Flawfinder: ignore */
270 char *temp_data = new char[strlen(mDataFilename) + 10]; 274 if (!temp_index)
275 {
276 llerrs << "Out of the memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
277 return;
278 }
279 char *temp_data = new char[strlen(mDataFilename) + 10]; /* Flawfinder: ignore */
280 if (!temp_data)
281 {
282 llerrs << "Out of the memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
283 return;
284 }
271 285
272 for (U32 count = 0; count < 256; count++) 286 for (U32 count = 0; count < 256; count++)
273 { 287 {
274 sprintf(temp_index, "%s.%u", mIndexFilename, count); 288 sprintf(temp_index, "%s.%u", mIndexFilename, count); /* Flawfinder: ignore */
275 sprintf(temp_data, "%s.%u", mDataFilename, count); 289 sprintf(temp_data, "%s.%u", mDataFilename, count); /* Flawfinder: ignore */
276 290
277 // try just opening, then creating, each alternate 291 // try just opening, then creating, each alternate
278 if ((mDataFP = openAndLock(temp_data, "r+b", FALSE))) 292 if ((mDataFP = openAndLock(temp_data, "r+b", FALSE)))
@@ -313,8 +327,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
313 if (!mReadOnly && mRemoveAfterCrash) 327 if (!mReadOnly && mRemoveAfterCrash)
314 { 328 {
315 llstat marker_info; 329 llstat marker_info;
316 char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; 330 char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; /* Flawfinder: ignore */
317 sprintf(marker, "%s.open", mDataFilename); 331 if (!marker )
332 {
333 llerrs << "Out of memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
334 return;
335 }
336 sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */
318 if (!LLFile::stat(marker, &marker_info)) 337 if (!LLFile::stat(marker, &marker_info))
319 { 338 {
320 // marker exists, kill the lock and the VFS files 339 // marker exists, kill the lock and the VFS files
@@ -361,9 +380,8 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
361 380
362 U8 *tmp_ptr = buffer; 381 U8 *tmp_ptr = buffer;
363 382
364 LLLinkedList<LLVFSBlock> files_by_loc; 383 std::vector<LLVFSFileBlock*> files_by_loc;
365 files_by_loc.setInsertBefore(LLVFSBlock::insertFirstLL); 384
366
367 while (tmp_ptr < buffer + fbuf.st_size) 385 while (tmp_ptr < buffer + fbuf.st_size)
368 { 386 {
369 LLVFSFileBlock *block = new LLVFSFileBlock(); 387 LLVFSFileBlock *block = new LLVFSFileBlock();
@@ -383,7 +401,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
383 block->mFileType < LLAssetType::AT_COUNT) 401 block->mFileType < LLAssetType::AT_COUNT)
384 { 402 {
385 mFileBlocks.insert(fileblock_map::value_type(*block, block)); 403 mFileBlocks.insert(fileblock_map::value_type(*block, block));
386 files_by_loc.addDataSorted(block); 404 files_by_loc.push_back(block);
387 } 405 }
388 else 406 else
389 if (block->mLength && block->mSize > 0) 407 if (block->mLength && block->mSize > 0)
@@ -419,22 +437,40 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
419 tmp_ptr += block->SERIAL_SIZE; 437 tmp_ptr += block->SERIAL_SIZE;
420 } 438 }
421 delete[] buffer; 439 delete[] buffer;
422 440
423 // discover all the free blocks 441 std::sort(
424 LLVFSFileBlock *last_file_block = (LLVFSFileBlock*)files_by_loc.getFirstData(); 442 files_by_loc.begin(),
425 443 files_by_loc.end(),
426 if (last_file_block) 444 LLVFSFileBlock::locationSortPredicate);
445
446 // There are 3 cases that have to be considered.
447 // 1. No blocks
448 // 2. One block.
449 // 3. Two or more blocks.
450 if (!files_by_loc.empty())
427 { 451 {
428 // check for empty space at the beginning 452 // cur walks through the list.
453 std::vector<LLVFSFileBlock*>::iterator cur = files_by_loc.begin();
454 std::vector<LLVFSFileBlock*>::iterator end = files_by_loc.end();
455 LLVFSFileBlock* last_file_block = *cur;
456
457 // Check to see if there is an empty space before the first file.
429 if (last_file_block->mLocation > 0) 458 if (last_file_block->mLocation > 0)
430 { 459 {
431 LLVFSBlock *block = new LLVFSBlock(0, last_file_block->mLocation); 460 // If so, create a free block.
432 addFreeBlock(block); 461 addFreeBlock(new LLVFSBlock(0, last_file_block->mLocation));
433 } 462 }
434 463
435 LLVFSFileBlock *cur_file_block; 464 // Walk through the 2nd+ block. If there is a free space
436 while ((cur_file_block = (LLVFSFileBlock*)files_by_loc.getNextData())) 465 // between cur_file_block and last_file_block, add it to
466 // the free space collection. This block will not need to
467 // run in the case there is only one entry in the VFS.
468 ++cur;
469 while( cur != end )
437 { 470 {
471 LLVFSFileBlock* cur_file_block = *cur;
472
473 // Dupe check on the block
438 if (cur_file_block->mLocation == last_file_block->mLocation 474 if (cur_file_block->mLocation == last_file_block->mLocation
439 && cur_file_block->mLength == last_file_block->mLength) 475 && cur_file_block->mLength == last_file_block->mLength)
440 { 476 {
@@ -451,21 +487,29 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
451 if (cur_file_block->mLength > 0) 487 if (cur_file_block->mLength > 0)
452 { 488 {
453 // convert to hole 489 // convert to hole
454 LLVFSBlock* block = new LLVFSBlock(cur_file_block->mLocation, 490 addFreeBlock(
455 cur_file_block->mLength); 491 new LLVFSBlock(
456 addFreeBlock(block); 492 cur_file_block->mLocation,
493 cur_file_block->mLength));
457 } 494 }
458 lockData(); // needed for sync() 495 lockData(); // needed for sync()
459 sync(cur_file_block, TRUE); // remove first on disk 496 sync(cur_file_block, TRUE); // remove first on disk
460 sync(last_file_block, TRUE); // remove last on disk 497 sync(last_file_block, TRUE); // remove last on disk
461 unlockData(); // needed for sync() 498 unlockData(); // needed for sync()
462 last_file_block = cur_file_block; 499 last_file_block = cur_file_block;
500 ++cur;
463 continue; 501 continue;
464 } 502 }
465 503
466 U32 loc = last_file_block->mLocation + last_file_block->mLength; 504 // Figure out where the last block ended.
505 U32 loc = last_file_block->mLocation+last_file_block->mLength;
506
507 // Figure out how much space there is between where
508 // the last block ended and this block begins.
467 S32 length = cur_file_block->mLocation - loc; 509 S32 length = cur_file_block->mLocation - loc;
468 510
511 // Check for more errors... Seeing if the current
512 // entry and the last entry make sense together.
469 if (length < 0 || loc < 0 || loc > data_size) 513 if (length < 0 || loc < 0 || loc > data_size)
470 { 514 {
471 // Invalid VFS 515 // Invalid VFS
@@ -487,27 +531,25 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
487 return; 531 return;
488 } 532 }
489 533
534 // we don't want to add empty blocks to the list...
490 if (length > 0) 535 if (length > 0)
491 { 536 {
492 LLVFSBlock *block = new LLVFSBlock(loc, length); 537 addFreeBlock(new LLVFSBlock(loc, length));
493 addFreeBlock(block);
494 } 538 }
495
496 last_file_block = cur_file_block; 539 last_file_block = cur_file_block;
540 ++cur;
497 } 541 }
498 542
499 // also note any empty space at the end 543 // also note any empty space at the end
500 U32 loc = last_file_block->mLocation + last_file_block->mLength; 544 U32 loc = last_file_block->mLocation + last_file_block->mLength;
501 if (loc < data_size) 545 if (loc < data_size)
502 { 546 {
503 LLVFSBlock *block = new LLVFSBlock(loc, data_size - loc); 547 addFreeBlock(new LLVFSBlock(loc, data_size - loc));
504 addFreeBlock(block);
505 } 548 }
506 } 549 }
507 else 550 else // There where no blocks in the file.
508 { 551 {
509 LLVFSBlock *first_block = new LLVFSBlock(0, data_size); 552 addFreeBlock(new LLVFSBlock(0, data_size));
510 addFreeBlock(first_block);
511 } 553 }
512 } 554 }
513 else 555 else
@@ -542,8 +584,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
542 if (!mReadOnly && mRemoveAfterCrash) 584 if (!mReadOnly && mRemoveAfterCrash)
543 { 585 {
544 char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; 586 char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1];
545 sprintf(marker, "%s.open", mDataFilename); 587 if (!marker)
546 FILE* marker_fp = LLFile::fopen(marker, "w"); 588 {
589 llerrs << "Out of memory in LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)" << llendl;
590 return;
591 }
592 sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */
593 FILE* marker_fp = LLFile::fopen(marker, "w"); /* Flawfinder: ignore */
547 if (marker_fp) 594 if (marker_fp)
548 { 595 {
549 fclose(marker_fp); 596 fclose(marker_fp);
@@ -586,7 +633,12 @@ LLVFS::~LLVFS()
586 if (!mReadOnly && mRemoveAfterCrash) 633 if (!mReadOnly && mRemoveAfterCrash)
587 { 634 {
588 char* marker_file = new char[strlen(mDataFilename) + strlen(".open") + 1]; 635 char* marker_file = new char[strlen(mDataFilename) + strlen(".open") + 1];
589 sprintf(marker_file, "%s.open", mDataFilename); 636 if (marker_file == NULL)
637 {
638 llerrs << "Memory Allocation Failure" << llendl;
639 return;
640 }
641 sprintf(marker_file, "%s.open", mDataFilename); /* Flawfinder: ignore */
590 LLFile::remove(marker_file); 642 LLFile::remove(marker_file);
591 delete [] marker_file; 643 delete [] marker_file;
592 marker_file = NULL; 644 marker_file = NULL;
@@ -738,12 +790,17 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type
738 } 790 }
739 791
740 // round all sizes upward to KB increments 792 // round all sizes upward to KB increments
741 if (max_size & FILE_BLOCK_MASK) 793 // SJB: Need to not round for the new texture-pipeline code so we know the correct
794 // max file size. Need to investigate the potential problems with this...
795 if (file_type != LLAssetType::AT_TEXTURE)
742 { 796 {
743 max_size += FILE_BLOCK_MASK; 797 if (max_size & FILE_BLOCK_MASK)
744 max_size &= ~FILE_BLOCK_MASK; 798 {
745 } 799 max_size += FILE_BLOCK_MASK;
746 800 max_size &= ~FILE_BLOCK_MASK;
801 }
802 }
803
747 if (block && block->mLength > 0) 804 if (block && block->mLength > 0)
748 { 805 {
749 block->mAccessTime = (U32)time(NULL); 806 block->mAccessTime = (U32)time(NULL);
@@ -1230,6 +1287,7 @@ void LLVFS::eraseBlockLength(LLVFSBlock *block)
1230 S32 length = block->mLength; 1287 S32 length = block->mLength;
1231 blocks_length_map_t::iterator iter = mFreeBlocksByLength.lower_bound(length); 1288 blocks_length_map_t::iterator iter = mFreeBlocksByLength.lower_bound(length);
1232 blocks_length_map_t::iterator end = mFreeBlocksByLength.end(); 1289 blocks_length_map_t::iterator end = mFreeBlocksByLength.end();
1290 bool found_block = false;
1233 while(iter != end) 1291 while(iter != end)
1234 { 1292 {
1235 LLVFSBlock *tblock = iter->second; 1293 LLVFSBlock *tblock = iter->second;
@@ -1237,13 +1295,14 @@ void LLVFS::eraseBlockLength(LLVFSBlock *block)
1237 if (tblock == block) 1295 if (tblock == block)
1238 { 1296 {
1239 mFreeBlocksByLength.erase(iter); 1297 mFreeBlocksByLength.erase(iter);
1298 found_block = true;
1240 break; 1299 break;
1241 } 1300 }
1242 ++iter; 1301 ++iter;
1243 } 1302 }
1244 if (iter == end) 1303 if(!found_block)
1245 { 1304 {
1246 llerrs << "eraseBlock could not find block" << llendl; 1305 llwarns << "eraseBlock could not find block" << llendl;
1247 } 1306 }
1248} 1307}
1249 1308
@@ -1963,7 +2022,7 @@ LLString get_extension(LLAssetType::EType type)
1963 switch(type) 2022 switch(type)
1964 { 2023 {
1965 case LLAssetType::AT_TEXTURE: 2024 case LLAssetType::AT_TEXTURE:
1966 extension = ".jp2"; // ".j2c"; // IrfanView recognizes .jp2 -sjb 2025 extension = ".j2c";
1967 break; 2026 break;
1968 case LLAssetType::AT_SOUND: 2027 case LLAssetType::AT_SOUND:
1969 extension = ".ogg"; 2028 extension = ".ogg";
@@ -2033,7 +2092,7 @@ void LLVFS::dumpFiles()
2033 lockData(); 2092 lockData();
2034 2093
2035 LLString extension = get_extension(type); 2094 LLString extension = get_extension(type);
2036 LLString filename = id.getString() + extension; 2095 LLString filename = id.asString() + extension;
2037 llinfos << " Writing " << filename << llendl; 2096 llinfos << " Writing " << filename << llendl;
2038 apr_file_t* file = ll_apr_file_open(filename, LL_APR_WB); 2097 apr_file_t* file = ll_apr_file_open(filename, LL_APR_WB);
2039 ll_apr_file_write(file, buffer, size); 2098 ll_apr_file_write(file, buffer, size);
@@ -2064,7 +2123,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2064 // first test the lock in a non-destructive way 2123 // first test the lock in a non-destructive way
2065 if (strstr(mode, "w")) 2124 if (strstr(mode, "w"))
2066 { 2125 {
2067 fp = LLFile::fopen(filename, "rb"); 2126 fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
2068 if (fp) 2127 if (fp)
2069 { 2128 {
2070 fd = fileno(fp); 2129 fd = fileno(fp);
@@ -2079,7 +2138,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2079 } 2138 }
2080 2139
2081 // now actually open the file for use 2140 // now actually open the file for use
2082 fp = LLFile::fopen(filename, mode); 2141 fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */
2083 if (fp) 2142 if (fp)
2084 { 2143 {
2085 fd = fileno(fp); 2144 fd = fileno(fp);