mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-11 21:37:47 +01:00
Fixes #1099
- Moves Config --> Type - Moves Type -> TypeSpec - ResType -> ResTypeSpec - ResConfig -> ResType This is to match AOSP and ease the transitions/updates of new AOSP drops
This commit is contained in:
parent
1e5dc3006e
commit
6c4167fba4
@ -1,72 +0,0 @@
|
||||
/**
|
||||
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*
|
||||
* 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 brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.err.UndefinedResObject;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResConfig {
|
||||
private final ResConfigFlags mFlags;
|
||||
private final Map<ResResSpec, ResResource> mResources = new LinkedHashMap<ResResSpec, ResResource>();
|
||||
|
||||
public ResConfig(ResConfigFlags flags) {
|
||||
this.mFlags = flags;
|
||||
}
|
||||
|
||||
public Set<ResResource> listResources() {
|
||||
return new LinkedHashSet<ResResource>(mResources.values());
|
||||
}
|
||||
|
||||
public ResResource getResource(ResResSpec spec) throws AndrolibException {
|
||||
ResResource res = mResources.get(spec);
|
||||
if (res == null) {
|
||||
throw new UndefinedResObject(String.format(
|
||||
"resource: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Set<ResResSpec> listResSpecs() {
|
||||
return mResources.keySet();
|
||||
}
|
||||
|
||||
public ResConfigFlags getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public void addResource(ResResource res) throws AndrolibException {
|
||||
addResource(res, false);
|
||||
}
|
||||
|
||||
public void addResource(ResResource res, boolean overwrite)
|
||||
throws AndrolibException {
|
||||
ResResSpec spec = res.getResSpec();
|
||||
if (mResources.put(spec, res) != null && !overwrite) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple resources: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mFlags.toString();
|
||||
}
|
||||
}
|
@ -33,8 +33,8 @@ public class ResPackage {
|
||||
private final int mId;
|
||||
private final String mName;
|
||||
private final Map<ResID, ResResSpec> mResSpecs = new LinkedHashMap<ResID, ResResSpec>();
|
||||
private final Map<ResConfigFlags, ResConfig> mConfigs = new LinkedHashMap<ResConfigFlags, ResConfig>();
|
||||
private final Map<String, ResType> mTypes = new LinkedHashMap<String, ResType>();
|
||||
private final Map<ResConfigFlags, ResType> mConfigs = new LinkedHashMap<ResConfigFlags, ResType>();
|
||||
private final Map<String, ResTypeSpec> mTypes = new LinkedHashMap<String, ResTypeSpec>();
|
||||
private final Set<ResID> mSynthesizedRes = new HashSet<ResID>();
|
||||
|
||||
private ResValueFactory mValueFactory;
|
||||
@ -61,16 +61,16 @@ public class ResPackage {
|
||||
return spec;
|
||||
}
|
||||
|
||||
public List<ResConfig> getConfigs() {
|
||||
return new ArrayList<ResConfig>(mConfigs.values());
|
||||
public List<ResType> getConfigs() {
|
||||
return new ArrayList<ResType>(mConfigs.values());
|
||||
}
|
||||
|
||||
public boolean hasConfig(ResConfigFlags flags) {
|
||||
return mConfigs.containsKey(flags);
|
||||
}
|
||||
|
||||
public ResConfig getConfig(ResConfigFlags flags) throws AndrolibException {
|
||||
ResConfig config = mConfigs.get(flags);
|
||||
public ResType getConfig(ResConfigFlags flags) throws AndrolibException {
|
||||
ResType config = mConfigs.get(flags);
|
||||
if (config == null) {
|
||||
throw new UndefinedResObject("config: " + flags);
|
||||
}
|
||||
@ -81,26 +81,26 @@ public class ResPackage {
|
||||
return mResSpecs.size();
|
||||
}
|
||||
|
||||
public ResConfig getOrCreateConfig(ResConfigFlags flags)
|
||||
public ResType getOrCreateConfig(ResConfigFlags flags)
|
||||
throws AndrolibException {
|
||||
ResConfig config = mConfigs.get(flags);
|
||||
ResType config = mConfigs.get(flags);
|
||||
if (config == null) {
|
||||
config = new ResConfig(flags);
|
||||
config = new ResType(flags);
|
||||
mConfigs.put(flags, config);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public List<ResType> listTypes() {
|
||||
return new ArrayList<ResType>(mTypes.values());
|
||||
public List<ResTypeSpec> listTypes() {
|
||||
return new ArrayList<ResTypeSpec>(mTypes.values());
|
||||
}
|
||||
|
||||
public boolean hasType(String typeName) {
|
||||
return mTypes.containsKey(typeName);
|
||||
}
|
||||
|
||||
public ResType getType(String typeName) throws AndrolibException {
|
||||
ResType type = mTypes.get(typeName);
|
||||
public ResTypeSpec getType(String typeName) throws AndrolibException {
|
||||
ResTypeSpec type = mTypes.get(typeName);
|
||||
if (type == null) {
|
||||
throw new UndefinedResObject("type: " + typeName);
|
||||
}
|
||||
@ -120,13 +120,13 @@ public class ResPackage {
|
||||
}
|
||||
|
||||
public Collection<ResValuesFile> listValuesFiles() {
|
||||
Map<Duo<ResType, ResConfig>, ResValuesFile> ret = new HashMap<Duo<ResType, ResConfig>, ResValuesFile>();
|
||||
Map<Duo<ResTypeSpec, ResType>, ResValuesFile> ret = new HashMap<Duo<ResTypeSpec, ResType>, ResValuesFile>();
|
||||
for (ResResSpec spec : mResSpecs.values()) {
|
||||
for (ResResource res : spec.listResources()) {
|
||||
if (res.getValue() instanceof ResValuesXmlSerializable) {
|
||||
ResType type = res.getResSpec().getType();
|
||||
ResConfig config = res.getConfig();
|
||||
Duo<ResType, ResConfig> key = new Duo<ResType, ResConfig>(
|
||||
ResTypeSpec type = res.getResSpec().getType();
|
||||
ResType config = res.getConfig();
|
||||
Duo<ResTypeSpec, ResType> key = new Duo<ResTypeSpec, ResType>(
|
||||
type, config);
|
||||
ResValuesFile values = ret.get(key);
|
||||
if (values == null) {
|
||||
@ -162,13 +162,13 @@ public class ResPackage {
|
||||
}
|
||||
}
|
||||
|
||||
public void addConfig(ResConfig config) throws AndrolibException {
|
||||
public void addConfig(ResType config) throws AndrolibException {
|
||||
if (mConfigs.put(config.getFlags(), config) != null) {
|
||||
throw new AndrolibException("Multiple configs: " + config);
|
||||
}
|
||||
}
|
||||
|
||||
public void addType(ResType type) throws AndrolibException {
|
||||
public void addType(ResTypeSpec type) throws AndrolibException {
|
||||
if (mTypes.containsKey(type.getName())) {
|
||||
LOGGER.warning("Multiple types detected! " + type + " ignored!");
|
||||
} else {
|
||||
|
@ -28,10 +28,10 @@ public class ResResSpec {
|
||||
private final ResID mId;
|
||||
private final String mName;
|
||||
private final ResPackage mPackage;
|
||||
private final ResType mType;
|
||||
private final ResTypeSpec mType;
|
||||
private final Map<ResConfigFlags, ResResource> mResources = new LinkedHashMap<ResConfigFlags, ResResource>();
|
||||
|
||||
public ResResSpec(ResID id, String name, ResPackage pkg, ResType type) {
|
||||
public ResResSpec(ResID id, String name, ResPackage pkg, ResTypeSpec type) {
|
||||
this.mId = id;
|
||||
this.mName = name;
|
||||
this.mPackage = pkg;
|
||||
@ -42,7 +42,7 @@ public class ResResSpec {
|
||||
return new LinkedHashSet<ResResource>(mResources.values());
|
||||
}
|
||||
|
||||
public ResResource getResource(ResConfig config) throws AndrolibException {
|
||||
public ResResource getResource(ResType config) throws AndrolibException {
|
||||
return getResource(config.getFlags());
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public class ResResSpec {
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean hasResource(ResConfig config) {
|
||||
public boolean hasResource(ResType config) {
|
||||
return hasResource(config.getFlags());
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ public class ResResSpec {
|
||||
return mPackage;
|
||||
}
|
||||
|
||||
public ResType getType() {
|
||||
public ResTypeSpec getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@ import brut.androlib.res.data.value.ResValue;
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResResource {
|
||||
private final ResConfig mConfig;
|
||||
private final ResType mConfig;
|
||||
private final ResResSpec mResSpec;
|
||||
private final ResValue mValue;
|
||||
|
||||
public ResResource(ResConfig config, ResResSpec spec, ResValue value) {
|
||||
public ResResource(ResType config, ResResSpec spec, ResValue value) {
|
||||
this.mConfig = config;
|
||||
this.mResSpec = spec;
|
||||
this.mValue = value;
|
||||
@ -38,7 +38,7 @@ public class ResResource {
|
||||
+ mConfig.getFlags().getQualifiers() + "/" + mResSpec.getName();
|
||||
}
|
||||
|
||||
public ResConfig getConfig() {
|
||||
public ResType getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
|
@ -23,49 +23,50 @@ import java.util.*;
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public final class ResType {
|
||||
private final String mName;
|
||||
private final Map<String, ResResSpec> mResSpecs = new LinkedHashMap<String, ResResSpec>();
|
||||
public class ResType {
|
||||
private final ResConfigFlags mFlags;
|
||||
private final Map<ResResSpec, ResResource> mResources = new LinkedHashMap<ResResSpec, ResResource>();
|
||||
|
||||
private final ResTable mResTable;
|
||||
private final ResPackage mPackage;
|
||||
|
||||
public ResType(String name, ResTable resTable, ResPackage package_) {
|
||||
this.mName = name;
|
||||
this.mResTable = resTable;
|
||||
this.mPackage = package_;
|
||||
public ResType(ResConfigFlags flags) {
|
||||
this.mFlags = flags;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
public Set<ResResource> listResources() {
|
||||
return new LinkedHashSet<ResResource>(mResources.values());
|
||||
}
|
||||
|
||||
public boolean isString() {
|
||||
return mName.equalsIgnoreCase("string");
|
||||
public ResResource getResource(ResResSpec spec) throws AndrolibException {
|
||||
ResResource res = mResources.get(spec);
|
||||
if (res == null) {
|
||||
throw new UndefinedResObject(String.format(
|
||||
"resource: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Set<ResResSpec> listResSpecs() {
|
||||
return new LinkedHashSet<ResResSpec>(mResSpecs.values());
|
||||
return mResources.keySet();
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(String name) throws AndrolibException {
|
||||
ResResSpec spec = mResSpecs.get(name);
|
||||
if (spec == null) {
|
||||
throw new UndefinedResObject(String.format("resource spec: %s/%s",
|
||||
getName(), name));
|
||||
}
|
||||
return spec;
|
||||
public ResConfigFlags getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public void addResSpec(ResResSpec spec) throws AndrolibException {
|
||||
if (mResSpecs.put(spec.getName(), spec) != null) {
|
||||
public void addResource(ResResource res) throws AndrolibException {
|
||||
addResource(res, false);
|
||||
}
|
||||
|
||||
public void addResource(ResResource res, boolean overwrite)
|
||||
throws AndrolibException {
|
||||
ResResSpec spec = res.getResSpec();
|
||||
if (mResources.put(spec, res) != null && !overwrite) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple res specs: %s/%s", getName(), spec.getName()));
|
||||
"Multiple resources: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mName;
|
||||
return mFlags.toString();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*
|
||||
* 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 brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.err.UndefinedResObject;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public final class ResTypeSpec {
|
||||
private final String mName;
|
||||
private final Map<String, ResResSpec> mResSpecs = new LinkedHashMap<String, ResResSpec>();
|
||||
|
||||
private final ResTable mResTable;
|
||||
private final ResPackage mPackage;
|
||||
|
||||
public ResTypeSpec(String name, ResTable resTable, ResPackage package_) {
|
||||
this.mName = name;
|
||||
this.mResTable = resTable;
|
||||
this.mPackage = package_;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public boolean isString() {
|
||||
return mName.equalsIgnoreCase("string");
|
||||
}
|
||||
|
||||
public Set<ResResSpec> listResSpecs() {
|
||||
return new LinkedHashSet<ResResSpec>(mResSpecs.values());
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(String name) throws AndrolibException {
|
||||
ResResSpec spec = mResSpecs.get(name);
|
||||
if (spec == null) {
|
||||
throw new UndefinedResObject(String.format("resource spec: %s/%s",
|
||||
getName(), name));
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
public void addResSpec(ResResSpec spec) throws AndrolibException {
|
||||
if (mResSpecs.put(spec.getName(), spec) != null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple res specs: %s/%s", getName(), spec.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mName;
|
||||
}
|
||||
}
|
@ -24,11 +24,11 @@ import java.util.Set;
|
||||
*/
|
||||
public class ResValuesFile {
|
||||
private final ResPackage mPackage;
|
||||
private final ResType mType;
|
||||
private final ResConfig mConfig;
|
||||
private final ResTypeSpec mType;
|
||||
private final ResType mConfig;
|
||||
private final Set<ResResource> mResources = new LinkedHashSet<ResResource>();
|
||||
|
||||
public ResValuesFile(ResPackage pkg, ResType type, ResConfig config) {
|
||||
public ResValuesFile(ResPackage pkg, ResTypeSpec type, ResType config) {
|
||||
this.mPackage = pkg;
|
||||
this.mType = type;
|
||||
this.mConfig = config;
|
||||
@ -44,11 +44,11 @@ public class ResValuesFile {
|
||||
return mResources;
|
||||
}
|
||||
|
||||
public ResType getType() {
|
||||
public ResTypeSpec getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public ResConfig getConfig() {
|
||||
public ResType getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class ARSCDecoder {
|
||||
throws AndrolibException {
|
||||
try {
|
||||
ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, findFlagsOffsets, keepBroken);
|
||||
ResPackage[] pkgs = decoder.readTable();
|
||||
ResPackage[] pkgs = decoder.readTableHeader();
|
||||
return new ARSCData(pkgs, decoder.mFlagsOffsets == null
|
||||
? null
|
||||
: decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), resTable);
|
||||
@ -66,7 +66,7 @@ public class ARSCDecoder {
|
||||
mKeepBroken = keepBroken;
|
||||
}
|
||||
|
||||
private ResPackage[] readTable() throws IOException, AndrolibException {
|
||||
private ResPackage[] readTableHeader() throws IOException, AndrolibException {
|
||||
nextChunkCheckType(Header.TYPE_TABLE);
|
||||
int packageCount = mIn.readInt();
|
||||
|
||||
@ -75,12 +75,12 @@ public class ARSCDecoder {
|
||||
|
||||
nextChunk();
|
||||
for (int i = 0; i < packageCount; i++) {
|
||||
packages[i] = readPackage();
|
||||
packages[i] = readTablePackage();
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
private ResPackage readPackage() throws IOException, AndrolibException {
|
||||
private ResPackage readTablePackage() throws IOException, AndrolibException {
|
||||
checkChunkType(Header.TYPE_PACKAGE);
|
||||
int id = (byte) mIn.readInt();
|
||||
|
||||
@ -96,10 +96,10 @@ public class ARSCDecoder {
|
||||
}
|
||||
|
||||
String name = mIn.readNullEndedString(128, true);
|
||||
/* typeStrings */mIn.skipInt();
|
||||
/* lastPublicType */mIn.skipInt();
|
||||
/* keyStrings */mIn.skipInt();
|
||||
/* lastPublicKey */mIn.skipInt();
|
||||
/* typeStrings */mIn.skipInt();
|
||||
/* lastPublicType */mIn.skipInt();
|
||||
/* keyStrings */mIn.skipInt();
|
||||
/* lastPublicKey */mIn.skipInt();
|
||||
|
||||
mTypeNames = StringBlock.read(mIn);
|
||||
mSpecNames = StringBlock.read(mIn);
|
||||
@ -112,8 +112,8 @@ public class ARSCDecoder {
|
||||
readLibraryType();
|
||||
}
|
||||
|
||||
while (mHeader.type == Header.TYPE_TYPE) {
|
||||
readType();
|
||||
while (mHeader.type == Header.TYPE_SPEC_TYPE) {
|
||||
readTableTypeSpec();
|
||||
}
|
||||
|
||||
return mPkg;
|
||||
@ -132,13 +132,13 @@ public class ARSCDecoder {
|
||||
LOGGER.info(String.format("Decoding Shared Library (%s), pkgId: %d", packageName, packageId));
|
||||
}
|
||||
|
||||
while(nextChunk().type == Header.TYPE_CONFIG) {
|
||||
readConfig();
|
||||
while(nextChunk().type == Header.TYPE_TYPE) {
|
||||
readTableTypeSpec();
|
||||
}
|
||||
}
|
||||
|
||||
private ResType readType() throws AndrolibException, IOException {
|
||||
checkChunkType(Header.TYPE_TYPE);
|
||||
private ResTypeSpec readTableTypeSpec() throws AndrolibException, IOException {
|
||||
checkChunkType(Header.TYPE_SPEC_TYPE);
|
||||
byte id = mIn.readByte();
|
||||
mIn.skipBytes(3);
|
||||
int entryCount = mIn.readInt();
|
||||
@ -152,29 +152,30 @@ public class ARSCDecoder {
|
||||
/* flags */mIn.skipBytes(entryCount * 4);
|
||||
|
||||
mResId = (0xff000000 & mResId) | id << 16;
|
||||
mType = new ResType(mTypeNames.getString(id - 1), mResTable, mPkg);
|
||||
mPkg.addType(mType);
|
||||
mTypeSpec = new ResTypeSpec(mTypeNames.getString(id - 1), mResTable, mPkg);
|
||||
mPkg.addType(mTypeSpec);
|
||||
|
||||
while (nextChunk().type == Header.TYPE_CONFIG) {
|
||||
readConfig();
|
||||
while (nextChunk().type == Header.TYPE_TYPE) {
|
||||
readTableType();
|
||||
}
|
||||
|
||||
addMissingResSpecs();
|
||||
|
||||
return mType;
|
||||
return mTypeSpec;
|
||||
}
|
||||
|
||||
private ResConfig readConfig() throws IOException, AndrolibException {
|
||||
checkChunkType(Header.TYPE_CONFIG);
|
||||
/* typeId */mIn.skipInt();
|
||||
private ResType readTableType() throws IOException, AndrolibException {
|
||||
checkChunkType(Header.TYPE_TYPE);
|
||||
/* typeId */mIn.skipBytes(1);
|
||||
/* res0, res1 */mIn.skipBytes(3);
|
||||
int entryCount = mIn.readInt();
|
||||
/* entriesStart */mIn.skipInt();
|
||||
/* entriesStart */mIn.skipInt();
|
||||
|
||||
ResConfigFlags flags = readConfigFlags();
|
||||
int[] entryOffsets = mIn.readIntArray(entryCount);
|
||||
|
||||
if (flags.isInvalid) {
|
||||
String resName = mType.getName() + flags.getQualifiers();
|
||||
String resName = mTypeSpec.getName() + flags.getQualifiers();
|
||||
if (mKeepBroken) {
|
||||
LOGGER.warning("Invalid config flags detected: " + resName);
|
||||
} else {
|
||||
@ -182,7 +183,7 @@ public class ARSCDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
mConfig = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
|
||||
mType = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
|
||||
|
||||
for (int i = 0; i < entryOffsets.length; i++) {
|
||||
if (entryOffsets[i] != -1) {
|
||||
@ -192,7 +193,7 @@ public class ARSCDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
return mConfig;
|
||||
return mType;
|
||||
}
|
||||
|
||||
private void readEntry() throws IOException, AndrolibException {
|
||||
@ -202,10 +203,10 @@ public class ARSCDecoder {
|
||||
|
||||
ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() : readComplexEntry();
|
||||
|
||||
if (mType.isString() && value instanceof ResFileValue) {
|
||||
if (mTypeSpec.isString() && value instanceof ResFileValue) {
|
||||
value = new ResStringValue(value.toString(), ((ResFileValue) value).getRawIntValue());
|
||||
}
|
||||
if (mConfig == null) {
|
||||
if (mType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,19 +215,18 @@ public class ARSCDecoder {
|
||||
if (mPkg.hasResSpec(resId)) {
|
||||
spec = mPkg.getResSpec(resId);
|
||||
} else {
|
||||
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mType);
|
||||
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mTypeSpec);
|
||||
mPkg.addResSpec(spec);
|
||||
mType.addResSpec(spec);
|
||||
mTypeSpec.addResSpec(spec);
|
||||
}
|
||||
ResResource res = new ResResource(mConfig, spec, value);
|
||||
ResResource res = new ResResource(mType, spec, value);
|
||||
|
||||
mConfig.addResource(res);
|
||||
mType.addResource(res);
|
||||
spec.addResource(res);
|
||||
mPkg.addResource(res);
|
||||
}
|
||||
|
||||
private ResBagValue readComplexEntry() throws IOException,
|
||||
AndrolibException {
|
||||
private ResBagValue readComplexEntry() throws IOException, AndrolibException {
|
||||
int parent = mIn.readInt();
|
||||
int count = mIn.readInt();
|
||||
|
||||
@ -394,19 +394,19 @@ public class ARSCDecoder {
|
||||
continue;
|
||||
}
|
||||
|
||||
ResResSpec spec = new ResResSpec(new ResID(resId | i), String.format("APKTOOL_DUMMY_%04x", i), mPkg, mType);
|
||||
ResResSpec spec = new ResResSpec(new ResID(resId | i), String.format("APKTOOL_DUMMY_%04x", i), mPkg, mTypeSpec);
|
||||
mPkg.addResSpec(spec);
|
||||
mType.addResSpec(spec);
|
||||
mTypeSpec.addResSpec(spec);
|
||||
|
||||
if (mConfig == null) {
|
||||
mConfig = mPkg.getOrCreateConfig(new ResConfigFlags());
|
||||
if (mType == null) {
|
||||
mType = mPkg.getOrCreateConfig(new ResConfigFlags());
|
||||
}
|
||||
|
||||
ResValue value = new ResBoolValue(false, 0, null);
|
||||
ResResource res = new ResResource(mConfig, spec, value);
|
||||
ResResource res = new ResResource(mType, spec, value);
|
||||
|
||||
mPkg.addResource(res);
|
||||
mConfig.addResource(res);
|
||||
mType.addResource(res);
|
||||
spec.addResource(res);
|
||||
}
|
||||
}
|
||||
@ -439,8 +439,8 @@ public class ARSCDecoder {
|
||||
private StringBlock mTypeNames;
|
||||
private StringBlock mSpecNames;
|
||||
private ResPackage mPkg;
|
||||
private ResTypeSpec mTypeSpec;
|
||||
private ResType mType;
|
||||
private ResConfig mConfig;
|
||||
private int mResId;
|
||||
private boolean[] mMissingResSpecs;
|
||||
|
||||
@ -468,8 +468,7 @@ public class ARSCDecoder {
|
||||
}
|
||||
|
||||
public final static short TYPE_NONE = -1, TYPE_TABLE = 0x0002,
|
||||
TYPE_PACKAGE = 0x0200, TYPE_TYPE = 0x0202, TYPE_LIBRARY = 0x0203,
|
||||
TYPE_CONFIG = 0x0201;
|
||||
TYPE_PACKAGE = 0x0200, TYPE_TYPE = 0x0201, TYPE_SPEC_TYPE = 0x0202, TYPE_LIBRARY = 0x0203;
|
||||
}
|
||||
|
||||
public static class FlagsOffset {
|
||||
@ -515,20 +514,15 @@ public class ARSCDecoder {
|
||||
}
|
||||
|
||||
public int findPackageWithMostResSpecs() {
|
||||
int count = -1;
|
||||
int count = mPackages[0].getResSpecCount();
|
||||
int id = 0;
|
||||
|
||||
// set starting point to package id 0.
|
||||
count = mPackages[0].getResSpecCount();
|
||||
|
||||
// loop through packages looking for largest
|
||||
for (int i = 0; i < mPackages.length; i++) {
|
||||
if (mPackages[i].getResSpecCount() >= count) {
|
||||
count = mPackages[i].getResSpecCount();
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user