aboutsummaryrefslogtreecommitdiffstats
path: root/tools/rescompressor
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /tools/rescompressor
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'tools/rescompressor')
-rw-r--r--tools/rescompressor/bin/ya.make17
-rw-r--r--tools/rescompressor/main.cpp150
-rw-r--r--tools/rescompressor/ya.make13
3 files changed, 180 insertions, 0 deletions
diff --git a/tools/rescompressor/bin/ya.make b/tools/rescompressor/bin/ya.make
new file mode 100644
index 0000000000..0cf12b4918
--- /dev/null
+++ b/tools/rescompressor/bin/ya.make
@@ -0,0 +1,17 @@
+OWNER(heretic g:ymake)
+
+PROGRAM(rescompressor)
+
+PEERDIR(
+ library/cpp/resource
+)
+
+SRCDIR(
+ tools/rescompressor
+)
+
+SRCS(
+ main.cpp
+)
+
+END()
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;
+}
diff --git a/tools/rescompressor/ya.make b/tools/rescompressor/ya.make
new file mode 100644
index 0000000000..4c118c0bc6
--- /dev/null
+++ b/tools/rescompressor/ya.make
@@ -0,0 +1,13 @@
+OWNER(heretic g:ymake)
+
+IF (USE_PREBUILT_TOOLS)
+ INCLUDE(${ARCADIA_ROOT}/build/prebuilt/tools/rescompressor/ya.make.prebuilt)
+ENDIF()
+
+IF (NOT PREBUILT)
+ INCLUDE(${ARCADIA_ROOT}/tools/rescompressor/bin/ya.make)
+ENDIF()
+
+RECURSE(
+ bin
+)