85 lines
2.1 KiB
C++
85 lines
2.1 KiB
C++
#include "filereaderimpl.h"
|
|
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <filesystem> //c++17 required
|
|
|
|
namespace Beatsaber {
|
|
|
|
static const std::string* findbest(const std::vector<std::string>& haystack, const std::string& needle) {
|
|
for(const auto& it : haystack) {
|
|
if(it == needle) return ⁢
|
|
if(strcasecmp(it.c_str(), needle.c_str()) == 0) return ⁢
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
FolderReader::FolderReader(const std::string& path) : path(path) {
|
|
// make path end with /
|
|
if(path.rfind('/') != path.size()-1)
|
|
this->path += "/";
|
|
}
|
|
FolderReader::~FolderReader() {}
|
|
|
|
std::shared_ptr<std::istream> FolderReader::getFileStream(const std::string& filename) {
|
|
std::shared_ptr<std::ifstream> stream = std::make_shared<std::ifstream>(path + filename);
|
|
if(!stream->is_open()) {
|
|
//search for other files
|
|
std::vector<std::string> entrys;
|
|
getEntrys(entrys);
|
|
const std::string* best = findbest(entrys, filename);
|
|
if(best) {
|
|
return std::make_shared<std::ifstream>(path + *best);
|
|
}
|
|
}
|
|
return stream;
|
|
}
|
|
|
|
void FolderReader::getEntrys(std::vector<std::string>& out) const {
|
|
for(const auto& i : std::filesystem::directory_iterator(path)) {
|
|
if(i.is_regular_file() && i.exists()) {
|
|
std::string filename = i.path().filename();
|
|
if(!filename.empty() && filename[0] != '.') { //ignore dotfiles
|
|
out.push_back(filename);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#if BEATSABERZIPSUPPORT == 1
|
|
ZipReader::ZipReader(const std::string& path) : file(path) {}
|
|
|
|
ZipReader::~ZipReader() {
|
|
file.close();
|
|
}
|
|
|
|
std::shared_ptr<std::istream> ZipReader::getFileStream(const std::string& filename) {
|
|
std::shared_ptr<std::istream> stream = file.getInputStream(filename);
|
|
|
|
if(!stream) {
|
|
//search for other files
|
|
std::vector<std::string> entrys;
|
|
getEntrys(entrys);
|
|
const std::string* best = findbest(entrys, filename);
|
|
if(best) {
|
|
return file.getInputStream(*best);
|
|
}
|
|
}
|
|
|
|
return stream;
|
|
}
|
|
|
|
void ZipReader::getEntrys(std::vector<std::string>& out) const {
|
|
const auto entr = file.entries();
|
|
out.reserve(entr.size());
|
|
for(auto it : entr) {
|
|
if(!it->isDirectory() && it->isValid()) {
|
|
out.push_back(it->getFileName());
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} |