diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /tools/rescompressor/main.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'tools/rescompressor/main.cpp')
-rw-r--r-- | tools/rescompressor/main.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/tools/rescompressor/main.cpp b/tools/rescompressor/main.cpp new file mode 100644 index 0000000000..9aba1002c5 --- /dev/null +++ b/tools/rescompressor/main.cpp @@ -0,0 +1,150 @@ +#include <library/cpp/resource/registry.h> +#include <util/stream/file.h> +#include <util/folder/path.h> + +using namespace NResource; + +class TAsmWriter { +private: + IOutputStream& AsmOut; + TString AsmPrefix; + +public: + TAsmWriter(IOutputStream& out, const TString& prefix) : AsmOut(out), AsmPrefix(prefix) + { + } + + void Write(TStringBuf filename, const TString& data, bool raw) { + TString constname(Basename(filename)); + if (constname.rfind('.') != TStringBuf::npos) { + constname = constname.substr(0, constname.rfind('.')); + } + WriteHeader(constname); + if (raw) { + WriteRaw(constname, data); + } else { + WriteIncBin(constname, filename, data); + } + WriteFooter(constname); + WriteSymbolSize(constname); + } + +private: + void WriteHeader(const TStringBuf& constname) { + AsmOut << "global " << AsmPrefix << constname << "\n"; + AsmOut << "global " << AsmPrefix << constname << "Size\n"; + AsmOut << "SECTION .rodata\n"; + } + + void WriteFooter(TStringBuf constname) { + AsmOut << AsmPrefix << constname << "Size:\n"; + AsmOut << "dd " << AsmPrefix << constname << ".end - " << AsmPrefix << constname << "\n"; + } + + void WriteSymbolSize(TStringBuf constname) { + AsmOut << "%ifidn __OUTPUT_FORMAT__,elf64\n"; + AsmOut << "size " << AsmPrefix << constname << " " << AsmPrefix << constname << ".end - " << AsmPrefix << constname << "\n"; + AsmOut << "size " << AsmPrefix << constname << "Size 4\n"; + AsmOut << "%endif\n"; + } + + void WriteIncBin(TStringBuf constname, TStringBuf filename, const TString& data) { + AsmOut << AsmPrefix << constname << ":\nincbin \"" << Basename(filename) << "\"\n"; + AsmOut << ".end:\n"; + TFixedBufferFileOutput out(filename.data()); + out << data; + } + + void WriteRaw(TStringBuf constname, const TString& data) { + AsmOut << AsmPrefix << constname << ":\ndb "; + for (size_t i = 0; i < data.size() - 1; i++) { + unsigned char c = static_cast<unsigned char>(data[i]); + AsmOut << IntToString<10, unsigned char>(c) << ","; + } + AsmOut << IntToString<10, unsigned char>(static_cast<unsigned char>(data[data.size() - 1])) << "\n"; + AsmOut << ".end:\n"; + } + + TString Basename(TStringBuf origin) { + TString result(origin); + if (result.rfind('/') != TString::npos) { + result = result.substr(result.rfind('/') + 1); + } else if (result.rfind('\\') != TString::npos) { + result = result.substr(result.rfind('\\') + 1); + } + return result; + } +}; + +static TString CompressPath(const TVector<TStringBuf>& replacements, TStringBuf in) { + for (auto r : replacements) { + TStringBuf from, to; + r.Split('=', from, to); + if (in.StartsWith(from)) { + return Compress(TString(to) + in.SubStr(from.Size())); + } + } + + return Compress(in); +} + +int main(int argc, char** argv) { + int ind = 0; + if (argc < 4) { + Cerr << "usage: " << argv[ind] << "asm_output --prefix? [-? origin_resource ro_resource]+" << Endl; + return 1; + } + + TVector<TStringBuf> replacements; + + ind++; + TFixedBufferFileOutput asmout(argv[ind]); + ind++; + TString prefix; + if (TStringBuf(argv[ind]) == "--prefix") { + prefix = "_"; + ind++; + } + else { + prefix = ""; + } + + while (TStringBuf(argv[ind]).StartsWith("--replace=")) { + replacements.push_back(TStringBuf(argv[ind]).SubStr(TStringBuf("--replace=").Size())); + ind++; + } + + TAsmWriter aw(asmout, prefix); + bool raw; + bool error = false; + while (ind < argc) { + TString compressed; + if ("-"sv == argv[ind]) { + ind++; + if (ind >= argc) { + error = true; + break; + } + compressed = CompressPath(replacements, TStringBuf(argv[ind])); + raw = true; + } + else { + TUnbufferedFileInput inp(argv[ind]); + TString data = inp.ReadAll(); + compressed = Compress(TStringBuf(data.data(), data.size())); + raw = false; + } + ind++; + if (ind >= argc) { + error = true; + break; + } + aw.Write(argv[ind], compressed, raw); + ind++; + } + if (error) { + Cerr << "Incorrect number of parameters at argument " << ind - 1 << argv[ind-1] << Endl; + return 1; + } + return 0; +} |