mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 03:42:48 +01:00
Rewrite FileIndex to use boost::filesystem instead of POSIX
This commit is contained in:
parent
836fe92f2f
commit
196f9f6d25
@ -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})
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user