ARSCDecoder: modified interface to be more flexible - added ARSCData class.

This commit is contained in:
Ryszard Wiśniewski 2010-06-02 14:51:33 +02:00
parent 58e7d6960f
commit 5fda5dbf00
2 changed files with 52 additions and 16 deletions

View File

@ -294,8 +294,8 @@ final public class AndrolibResources {
ResTable resTable) throws AndrolibException { ResTable resTable) throws AndrolibException {
try { try {
return ARSCDecoder.decode( return ARSCDecoder.decode(
apkFile.getDirectory().getFileInput("resources.arsc"), apkFile.getDirectory().getFileInput("resources.arsc"), false,
resTable); resTable).getPackages();
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException( throw new AndrolibException(
"Could not load resources.arsc from file: " + apkFile, ex); "Could not load resources.arsc from file: " + apkFile, ex);
@ -378,7 +378,8 @@ final public class AndrolibResources {
public void publicizeResources(byte[] arsc) throws AndrolibException { public void publicizeResources(byte[] arsc) throws AndrolibException {
for (FlagsOffset flags : for (FlagsOffset flags :
ARSCDecoder.findFlagsOffsets(new ByteArrayInputStream(arsc))) { ARSCDecoder.decode(new ByteArrayInputStream(arsc), true)
.getFlagsOffsets()) {
int offset = flags.offset + 3; int offset = flags.offset + 3;
int end = offset + 4 * flags.count; int end = offset + 4 * flags.count;
while(offset < end) { while(offset < end) {

View File

@ -32,26 +32,26 @@ import org.apache.commons.io.input.CountingInputStream;
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ARSCDecoder { public class ARSCDecoder {
public static ResPackage[] decode(InputStream arscStream, ResTable resTable) public static ARSCData decode(InputStream arscStream,
throws AndrolibException { boolean findFlagsOffsets) throws AndrolibException {
try { return decode(arscStream, findFlagsOffsets, new ResTable());
return new ARSCDecoder(arscStream, resTable, false).readTable();
} catch (IOException ex) {
throw new AndrolibException("Could not decode arsc file", ex);
}
} }
public static List<FlagsOffset> findFlagsOffsets(InputStream arscStream) public static ARSCData decode(InputStream arscStream,
boolean findFlagsOffsets, ResTable resTable)
throws AndrolibException { throws AndrolibException {
try { try {
ResTable resTable = new ResTable(); ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable,
ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, true); findFlagsOffsets);
decoder.readTable(); ResPackage[] pkgs = decoder.readTable();
return decoder.mFlagsOffsets; return new ARSCData(
pkgs,
decoder.mFlagsOffsets == null ? null :
decoder.mFlagsOffsets.toArray(new FlagsOffset[0]),
resTable);
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException("Could not decode arsc file", ex); throw new AndrolibException("Could not decode arsc file", ex);
} }
} }
private ARSCDecoder(InputStream arscStream, ResTable resTable, private ARSCDecoder(InputStream arscStream, ResTable resTable,
@ -357,4 +357,39 @@ public class ARSCDecoder {
private static final Logger LOGGER = private static final Logger LOGGER =
Logger.getLogger(ARSCDecoder.class.getName()); Logger.getLogger(ARSCDecoder.class.getName());
public static class ARSCData {
public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets,
ResTable resTable) {
mPackages = packages;
mFlagsOffsets = flagsOffsets;
mResTable = resTable;
}
public FlagsOffset[] getFlagsOffsets() {
return mFlagsOffsets;
}
public ResPackage[] getPackages() {
return mPackages;
}
public ResPackage getOnePackage() throws AndrolibException {
if (mPackages.length != 1) {
throw new AndrolibException(
"Arsc file contains zero or multiple packages");
}
return mPackages[0];
}
public ResTable getResTable() {
return mResTable;
}
private final ResPackage[] mPackages;
private final FlagsOffset[] mFlagsOffsets;
private final ResTable mResTable;
}
} }