Refactor zipalign to allow unit tests
Test: Self-tested Bug: NA Change-Id: I322b78c5e18082f7abf7427cdc62dbabcb18b4a0
This commit is contained in:
parent
baade4a3c4
commit
0f29f54695
8 changed files with 254 additions and 129 deletions
|
@ -4,20 +4,31 @@
|
|||
// Zip alignment tool
|
||||
//
|
||||
|
||||
cc_binary_host {
|
||||
name: "zipalign",
|
||||
cc_defaults {
|
||||
name: "zipalign_defaults",
|
||||
target: {
|
||||
windows: {
|
||||
host_ldlibs: ["-lpthread"],
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cc_library_host_static {
|
||||
name: "libzipalign",
|
||||
srcs: [
|
||||
"ZipAlign.cpp",
|
||||
"ZipEntry.cpp",
|
||||
"ZipFile.cpp",
|
||||
],
|
||||
|
||||
export_include_dirs: [
|
||||
"include",
|
||||
],
|
||||
cflags: ["-Wall", "-Werror"],
|
||||
|
||||
// NOTE: Do not add any shared_libs dependencies because they will break the
|
||||
// static_sdk_tools target.
|
||||
static_libs: [
|
||||
whole_static_libs: [
|
||||
"libutils",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
|
@ -26,11 +37,32 @@ cc_binary_host {
|
|||
"libbase",
|
||||
"libzopfli",
|
||||
],
|
||||
|
||||
target: {
|
||||
windows: {
|
||||
host_ldlibs: ["-lpthread"],
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
defaults: ["zipalign_defaults"],
|
||||
}
|
||||
|
||||
cc_binary_host {
|
||||
name: "zipalign",
|
||||
srcs: [
|
||||
"ZipAlignMain.cpp",
|
||||
],
|
||||
cflags: ["-Wall", "-Werror"],
|
||||
static_libs: [
|
||||
"libzipalign",
|
||||
],
|
||||
defaults: ["zipalign_defaults"],
|
||||
}
|
||||
|
||||
cc_test_host {
|
||||
name: "zipalign_tests",
|
||||
srcs: [
|
||||
"tests/src/*_test.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"libzipalign",
|
||||
"libgmock",
|
||||
],
|
||||
data: [
|
||||
"tests/data/unaligned.zip",
|
||||
],
|
||||
defaults: ["zipalign_defaults"],
|
||||
}
|
||||
|
|
|
@ -14,35 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Zip alignment tool
|
||||
*/
|
||||
#include "ZipFile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
/*
|
||||
* Show program usage.
|
||||
*/
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Zip alignment utility\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
|
||||
fprintf(stderr,
|
||||
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
|
||||
" zipalign -c [-p] [-v] <align> infile.zip\n\n" );
|
||||
fprintf(stderr,
|
||||
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
|
||||
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
|
||||
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
|
||||
fprintf(stderr, " -p: memory page alignment for stored shared object files\n");
|
||||
fprintf(stderr, " -v: verbose output\n");
|
||||
fprintf(stderr, " -z: recompress using Zopfli\n");
|
||||
}
|
||||
namespace android {
|
||||
|
||||
static int getAlignment(bool pageAlignSharedLibs, int defaultAlignment,
|
||||
ZipEntry* pEntry) {
|
||||
|
@ -126,7 +104,7 @@ static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfl
|
|||
* Process a file. We open the input and output files, failing if the
|
||||
* output file exists and "force" wasn't specified.
|
||||
*/
|
||||
static int process(const char* inFileName, const char* outFileName,
|
||||
int process(const char* inFileName, const char* outFileName,
|
||||
int alignment, bool force, bool zopfli, bool pageAlignSharedLibs)
|
||||
{
|
||||
ZipFile zin, zout;
|
||||
|
@ -169,7 +147,7 @@ static int process(const char* inFileName, const char* outFileName,
|
|||
/*
|
||||
* Verify the alignment of a zip archive.
|
||||
*/
|
||||
static int verify(const char* fileName, int alignment, bool verbose,
|
||||
int verify(const char* fileName, int alignment, bool verbose,
|
||||
bool pageAlignSharedLibs)
|
||||
{
|
||||
ZipFile zipFile;
|
||||
|
@ -218,92 +196,4 @@ static int verify(const char* fileName, int alignment, bool verbose,
|
|||
return foundBad ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse args.
|
||||
*/
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
bool wantUsage = false;
|
||||
bool check = false;
|
||||
bool force = false;
|
||||
bool verbose = false;
|
||||
bool zopfli = false;
|
||||
bool pageAlignSharedLibs = false;
|
||||
int result = 1;
|
||||
int alignment;
|
||||
char* endp;
|
||||
|
||||
if (argc < 4) {
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc && argv[0][0] == '-') {
|
||||
const char* cp = argv[0] +1;
|
||||
|
||||
while (*cp != '\0') {
|
||||
switch (*cp) {
|
||||
case 'c':
|
||||
check = true;
|
||||
break;
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'z':
|
||||
zopfli = true;
|
||||
break;
|
||||
case 'p':
|
||||
pageAlignSharedLibs = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
cp++;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!((check && argc == 2) || (!check && argc == 3))) {
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
alignment = strtol(argv[0], &endp, 10);
|
||||
if (*endp != '\0' || alignment <= 0) {
|
||||
fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (check) {
|
||||
/* check existing archive for correct alignment */
|
||||
result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
|
||||
} else {
|
||||
/* create the new archive */
|
||||
result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
|
||||
|
||||
/* trust, but verify */
|
||||
if (result == 0) {
|
||||
result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
if (wantUsage) {
|
||||
usage();
|
||||
result = 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace android
|
||||
|
|
136
tools/zipalign/ZipAlignMain.cpp
Normal file
136
tools/zipalign/ZipAlignMain.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Zip alignment tool
|
||||
*/
|
||||
|
||||
#include "ZipAlign.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
/*
|
||||
* Show program usage.
|
||||
*/
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Zip alignment utility\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
|
||||
fprintf(stderr,
|
||||
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
|
||||
" zipalign -c [-p] [-v] <align> infile.zip\n\n" );
|
||||
fprintf(stderr,
|
||||
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
|
||||
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
|
||||
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
|
||||
fprintf(stderr, " -p: memory page alignment for stored shared object files\n");
|
||||
fprintf(stderr, " -v: verbose output\n");
|
||||
fprintf(stderr, " -z: recompress using Zopfli\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse args.
|
||||
*/
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
bool wantUsage = false;
|
||||
bool check = false;
|
||||
bool force = false;
|
||||
bool verbose = false;
|
||||
bool zopfli = false;
|
||||
bool pageAlignSharedLibs = false;
|
||||
int result = 1;
|
||||
int alignment;
|
||||
char* endp;
|
||||
|
||||
if (argc < 4) {
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc && argv[0][0] == '-') {
|
||||
const char* cp = argv[0] +1;
|
||||
|
||||
while (*cp != '\0') {
|
||||
switch (*cp) {
|
||||
case 'c':
|
||||
check = true;
|
||||
break;
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'z':
|
||||
zopfli = true;
|
||||
break;
|
||||
case 'p':
|
||||
pageAlignSharedLibs = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
cp++;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!((check && argc == 2) || (!check && argc == 3))) {
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
alignment = strtol(argv[0], &endp, 10);
|
||||
if (*endp != '\0' || alignment <= 0) {
|
||||
fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
|
||||
wantUsage = true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (check) {
|
||||
/* check existing archive for correct alignment */
|
||||
result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
|
||||
} else {
|
||||
/* create the new archive */
|
||||
result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
|
||||
|
||||
/* trust, but verify */
|
||||
if (result == 0) {
|
||||
result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
if (wantUsage) {
|
||||
usage();
|
||||
result = 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
using namespace android;
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Initialize a new ZipEntry structure from a FILE* positioned at a
|
||||
|
@ -696,3 +696,5 @@ void ZipEntry::CentralDirEntry::dump(void) const
|
|||
ALOGD(" comment: '%s'\n", mFileComment);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
using namespace android;
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Some environments require the "b", some choke on it.
|
||||
|
@ -134,7 +134,7 @@ status_t ZipFile::open(const char* zipFileName, int flags)
|
|||
/*
|
||||
* Return the Nth entry in the archive.
|
||||
*/
|
||||
android::ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
||||
ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
||||
{
|
||||
if (idx < 0 || idx >= (int) mEntries.size())
|
||||
return NULL;
|
||||
|
@ -145,7 +145,7 @@ android::ZipEntry* ZipFile::getEntryByIndex(int idx) const
|
|||
/*
|
||||
* Find an entry by name.
|
||||
*/
|
||||
android::ZipEntry* ZipFile::getEntryByName(const char* fileName) const
|
||||
ZipEntry* ZipFile::getEntryByName(const char* fileName) const
|
||||
{
|
||||
/*
|
||||
* Do a stupid linear string-compare search.
|
||||
|
@ -1397,3 +1397,4 @@ void ZipFile::EndOfCentralDir::dump(void) const
|
|||
mCentralDirSize, mCentralDirOffset, mCommentLen);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
|
49
tools/zipalign/include/ZipAlign.h
Normal file
49
tools/zipalign/include/ZipAlign.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ZIPALIGN_H
|
||||
#define ZIPALIGN_H
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Generate a new, aligned, zip "output" from an "input" zip.
|
||||
* - alignTo: Alignment (in bytes) for uncompressed entries.
|
||||
* - force : Overwrite output if it exists, fail otherwise.
|
||||
* - zopfli : Recompress compressed entries with more efficient algorithm.
|
||||
* Copy compressed entries as-is, and unaligned, otherwise.
|
||||
* - pageAlignSharedLibs: Align .so files to 4096 and other files to
|
||||
* alignTo, or all files to alignTo if false..
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int process(const char* input, const char* output, int alignTo, bool force,
|
||||
bool zopfli, bool pageAlignSharedLibs);
|
||||
|
||||
/*
|
||||
* Verify the alignment of a zip archive.
|
||||
* - alignTo: Alignment (in bytes) for uncompressed entries.
|
||||
* - pageAlignSharedLibs: Align .so files to 4096 and other files to
|
||||
* alignTo, or all files to alignTo if false..
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int verify(const char* fileName, int alignTo, bool verbose,
|
||||
bool pageAlignSharedLibs);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ZIPALIGN_H
|
BIN
tools/zipalign/tests/data/unaligned.zip
Normal file
BIN
tools/zipalign/tests/data/unaligned.zip
Normal file
Binary file not shown.
15
tools/zipalign/tests/src/align_test.cpp
Normal file
15
tools/zipalign/tests/src/align_test.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ZipAlign.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
TEST(Align, Unaligned) {
|
||||
const char* src = "tests/data/unaligned.zip";
|
||||
const char* dst = "tests/data/unaligned_out.zip";
|
||||
int result = process(src, dst, 4, true, false, 4096);
|
||||
ASSERT_EQ(0, result);
|
||||
}
|
Loading…
Reference in a new issue