mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-29 22:04:25 +02:00
accessible ZipAligner
This commit is contained in:
parent
c517505cbf
commit
61b3b6aee5
@ -30,20 +30,30 @@ import java.util.List;
|
||||
|
||||
public class ApkWriter extends ZipFileOutput {
|
||||
private final Collection<? extends InputSource> sourceList;
|
||||
private ZipAligner zipAligner;
|
||||
|
||||
public ApkWriter(File file, Collection<? extends InputSource> sourceList) throws IOException {
|
||||
super(file);
|
||||
this.sourceList = sourceList;
|
||||
this.zipAligner = ZipAligner.apkAligner();
|
||||
}
|
||||
public void write()throws IOException {
|
||||
List<OutputSource> outputList = buildOutputEntry();
|
||||
BufferFileInput buffer = writeBuffer(outputList);
|
||||
buffer.unlock();
|
||||
ZipAligner aligner = new ZipAligner();
|
||||
align(aligner, outputList);
|
||||
align(outputList);
|
||||
writeApk(outputList);
|
||||
writeCEH(outputList);
|
||||
buffer.close();
|
||||
this.close();
|
||||
}
|
||||
public ZipAligner getZipAligner() {
|
||||
return zipAligner;
|
||||
}
|
||||
public void setZipAligner(ZipAligner zipAligner) {
|
||||
this.zipAligner = zipAligner;
|
||||
}
|
||||
|
||||
private void writeCEH(List<OutputSource> outputList) throws IOException{
|
||||
EndRecord endRecord = new EndRecord();
|
||||
endRecord.setSignature(ZipSignature.END_RECORD);
|
||||
@ -73,7 +83,8 @@ public class ApkWriter extends ZipFileOutput {
|
||||
output.close();
|
||||
return input;
|
||||
}
|
||||
private void align(ZipAligner aligner, List<OutputSource> outputList) throws IOException{
|
||||
private void align(List<OutputSource> outputList){
|
||||
ZipAligner aligner = getZipAligner();
|
||||
for(OutputSource outputSource:outputList){
|
||||
outputSource.align(aligner);
|
||||
}
|
||||
|
@ -29,18 +29,23 @@ import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public class OutputSource {
|
||||
class OutputSource {
|
||||
private final InputSource inputSource;
|
||||
private LocalFileHeader lfh;
|
||||
private EntryBuffer entryBuffer;
|
||||
|
||||
public OutputSource(InputSource inputSource){
|
||||
OutputSource(InputSource inputSource){
|
||||
this.inputSource = inputSource;
|
||||
}
|
||||
public void align(ZipAligner aligner){
|
||||
aligner.align(getInputSource(), getLocalFileHeader());
|
||||
void align(ZipAligner aligner){
|
||||
LocalFileHeader lfh = getLocalFileHeader();
|
||||
if(aligner == null){
|
||||
lfh.setExtra(null);
|
||||
}else {
|
||||
aligner.align(getInputSource(), lfh);
|
||||
}
|
||||
}
|
||||
public void makeBuffer(BufferFileInput input, BufferFileOutput output) throws IOException {
|
||||
void makeBuffer(BufferFileInput input, BufferFileOutput output) throws IOException {
|
||||
EntryBuffer entryBuffer = this.entryBuffer;
|
||||
if(entryBuffer != null){
|
||||
return;
|
||||
@ -62,7 +67,7 @@ public class OutputSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void writeApk(ApkWriter apkWriter) throws IOException{
|
||||
void writeApk(ApkWriter apkWriter) throws IOException{
|
||||
EntryBuffer entryBuffer = this.entryBuffer;
|
||||
FileChannel input = entryBuffer.getZipFileInput().getFileChannel();
|
||||
input.position(entryBuffer.getOffset());
|
||||
@ -71,7 +76,7 @@ public class OutputSource {
|
||||
writeData(input, entryBuffer.getLength(), apkWriter);
|
||||
writeDD(lfh.getDataDescriptor(), apkWriter);
|
||||
}
|
||||
public void writeCEH(ApkWriter apkWriter) throws IOException{
|
||||
void writeCEH(ApkWriter apkWriter) throws IOException{
|
||||
LocalFileHeader lfh = getLocalFileHeader();
|
||||
CentralEntryHeader ceh = CentralEntryHeader.fromLocalFileHeader(lfh);
|
||||
ceh.writeBytes(apkWriter.getOutputStream());
|
||||
@ -127,10 +132,10 @@ public class OutputSource {
|
||||
}
|
||||
}
|
||||
|
||||
public InputSource getInputSource() {
|
||||
InputSource getInputSource() {
|
||||
return inputSource;
|
||||
}
|
||||
public LocalFileHeader getLocalFileHeader(){
|
||||
LocalFileHeader getLocalFileHeader(){
|
||||
if(lfh == null){
|
||||
lfh = createLocalFileHeader();
|
||||
clearAlignment(lfh);
|
||||
|
@ -19,21 +19,56 @@ import com.reandroid.archive.InputSource;
|
||||
import com.reandroid.archive2.block.DataDescriptor;
|
||||
import com.reandroid.archive2.block.LocalFileHeader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public class ZipAligner {
|
||||
private final Map<Pattern, Integer> alignmentMap;
|
||||
private int defaultAlignment;
|
||||
private boolean enableDataDescriptor;
|
||||
private long mTotalPadding;
|
||||
private long mCurrentOffset;
|
||||
private boolean enableDataDescriptor = true;
|
||||
|
||||
public ZipAligner(){
|
||||
alignmentMap = new HashMap<>();
|
||||
}
|
||||
public void align(InputSource inputSource, LocalFileHeader lfh){
|
||||
|
||||
public void setFileAlignment(Pattern patternFileName, int alignment){
|
||||
if(patternFileName == null){
|
||||
return;
|
||||
}
|
||||
alignmentMap.remove(patternFileName);
|
||||
if(alignment >= 0){
|
||||
alignmentMap.put(patternFileName, alignment);
|
||||
}
|
||||
}
|
||||
public void clearFileAlignment(){
|
||||
alignmentMap.clear();
|
||||
}
|
||||
public void setDefaultAlignment(int defaultAlignment) {
|
||||
if(defaultAlignment < 0){
|
||||
defaultAlignment = 0;
|
||||
}
|
||||
this.defaultAlignment = defaultAlignment;
|
||||
}
|
||||
public void reset(){
|
||||
mTotalPadding = 0;
|
||||
mCurrentOffset = 0;
|
||||
}
|
||||
public void setEnableDataDescriptor(boolean enableDataDescriptor) {
|
||||
this.enableDataDescriptor = enableDataDescriptor;
|
||||
}
|
||||
|
||||
void align(InputSource inputSource, LocalFileHeader lfh){
|
||||
int padding;
|
||||
if(inputSource.getMethod() != ZipEntry.STORED){
|
||||
padding = 0;
|
||||
createDataDescriptor(lfh);
|
||||
}else {
|
||||
int alignment = getAlignment(inputSource);
|
||||
int alignment = getAlignment(inputSource.getAlias());
|
||||
long newOffset = mCurrentOffset + mTotalPadding;
|
||||
padding = (int) ((alignment - (newOffset % alignment)) % alignment);
|
||||
mTotalPadding += padding;
|
||||
@ -54,21 +89,23 @@ public class ZipAligner {
|
||||
}
|
||||
lfh.setDataDescriptor(dataDescriptor);
|
||||
}
|
||||
public void reset(){
|
||||
mTotalPadding = 0;
|
||||
mCurrentOffset = 0;
|
||||
}
|
||||
public void setEnableDataDescriptor(boolean enableDataDescriptor) {
|
||||
this.enableDataDescriptor = enableDataDescriptor;
|
||||
private int getAlignment(String name){
|
||||
for(Map.Entry<Pattern, Integer> entry:alignmentMap.entrySet()){
|
||||
Matcher matcher = entry.getKey().matcher(name);
|
||||
if(matcher.matches()){
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return defaultAlignment;
|
||||
}
|
||||
|
||||
private int getAlignment(InputSource inputSource){
|
||||
String name = inputSource.getAlias();
|
||||
if(name.startsWith("lib/") && name.endsWith(".so")){
|
||||
return ALIGNMENT_PAGE;
|
||||
}else {
|
||||
return ALIGNMENT_4;
|
||||
}
|
||||
public static ZipAligner apkAligner(){
|
||||
ZipAligner zipAligner = new ZipAligner();
|
||||
zipAligner.setDefaultAlignment(ALIGNMENT_4);
|
||||
Pattern patternNativeLib = Pattern.compile("^lib/.+\\.so$");
|
||||
zipAligner.setFileAlignment(patternNativeLib, ALIGNMENT_PAGE);
|
||||
zipAligner.setEnableDataDescriptor(true);
|
||||
return zipAligner;
|
||||
}
|
||||
|
||||
private static final int ALIGNMENT_4 = 4;
|
||||
|
Loading…
x
Reference in New Issue
Block a user