| 197 | template <typename T> int64_t LE(T x) { return flatbuffers::EndianScalar((int64_t)x); }; |
| 198 | |
| 199 | string BuildPakFile(string &pakfile, string &metadata_buffer, set<string> &files, uint64_t src_hash, |
| 200 | const string &c_codegen) { |
| 201 | // All offsets in 64bit, just in-case we ever want pakfiles > 4GB :) |
| 202 | // Since we're building this in memory, they can only be created by a 64bit build. |
| 203 | vector<int64_t> filestarts; |
| 204 | vector<int64_t> namestarts; |
| 205 | vector<int64_t> uncompressed; |
| 206 | vector<string> filenames; |
| 207 | auto add_file = [&](string_view buf, string_view filename) { |
| 208 | filestarts.push_back(LE(pakfile.size())); |
| 209 | filenames.push_back(string(filename)); |
| 210 | LOG_INFO("adding to pakfile: ", filename); |
| 211 | if (IsCompressed(filename)) { |
| 212 | string out; |
| 213 | WEntropyCoder<true>((uint8_t *)buf.data(), buf.length(), buf.length(), out); |
| 214 | pakfile += out; |
| 215 | uncompressed.push_back(buf.length()); |
| 216 | } else { |
| 217 | pakfile += buf; |
| 218 | uncompressed.push_back(-1); |
| 219 | } |
| 220 | }; |
| 221 | // Start with a magic id, just for the hell of it. |
| 222 | pakfile.insert(pakfile.end(), magic, magic + magic_size); |
| 223 | // Metadata always first entry. |
| 224 | add_file(metadata_buffer, mdname); |
| 225 | if (!c_codegen.empty()) { |
| 226 | add_file(c_codegen, ccname); |
| 227 | } |
| 228 | // Followed by all files. |
| 229 | files.insert("data/shaders/default.materials"); // If it hadn't already been added. |
| 230 | string buf; |
| 231 | function<string(const string &)> addrec; |
| 232 | addrec = [&](const string &filename) -> string { |
| 233 | auto l = LoadFile(filename, &buf); |
| 234 | if (l >= 0) { |
| 235 | add_file(buf, filename); |
| 236 | } else { |
| 237 | auto base = filename; |
| 238 | auto pat = string{}; |
| 239 | auto pos = filename.find("#"); |
| 240 | if (pos != filename.npos) { |
| 241 | pat = filename.substr(pos + 1); |
| 242 | base = filename.substr(0, pos); |
| 243 | } |
| 244 | vector<DirectoryInfo> dir; |
| 245 | if (!ScanDir(base, dir)) return "cannot load file/dir for pakfile: " + filename; |
| 246 | for (auto &entry : dir) { |
| 247 | if (!pat.empty() && entry.name.find(pat) == entry.name.npos) continue; |
| 248 | auto fn = base; |
| 249 | if (fn.back() != '/') fn += "/"; |
| 250 | fn += entry.name; |
| 251 | auto err = addrec(fn); |
| 252 | if (!err.empty()) return err; |
| 253 | } |
| 254 | } |
| 255 | return ""; |
| 256 | }; |
no test coverage detected