Implement --nocompress_suffixes option.
The planned replacement of the ApkBuilder with singlejar uses it.
--
MOS_MIGRATED_REVID=134290339
diff --git a/src/tools/singlejar/BUILD b/src/tools/singlejar/BUILD
index 63f6a45..cd02415 100644
--- a/src/tools/singlejar/BUILD
+++ b/src/tools/singlejar/BUILD
@@ -340,6 +340,7 @@
java_library(
name = "test1",
resources = [
+ "options.cc",
"zip_headers.h",
"zlib_interface.h",
],
diff --git a/src/tools/singlejar/options.cc b/src/tools/singlejar/options.cc
index 7c609d8..11484c4 100644
--- a/src/tools/singlejar/options.cc
+++ b/src/tools/singlejar/options.cc
@@ -37,7 +37,8 @@
tokens.MatchAndSet("--no_duplicates", &no_duplicates) ||
tokens.MatchAndSet("--verbose", &verbose) ||
tokens.MatchAndSet("--warn_duplicate_resources",
- &warn_duplicate_resources)) {
+ &warn_duplicate_resources) ||
+ tokens.MatchAndSet("--nocompress_suffixes", &nocompress_suffixes)) {
continue;
} else if (tokens.MatchAndSet("--build_info_file", &optarg)) {
build_info_files.push_back(optarg);
diff --git a/src/tools/singlejar/options.h b/src/tools/singlejar/options.h
index 753f0a2..cc01cd8 100644
--- a/src/tools/singlejar/options.h
+++ b/src/tools/singlejar/options.h
@@ -44,6 +44,7 @@
std::vector<std::string> build_info_files;
std::vector<std::string> build_info_lines;
std::vector<std::string> include_prefixes;
+ std::vector<std::string> nocompress_suffixes;
bool exclude_build_data;
bool force_compression;
bool normalize_timestamps;
diff --git a/src/tools/singlejar/options_test.cc b/src/tools/singlejar/options_test.cc
index 4a4d53a..14e1d4e 100644
--- a/src/tools/singlejar/options_test.cc
+++ b/src/tools/singlejar/options_test.cc
@@ -84,7 +84,8 @@
"--resources", "res1", "res2",
"--classpath_resources", "cpres1", "cpres2",
"--sources", "jar3",
- "--include_prefixes", "prefix1", "prefix2"};
+ "--include_prefixes", "prefix1", "prefix2",
+ "--nocompress_suffixes", ".png", ".so"};
Options options;
options.ParseCommandLine(arraysize(args), args);
@@ -101,6 +102,9 @@
ASSERT_EQ(2, options.include_prefixes.size());
EXPECT_EQ("prefix1", options.include_prefixes[0]);
EXPECT_EQ("prefix2", options.include_prefixes[1]);
+ EXPECT_EQ(2, options.nocompress_suffixes.size());
+ EXPECT_EQ(".png", options.nocompress_suffixes[0]);
+ EXPECT_EQ(".so", options.nocompress_suffixes[1]);
}
TEST(OptionsTest, EmptyMultiOptargs) {
diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc
index d5e2c10..77880a1 100644
--- a/src/tools/singlejar/output_jar.cc
+++ b/src/tools/singlejar/output_jar.cc
@@ -200,7 +200,19 @@
// Then classpath resources.
for (auto &classpath_resource : classpath_resources_) {
- WriteEntry(classpath_resource->OutputEntry(compress));
+ bool do_compress = compress;
+ if (do_compress && !options_->nocompress_suffixes.empty()) {
+ for (auto &suffix : options_->nocompress_suffixes) {
+ auto entry_name = classpath_resource->filename();
+ if (entry_name.length() >= suffix.size() &&
+ !entry_name.compare(entry_name.length() - suffix.size(),
+ suffix.size(), suffix)) {
+ do_compress = false;
+ break;
+ }
+ }
+ }
+ WriteEntry(classpath_resource->OutputEntry(do_compress));
}
// Then copy source files' contents.
@@ -340,30 +352,32 @@
}
}
- // For the file entries and unless preserve_compression option is set,
- // decide what to do with an entry depending on force_compress option
- // and entry's current state:
- // force_compress preserve_compress compressed Action
- // N N N Copy
- // N N Y Decompress
- // N Y * Copy
- // Y * N Compress
- // Y N Y Copy
- // Y Y can't be
- if (is_file &&
- !options_->preserve_compression &&
- ((options_->force_compression &&
- jar_entry->compression_method() == Z_NO_COMPRESSION) ||
- (!options_->force_compression && !options_->preserve_compression &&
- jar_entry->compression_method() == Z_DEFLATED))) {
- // Change compression.
- Concatenator combiner(jar_entry->file_name_string());
- if (!combiner.Merge(jar_entry, lh)) {
- diag_err(1, "%s:%d: cannot add %.*s", __FILE__, __LINE__,
- jar_entry->file_name_length(), jar_entry->file_name());
+ // For the file entries, decide whether output should be compressed.
+ if (is_file) {
+ bool input_compressed =
+ jar_entry->compression_method() != Z_NO_COMPRESSION;
+ bool output_compressed =
+ options_->force_compression ||
+ (options_->preserve_compression && input_compressed);
+ if (output_compressed && !options_->nocompress_suffixes.empty()) {
+ for (auto &suffix : options_->nocompress_suffixes) {
+ if (file_name_length >= suffix.size() &&
+ !strncmp(file_name + file_name_length - suffix.size(),
+ suffix.c_str(), suffix.size())) {
+ output_compressed = false;
+ break;
+ }
+ }
}
- WriteEntry(combiner.OutputEntry(options_->force_compression));
- continue;
+ if (input_compressed != output_compressed) {
+ Concatenator combiner(jar_entry->file_name_string());
+ if (!combiner.Merge(jar_entry, lh)) {
+ diag_err(1, "%s:%d: cannot add %.*s", __FILE__, __LINE__,
+ jar_entry->file_name_length(), jar_entry->file_name());
+ }
+ WriteEntry(combiner.OutputEntry(output_compressed));
+ continue;
+ }
}
// Now we have to copy:
diff --git a/src/tools/singlejar/output_jar_simple_test.cc b/src/tools/singlejar/output_jar_simple_test.cc
index 6bad8e3..5bd0eca 100644
--- a/src/tools/singlejar/output_jar_simple_test.cc
+++ b/src/tools/singlejar/output_jar_simple_test.cc
@@ -643,4 +643,36 @@
EXPECT_EQ("build: foo", GetEntryContents(out_path, kBuildDataFile));
}
+// Test that the entries with suffixes in --nocompressed_suffixes are
+// not compressed. This applies both to the source archives' entries and
+// standalone files.
+TEST_F(OutputJarSimpleTest, Nocompress) {
+ string res1_path =
+ CreateTextFile("resource.foo", "line1\nline2\nline3\nline4\n");
+ string res2_path =
+ CreateTextFile("resource.bar", "line1\nline2\nline3\nline4\n");
+ string out_path = OutputFilePath("out.jar");
+ CreateOutput(out_path,
+ {"--compression", "--sources",
+ DATA_DIR_TOP "src/tools/singlejar/libtest1.jar", "--resources",
+ res1_path, res2_path, "--nocompress_suffixes", ".foo", ".h"});
+ InputJar input_jar;
+ ASSERT_TRUE(input_jar.Open(out_path));
+ const LH *lh;
+ const CDH *cdh;
+ while ((cdh = input_jar.NextEntry(&lh))) {
+ const char *entry_name_end = lh->file_name() + lh->file_name_length();
+ if (!strncmp(entry_name_end - 4, ".foo", 4) ||
+ !strncmp(entry_name_end - 2, ".h", 2)) {
+ EXPECT_EQ(Z_NO_COMPRESSION, lh->compression_method())
+ << "Expected " << lh->file_name_string() << " uncompressed";
+ } else if (!strncmp(entry_name_end - 3, ".cc", 3) ||
+ !strncmp(entry_name_end - 4, ".bar", 4)) {
+ EXPECT_EQ(Z_DEFLATED, lh->compression_method())
+ << "Expected " << lh->file_name_string() << " compressed";
+ }
+ }
+ input_jar.Close();
+}
+
} // namespace