diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llvfs/llvfs.cpp | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-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.cpp | 177 |
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 | ||
74 | public: | 73 | public: |
@@ -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); |