Add alternative constructor

Add constructor that can use a bytestream so we can parse a DexFile
completely in memory
This commit is contained in:
Ryan Welton 2013-09-19 23:42:19 -04:00
parent a0c24f1c9f
commit 4ab8df84b0

View File

@ -278,18 +278,12 @@ public class DexFile
* @see #getPreserveSignedRegisters * @see #getPreserveSignedRegisters
* @throws IOException if an IOException occurs * @throws IOException if an IOException occurs
*/ */
public DexFile(File file, boolean preserveSignedRegisters, boolean skipInstructions) public DexFile(File file, boolean preserveSignedRegisters, boolean skipInstructions) throws IOException {
throws IOException {
this(preserveSignedRegisters, skipInstructions); this(preserveSignedRegisters, skipInstructions);
InputStream dexFileInputStream = null;
long fileLength;
byte[] magic = FileUtils.readFile(file, 0, 8);
InputStream inputStream = null;
Input in = null;
ZipFile zipFile = null; ZipFile zipFile = null;
byte[] magic = FileUtils.readFile(file, 0, 8);
try { long fileLength;
//do we have a zip file? //do we have a zip file?
if (magic[0] == 0x50 && magic[1] == 0x4B) { if (magic[0] == 0x50 && magic[1] == 0x4B) {
zipFile = new ZipFile(file); zipFile = new ZipFile(file);
@ -305,13 +299,8 @@ public class DexFile
} else if (fileLength > Integer.MAX_VALUE) { } else if (fileLength > Integer.MAX_VALUE) {
throw new RuntimeException("The classes.dex file in " + file.getName() + " is too large to read in"); throw new RuntimeException("The classes.dex file in " + file.getName() + " is too large to read in");
} }
inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry)); dexFileInputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry));
inputStream.mark(8);
for (int i=0; i<8; i++) {
magic[i] = (byte)inputStream.read();
}
inputStream.reset();
} else { } else {
fileLength = file.length(); fileLength = file.length();
if (fileLength < 40) { if (fileLength < 40) {
@ -322,7 +311,39 @@ public class DexFile
} else if (fileLength > Integer.MAX_VALUE) { } else if (fileLength > Integer.MAX_VALUE) {
throw new RuntimeException(file.getName() + " is too large to read in"); throw new RuntimeException(file.getName() + " is too large to read in");
} }
inputStream = new FileInputStream(file); dexFileInputStream = new FileInputStream(file);
}
intializeHelper(dexFileInputStream,fileLength,preserveSignedRegisters,skipInstructions);
}
/**
* Construct a new DexFile instance from a given input stream,
* and optionally keep track of any registers in the debug information that are signed,
* so they will be written in the same format.
* @param dexFileInputStream The dex file to read in
* @param dexFileLength length of the dex file to be read
* @param preserveSignedRegisters If true, keep track of any registers in the debug information
* that are signed, so they will be written in the same format.
* @param skipInstructions If true, skip the instructions in any code item.
* @see #getPreserveSignedRegisters
* @throws IOException if an IOException occurs
*/
public DexFile(InputStream dexFileInputStream, long dexFileLength, boolean preserveSignedRegisters, boolean skipInstructions)
throws IOException {
this(preserveSignedRegisters, skipInstructions);
intializeHelper(dexFileInputStream, dexFileLength, preserveSignedRegisters,skipInstructions);
}
private void intializeHelper(InputStream inputStream, long dexFileLength, boolean preserveSignedRegisters, boolean skipInstructions)
throws IOException {
Input in = null;
try {
byte[] magic = new byte[8];
int magicRead = inputStream.read(magic);
if(magicRead < 8){
throw new RuntimeException("Error reading Magic bytes");
} }
byte[] dexMagic, odexMagic; byte[] dexMagic, odexMagic;
@ -367,7 +388,7 @@ public class DexFile
odexDependencies = new OdexDependencies( odexDependencies = new OdexDependencies(
new ByteArrayInput(FileUtils.readStream(inputStream, odexHeader.depsLength))); new ByteArrayInput(FileUtils.readStream(inputStream, odexHeader.depsLength)));
} else if (isDex) { } else if (isDex) {
in = new ByteArrayInput(FileUtils.readStream(inputStream, (int)fileLength)); in = new ByteArrayInput(FileUtils.readStream(inputStream, (int)dexFileLength));
} else { } else {
StringBuffer sb = new StringBuffer("bad magic value:"); StringBuffer sb = new StringBuffer("bad magic value:");
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
@ -380,9 +401,6 @@ public class DexFile
if (inputStream != null) { if (inputStream != null) {
inputStream.close(); inputStream.close();
} }
if (zipFile != null) {
zipFile.close();
}
} }
ReadContext readContext = new ReadContext(); ReadContext readContext = new ReadContext();