1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

Rewrite FileIndex to use boost::filesystem instead of POSIX

This commit is contained in:
darkf 2016-08-03 17:09:47 -07:00
parent 836fe92f2f
commit 196f9f6d25
4 changed files with 37 additions and 110 deletions

View File

@ -1,6 +1,9 @@
###########################################################
## RWLIB
###########################################################
find_package(Boost COMPONENTS filesystem system REQUIRED)
SET(RWLIB_SOURCES
# GL stuff is only here temporarily, hoping to move it back to rwengine
@ -44,11 +47,13 @@ add_library(rwlib
)
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/source")
"${CMAKE_CURRENT_SOURCE_DIR}/source"
"${Boost_INCLUDE_DIRS}")
target_include_directories(rwlib
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/source")
target_link_libraries(rwlib
${OPENGL_LIBRARIES}
${OPENRW_PLATFORM_LIBS})
${OPENRW_PLATFORM_LIBS}
${Boost_LIBRARIES})

View File

@ -1,100 +1,40 @@
#include <algorithm>
#include <fstream>
#include <boost/filesystem.hpp>
#include <platform/FileIndex.hpp>
#include <loaders/LoaderIMG.hpp>
#include <algorithm>
#include <fstream>
#ifndef RW_WINDOWS
#include <dirent.h>
#else
#include <platform/msdirent.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
void FileIndex::indexDirectory(const std::string& directory)
{
DIR* dp = opendir(directory.c_str());
dirent* ep;
std::string realName, lowerName;
if ( dp == NULL ) {
throw std::runtime_error("Unable to open directory: " + directory);
}
while( (ep = readdir(dp)) )
{
realName = ep->d_name;
lowerName = realName;
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
bool isRegularFile = false;
if (ep->d_type != DT_UNKNOWN) {
isRegularFile = ep->d_type == DT_REG;
} else {
std::string filepath = directory +"/"+ realName;
struct stat filedata;
if (stat(filepath.c_str(), &filedata) == 0) {
isRegularFile = S_ISREG(filedata.st_mode);
}
}
if (isRegularFile) {
files[ lowerName ] = {
lowerName,
realName,
directory,
""
};
}
}
closedir(dp);
}
using namespace boost::filesystem;
void FileIndex::indexTree(const std::string& root)
{
indexDirectory(root);
DIR* dp = opendir(root.c_str());
dirent* ep;
if ( dp == NULL ) {
throw std::runtime_error("Unable to open directory: " + root);
}
while( (ep = readdir(dp)) )
{
std::string filepath = root +"/"+ ep->d_name;
for(const auto& entry : recursive_directory_iterator(root)) {
std::string directory = entry.path().parent_path().string();
std::string realName = entry.path().filename().string();
std::string lowerName = realName;
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
bool isDirectory = false;
if (ep->d_type != DT_UNKNOWN) {
isDirectory = ep->d_type == DT_DIR;
} else {
struct stat filedata;
if (stat(filepath.c_str(), &filedata) == 0) {
isDirectory = S_ISDIR(filedata.st_mode);
}
}
if (isDirectory && ep->d_name[0] != '.') {
indexTree(filepath);
if(is_regular_file(entry.path())) {
files[lowerName] = {lowerName, realName, directory, ""};
}
}
closedir(dp);
}
void FileIndex::indexArchive(const std::string& archive)
{
// Split directory from archive name
auto slash = archive.find_last_of('/');
auto directory = archive.substr(0, slash);
auto archivebasename = archive.substr(slash+1);
auto archivepath = directory + "/" + archivebasename;
path archive_path = path(archive);
path directory = archive_path.parent_path();
path archive_basename = archive_path.stem();
path archive_full_path = directory/archive_basename;
LoaderIMG img;
if( ! img.load( archivepath ) )
{
throw std::runtime_error("Failed to load IMG archive: " + archivepath);
LoaderIMG img;
if(!img.load(archive_full_path.string())) {
throw std::runtime_error("Failed to load IMG archive: " + archive_full_path.string());
}
std::string lowerName;
for( size_t i = 0; i < img.getAssetCount(); ++i )
{
for( size_t i = 0; i < img.getAssetCount(); ++i ) {
auto& asset = img.getAssetInfoByIndex(i);
if( asset.size == 0 ) continue;
@ -102,20 +42,14 @@ void FileIndex::indexArchive(const std::string& archive)
lowerName = asset.name;
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
files[ lowerName ] = {
lowerName,
asset.name,
directory,
archivebasename
};
files[lowerName] = {lowerName, asset.name, directory.string(), archive_basename.string()};
}
}
bool FileIndex::findFile(const std::string& filename, FileIndex::IndexData& filedata)
{
auto iterator = files.find( filename );
if( iterator == files.end() )
{
auto iterator = files.find(filename);
if( iterator == files.end() ) {
return false;
}
@ -127,8 +61,7 @@ bool FileIndex::findFile(const std::string& filename, FileIndex::IndexData& file
FileHandle FileIndex::openFile(const std::string& filename)
{
auto iterator = files.find( filename );
if( iterator == files.end() )
{
if( iterator == files.end() ) {
return nullptr;
}
@ -140,26 +73,22 @@ FileHandle FileIndex::openFile(const std::string& filename)
char* data = nullptr;
size_t length = 0;
if( isArchive )
{
if( isArchive ) {
fsName = f.directory + "/" + f.archive;
LoaderIMG img;
if( ! img.load(fsName) )
{
if( ! img.load(fsName) ) {
throw std::runtime_error("Failed to load IMG archive: " + fsName);
}
LoaderIMGFile file;
if( img.findAssetInfo(f.originalName, file) )
{
if( img.findAssetInfo(f.originalName, file) ) {
length = file.size * 2048;
data = img.loadToMemory(f.originalName);
}
}
else
{
else {
std::ifstream dfile(fsName.c_str(), std::ios_base::binary);
if ( ! dfile.is_open()) {
throw std::runtime_error("Unable to open file: " + fsName);
@ -172,8 +101,7 @@ FileHandle FileIndex::openFile(const std::string& filename)
dfile.read(data, length);
}
if( data == nullptr )
{
if( data == nullptr ) {
return nullptr;
}

View File

@ -19,12 +19,6 @@ public:
/// The archive filename (if applicable)
std::string archive;
};
/**
* Adds the files contained within the given directory to the
* file index.
*/
void indexDirectory(const std::string& directory);
/**
* Adds the files contained within the given directory tree to the

View File

@ -9,7 +9,7 @@ BOOST_AUTO_TEST_CASE(test_index)
{
FileIndex index;
index.indexDirectory(Global::getGamePath()+"/data");
index.indexTree(Global::getGamePath()+"/data");
FileIndex::IndexData data;
BOOST_CHECK( index.findFile("cullzone.dat", data) );
@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(test_file)
{
FileIndex index;
index.indexDirectory(Global::getGamePath()+"/data");
index.indexTree(Global::getGamePath()+"/data");
auto handle = index.openFile("cullzone.dat");
BOOST_CHECK( handle != nullptr );