diff options
Diffstat (limited to 'indra/llvfs/llvfs.cpp')
-rw-r--r-- | indra/llvfs/llvfs.cpp | 389 |
1 files changed, 184 insertions, 205 deletions
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index 417e48c07c..c1fe21c57d 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -2,30 +2,25 @@ * @file llvfs.cpp * @brief Implementation of virtual file system * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,7 +40,9 @@ #endif #include "llvfs.h" + #include "llstl.h" +#include "lltimer.h" const S32 FILE_BLOCK_MASK = 0x000003FF; // 1024-byte blocks const S32 VFS_CLEANUP_SIZE = 5242880; // how much space we free up in a single stroke @@ -231,9 +228,11 @@ struct LLVFSFileBlock_less const S32 LLVFSFileBlock::SERIAL_SIZE = 34; - -LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) -: mRemoveAfterCrash(remove_after_crash) + +LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) +: mRemoveAfterCrash(remove_after_crash), + mDataFP(NULL), + mIndexFP(NULL) { mDataMutex = new LLMutex(0); @@ -244,29 +243,26 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r } mValid = VFSVALID_OK; mReadOnly = read_only; - mIndexFilename = new char[strlen(index_filename) + 1]; /* Flawfinder: ignore */ - mDataFilename = new char[strlen(data_filename) + 1]; /* Flawfinder: ignore */ - if (mIndexFilename == NULL || mDataFilename == NULL) - { - llerrs << "Memory Allocation Failure" << llendl; - return; - } - strcpy(mIndexFilename, index_filename); /* Flawfinder: ignore */ - strcpy(mDataFilename, data_filename); /* Flawfinder: ignore */ + mIndexFilename = index_filename; + mDataFilename = data_filename; const char *file_mode = mReadOnly ? "rb" : "r+b"; - if (! (mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly))) + LL_INFOS("VFS") << "Attempting to open VFS index file " << mIndexFilename << LL_ENDL; + LL_INFOS("VFS") << "Attempting to open VFS data file " << mDataFilename << LL_ENDL; + + mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly); + if (!mDataFP) { - if (mReadOnly) { - llwarns << "Can't find " << mDataFilename << " to open read-only VFS" << llendl; + LL_WARNS("VFS") << "Can't find " << mDataFilename << " to open read-only VFS" << LL_ENDL; mValid = VFSVALID_BAD_CANNOT_OPEN_READONLY; return; } - - if((mDataFP = openAndLock(mDataFilename, "w+b", FALSE))) + + mDataFP = openAndLock(mDataFilename, "w+b", FALSE); + if (mDataFP) { // Since we're creating this data file, assume any index file is bogus // remove the index, since this vfs is now blank @@ -274,56 +270,12 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r } else { - llwarns << "Can't open VFS data file " << mDataFilename << " attempting to use alternate" << llendl; - - char *temp_index = new char[strlen(mIndexFilename) + 10]; /* Flawfinder: ignore */ - if (!temp_index) - { - 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; - return; - } - char *temp_data = new char[strlen(mDataFilename) + 10]; /* Flawfinder: ignore */ - if (!temp_data) - { - 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; - return; - } - - for (U32 count = 0; count < 256; count++) - { - sprintf(temp_index, "%s.%u", mIndexFilename, count); /* Flawfinder: ignore */ - sprintf(temp_data, "%s.%u", mDataFilename, count); /* Flawfinder: ignore */ - - // try just opening, then creating, each alternate - if ((mDataFP = openAndLock(temp_data, "r+b", FALSE))) - { - break; - } - - if ((mDataFP = openAndLock(temp_data, "w+b", FALSE))) - { - // we're creating the datafile, so nuke the indexfile - LLFile::remove(temp_index); - break; - } - } - - if (! mDataFP) - { - llwarns << "Couldn't open vfs data file after trying many alternates" << llendl; - mValid = VFSVALID_BAD_CANNOT_CREATE; - delete[] temp_index; - delete[] temp_data; - return; - } - - delete[] mIndexFilename; - delete[] mDataFilename; - - mIndexFilename = temp_index; - mDataFilename = temp_data; + LL_WARNS("VFS") << "Couldn't open vfs data file " + << mDataFilename << LL_ENDL; + mValid = VFSVALID_BAD_CANNOT_CREATE; + return; } - + if (presize) { presizeDataFile(presize); @@ -335,20 +287,14 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r if (!mReadOnly && mRemoveAfterCrash) { llstat marker_info; - char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; /* Flawfinder: ignore */ - if (!marker ) - { - 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; - return; - } - sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */ + std::string marker = mDataFilename + ".open"; if (!LLFile::stat(marker, &marker_info)) { // marker exists, kill the lock and the VFS files unlockAndClose(mDataFP); mDataFP = NULL; - llwarns << "VFS: File left open on last run, removing old VFS file " << mDataFilename << llendl; + LL_WARNS("VFS") << "VFS: File left open on last run, removing old VFS file " << mDataFilename << LL_ENDL; LLFile::remove(mIndexFilename); LLFile::remove(mDataFilename); LLFile::remove(marker); @@ -356,7 +302,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r mDataFP = openAndLock(mDataFilename, "w+b", FALSE); if (!mDataFP) { - llwarns << "Can't open VFS data file in crash recovery" << llendl; + LL_WARNS("VFS") << "Can't open VFS data file in crash recovery" << LL_ENDL; mValid = VFSVALID_BAD_CANNOT_CREATE; return; } @@ -366,8 +312,6 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r presizeDataFile(presize); } } - delete [] marker; - marker = NULL; } // determine the real file size @@ -380,21 +324,20 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r llstat fbuf; if (! LLFile::stat(mIndexFilename, &fbuf) && fbuf.st_size >= LLVFSFileBlock::SERIAL_SIZE && - (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly)) + (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly)) // Yes, this is an assignment and not '==' ) { - U8 *buffer = new U8[fbuf.st_size]; - size_t nread = fread(buffer, 1, fbuf.st_size, mIndexFP); - - U8 *tmp_ptr = buffer; - + std::vector<U8> buffer(fbuf.st_size); + size_t buf_offset = 0; + size_t nread = fread(&buffer[0], 1, fbuf.st_size, mIndexFP); + std::vector<LLVFSFileBlock*> files_by_loc; - while (tmp_ptr < buffer + nread) + while (buf_offset < nread) { LLVFSFileBlock *block = new LLVFSFileBlock(); - block->deserialize(tmp_ptr, (S32)(tmp_ptr - buffer)); + block->deserialize(&buffer[buf_offset], (S32)buf_offset); // Do sanity check on this block. // Note that this skips zero size blocks, which helps VFS @@ -414,11 +357,10 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r if (block->mLength && block->mSize > 0) { // this is corrupt, not empty - llwarns << "VFS corruption: " << block->mFileID << " (" << block->mFileType << ") at index " << block->mIndexLocation << " DS: " << data_size << llendl; - llwarns << "Length: " << block->mLength << "\tLocation: " << block->mLocation << "\tSize: " << block->mSize << llendl; - llwarns << "File has bad data - VFS removed" << llendl; + LL_WARNS("VFS") << "VFS corruption: " << block->mFileID << " (" << block->mFileType << ") at index " << block->mIndexLocation << " DS: " << data_size << LL_ENDL; + LL_WARNS("VFS") << "Length: " << block->mLength << "\tLocation: " << block->mLocation << "\tSize: " << block->mSize << LL_ENDL; + LL_WARNS("VFS") << "File has bad data - VFS removed" << LL_ENDL; - delete[] buffer; delete block; unlockAndClose( mIndexFP ); @@ -429,21 +371,25 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r mDataFP = NULL; LLFile::remove( mDataFilename ); + LL_WARNS("VFS") << "Deleted corrupt VFS files " + << mDataFilename + << " and " + << mIndexFilename + << LL_ENDL; + mValid = VFSVALID_BAD_CORRUPT; return; } else { // this is a null or bad entry, skip it - S32 index_loc = (S32)(tmp_ptr - buffer); - mIndexHoles.push_back(index_loc); + mIndexHoles.push_back(buf_offset); delete block; } - tmp_ptr += LLVFSFileBlock::SERIAL_SIZE; + buf_offset += LLVFSFileBlock::SERIAL_SIZE; } - delete[] buffer; std::sort( files_by_loc.begin(), @@ -481,13 +427,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r if (cur_file_block->mLocation == last_file_block->mLocation && cur_file_block->mLength == last_file_block->mLength) { - llwarns << "VFS: removing duplicate entry" + LL_WARNS("VFS") << "VFS: removing duplicate entry" << " at " << cur_file_block->mLocation << " length " << cur_file_block->mLength << " size " << cur_file_block->mSize << " ID " << cur_file_block->mFileID << " type " << cur_file_block->mFileType - << llendl; + << LL_ENDL; // Duplicate entries. Nuke them both for safety. mFileBlocks.erase(*cur_file_block); // remove ID/type entry @@ -528,12 +474,19 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r mDataFP = NULL; LLFile::remove( mDataFilename ); - llwarns << "VFS: overlapping entries" + LL_WARNS("VFS") << "VFS: overlapping entries" << " at " << cur_file_block->mLocation << " length " << cur_file_block->mLength << " ID " << cur_file_block->mFileID << " type " << cur_file_block->mFileType - << llendl; + << LL_ENDL; + + LL_WARNS("VFS") << "Deleted corrupt VFS files " + << mDataFilename + << " and " + << mIndexFilename + << LL_ENDL; + mValid = VFSVALID_BAD_CORRUPT; return; } @@ -559,11 +512,11 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r addFreeBlock(new LLVFSBlock(0, data_size)); } } - else + else // Pre-existing index file wasn't opened { if (mReadOnly) { - llwarns << "Can't find " << mIndexFilename << " to open read-only VFS" << llendl; + LL_WARNS("VFS") << "Can't find " << mIndexFilename << " to open read-only VFS" << LL_ENDL; mValid = VFSVALID_BAD_CANNOT_OPEN_READONLY; return; } @@ -572,7 +525,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r mIndexFP = openAndLock(mIndexFilename, "w+b", FALSE); if (!mIndexFP) { - llwarns << "Couldn't open an index file for the VFS, probably a sharing violation!" << llendl; + LL_WARNS("VFS") << "Couldn't open an index file for the VFS, probably a sharing violation!" << LL_ENDL; unlockAndClose( mDataFP ); mDataFP = NULL; @@ -590,24 +543,17 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r // Open marker file to look for bad shutdowns if (!mReadOnly && mRemoveAfterCrash) { - char* marker = new char[strlen(mDataFilename) + strlen(".open") + 1]; - if (!marker) - { - 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; - return; - } - sprintf(marker, "%s.open", mDataFilename); /* Flawfinder: ignore */ - FILE* marker_fp = LLFile::fopen(marker, "w"); /* Flawfinder: ignore */ + std::string marker = mDataFilename + ".open"; + LLFILE* marker_fp = LLFile::fopen(marker, "w"); /* Flawfinder: ignore */ if (marker_fp) { fclose(marker_fp); marker_fp = NULL; } - delete [] marker; - marker = NULL; } - llinfos << "VFS: Using index file " << mIndexFilename << " and data file " << mDataFilename << llendl; + LL_INFOS("VFS") << "Using VFS index file " << mIndexFilename << LL_ENDL; + LL_INFOS("VFS") << "Using VFS data file " << mDataFilename << LL_ENDL; mValid = VFSVALID_OK; } @@ -616,7 +562,7 @@ LLVFS::~LLVFS() { if (mDataMutex->isLocked()) { - llerrs << "LLVFS destroyed with mutex locked" << llendl; + LL_ERRS("VFS") << "LLVFS destroyed with mutex locked" << LL_ENDL; } unlockAndClose(mIndexFP); @@ -639,26 +585,54 @@ LLVFS::~LLVFS() // Remove marker file if (!mReadOnly && mRemoveAfterCrash) { - char* marker_file = new char[strlen(mDataFilename) + strlen(".open") + 1]; - if (marker_file == NULL) - { - llerrs << "Memory Allocation Failure" << llendl; - return; + std::string marker = mDataFilename + ".open"; + LLFile::remove(marker); + } + + delete mDataMutex; +} + + +// Use this function normally to create LLVFS files. +// Will append digits to the end of the filename with multiple re-trys +// static +LLVFS * LLVFS::createLLVFS(const std::string& index_filename, + const std::string& data_filename, + const BOOL read_only, + const U32 presize, + const BOOL remove_after_crash) +{ + LLVFS * new_vfs = new LLVFS(index_filename, data_filename, read_only, presize, remove_after_crash); + + if( !new_vfs->isValid() ) + { // First name failed, retry with new names + std::string retry_vfs_index_name; + std::string retry_vfs_data_name; + S32 count = 0; + while (!new_vfs->isValid() && + count < 256) + { // Append '.<number>' to end of filenames + retry_vfs_index_name = index_filename + llformat(".%u",count); + retry_vfs_data_name = data_filename + llformat(".%u", count); + + delete new_vfs; // Delete bad VFS and try again + new_vfs = new LLVFS(retry_vfs_index_name, retry_vfs_data_name, read_only, presize, remove_after_crash); + + count++; } - sprintf(marker_file, "%s.open", mDataFilename); /* Flawfinder: ignore */ - LLFile::remove(marker_file); - delete [] marker_file; - marker_file = NULL; } - delete[] mIndexFilename; - mIndexFilename = NULL; - delete[] mDataFilename; - mDataFilename = NULL; + if( !new_vfs->isValid() ) + { + delete new_vfs; // Delete bad VFS + new_vfs = NULL; // Total failure + } - delete mDataMutex; + return new_vfs; } + + void LLVFS::presizeDataFile(const U32 size) { if (!mDataFP) @@ -767,8 +741,14 @@ S32 LLVFS::getMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type BOOL LLVFS::checkAvailable(S32 max_size) { + lockData(); + blocks_length_map_t::iterator iter = mFreeBlocksByLength.lower_bound(max_size); // first entry >= size - return (iter == mFreeBlocksByLength.end()) ? FALSE : TRUE; + const BOOL res(iter == mFreeBlocksByLength.end() ? FALSE : TRUE); + + unlockData(); + + return res; } BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type, S32 max_size) @@ -874,40 +854,42 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type if (free_block) { + // Save location where data is going, useFreeSpace will move free_block->mLocation; + U32 new_data_location = free_block->mLocation; + + //mark the free block as used so it does not + //interfere with other operations such as addFreeBlock + useFreeSpace(free_block, max_size); // useFreeSpace takes ownership (and may delete) free_block + if (block->mLength > 0) { // create a new free block where this file used to be LLVFSBlock *new_free_block = new LLVFSBlock(block->mLocation, block->mLength); addFreeBlock(new_free_block); - + if (block->mSize > 0) { // move the file into the new block - U8 *buffer = new U8[block->mSize]; + std::vector<U8> buffer(block->mSize); fseek(mDataFP, block->mLocation, SEEK_SET); - if (fread(buffer, block->mSize, 1, mDataFP) == 1) + if (fread(&buffer[0], block->mSize, 1, mDataFP) == 1) { - fseek(mDataFP, free_block->mLocation, SEEK_SET); - if (fwrite(buffer, block->mSize, 1, mDataFP) != 1) + fseek(mDataFP, new_data_location, SEEK_SET); + if (fwrite(&buffer[0], block->mSize, 1, mDataFP) != 1) { llwarns << "Short write" << llendl; } } else { llwarns << "Short read" << llendl; } - - delete[] buffer; } } - block->mLocation = free_block->mLocation; + block->mLocation = new_data_location; block->mLength = max_size; - // Must call useFreeSpace before sync(), as sync() - // unlocks data structures. - useFreeSpace(free_block, max_size); sync(block); @@ -1122,14 +1104,14 @@ S32 LLVFS::getData(const LLUUID &file_id, const LLAssetType::EType file_type, U8 } } - unlockData(); - if (do_read) { fseek(mDataFP, location, SEEK_SET); bytesread = (S32)fread(buffer, 1, length, mDataFP); } + unlockData(); + return bytesread; } @@ -1194,8 +1176,6 @@ S32 LLVFS::storeData(const LLUUID &file_id, const LLAssetType::EType file_type, } U32 file_location = location + block->mLocation; - unlockData(); - fseek(mDataFP, file_location, SEEK_SET); S32 write_len = (S32)fwrite(buffer, 1, length, mDataFP); if (write_len != length) @@ -1204,7 +1184,6 @@ S32 LLVFS::storeData(const LLUUID &file_id, const LLAssetType::EType file_type, } // fflush(mDataFP); - lockData(); if (location + length > block->mSize) { block->mSize = location + write_len; @@ -1316,7 +1295,7 @@ void LLVFS::eraseBlockLength(LLVFSBlock *block) } if(!found_block) { - llwarns << "eraseBlock could not find block" << llendl; + llerrs << "eraseBlock could not find block" << llendl; } } @@ -1453,7 +1432,7 @@ void LLVFS::addFreeBlock(LLVFSBlock *block) // } //} - +// length bytes from free_block are going to be used (so they are no longer free) void LLVFS::useFreeSpace(LLVFSBlock *free_block, S32 length) { if (free_block->mLength == length) @@ -1536,8 +1515,6 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove) block->serialize(buffer); } - unlockData(); - // If set_index_to_end, file pointer is already at seek_pos // and we don't need to do anything. Only seek if not at end. if (!set_index_to_end) @@ -1549,11 +1526,10 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove) { llwarns << "Short write" << llendl; } - + + // *NOTE: Why was this commented out? // fflush(mIndexFP); - lockData(); - return; } @@ -1730,32 +1706,32 @@ void LLVFS::audit() fflush(mIndexFP); fseek(mIndexFP, 0, SEEK_END); - long index_size = ftell(mIndexFP); + size_t index_size = ftell(mIndexFP); fseek(mIndexFP, 0, SEEK_SET); BOOL vfs_corrupt = FALSE; - U8 *buffer = new U8[index_size]; + std::vector<U8> buffer(index_size); - if (fread(buffer, 1, index_size, mIndexFP) != index_size) + if (fread(&buffer[0], 1, index_size, mIndexFP) != index_size) { llwarns << "Index truncated" << llendl; vfs_corrupt = TRUE; } - U8 *tmp_ptr = buffer; + size_t buf_offset = 0; std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files; U32 cur_time = (U32)time(NULL); std::vector<LLVFSFileBlock*> audit_blocks; - while (!vfs_corrupt && tmp_ptr < buffer + index_size) + while (!vfs_corrupt && buf_offset < index_size) { LLVFSFileBlock *block = new LLVFSFileBlock(); audit_blocks.push_back(block); - block->deserialize(tmp_ptr, (S32)(tmp_ptr - buffer)); - tmp_ptr += block->SERIAL_SIZE; + block->deserialize(&buffer[buf_offset], (S32)buf_offset); + buf_offset += block->SERIAL_SIZE; // do sanity check on this block if (block->mLength >= 0 && @@ -1814,8 +1790,6 @@ void LLVFS::audit() } } - delete[] buffer; - if (!vfs_corrupt) { for (fileblock_map::iterator it = mFileBlocks.begin(); it != mFileBlocks.end(); ++it) @@ -2041,31 +2015,30 @@ void LLVFS::dumpStatistics() } // Debug Only! -LLString get_extension(LLAssetType::EType type) +std::string get_extension(LLAssetType::EType type) { - LLString extension; + std::string extension; switch(type) { - case LLAssetType::AT_TEXTURE: - extension = ".j2c"; + case LLAssetType::AT_TEXTURE: + extension = ".jp2"; // formerly ".j2c" break; - case LLAssetType::AT_SOUND: + case LLAssetType::AT_SOUND: extension = ".ogg"; break; - case LLAssetType::AT_SOUND_WAV: + case LLAssetType::AT_SOUND_WAV: extension = ".wav"; break; - case LLAssetType::AT_TEXTURE_TGA: + case LLAssetType::AT_TEXTURE_TGA: extension = ".tga"; break; - case LLAssetType::AT_IMAGE_JPEG: - extension = ".jpeg"; - break; - case LLAssetType::AT_ANIMATION: + case LLAssetType::AT_ANIMATION: extension = ".lla"; break; - default: - extension = ".data"; + default: + // Just use the asset server filename extension in most cases + extension += "."; + extension += LLAssetType::lookup(type); break; } return extension; @@ -2084,7 +2057,7 @@ void LLVFS::listFiles() if (length != BLOCK_LENGTH_INVALID && size > 0) { LLUUID id = file_spec.mFileID; - LLString extension = get_extension(file_spec.mFileType); + std::string extension = get_extension(file_spec.mFileType); llinfos << " File: " << id << " Type: " << LLAssetType::getDesc(file_spec.mFileType) << " Size: " << size @@ -2100,6 +2073,7 @@ void LLVFS::dumpFiles() { lockData(); + S32 files_extracted = 0; for (fileblock_map::iterator it = mFileBlocks.begin(); it != mFileBlocks.end(); ++it) { LLVFSFileSpecifier file_spec = it->first; @@ -2110,23 +2084,28 @@ void LLVFS::dumpFiles() { LLUUID id = file_spec.mFileID; LLAssetType::EType type = file_spec.mFileType; - U8* buffer = new U8[size]; + std::vector<U8> buffer(size); unlockData(); - getData(id, type, buffer, 0, size); + getData(id, type, &buffer[0], 0, size); lockData(); - LLString extension = get_extension(type); - LLString filename = id.asString() + extension; + std::string extension = get_extension(type); + std::string filename = id.asString() + extension; llinfos << " Writing " << filename << llendl; - apr_file_t* file = ll_apr_file_open(filename, LL_APR_WB); - ll_apr_file_write(file, buffer, size); - apr_file_close(file); - delete[] buffer; + + LLAPRFile outfile; + outfile.open(filename, LL_APR_WB); + outfile.write(&buffer[0], size); + outfile.close(); + + files_extracted++; } } unlockData(); + + llinfos << "Extracted " << files_extracted << " files out of " << mFileBlocks.size() << llendl; } //============================================================================ @@ -2134,7 +2113,7 @@ void LLVFS::dumpFiles() //============================================================================ // static -FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) +LLFILE *LLVFS::openAndLock(const std::string& filename, const char* mode, BOOL read_lock) { #if LL_WINDOWS @@ -2142,7 +2121,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) #else - FILE *fp; + LLFILE *fp; int fd; // first test the lock in a non-destructive way @@ -2152,7 +2131,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) fl.l_start = 0; fl.l_len = 1; #else // !LL_SOLARIS - if (strstr(mode, "w")) + if (strchr(mode, 'w') != NULL) { fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ if (fp) @@ -2192,7 +2171,7 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock) } // static -void LLVFS::unlockAndClose(FILE *fp) +void LLVFS::unlockAndClose(LLFILE *fp) { if (fp) { |