libBeatsaber/src/filereader.cpp

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 &it;
if(strcasecmp(it.c_str(), needle.c_str()) == 0) return &it;
}
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
}