mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-25 13:31:41 +00:00
implemented enough of zipios support...
...to get campaign scenarios and maps loaded from zip files
This commit is contained in:
parent
5926fe9f04
commit
139a0af373
@ -102,6 +102,7 @@ wesnoth_SOURCES = about.cpp \
|
||||
widgets/slider.cpp \
|
||||
widgets/textbox.cpp \
|
||||
widgets/widget.cpp \
|
||||
zipios++/xcoll.cpp \
|
||||
sdl_ttf/SDL_ttf.c \
|
||||
about.hpp \
|
||||
actions.hpp \
|
||||
@ -184,6 +185,7 @@ wesnoth_SOURCES = about.cpp \
|
||||
widgets/slider.hpp \
|
||||
widgets/textbox.hpp \
|
||||
widgets/widget.hpp \
|
||||
zipios++/xcoll.hpp \
|
||||
sdl_ttf/SDL_ttf.h \
|
||||
wesconfig.h
|
||||
|
||||
|
@ -63,14 +63,16 @@ BPath be_path;
|
||||
#include "util.hpp"
|
||||
|
||||
#ifdef USE_ZIPIOS
|
||||
#include <sstream>
|
||||
#include <zipios++/collcoll.h>
|
||||
#include <zipios++/dircoll.h>
|
||||
#include <zipios++/zipfile.h>
|
||||
#include <zipios++/simplesmartptr.h>
|
||||
#include <zipios++/basicentry.h>
|
||||
#include "zipios++/xcoll.hpp"
|
||||
|
||||
namespace {
|
||||
zipios::CColl the_collection;
|
||||
xzipios::XCColl the_collection;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -87,19 +89,12 @@ bool filesystem_init()
|
||||
std::cerr << "system collection has " << dir.size() << " elements\n";
|
||||
the_collection.addCollection(dir);
|
||||
# if 1
|
||||
// look for zip files
|
||||
zipios::DirectoryCollection dir2(game_config::path,false);
|
||||
if (!dir2.entries().empty())
|
||||
for (zipios::ConstEntries::iterator i = dir2.entries().begin(); i != dir2.entries().end(); ++i) {
|
||||
// FIXME: why the heck is the 1st entry corrupted !?
|
||||
if (i == dir2.entries().begin()) continue;
|
||||
|
||||
zipios::EntryPointer j = *i;
|
||||
zipios::FileEntry& k = *j;
|
||||
//for (int a=0; a<sizeof(k); a++) std::cerr << std::hex << (unsigned int)(((unsigned char*)&k)[a]) << ".";
|
||||
// std::cerr << std::dec << "\n";
|
||||
//continue;
|
||||
if (k.isValid()) {
|
||||
const std::string fname = k.getName();
|
||||
zipios::ConstEntries entries = dir2.entries();
|
||||
for (zipios::ConstEntries::iterator i = entries.begin(); i != entries.end(); ++i) {
|
||||
if ((**i).isValid()) {
|
||||
const std::string fname = (**i).getName();
|
||||
const std::string suffix = ".zip";
|
||||
if (0 == fname.compare(fname.size() - suffix.size(), suffix.size(), suffix)) {
|
||||
zipios::ZipFile zip(game_config::path + "/" + fname);
|
||||
@ -132,80 +127,89 @@ void get_files_in_dir(const std::string& directory,
|
||||
std::vector<std::string>* dirs,
|
||||
FILE_NAME_MODE mode)
|
||||
{
|
||||
//if we have a path to find directories in, then convert relative
|
||||
//pathnames to be rooted on the wesnoth path
|
||||
if(!directory.empty() && directory[0] != '/' && !game_config::path.empty()){
|
||||
const std::string& dir = game_config::path + "/" + directory;
|
||||
if(is_directory(dir)) {
|
||||
get_files_in_dir(dir,files,dirs,mode);
|
||||
#ifdef USE_ZIPIOS
|
||||
if (the_collection.hasSubdir(directory)) {
|
||||
the_collection.childrenOf(directory, files, dirs);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
//if we have a path to find directories in, then convert relative
|
||||
//pathnames to be rooted on the wesnoth path
|
||||
if(!directory.empty() && directory[0] != '/' && !game_config::path.empty()){
|
||||
const std::string& dir = game_config::path + "/" + directory;
|
||||
if(is_directory(dir)) {
|
||||
get_files_in_dir(dir,files,dirs,mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_finddata_t fileinfo;
|
||||
long dir = _findfirst((directory + "/*.*").c_str(),&fileinfo);
|
||||
#else
|
||||
|
||||
DIR* dir = opendir(directory.c_str());
|
||||
#endif
|
||||
|
||||
if(DIR_INVALID(dir)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_finddata_t fileinfo;
|
||||
long dir = _findfirst((directory + "/*.*").c_str(),&fileinfo);
|
||||
#else
|
||||
|
||||
DIR* dir = opendir(directory.c_str());
|
||||
#endif
|
||||
|
||||
if(DIR_INVALID(dir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
int res = dir;
|
||||
do {
|
||||
if(fileinfo.name[0] != '.') {
|
||||
const std::string path = (mode == ENTIRE_FILE_PATH ?
|
||||
directory + "/" : std::string("")) + fileinfo.name;
|
||||
int res = dir;
|
||||
do {
|
||||
if(fileinfo.name[0] != '.') {
|
||||
const std::string path = (mode == ENTIRE_FILE_PATH ?
|
||||
directory + "/" : std::string("")) + fileinfo.name;
|
||||
|
||||
if(fileinfo.attrib&_A_SUBDIR) {
|
||||
if(dirs != NULL)
|
||||
dirs->push_back(path);
|
||||
} else {
|
||||
if(files != NULL)
|
||||
files->push_back(path);
|
||||
if(fileinfo.attrib&_A_SUBDIR) {
|
||||
if(dirs != NULL)
|
||||
dirs->push_back(path);
|
||||
} else {
|
||||
if(files != NULL)
|
||||
files->push_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = _findnext(dir,&fileinfo);
|
||||
} while(!DIR_INVALID(res));
|
||||
res = _findnext(dir,&fileinfo);
|
||||
} while(!DIR_INVALID(res));
|
||||
|
||||
_findclose(dir);
|
||||
_findclose(dir);
|
||||
|
||||
#else
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dir)) != NULL) {
|
||||
if(entry->d_name[0] == '.')
|
||||
continue;
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dir)) != NULL) {
|
||||
if(entry->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
const std::string name((directory + "/") + entry->d_name);
|
||||
const std::string name((directory + "/") + entry->d_name);
|
||||
|
||||
struct stat st;
|
||||
if (::stat(name.c_str(), &st) != -1) {
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (files != NULL) {
|
||||
if (mode == ENTIRE_FILE_PATH)
|
||||
files->push_back(name);
|
||||
else
|
||||
files->push_back(entry->d_name);
|
||||
}
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (dirs != NULL) {
|
||||
if (mode == ENTIRE_FILE_PATH)
|
||||
dirs->push_back(name);
|
||||
else
|
||||
dirs->push_back(entry->d_name);
|
||||
struct stat st;
|
||||
if (::stat(name.c_str(), &st) != -1) {
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (files != NULL) {
|
||||
if (mode == ENTIRE_FILE_PATH)
|
||||
files->push_back(name);
|
||||
else
|
||||
files->push_back(entry->d_name);
|
||||
}
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (dirs != NULL) {
|
||||
if (mode == ENTIRE_FILE_PATH)
|
||||
dirs->push_back(name);
|
||||
else
|
||||
dirs->push_back(entry->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
closedir(dir);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(files != NULL)
|
||||
std::sort(files->begin(),files->end());
|
||||
@ -423,6 +427,11 @@ void read_file_internal(const std::string& fname, std::string& res)
|
||||
|
||||
std::string read_stream(std::istream& s)
|
||||
{
|
||||
#if 1
|
||||
std::stringstream ss;
|
||||
ss << s.rdbuf();
|
||||
return ss.str();
|
||||
#else
|
||||
std::vector<char> v;
|
||||
const int block_size = 65536;
|
||||
|
||||
@ -440,6 +449,7 @@ std::string read_stream(std::istream& s)
|
||||
res.resize(v.size());
|
||||
std::copy(v.begin(),v.end(),res.begin());
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string read_stdin()
|
||||
@ -451,6 +461,7 @@ std::string read_file(const std::string& fname)
|
||||
{
|
||||
//if we have a path to the data,
|
||||
//convert any filepath which is relative
|
||||
//std::cerr << "Reading " << fname << "\n";
|
||||
#ifdef USE_ZIPIOS
|
||||
if(!fname.empty() && fname[0] != '/') {
|
||||
zipios::ConstEntryPointer p = the_collection.getEntry(fname);
|
||||
@ -545,10 +556,17 @@ bool is_directory_internal(const std::string& fname)
|
||||
|
||||
bool is_directory(const std::string& fname)
|
||||
{
|
||||
#ifdef USE_ZIPIOS
|
||||
if(!fname.empty() && fname[0] != '/') {
|
||||
return the_collection.hasSubdir(fname);
|
||||
}
|
||||
|
||||
#else
|
||||
if(!fname.empty() && fname[0] != '/' && !game_config::path.empty()) {
|
||||
if(is_directory_internal(game_config::path + "/" + fname))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return is_directory_internal(fname);
|
||||
}
|
||||
|
51
src/zipios++/xcoll.cpp
Normal file
51
src/zipios++/xcoll.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#ifdef USE_ZIPIOS
|
||||
|
||||
#include <vector>
|
||||
#include "xcoll.hpp"
|
||||
#include "wassert.hpp"
|
||||
#include <zipios++/fileentry.h>
|
||||
|
||||
bool xzipios::XCColl::hasSubdir(const std::string path) const {
|
||||
zipios::ConstEntries e = entries();
|
||||
for (zipios::ConstEntries::iterator i = e.begin(); i != e.end(); ++i) {
|
||||
std::string name = (**i).getName();
|
||||
//std::cerr << " considering " << name << "\n";
|
||||
if ((0 == name.compare(0, path.size(), path)) &&
|
||||
((path[path.size()-1] == '/') || (name[path.size()] == '/')))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void xzipios::XCColl::childrenOf(std::string path,
|
||||
std::vector<std::string>* files,
|
||||
std::vector<std::string>* dirs) const {
|
||||
// be sure the dirname ends with a slash
|
||||
if (path[path.size()-1] != '/') path += '/';
|
||||
|
||||
zipios::ConstEntries e = entries();
|
||||
for (zipios::ConstEntries::iterator i = e.begin(); i != e.end(); ++i) {
|
||||
std::string name = (**i).getName();
|
||||
//std::cerr << " considering " << name << "\n";
|
||||
if (0 == name.compare(0, path.size(), path)) {
|
||||
size_t pos = 0; // cannot be returned by find
|
||||
if ((files!=NULL) &&
|
||||
((pos = name.find('/', path.size())) == std::string::npos) &&
|
||||
(name != path)) {
|
||||
files->push_back(name);
|
||||
} else if ((dirs!=NULL) &&
|
||||
((pos && (pos!=std::string::npos)) ? pos : (name.find('/', path.size()) != std::string::npos))) {
|
||||
wassert(pos!=0);
|
||||
std::string s = name.substr(0, pos);
|
||||
// FIXME: find more efficient ? (eg. look at last entry added first)
|
||||
std::vector<std::string>::iterator j;
|
||||
for (j = dirs->begin(); j != dirs->end(); ++j)
|
||||
if (*j == s) break;
|
||||
if (j == dirs->end())
|
||||
dirs->push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined USE_ZIPIOS
|
19
src/zipios++/xcoll.hpp
Normal file
19
src/zipios++/xcoll.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef XZIPIOS_XCOLL_H
|
||||
#define XZIPIOS_XCOLL_H
|
||||
|
||||
#include <zipios++/collcoll.h>
|
||||
|
||||
#define stubmethod(rtype,name,proto) rtype name
|
||||
namespace xzipios {
|
||||
|
||||
class XCColl: public zipios::CColl {
|
||||
public:
|
||||
// explicit XCColl
|
||||
bool hasSubdir(const std::string) const ;
|
||||
void xzipios::XCColl::childrenOf(std::string path,
|
||||
std::vector<std::string>* files,
|
||||
std::vector<std::string>* dirs) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // XZIPIOS_XCOLL_H
|
Loading…
x
Reference in New Issue
Block a user