diff --git a/src/main/java/com/reandroid/archive/ByteInputSource.java b/src/main/java/com/reandroid/archive/ByteInputSource.java index a6bafaf..61708a6 100644 --- a/src/main/java/com/reandroid/archive/ByteInputSource.java +++ b/src/main/java/com/reandroid/archive/ByteInputSource.java @@ -21,7 +21,7 @@ import java.io.InputStream; import java.io.OutputStream; public class ByteInputSource extends InputSource{ - private final byte[] inBytes; + private byte[] inBytes; public ByteInputSource(byte[] inBytes, String name) { super(name); this.inBytes=inBytes; @@ -39,4 +39,8 @@ public class ByteInputSource extends InputSource{ public byte[] getBytes() { return inBytes; } + @Override + public void disposeInputSource(){ + inBytes=new byte[0]; + } } diff --git a/src/main/java/com/reandroid/archive/InputSource.java b/src/main/java/com/reandroid/archive/InputSource.java index d5eb332..407a001 100644 --- a/src/main/java/com/reandroid/archive/InputSource.java +++ b/src/main/java/com/reandroid/archive/InputSource.java @@ -32,6 +32,8 @@ public abstract class InputSource { this.name = name; this.alias = InputSourceUtil.sanitize(name); } + public void disposeInputSource(){ + } public int getSort() { return sort; } diff --git a/src/main/java/com/reandroid/archive/ZipArchive.java b/src/main/java/com/reandroid/archive/ZipArchive.java index d58e64a..d559c5d 100644 --- a/src/main/java/com/reandroid/archive/ZipArchive.java +++ b/src/main/java/com/reandroid/archive/ZipArchive.java @@ -47,6 +47,7 @@ public class ZipArchive { FileOutputStream outputStream=new FileOutputStream(file); inputSource.write(outputStream); outputStream.close(); + inputSource.disposeInputSource(); } private File toOutFile(File outDir, String path){ path=path.replace('/', File.separatorChar); diff --git a/src/main/java/com/reandroid/archive/ZipSerializer.java b/src/main/java/com/reandroid/archive/ZipSerializer.java index 9a36449..8c8ac92 100644 --- a/src/main/java/com/reandroid/archive/ZipSerializer.java +++ b/src/main/java/com/reandroid/archive/ZipSerializer.java @@ -57,6 +57,7 @@ public class ZipSerializer { } length+=write(zipOutputStream, inputSource); zipOutputStream.closeEntry(); + inputSource.disposeInputSource(); } zipOutputStream.close(); return length; diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLEncodeSource.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLEncodeSource.java new file mode 100644 index 0000000..ad73bc1 --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLEncodeSource.java @@ -0,0 +1,80 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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. + */ +package com.reandroid.lib.apk.xmlencoder; + +import com.reandroid.archive.ByteInputSource; +import com.reandroid.lib.apk.CrcOutputStream; +import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock; +import com.reandroid.xml.XMLException; +import com.reandroid.xml.source.XMLSource; + +import java.io.IOException; +import java.io.OutputStream; + +public class XMLEncodeSource extends ByteInputSource { + private final EncodeMaterials encodeMaterials; + private final XMLSource xmlSource; + private ResXmlBlock resXmlBlock; + public XMLEncodeSource(EncodeMaterials encodeMaterials, XMLSource xmlSource){ + super(new byte[0], xmlSource.getPath()); + this.encodeMaterials=encodeMaterials; + this.xmlSource=xmlSource; + } + @Override + public long getLength() throws IOException{ + return getResXmlBlock().countBytes(); + } + @Override + public long getCrc() throws IOException{ + ResXmlBlock resXmlBlock = getResXmlBlock(); + CrcOutputStream outputStream=new CrcOutputStream(); + resXmlBlock.writeBytes(outputStream); + return outputStream.getCrcValue(); + } + @Override + public long write(OutputStream outputStream) throws IOException { + return getResXmlBlock().writeBytes(outputStream); + } + @Override + public byte[] getBytes() { + try { + return getResXmlBlock().getBytes(); + } catch (IOException ignored) { + } + //should not reach here + return new byte[0]; + } + public ResXmlBlock getResXmlBlock() throws IOException{ + if(resXmlBlock!=null){ + return resXmlBlock; + } + try { + XMLFileEncoder xmlFileEncoder=new XMLFileEncoder(encodeMaterials); + encodeMaterials.logVerbose("Encoding xml: "+xmlSource.getPath()); + resXmlBlock = xmlFileEncoder.encode(xmlSource.getXMLDocument()); + } catch (XMLException ex) { + throw new IOException(ex.getMessage(), ex); + } + return resXmlBlock; + } + @Override + public void disposeInputSource(){ + this.xmlSource.disposeXml(); + if(this.resXmlBlock!=null){ + resXmlBlock=null; + } + } +} diff --git a/src/main/java/com/reandroid/lib/arsc/array/PackageArray.java b/src/main/java/com/reandroid/lib/arsc/array/PackageArray.java index 63f6f8a..a704b8d 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/PackageArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/PackageArray.java @@ -36,6 +36,25 @@ public class PackageArray extends BlockArray this.mPackageCount=packageCount; mPackageCount.setBlockLoad(this); } + public PackageBlock pickOne(){ + PackageBlock[] items=getChildes(); + if(items==null||items.length==0){ + return null; + } + if(items.length==1){ + return items[0]; + } + PackageBlock largest=null; + for(PackageBlock packageBlock:items){ + if(largest==null){ + largest=packageBlock; + }else if(packageBlock.getEntriesGroupMap().size() > + largest.getEntriesGroupMap().size()){ + largest=packageBlock; + } + } + return largest; + } public void sort(){ for(PackageBlock packageBlock:listItems()){ packageBlock.sortTypes(); diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java index c9bcca3..756d481 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java @@ -47,6 +47,9 @@ public class TableBlock extends BaseChunk implements JSONConvert { addChild(mTableStringPool); addChild(mPackageArray); } + public PackageBlock pickOne(){ + return getPackageArray().pickOne(); + } public void sortPackages(){ getPackageArray().sort(); } diff --git a/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java b/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java index 49512ec..5b7333a 100755 --- a/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java +++ b/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java @@ -35,6 +35,12 @@ import java.util.regex.Pattern; if(txt==null){ return null; } + if("@empty".equals(txt)){ + return new EncodeResult(ValueType.NULL, 0); + } + if("@null".equals(txt)){ + return new EncodeResult(ValueType.REFERENCE, 0); + } EncodeResult result=encodeColor(txt); if(result!=null){ return result; @@ -807,7 +813,7 @@ import java.util.regex.Pattern; 1.0f / (1 << 15) * MANTISSA_MULT, 1.0f / (1 << 23) * MANTISSA_MULT }; public static final Pattern PATTERN_COLOR = Pattern.compile("^#([0-9a-fA-F]{6,8})$"); - public static final Pattern PATTERN_DIMEN = Pattern.compile("^(-?)([0-9]+\\.[0-9E\\-+]+)([dimnpstx%]{0,3})$"); + public static final Pattern PATTERN_DIMEN = Pattern.compile("^(-?)([0-9]+\\.[0-9E+]+)([dimnpstx%]{0,3})$"); private static final Pattern PATTERN_INTEGER = Pattern.compile("^(-?)([0-9]+)$"); private static final Pattern PATTERN_HEX = Pattern.compile("^0x[0-9a-fA-F]+$"); public static final Pattern PATTERN_REFERENCE = Pattern.compile("^([?@])(([^\\s:@?/]+:)?)([^\\s:@?/]+)/([^\\s:@?/]+)$"); diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java b/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java index 1ad728c..fcca494 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java @@ -82,6 +82,10 @@ public class ResValueBagItem extends BaseResValueItem{ return getInt(OFFSET_ID); } + public void setTypeAndData(ValueType valueType, int data){ + setType(valueType); + setData(data); + } @Override public void setType(ValueType valueType){ byte type=0; diff --git a/src/main/java/com/reandroid/xml/source/XMLDocumentSource.java b/src/main/java/com/reandroid/xml/source/XMLDocumentSource.java new file mode 100644 index 0000000..20ede1a --- /dev/null +++ b/src/main/java/com/reandroid/xml/source/XMLDocumentSource.java @@ -0,0 +1,39 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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. + */ +package com.reandroid.xml.source; + +import com.reandroid.xml.XMLDocument; + +public class XMLDocumentSource implements XMLSource{ + private final String path; + private XMLDocument xmlDocument; + public XMLDocumentSource(String path, XMLDocument xmlDocument){ + this.path=path; + this.xmlDocument=xmlDocument; + } + @Override + public String getPath() { + return path; + } + @Override + public XMLDocument getXMLDocument(){ + return xmlDocument; + } + @Override + public void disposeXml() { + xmlDocument=null; + } +} diff --git a/src/main/java/com/reandroid/xml/source/XMLFileSource.java b/src/main/java/com/reandroid/xml/source/XMLFileSource.java new file mode 100644 index 0000000..5eac4f6 --- /dev/null +++ b/src/main/java/com/reandroid/xml/source/XMLFileSource.java @@ -0,0 +1,46 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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. + */ +package com.reandroid.xml.source; + +import com.reandroid.xml.XMLDocument; +import com.reandroid.xml.XMLException; + +import java.io.File; + +public class XMLFileSource implements XMLSource{ + private final String path; + private final File file; + public XMLFileSource(String path, File file){ + this.path=path; + this.file=file; + } + public File getFile(){ + return this.file; + } + @Override + public String getPath() { + return path; + } + @Override + public XMLDocument getXMLDocument() throws XMLException { + return XMLDocument.load(getFile()); + } + @Override + public void disposeXml() { + } + + +} diff --git a/src/main/java/com/reandroid/xml/source/XMLSource.java b/src/main/java/com/reandroid/xml/source/XMLSource.java new file mode 100644 index 0000000..687dc14 --- /dev/null +++ b/src/main/java/com/reandroid/xml/source/XMLSource.java @@ -0,0 +1,25 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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. + */ +package com.reandroid.xml.source; + +import com.reandroid.xml.XMLDocument; +import com.reandroid.xml.XMLException; + +public interface XMLSource { + public void disposeXml(); + public String getPath(); + public XMLDocument getXMLDocument() throws XMLException; +} diff --git a/src/main/java/com/reandroid/xml/source/XMLStringSource.java b/src/main/java/com/reandroid/xml/source/XMLStringSource.java new file mode 100644 index 0000000..baee62e --- /dev/null +++ b/src/main/java/com/reandroid/xml/source/XMLStringSource.java @@ -0,0 +1,43 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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. + */ +package com.reandroid.xml.source; + +import com.reandroid.xml.XMLDocument; +import com.reandroid.xml.XMLException; + +public class XMLStringSource implements XMLSource{ + private final String path; + private String xmlString; + public XMLStringSource(String path, String xmlString){ + this.path=path; + this.xmlString=xmlString; + } + public String getXmlString() { + return xmlString; + } + @Override + public String getPath() { + return path; + } + @Override + public XMLDocument getXMLDocument() throws XMLException { + return XMLDocument.load(xmlString); + } + @Override + public void disposeXml() { + this.xmlString=null; + } +}