1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include <string>
#include <vector>
#include "DataDirsAccess.h"
#include "FileQueryFlags.h"
#include "System/Log/ILog.h"
#include <zlib.h>
#include <string.h> //strnlen
static const int bufsize = 4096;
class RapidEntry{
public:
RapidEntry() {
value.resize(entries);
}
RapidEntry(const std::string& line) {
value.resize(entries);
size_t pos = 0, start = 0;
for(size_t i=0; i<entries; i++) {
pos = line.find(delim, start);
value[i] = (line.substr(start, pos - start));
start = pos + 1;
}
}
const std::string& GetTag() const
{
return value[0];
}
const std::string& GetPackageHash() const
{
return value[1];
}
const std::string& GetParentGameName() const
{
return value[2];
}
const std::string& GetName() const
{
return value[3];
}
private:
static const char delim = ',';
static const size_t entries = 4;
std::vector<std::string> value;
};
template <typename Lambda>
static bool GetRapidEntry(const std::string& file, RapidEntry* re, Lambda p)
{
gzFile in = gzopen(file.c_str(), "rb");
if (in == NULL) {
LOG_L(L_ERROR, "couldn't open %s", file.c_str());
return false;
}
char buf[bufsize];
while (gzgets(in, buf, bufsize) != NULL) {
size_t len = strnlen(buf, bufsize);
if (len <= 2) continue; //line to short/invalid, skip
if (buf[len-1] == '\n') len--;
if (buf[len-1] == '\r') len--;
*re = RapidEntry(std::string(buf, len));
if (p(*re)) {
gzclose(in);
return true;
}
}
gzclose(in);
return false;
}
std::string GetRapidPackageFromTag(const std::string& tag)
{
const auto files = dataDirsAccess.FindFiles("rapid", "versions.gz", FileQueryFlags::RECURSE);
for (const std::string file: files) {
RapidEntry re;
if (GetRapidEntry(dataDirsAccess.LocateFile(file), &re, [&](const RapidEntry& re) { return re.GetTag() == tag; }))
return re.GetName();
}
return tag;
}
std::string GetRapidTagFromPackage(const std::string& pkg)
{
const auto files = dataDirsAccess.FindFiles("rapid", "versions.gz", FileQueryFlags::RECURSE);
for (const std::string file: files) {
RapidEntry re;
if (GetRapidEntry(dataDirsAccess.LocateFile(file), &re, [&](const RapidEntry& re) { return re.GetPackageHash() == pkg; }))
return re.GetTag();
}
return "rapid_tag_unknown";
}
|