7 #include <ext/zlib/zlib.h>
54 void scanPath(
const string& path, vector<string>& totalFiles) {
57 virtual ~ListFilter() {}
59 bool accept(
const string& pathName,
const string& fileName)
override {
60 if (fileName ==
".")
return false;
61 if (fileName ==
"..")
return false;
62 if (FileSystem::getInstance()->isPath(pathName +
"/" + fileName) ==
true)
return true;
63 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
65 if (StringTools::endsWith(fileNameLowerCase,
".ogg") ==
true)
return true;
67 if (StringTools::endsWith(fileNameLowerCase,
".ttf") ==
true)
return true;
69 if (StringTools::endsWith(fileNameLowerCase,
".icns") ==
true)
return true;
70 if (StringTools::endsWith(fileNameLowerCase,
".ico") ==
true)
return true;
71 if (StringTools::endsWith(fileNameLowerCase,
".png") ==
true)
return true;
73 if (StringTools::endsWith(fileNameLowerCase,
".mpg") ==
true)
return true;
75 if (StringTools::endsWith(fileNameLowerCase,
".dae") ==
true)
return true;
76 if (StringTools::endsWith(fileNameLowerCase,
".fbx") ==
true)
return true;
77 if (StringTools::endsWith(fileNameLowerCase,
".glb") ==
true)
return true;
78 if (StringTools::endsWith(fileNameLowerCase,
".tm") ==
true)
return true;
80 if (StringTools::endsWith(fileNameLowerCase,
".properties") ==
true)
return true;
82 if (StringTools::endsWith(fileNameLowerCase,
".cl") ==
true)
return true;
83 if (StringTools::endsWith(fileNameLowerCase,
".frag") ==
true)
return true;
84 if (StringTools::endsWith(fileNameLowerCase,
".glsl") ==
true)
return true;
85 if (StringTools::endsWith(fileNameLowerCase,
".vert") ==
true)
return true;
87 if (StringTools::endsWith(fileNameLowerCase,
".tmodel") ==
true)
return true;
89 if (StringTools::endsWith(fileNameLowerCase,
".tscene") ==
true)
return true;
91 if (StringTools::endsWith(fileNameLowerCase,
".tparticle") ==
true)
return true;
93 if (StringTools::endsWith(fileNameLowerCase,
".tterrain") ==
true)
return true;
95 if (StringTools::endsWith(fileNameLowerCase,
".tscript") ==
true)
return true;
97 if (StringTools::endsWith(fileNameLowerCase,
".xml") ==
true)
return true;
99 if (fileName.rfind(
".") == string::npos ||
100 (fileName.rfind(
"/") != string::npos &&
101 fileName.rfind(
".") < fileName.rfind(
"/"))) {
109 ListFilter listFilter;
110 vector<string> files;
112 FileSystem::getInstance()->list(path, files, &listFilter);
114 for (
const auto& fileName: files) {
115 if (FileSystem::getInstance()->isPath(path +
"/" + fileName) ==
false) {
116 totalFiles.push_back(path +
"/" + fileName);
118 scanPath(path +
"/" + fileName, totalFiles);
123 void processFile(
const string& fileName, vector<FileInformation>& fileInformations) {
124 Console::print(
"Processing file: " + fileName);
127 vector<uint8_t> content;
128 FileSystem::getInstance()->getContent(
129 FileSystem::getInstance()->getPathName(fileName),
130 FileSystem::getInstance()->getFileName(fileName),
135 ofstream ofs(std::filesystem::u8path(
"archive.ta"), ofstream::binary | ofstream::app);
136 ofs.seekp(0, ofstream::end);
137 uint64_t fileOffset = ofs.tellp();
140 uint64_t bytesCompressed = 0;
141 uint8_t compressed = 1;
144 if (compressed == 1) {
153 unsigned char in[
CHUNK];
154 unsigned char out[
CHUNK];
157 strm.zalloc = Z_NULL;
159 strm.opaque = Z_NULL;
160 ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
162 Console::println(
"processFile(): Error compressing file: Aborting");
167 size_t inPosition = 0;
168 size_t inBytes = content.size();
170 auto inStartPosition = inPosition;
171 for (
size_t i = 0; i <
CHUNK; i++) {
172 if (inPosition == inBytes)
break;
173 in[i] = content[inPosition];
176 strm.avail_in = inPosition - inStartPosition;
177 flush = inPosition == inBytes?Z_FINISH:Z_NO_FLUSH;
182 strm.avail_out =
CHUNK;
184 ret = deflate(&strm, flush);
185 assert(ret != Z_STREAM_ERROR);
186 have =
CHUNK - strm.avail_out;
187 ofs.write((
char*)out, have);
188 bytesCompressed+= have;
189 }
while (strm.avail_out == 0);
190 assert(strm.avail_in == 0);
193 }
while (flush != Z_FINISH);
194 assert(ret == Z_STREAM_END);
197 (void) deflateEnd(&strm);
199 ofs.write((
char*)content.data(), content.size());
205 fileInformation.
name = fileName;
206 fileInformation.
bytes = content.size();
209 fileInformation.
offset = fileOffset;
211 fileInformations.push_back(fileInformation);
214 Console::println(
", processed " + to_string(content.size()) +
" bytes" + (compressed == 1?
", " + to_string(bytesCompressed) +
" bytes compressed":
""));
217 int main(
int argc,
char** argv)
219 Console::println(
string(
"archive ") + Version::getVersion());
220 Console::println(Version::getCopyright());
224 Console::println(
"Usage: archive");
225 Application::exit(Application::EXITCODE_FAILURE);
229 Console::println(
"Scanning files");
230 vector<string> files;
235 Console::println(
"Processing files");
239 ofstream ofs(std::filesystem::u8path(
"archive.ta"), ofstream::binary | ofstream::trunc);
244 vector<FileInformation> fileInformations;
245 for (
const auto& fileName: files) {
251 ofstream ofs(std::filesystem::u8path(
"archive.ta"), ofstream::binary | ofstream::app);
252 ofs.seekp(0, ofstream::end);
253 uint32_t fileInformationOffsetEnd = 0LL;
254 uint64_t fileInformationOffset = ofs.tellp();
255 for (
const auto& fileInformation: fileInformations) {
256 uint32_t nameSize = fileInformation.name.size();
257 ofs.write((
char*)&nameSize,
sizeof(nameSize));
258 for (
auto i = 0; i < nameSize; i++) ofs.write(&fileInformation.name[i], 1);
259 ofs.write((
char*)&fileInformation.bytes,
sizeof(fileInformation.bytes));
260 ofs.write((
char*)&fileInformation.compressed,
sizeof(fileInformation.compressed));
261 ofs.write((
char*)&fileInformation.bytesCompressed,
sizeof(fileInformation.bytesCompressed));
262 ofs.write((
char*)&fileInformation.offset,
sizeof(fileInformation.offset));
263 ofs.write((
char*)&fileInformation.executable,
sizeof(fileInformation.executable));
265 ofs.write((
char*)&fileInformationOffsetEnd,
sizeof(fileInformationOffsetEnd));
266 ofs.write((
char*)&fileInformationOffset,
sizeof(fileInformationOffset));
271 Application::exit(Application::EXITCODE_SUCCESS);
void scanPath(const string &path, vector< string > &totalFiles)
int main(int argc, char **argv)
void processFile(const string &fileName, vector< FileInformation > &fileInformations)
Application base class, please make sure to allocate application on heap to have correct application ...
File system singleton class.
std::exception Exception
Exception base class.
File system file name filter interface.
virtual bool accept(const string &path, const string &file)=0
Accept a file.