diff --git a/src/main.cpp b/src/main.cpp index 7c435d2..2a44621 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,134 @@ #include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +struct BinaryCode { + std::string fileName; + std::string variableName; + std::string data; + std::size_t hashName; + std::size_t dataSize; +}; + +BinaryCode GetBinaryCode(const fs::path& filePath) { + std::ifstream file{ filePath.string() , std::ios::binary | std::ios::ate }; + + std::cout << "File : " << filePath.string() << "\n"; + + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::cout << "FileSize : " << size << "\n"; + + std::string fileName = filePath.filename().string(); + std::remove(fileName.begin(), fileName.end(), '\"'); + + std::string ressourceName = fileName; + std::replace(ressourceName.begin(), ressourceName.end(), '.', '_'); + std::replace(ressourceName.begin(), ressourceName.end(), '-', '_'); + ressourceName += "_data"; + + std::vector buffer(size); + if (file.read(buffer.data(), size)) + { + /* worked! */ + + std::stringstream ss; + ss << "static const unsigned char " << ressourceName << "[] = {\n\t"; + + int charNumber = 0; + + for (std::size_t i = 0; i < size; i++) { + + if (charNumber >= 100) { + ss << "\n\t"; + charNumber = 0; + } + + int value = static_cast(static_cast(buffer.at(i))); + + charNumber += 2; + if (value >= 10) charNumber++; + if (value >= 100) charNumber++; + + ss << value << ","; + } + + ss << " \n"; + + ss << "};\n"; + + return { fileName, ressourceName, ss.str(), std::hash{}(fileName), static_cast(size) }; + + } else { + std::cout << "Failed opening " << filePath << " !\n"; + } + + return {}; + +} + + +void WriteHeaderFile(const std::vector& files) { + std::ofstream output{ "BinaryData.h" }; + output << "#pragma once\n\n"; + output << "#include \n\n"; + output << "namespace BinaryData {\n\n"; + output << "static const std::string FileNames[] = {\n\t"; + for (const auto& fileCode : files) { + output << "\"" << fileCode.fileName << "\", "; + } + output << "\n};\n\n"; + output << "const char* GetRessourceByName(const std::string& resName, std::size_t& size);\n\n"; + output << "}\n"; +} + +void WriteSourceFile(const std::vector& files) { + std::ofstream output{ "BinaryData.cpp" }; + output << "#include \"BinaryData.h\"\n\nnamespace BinaryData {\n\n"; + for (const auto& fileCode : files) { + output << fileCode.data << "\n"; + } + output << "const char* GetRessourceByName(const std::string& fileName, std::size_t& size){\n"; + output << "\tstd::size_t fileNameHash = std::hash{}(fileName);\n"; + output << "\tswitch(fileNameHash){\n"; + for (const auto& fileCode : files) { + output << "\t\tcase " << fileCode.hashName << "U: size=" << fileCode.dataSize << "U; return reinterpret_cast(" << fileCode.variableName << ");\n"; + } + output << "\t}\n"; + output << "\treturn nullptr;\n"; + output << "}\n\n} // namespace BinaryData\n"; +} + + +void BinaryConvert(const std::string& dirName) { + std::cout << "Scanning " << dirName << " ...\n"; + + std::vector fileCodes; + for (const auto& entry : fs::directory_iterator(dirName)) { + fileCodes.push_back(std::move(GetBinaryCode(entry.path()))); + } + + WriteHeaderFile(fileCodes); + WriteSourceFile(fileCodes); +} + + + -using namespace std; int main(int argc, char** argv) { - cout << "hello world!" << endl; + if (argc == 1 || argv[1] == std::string{ "--help" } || argc >= 3) { + std::cout << "Syntax : BinaryData " << std::endl; + return 0; + } else { + BinaryConvert(argv[1]); + } + return 0; } diff --git a/xmake.lua b/xmake.lua index 92c2ee3..ba9175d 100644 --- a/xmake.lua +++ b/xmake.lua @@ -3,6 +3,7 @@ add_rules("mode.debug", "mode.release") target("BinaryData") set_kind("binary") add_files("src/*.cpp") + set_languages("c++17") -- -- If you want to known more usage about xmake, please see https://xmake.io