mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-29 22:04:25 +02:00
better hex conversion
This commit is contained in:
parent
1b240b2281
commit
f5ec1381a4
@ -16,6 +16,7 @@
|
||||
package com.reandroid.apk;
|
||||
|
||||
import com.reandroid.archive.InputSource;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@ -148,7 +149,7 @@ public class PathSanitizer {
|
||||
}
|
||||
private static String createUniqueName(String name){
|
||||
int hash = name.hashCode();
|
||||
return String.format("alias_%08x", hash).toLowerCase();
|
||||
return "alias_" + HexUtil.toHexNoPrefix8(hash);
|
||||
}
|
||||
private static boolean isGoodSimpleName(String name){
|
||||
if(name==null){
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2022 github.com/REAndroid
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -19,6 +19,7 @@ import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.pool.SpecStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.util.ResNameMap;
|
||||
import com.reandroid.json.JSONArray;
|
||||
import com.reandroid.json.JSONObject;
|
||||
@ -379,7 +380,7 @@ import java.util.*;
|
||||
type.add(entry);
|
||||
}
|
||||
public String getHexId(){
|
||||
return String.format("0x%02x", id);
|
||||
return HexUtil.toHex2(id);
|
||||
}
|
||||
public JSONObject toJson(){
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
@ -575,7 +576,7 @@ import java.util.*;
|
||||
return entryMap.get(entryId);
|
||||
}
|
||||
public String getHexId(){
|
||||
return String.format("0x%02x", id);
|
||||
return HexUtil.toHex2(id);
|
||||
}
|
||||
public void add(Entry entry){
|
||||
if(entry==null){
|
||||
@ -733,7 +734,7 @@ import java.util.*;
|
||||
| (getEntryId() & 0xffff);
|
||||
}
|
||||
public String getHexId(){
|
||||
return String.format("0x%08x", getResourceId());
|
||||
return HexUtil.toHex8(getResourceId());
|
||||
}
|
||||
|
||||
public void writeXml(String indent, Writer writer) throws IOException{
|
||||
|
@ -21,6 +21,7 @@ import com.reandroid.arsc.chunk.StagedAlias;
|
||||
import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
@ -73,7 +74,7 @@ public class TableBlockJson {
|
||||
private String getFileName(TypeBlock typeBlock){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(String.format("%03d-", typeBlock.getIndex()));
|
||||
builder.append(String.format("0x%02x", typeBlock.getTypeId()));
|
||||
builder.append(HexUtil.toHex2(typeBlock.getTypeId()));
|
||||
String name= typeBlock.getTypeName();
|
||||
builder.append('-').append(name);
|
||||
builder.append(typeBlock.getResConfig().getQualifiers());
|
||||
@ -81,7 +82,7 @@ public class TableBlockJson {
|
||||
}
|
||||
private String getDirName(PackageBlock packageBlock){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(String.format("0x%02x", packageBlock.getId()));
|
||||
builder.append(HexUtil.toHex2((byte) packageBlock.getId()));
|
||||
builder.append("-");
|
||||
builder.append(packageBlock.getIndex());
|
||||
String name= ApkUtil.sanitizeForFileName(packageBlock.getName());
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.apk.xmldecoder;
|
||||
|
||||
import com.reandroid.apk.XmlHelper;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.ResTableMapEntry;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
@ -58,7 +59,7 @@ class BagDecoderAttr<OUTPUT> extends BagDecoder<OUTPUT>{
|
||||
int rawVal = item.getData();
|
||||
String value;
|
||||
if(item.getBagItem().getValueType() == ValueType.INT_HEX){
|
||||
value = String.format("0x%08x", rawVal);
|
||||
value = HexUtil.toHex8(rawVal);
|
||||
}else {
|
||||
value = String.valueOf(rawVal);
|
||||
}
|
||||
|
@ -1,359 +1,360 @@
|
||||
/*
|
||||
* 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.apk.xmlencoder;
|
||||
/*
|
||||
* 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.apk.xmlencoder;
|
||||
|
||||
import com.reandroid.apk.APKLogger;
|
||||
import com.reandroid.apk.FrameworkApk;
|
||||
import com.reandroid.apk.ResourceIds;
|
||||
import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.item.SpecString;
|
||||
import com.reandroid.arsc.util.FrameworkTable;
|
||||
import com.reandroid.arsc.util.ResNameMap;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.common.Frameworks;
|
||||
import com.reandroid.apk.APKLogger;
|
||||
import com.reandroid.apk.FrameworkApk;
|
||||
import com.reandroid.apk.ResourceIds;
|
||||
import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.item.SpecString;
|
||||
import com.reandroid.arsc.util.FrameworkTable;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.util.ResNameMap;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.common.Frameworks;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class EncodeMaterials {
|
||||
private final Set<ResourceIds.Table.Package> packageIdSet = new HashSet<>();
|
||||
private PackageBlock currentPackage;
|
||||
private final Set<FrameworkTable> frameworkTables = new HashSet<>();
|
||||
private APKLogger apkLogger;
|
||||
private boolean mForceCreateNamespaces = true;
|
||||
private Set<String> mFrameworkPackageNames;
|
||||
private final ResNameMap<Entry> mLocalResNameMap = new ResNameMap<>();
|
||||
public EncodeMaterials(){
|
||||
}
|
||||
public SpecString getSpecString(String name){
|
||||
return currentPackage.getSpecStringPool()
|
||||
.get(name)
|
||||
.get(0);
|
||||
}
|
||||
public Entry getAttributeBlock(String refString){
|
||||
String type = "attr";
|
||||
Entry entry = getAttributeBlock(type, refString);
|
||||
if(entry == null){
|
||||
type = "^attr-private";
|
||||
entry = getAttributeBlock(type, refString);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
private Entry getAttributeBlock(String type, String refString){
|
||||
String packageName = null;
|
||||
String name = refString;
|
||||
int i=refString.lastIndexOf(':');
|
||||
if(i>=0){
|
||||
packageName=refString.substring(0, i);
|
||||
name=refString.substring(i+1);
|
||||
}
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
public class EncodeMaterials {
|
||||
private final Set<ResourceIds.Table.Package> packageIdSet = new HashSet<>();
|
||||
private PackageBlock currentPackage;
|
||||
private final Set<FrameworkTable> frameworkTables = new HashSet<>();
|
||||
private APKLogger apkLogger;
|
||||
private boolean mForceCreateNamespaces = true;
|
||||
private Set<String> mFrameworkPackageNames;
|
||||
private final ResNameMap<Entry> mLocalResNameMap = new ResNameMap<>();
|
||||
public EncodeMaterials(){
|
||||
}
|
||||
public SpecString getSpecString(String name){
|
||||
return currentPackage.getSpecStringPool()
|
||||
.get(name)
|
||||
.get(0);
|
||||
}
|
||||
public Entry getAttributeBlock(String refString){
|
||||
String type = "attr";
|
||||
Entry entry = getAttributeBlock(type, refString);
|
||||
if(entry == null){
|
||||
type = "^attr-private";
|
||||
entry = getAttributeBlock(type, refString);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
private Entry getAttributeBlock(String type, String refString){
|
||||
String packageName = null;
|
||||
String name = refString;
|
||||
int i=refString.lastIndexOf(':');
|
||||
if(i>=0){
|
||||
packageName=refString.substring(0, i);
|
||||
name=refString.substring(i+1);
|
||||
}
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
|
||||
return getLocalEntry(type, name);
|
||||
}
|
||||
return getFrameworkEntry(type, name);
|
||||
}
|
||||
public int resolveReference(String refString){
|
||||
if("@null".equals(refString)){
|
||||
return 0;
|
||||
}
|
||||
Matcher matcher = ValueDecoder.PATTERN_REFERENCE.matcher(refString);
|
||||
if(!matcher.find()){
|
||||
ValueDecoder.EncodeResult ref = ValueDecoder.encodeHexReference(refString);
|
||||
if(ref!=null){
|
||||
return ref.value;
|
||||
}
|
||||
ref = ValueDecoder.encodeNullReference(refString);
|
||||
if(ref!=null){
|
||||
return ref.value;
|
||||
}
|
||||
throw new EncodeException(
|
||||
"Not proper reference string: '"+refString+"'");
|
||||
}
|
||||
String prefix=matcher.group(1);
|
||||
String packageName = matcher.group(2);
|
||||
if(packageName!=null && packageName.endsWith(":")){
|
||||
packageName=packageName.substring(0, packageName.length()-1);
|
||||
}
|
||||
String type = matcher.group(4);
|
||||
String name = matcher.group(5);
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
return resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageName, type, name);
|
||||
}
|
||||
public int resolveLocalResourceId(String type, String name){
|
||||
for(ResourceIds.Table.Package pkg:packageIdSet){
|
||||
Integer resId = pkg.getResourceId(type, name);
|
||||
if(resId!=null){
|
||||
return resId;
|
||||
}
|
||||
}
|
||||
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
||||
if(entryGroup!=null){
|
||||
return entryGroup.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Local entry not found: " +
|
||||
"type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(String packageName, String type, String name){
|
||||
Entry entry = getFrameworkEntry(packageName, type, name);
|
||||
if(entry !=null){
|
||||
return entry.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"package="+packageName+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(int packageId, String type, String name){
|
||||
Entry entry = getFrameworkEntry(packageId, type, name);
|
||||
if(entry !=null){
|
||||
return entry.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"packageId="+String.format("0x%02x", packageId)+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public EntryGroup getLocalEntryGroup(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
for(EntryGroup entryGroup : packageBlock.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Entry getLocalEntry(String type, String name){
|
||||
Entry entry =mLocalResNameMap.get(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
loadLocalEntryMap(type);
|
||||
entry =mLocalResNameMap.get(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
entry = searchLocalEntry(type, name);
|
||||
if(entry !=null){
|
||||
mLocalResNameMap.add(type, name, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
private Entry searchLocalEntry(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup.pickOne();
|
||||
}
|
||||
}
|
||||
SpecTypePair specTypePair=currentPackage.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
if(name.equals(entry.getName())){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
if(packageBlock==currentPackage){
|
||||
continue;
|
||||
}
|
||||
specTypePair=packageBlock.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
if(name.equals(entry.getName())){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private void loadLocalEntryMap(String type){
|
||||
ResNameMap<Entry> localMap = mLocalResNameMap;
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
SpecTypePair specTypePair=packageBlock.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
localMap.add(entry.getTypeName(),
|
||||
entry.getName(), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public Entry getFrameworkEntry(String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean isFrameworkPackageName(String packageName){
|
||||
return getFrameworkPackageNames().contains(packageName);
|
||||
}
|
||||
private Set<String> getFrameworkPackageNames(){
|
||||
if(mFrameworkPackageNames!=null){
|
||||
return mFrameworkPackageNames;
|
||||
}
|
||||
Set<String> results=new HashSet<>();
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
results.add(packageBlock.getName());
|
||||
}
|
||||
}
|
||||
mFrameworkPackageNames=results;
|
||||
return results;
|
||||
}
|
||||
public Entry getFrameworkEntry(String packageName, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageName.equals(packageBlock.getName())){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Entry getFrameworkEntry(int packageId, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageId==packageBlock.getId()){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EncodeMaterials setForceCreateNamespaces(boolean force) {
|
||||
this.mForceCreateNamespaces = force;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addPackageIds(ResourceIds.Table.Package packageIds) {
|
||||
packageIds.loadEntryMap();
|
||||
this.packageIdSet.add(packageIds);
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setCurrentPackage(PackageBlock currentPackage) {
|
||||
this.currentPackage = currentPackage;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addFramework(FrameworkApk frameworkApk) {
|
||||
if(frameworkApk!=null){
|
||||
addFramework(frameworkApk.getTableBlock());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addFramework(FrameworkTable frameworkTable) {
|
||||
frameworkTable.loadResourceNameMap();
|
||||
this.frameworkTables.add(frameworkTable);
|
||||
this.mFrameworkPackageNames=null;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setAPKLogger(APKLogger logger) {
|
||||
this.apkLogger = logger;
|
||||
return this;
|
||||
}
|
||||
return getLocalEntry(type, name);
|
||||
}
|
||||
return getFrameworkEntry(type, name);
|
||||
}
|
||||
public int resolveReference(String refString){
|
||||
if("@null".equals(refString)){
|
||||
return 0;
|
||||
}
|
||||
Matcher matcher = ValueDecoder.PATTERN_REFERENCE.matcher(refString);
|
||||
if(!matcher.find()){
|
||||
ValueDecoder.EncodeResult ref = ValueDecoder.encodeHexReference(refString);
|
||||
if(ref!=null){
|
||||
return ref.value;
|
||||
}
|
||||
ref = ValueDecoder.encodeNullReference(refString);
|
||||
if(ref!=null){
|
||||
return ref.value;
|
||||
}
|
||||
throw new EncodeException(
|
||||
"Not proper reference string: '"+refString+"'");
|
||||
}
|
||||
String prefix=matcher.group(1);
|
||||
String packageName = matcher.group(2);
|
||||
if(packageName!=null && packageName.endsWith(":")){
|
||||
packageName=packageName.substring(0, packageName.length()-1);
|
||||
}
|
||||
String type = matcher.group(4);
|
||||
String name = matcher.group(5);
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
return resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageName, type, name);
|
||||
}
|
||||
public int resolveLocalResourceId(String type, String name){
|
||||
for(ResourceIds.Table.Package pkg:packageIdSet){
|
||||
Integer resId = pkg.getResourceId(type, name);
|
||||
if(resId!=null){
|
||||
return resId;
|
||||
}
|
||||
}
|
||||
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
||||
if(entryGroup!=null){
|
||||
return entryGroup.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Local entry not found: " +
|
||||
"type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(String packageName, String type, String name){
|
||||
Entry entry = getFrameworkEntry(packageName, type, name);
|
||||
if(entry !=null){
|
||||
return entry.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"package="+packageName+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(int packageId, String type, String name){
|
||||
Entry entry = getFrameworkEntry(packageId, type, name);
|
||||
if(entry !=null){
|
||||
return entry.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"packageId=" + HexUtil.toHex2((byte) packageId)+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public EntryGroup getLocalEntryGroup(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
for(EntryGroup entryGroup : packageBlock.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Entry getLocalEntry(String type, String name){
|
||||
Entry entry =mLocalResNameMap.get(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
loadLocalEntryMap(type);
|
||||
entry =mLocalResNameMap.get(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
entry = searchLocalEntry(type, name);
|
||||
if(entry !=null){
|
||||
mLocalResNameMap.add(type, name, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
private Entry searchLocalEntry(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup.pickOne();
|
||||
}
|
||||
}
|
||||
SpecTypePair specTypePair=currentPackage.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
if(name.equals(entry.getName())){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
if(packageBlock==currentPackage){
|
||||
continue;
|
||||
}
|
||||
specTypePair=packageBlock.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
if(name.equals(entry.getName())){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private void loadLocalEntryMap(String type){
|
||||
ResNameMap<Entry> localMap = mLocalResNameMap;
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
SpecTypePair specTypePair=packageBlock.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(Entry entry :typeBlock.listEntries(true)){
|
||||
localMap.add(entry.getTypeName(),
|
||||
entry.getName(), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public Entry getFrameworkEntry(String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean isFrameworkPackageName(String packageName){
|
||||
return getFrameworkPackageNames().contains(packageName);
|
||||
}
|
||||
private Set<String> getFrameworkPackageNames(){
|
||||
if(mFrameworkPackageNames!=null){
|
||||
return mFrameworkPackageNames;
|
||||
}
|
||||
Set<String> results=new HashSet<>();
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
results.add(packageBlock.getName());
|
||||
}
|
||||
}
|
||||
mFrameworkPackageNames=results;
|
||||
return results;
|
||||
}
|
||||
public Entry getFrameworkEntry(String packageName, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageName.equals(packageBlock.getName())){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Entry getFrameworkEntry(int packageId, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageId==packageBlock.getId()){
|
||||
Entry entry = table.searchEntry(type, name);
|
||||
if(entry !=null){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EncodeMaterials setForceCreateNamespaces(boolean force) {
|
||||
this.mForceCreateNamespaces = force;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addPackageIds(ResourceIds.Table.Package packageIds) {
|
||||
packageIds.loadEntryMap();
|
||||
this.packageIdSet.add(packageIds);
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setCurrentPackage(PackageBlock currentPackage) {
|
||||
this.currentPackage = currentPackage;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addFramework(FrameworkApk frameworkApk) {
|
||||
if(frameworkApk!=null){
|
||||
addFramework(frameworkApk.getTableBlock());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addFramework(FrameworkTable frameworkTable) {
|
||||
frameworkTable.loadResourceNameMap();
|
||||
this.frameworkTables.add(frameworkTable);
|
||||
this.mFrameworkPackageNames=null;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setAPKLogger(APKLogger logger) {
|
||||
this.apkLogger = logger;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PackageBlock getCurrentPackage() {
|
||||
return currentPackage;
|
||||
}
|
||||
public boolean isForceCreateNamespaces() {
|
||||
return mForceCreateNamespaces;
|
||||
}
|
||||
public PackageBlock getCurrentPackage() {
|
||||
return currentPackage;
|
||||
}
|
||||
public boolean isForceCreateNamespaces() {
|
||||
return mForceCreateNamespaces;
|
||||
}
|
||||
|
||||
public String getCurrentPackageName(){
|
||||
return currentPackage.getName();
|
||||
}
|
||||
public int getCurrentPackageId(){
|
||||
return currentPackage.getId();
|
||||
}
|
||||
public String getCurrentPackageName(){
|
||||
return currentPackage.getName();
|
||||
}
|
||||
public int getCurrentPackageId(){
|
||||
return currentPackage.getId();
|
||||
}
|
||||
|
||||
public void logMessage(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logMessage(msg);
|
||||
}
|
||||
}
|
||||
public void logError(String msg, Throwable tr) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logError(msg, tr);
|
||||
}
|
||||
}
|
||||
public void logVerbose(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logVerbose(msg);
|
||||
}
|
||||
}
|
||||
public static EncodeMaterials create(TableBlock tableBlock){
|
||||
PackageBlock packageBlock = tableBlock.pickOne();
|
||||
if(packageBlock==null){
|
||||
throw new EncodeException("No packages found on table block");
|
||||
}
|
||||
return create(packageBlock);
|
||||
}
|
||||
public static EncodeMaterials create(PackageBlock packageBlock){
|
||||
ResourceIds resourceIds = new ResourceIds();
|
||||
resourceIds.loadPackageBlock(packageBlock);
|
||||
ResourceIds.Table.Package packageId = resourceIds.getTable().listPackages().get(0);
|
||||
EncodeMaterials encodeMaterials = new EncodeMaterials()
|
||||
.addPackageIds(packageId)
|
||||
.setCurrentPackage(packageBlock);
|
||||
TableBlock tableBlock = packageBlock.getTableBlock();
|
||||
for(TableBlock frameworkTable:tableBlock.getFrameWorks()){
|
||||
if(frameworkTable instanceof FrameworkTable){
|
||||
encodeMaterials.addFramework((FrameworkTable) frameworkTable);
|
||||
}
|
||||
}
|
||||
return encodeMaterials;
|
||||
}
|
||||
public void logMessage(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logMessage(msg);
|
||||
}
|
||||
}
|
||||
public void logError(String msg, Throwable tr) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logError(msg, tr);
|
||||
}
|
||||
}
|
||||
public void logVerbose(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logVerbose(msg);
|
||||
}
|
||||
}
|
||||
public static EncodeMaterials create(TableBlock tableBlock){
|
||||
PackageBlock packageBlock = tableBlock.pickOne();
|
||||
if(packageBlock==null){
|
||||
throw new EncodeException("No packages found on table block");
|
||||
}
|
||||
return create(packageBlock);
|
||||
}
|
||||
public static EncodeMaterials create(PackageBlock packageBlock){
|
||||
ResourceIds resourceIds = new ResourceIds();
|
||||
resourceIds.loadPackageBlock(packageBlock);
|
||||
ResourceIds.Table.Package packageId = resourceIds.getTable().listPackages().get(0);
|
||||
EncodeMaterials encodeMaterials = new EncodeMaterials()
|
||||
.addPackageIds(packageId)
|
||||
.setCurrentPackage(packageBlock);
|
||||
TableBlock tableBlock = packageBlock.getTableBlock();
|
||||
for(TableBlock frameworkTable:tableBlock.getFrameWorks()){
|
||||
if(frameworkTable instanceof FrameworkTable){
|
||||
encodeMaterials.addFramework((FrameworkTable) frameworkTable);
|
||||
}
|
||||
}
|
||||
return encodeMaterials;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package com.reandroid.archive2;
|
||||
|
||||
import com.reandroid.archive2.block.CentralEntryHeader;
|
||||
import com.reandroid.archive2.block.LocalFileHeader;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
@ -116,6 +117,7 @@ public class ArchiveEntry extends ZipEntry {
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "["+ getFileOffset()+"] "+getName()+getComment()+String.format(" 0x%08x", getCrc());
|
||||
return "["+ getFileOffset()+"] " + getName() + getComment()
|
||||
+ HexUtil.toHex(" 0x", getCrc(), 8);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
import com.reandroid.archive2.ZipSignature;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -134,12 +135,12 @@ public class CentralEntryHeader extends CommonHeader {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("SIG=").append(getSignature());
|
||||
builder.append(", versionMadeBy=").append(String.format("0x%04x", getVersionMadeBy()));
|
||||
builder.append(", versionExtract=").append(String.format("0x%04x", getVersionExtract()));
|
||||
builder.append(", versionMadeBy=").append(HexUtil.toHex4((short) getVersionMadeBy()));
|
||||
builder.append(", versionExtract=").append(HexUtil.toHex4((short) getVersionExtract()));
|
||||
builder.append(", GP={").append(getGeneralPurposeFlag()).append("}");
|
||||
builder.append(", method=").append(getMethod());
|
||||
builder.append(", date=").append(getDate());
|
||||
builder.append(", crc=").append(String.format("0x%08x", getCrc()));
|
||||
builder.append(", crc=").append(HexUtil.toHex8(getCrc()));
|
||||
builder.append(", cSize=").append(getCompressedSize());
|
||||
builder.append(", size=").append(getSize());
|
||||
builder.append(", fileNameLength=").append(getFileNameLength());
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
import com.reandroid.archive2.ZipSignature;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -287,12 +288,12 @@ public abstract class CommonHeader extends ZipHeader {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("SIG=").append(getSignature());
|
||||
builder.append(", versionMadeBy=").append(String.format("0x%04x", getVersionMadeBy()));
|
||||
builder.append(", platform=").append(String.format("0x%02x", getPlatform()));
|
||||
builder.append(", versionMadeBy=").append(HexUtil.toHex4((short) getVersionMadeBy()));
|
||||
builder.append(", platform=").append(HexUtil.toHex2((byte) getPlatform()));
|
||||
builder.append(", GP={").append(getGeneralPurposeFlag()).append("}");
|
||||
builder.append(", method=").append(getMethod());
|
||||
builder.append(", date=").append(getDate());
|
||||
builder.append(", crc=").append(String.format("0x%08x", getCrc()));
|
||||
builder.append(", crc=").append(HexUtil.toHex8(getCrc()));
|
||||
builder.append(", cSize=").append(getCompressedSize());
|
||||
builder.append(", size=").append(getSize());
|
||||
builder.append(", fileNameLength=").append(getFileNameLength());
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
import com.reandroid.archive2.ZipSignature;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class DataDescriptor extends ZipHeader{
|
||||
public DataDescriptor() {
|
||||
@ -44,7 +45,7 @@ public class DataDescriptor extends ZipHeader{
|
||||
public String toString(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(getSignature());
|
||||
builder.append(", crc=").append(String.format("0x%08x", getCrc()));
|
||||
builder.append(", crc=").append(HexUtil.toHex8(getCrc()));
|
||||
builder.append(", compressed=").append(getCompressedSize());
|
||||
builder.append(", size=").append(getSize());
|
||||
return builder.toString();
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
import com.reandroid.archive2.ZipSignature;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class EndRecord extends ZipHeader{
|
||||
public EndRecord() {
|
||||
@ -78,7 +79,7 @@ public class EndRecord extends ZipHeader{
|
||||
builder.append(", total dirs=").append(getTotalNumberOfDirectories());
|
||||
builder.append(", length=").append(getLengthOfCentralDirectory());
|
||||
builder.append(", offset=").append(getOffsetOfCentralDirectory());
|
||||
builder.append(", last=").append(String.format("0x%08x", getLastShort()));
|
||||
builder.append(", last=").append(HexUtil.toHex8(getLastShort()));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -39,7 +40,7 @@ public class SignatureId implements Comparable<SignatureId>{
|
||||
if (this.name != null) {
|
||||
return name + FILE_EXT_RAW;
|
||||
}
|
||||
return String.format("0x%08x", id) + FILE_EXT_RAW;
|
||||
return HexUtil.toHex8(id) + FILE_EXT_RAW;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@ -66,7 +67,7 @@ public class SignatureId implements Comparable<SignatureId>{
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
return "UNKNOWN(" + String.format("0x%08x", id) + ")";
|
||||
return "UNKNOWN(" + HexUtil.toHex8(id) + ")";
|
||||
}
|
||||
public static SignatureId valueOf(String name) {
|
||||
if (name == null) {
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.reandroid.archive2.io;
|
||||
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.CRC32;
|
||||
@ -124,6 +126,6 @@ public class CountingInputStream<T extends InputStream> extends InputStream {
|
||||
if(!mFinished || crc==null){
|
||||
return "[" + size + "]: " + inputStream.getClass().getSimpleName();
|
||||
}
|
||||
return "[size=" + size +", crc=" + String.format("0x%08x", mCheckSum) + "]: " + inputStream.getClass().getSimpleName();
|
||||
return "[size=" + size +", crc=" + HexUtil.toHex8(mCheckSum) + "]: " + inputStream.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.chunk;
|
||||
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public enum ChunkType {
|
||||
NULL((short)0x0000),
|
||||
|
||||
@ -45,7 +47,7 @@ public enum ChunkType {
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return name()+String.format("(0x%04x)", ((int) ID));
|
||||
return name() + "(" + HexUtil.toHex4(ID) + ")";
|
||||
}
|
||||
|
||||
public static ChunkType get(short id){
|
||||
|
@ -29,6 +29,7 @@ import com.reandroid.arsc.list.StagedAliasList;
|
||||
import com.reandroid.arsc.pool.SpecStringPool;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.LibraryInfo;
|
||||
import com.reandroid.arsc.value.ResConfig;
|
||||
@ -466,7 +467,7 @@ public class PackageBlock extends Chunk<PackageHeader>
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(super.toString());
|
||||
builder.append(", id=");
|
||||
builder.append(String.format("0x%02x", getId()));
|
||||
builder.append(HexUtil.toHex2((byte) getId()));
|
||||
builder.append(", name=");
|
||||
builder.append(getName());
|
||||
int libCount=getLibraryBlock().getLibraryCount();
|
||||
|
@ -1,162 +1,163 @@
|
||||
/*
|
||||
* 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.arsc.chunk;
|
||||
/*
|
||||
* 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.arsc.chunk;
|
||||
|
||||
import com.reandroid.arsc.array.TypeBlockArray;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.header.SpecHeader;
|
||||
import com.reandroid.arsc.item.*;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
import com.reandroid.arsc.array.TypeBlockArray;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.header.SpecHeader;
|
||||
import com.reandroid.arsc.item.*;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.List;
|
||||
|
||||
public class SpecBlock extends Chunk<SpecHeader> implements JSONConvert<JSONObject> {
|
||||
private final SpecFlagsArray specFlagsArray;
|
||||
public SpecBlock() {
|
||||
super(new SpecHeader(), 1);
|
||||
SpecHeader header = getHeaderBlock();
|
||||
this.specFlagsArray = new SpecFlagsArray(header.getEntryCount());
|
||||
addChild(specFlagsArray);
|
||||
}
|
||||
public void destroy(){
|
||||
setParent(null);
|
||||
getSpecFlagsArray().clear();
|
||||
}
|
||||
public SpecFlag getSpecFlag(int id){
|
||||
return getSpecFlagsArray().getFlag(id);
|
||||
}
|
||||
public SpecFlagsArray getSpecFlagsArray(){
|
||||
return specFlagsArray;
|
||||
}
|
||||
public List<Integer> listSpecFlags(){
|
||||
return specFlagsArray.toList();
|
||||
}
|
||||
public byte getTypeId(){
|
||||
return getHeaderBlock().getId().get();
|
||||
}
|
||||
public int getId(){
|
||||
return getHeaderBlock().getId().unsignedInt();
|
||||
}
|
||||
public void setId(int id){
|
||||
setTypeId((byte) (0xff & id));
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
getHeaderBlock().getId().set(id);
|
||||
getTypeBlockArray().setTypeId(id);
|
||||
}
|
||||
public TypeBlockArray getTypeBlockArray(){
|
||||
SpecTypePair specTypePair=getSpecTypePair();
|
||||
if(specTypePair!=null){
|
||||
return specTypePair.getTypeBlockArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
SpecTypePair getSpecTypePair(){
|
||||
return getParent(SpecTypePair.class);
|
||||
}
|
||||
public int getEntryCount() {
|
||||
return specFlagsArray.size();
|
||||
}
|
||||
public void setEntryCount(int count){
|
||||
specFlagsArray.setSize(count);
|
||||
specFlagsArray.refresh();
|
||||
}
|
||||
@Override
|
||||
protected void onChunkRefreshed() {
|
||||
specFlagsArray.refresh();
|
||||
}
|
||||
public class SpecBlock extends Chunk<SpecHeader> implements JSONConvert<JSONObject> {
|
||||
private final SpecFlagsArray specFlagsArray;
|
||||
public SpecBlock() {
|
||||
super(new SpecHeader(), 1);
|
||||
SpecHeader header = getHeaderBlock();
|
||||
this.specFlagsArray = new SpecFlagsArray(header.getEntryCount());
|
||||
addChild(specFlagsArray);
|
||||
}
|
||||
public void destroy(){
|
||||
setParent(null);
|
||||
getSpecFlagsArray().clear();
|
||||
}
|
||||
public SpecFlag getSpecFlag(int id){
|
||||
return getSpecFlagsArray().getFlag(id);
|
||||
}
|
||||
public SpecFlagsArray getSpecFlagsArray(){
|
||||
return specFlagsArray;
|
||||
}
|
||||
public List<Integer> listSpecFlags(){
|
||||
return specFlagsArray.toList();
|
||||
}
|
||||
public byte getTypeId(){
|
||||
return getHeaderBlock().getId().get();
|
||||
}
|
||||
public int getId(){
|
||||
return getHeaderBlock().getId().unsignedInt();
|
||||
}
|
||||
public void setId(int id){
|
||||
setTypeId((byte) (0xff & id));
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
getHeaderBlock().getId().set(id);
|
||||
getTypeBlockArray().setTypeId(id);
|
||||
}
|
||||
public TypeBlockArray getTypeBlockArray(){
|
||||
SpecTypePair specTypePair=getSpecTypePair();
|
||||
if(specTypePair!=null){
|
||||
return specTypePair.getTypeBlockArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
SpecTypePair getSpecTypePair(){
|
||||
return getParent(SpecTypePair.class);
|
||||
}
|
||||
public int getEntryCount() {
|
||||
return specFlagsArray.size();
|
||||
}
|
||||
public void setEntryCount(int count){
|
||||
specFlagsArray.setSize(count);
|
||||
specFlagsArray.refresh();
|
||||
}
|
||||
@Override
|
||||
protected void onChunkRefreshed() {
|
||||
specFlagsArray.refresh();
|
||||
}
|
||||
|
||||
public void merge(SpecBlock specBlock){
|
||||
if(specBlock == null || specBlock==this){
|
||||
return;
|
||||
}
|
||||
this.getSpecFlagsArray().merge(specBlock.getSpecFlagsArray());
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(super.toString());
|
||||
TypeBlockArray typeBlockArray=getTypeBlockArray();
|
||||
if(typeBlockArray!=null){
|
||||
builder.append(", typesCount=");
|
||||
builder.append(typeBlockArray.childesCount());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public void merge(SpecBlock specBlock){
|
||||
if(specBlock == null || specBlock==this){
|
||||
return;
|
||||
}
|
||||
this.getSpecFlagsArray().merge(specBlock.getSpecFlagsArray());
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(super.toString());
|
||||
TypeBlockArray typeBlockArray=getTypeBlockArray();
|
||||
if(typeBlockArray!=null){
|
||||
builder.append(", typesCount=");
|
||||
builder.append(typeBlockArray.childesCount());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.put(TypeBlock.NAME_id, getId());
|
||||
jsonObject.put(NAME_spec_flags, getSpecFlagsArray().toJson());
|
||||
return jsonObject;
|
||||
}
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.put(TypeBlock.NAME_id, getId());
|
||||
jsonObject.put(NAME_spec_flags, getSpecFlagsArray().toJson());
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
setId(json.getInt(TypeBlock.NAME_id));
|
||||
getSpecFlagsArray().fromJson(json.optJSONArray(NAME_spec_flags));
|
||||
}
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
setId(json.getInt(TypeBlock.NAME_id));
|
||||
getSpecFlagsArray().fromJson(json.optJSONArray(NAME_spec_flags));
|
||||
}
|
||||
|
||||
public enum Flag{
|
||||
SPEC_PUBLIC((byte) 0x40),
|
||||
SPEC_STAGED_API((byte) 0x20);
|
||||
public enum Flag{
|
||||
SPEC_PUBLIC((byte) 0x40),
|
||||
SPEC_STAGED_API((byte) 0x20);
|
||||
|
||||
private final byte flag;
|
||||
Flag(byte flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
public byte getFlag() {
|
||||
return flag;
|
||||
}
|
||||
public static boolean isPublic(byte flag){
|
||||
return (SPEC_PUBLIC.flag & flag) == SPEC_PUBLIC.flag;
|
||||
}
|
||||
public static boolean isStagedApi(byte flag){
|
||||
return (SPEC_STAGED_API.flag & flag) == SPEC_STAGED_API.flag;
|
||||
}
|
||||
public static String toString(byte flagValue){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean appendOnce = false;
|
||||
int sum = 0;
|
||||
int flagValueInt = flagValue & 0xff;
|
||||
for(Flag flag:values()){
|
||||
int flagInt = flag.flag & 0xff;
|
||||
if((flagInt & flagValueInt) != flagInt){
|
||||
continue;
|
||||
}
|
||||
if(appendOnce){
|
||||
builder.append('|');
|
||||
}
|
||||
builder.append(flag);
|
||||
appendOnce = true;
|
||||
sum = sum | flagInt;
|
||||
}
|
||||
if(sum != flagValueInt){
|
||||
if(appendOnce){
|
||||
builder.append('|');
|
||||
}
|
||||
builder.append(String.format("0x%02x", flagValueInt));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
private final byte flag;
|
||||
Flag(byte flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
public byte getFlag() {
|
||||
return flag;
|
||||
}
|
||||
public static boolean isPublic(byte flag){
|
||||
return (SPEC_PUBLIC.flag & flag) == SPEC_PUBLIC.flag;
|
||||
}
|
||||
public static boolean isStagedApi(byte flag){
|
||||
return (SPEC_STAGED_API.flag & flag) == SPEC_STAGED_API.flag;
|
||||
}
|
||||
public static String toString(byte flagValue){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean appendOnce = false;
|
||||
int sum = 0;
|
||||
int flagValueInt = flagValue & 0xff;
|
||||
for(Flag flag:values()){
|
||||
int flagInt = flag.flag & 0xff;
|
||||
if((flagInt & flagValueInt) != flagInt){
|
||||
continue;
|
||||
}
|
||||
if(appendOnce){
|
||||
builder.append('|');
|
||||
}
|
||||
builder.append(flag);
|
||||
appendOnce = true;
|
||||
sum = sum | flagInt;
|
||||
}
|
||||
if(sum != flagValueInt){
|
||||
if(appendOnce){
|
||||
builder.append('|');
|
||||
}
|
||||
builder.append(HexUtil.toHex2((byte) flagValueInt));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static final String NAME_spec = "spec";
|
||||
public static final String NAME_spec_flags = "spec_flags";
|
||||
public static final String NAME_flag = "flag";
|
||||
}
|
||||
public static final String NAME_spec = "spec";
|
||||
public static final String NAME_spec_flags = "spec_flags";
|
||||
public static final String NAME_flag = "flag";
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.*;
|
||||
import com.reandroid.arsc.pool.ResXmlStringPool;
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.AttributeValue;
|
||||
import com.reandroid.arsc.value.ValueItem;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
@ -419,10 +420,10 @@ public class ResXmlAttribute extends ValueItem implements AttributeValue, Compar
|
||||
if(group==null){
|
||||
//Lets ignore such error until XML encoder implemented
|
||||
//throw new XMLException("Failed to decode attribute name: "
|
||||
//+ String.format("@0x%08x", resourceId));
|
||||
name=String.format("@0x%08x", resourceId);
|
||||
//HexUtil.toHex8("@0x", resourceId));
|
||||
name = HexUtil.toHex8("@0x", resourceId);
|
||||
}else {
|
||||
name=group.getSpecName();
|
||||
name = group.getSpecName();
|
||||
}
|
||||
}
|
||||
String prefix = getNamePrefix();
|
||||
@ -445,7 +446,7 @@ public class ResXmlAttribute extends ValueItem implements AttributeValue, Compar
|
||||
if(fullName!=null ){
|
||||
int id=getNameResourceID();
|
||||
if(id!=0){
|
||||
fullName=fullName+"(@"+String.format("0x%08x",id)+")";
|
||||
fullName=fullName+"(@"+ HexUtil.toHex8(id)+")";
|
||||
}
|
||||
String valStr;
|
||||
ValueType valueType=getValueType();
|
||||
@ -456,7 +457,7 @@ public class ResXmlAttribute extends ValueItem implements AttributeValue, Compar
|
||||
}else if (valueType==ValueType.INT_DEC){
|
||||
valStr = String.valueOf(getData());
|
||||
}else {
|
||||
valStr = "["+valueType+"] " + String.format("0x%08x",getData());
|
||||
valStr = "["+valueType+"] " + HexUtil.toHex8(getData());
|
||||
}
|
||||
if(valStr!=null){
|
||||
return fullName+"=\""+valStr+"\"";
|
||||
|
@ -27,6 +27,7 @@ import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.TypeString;
|
||||
import com.reandroid.arsc.pool.SpecStringPool;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.ResConfig;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
@ -338,7 +339,7 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append(String.format("0x%02x", getTypeId()));
|
||||
builder.append(HexUtil.toHex2(getTypeId()));
|
||||
builder.append(" (");
|
||||
TypeString ts = getTypeString();
|
||||
if(ts!=null){
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.decoder;
|
||||
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
@ -43,7 +44,7 @@ public class ColorUtil {
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
String hex = String.format("%08x", data);
|
||||
String hex = HexUtil.toHexNoPrefix8(data);
|
||||
return "#" + hex.substring(index);
|
||||
}
|
||||
public static ValueDecoder.EncodeResult encode(String hexColor){
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.decoder;
|
||||
|
||||
import com.reandroid.apk.AndroidFrameworks;
|
||||
@ -25,6 +25,7 @@ import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.util.FrameworkTable;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.AttributeValue;
|
||||
import com.reandroid.arsc.value.Value;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
@ -57,7 +58,7 @@ public class Decoder {
|
||||
return null;
|
||||
}
|
||||
private String hexResourceName(int resourceId){
|
||||
return String.format("@0x%08x", resourceId);
|
||||
return HexUtil.toHex8("@0x", resourceId);
|
||||
}
|
||||
public String decodeValue(Value value){
|
||||
if(value==null){
|
||||
|
@ -20,6 +20,7 @@ import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.*;
|
||||
import com.reandroid.arsc.value.attribute.AttributeBag;
|
||||
import com.reandroid.common.EntryStore;
|
||||
@ -265,11 +266,11 @@ public class ValueDecoder {
|
||||
public static String decodeAttributeName(EntryStore store, PackageBlock currentPackage, int resourceId){
|
||||
EntryGroup entryGroup=searchEntryGroup(store, currentPackage, resourceId);
|
||||
if(entryGroup==null){
|
||||
return String.format("@0x%08x", resourceId);
|
||||
return HexUtil.toHex8("@0x", resourceId);
|
||||
}
|
||||
Entry entry =entryGroup.pickOne();
|
||||
if(entry ==null){
|
||||
return String.format("@0x%08x", resourceId);
|
||||
Entry entry = entryGroup.pickOne();
|
||||
if(entry == null){
|
||||
return HexUtil.toHex8("@0x", resourceId);
|
||||
}
|
||||
String prefix=null;
|
||||
if(currentPackage!=null){
|
||||
@ -705,7 +706,7 @@ public class ValueDecoder {
|
||||
}
|
||||
|
||||
private static String decodeHex(int rawVal){
|
||||
return String.format("0x%x", rawVal);
|
||||
return HexUtil.toHex(rawVal, 1);
|
||||
}
|
||||
private static String decodeInt(int rawVal){
|
||||
return String.valueOf(rawVal);
|
||||
@ -786,7 +787,7 @@ public class ValueDecoder {
|
||||
return entry1;
|
||||
}
|
||||
private static String toHexResourceId(int resourceId){
|
||||
return String.format("0x%08x", resourceId);
|
||||
return HexUtil.toHex8(resourceId);
|
||||
}
|
||||
private static boolean isEqualString(String str1, String str2){
|
||||
if(isEmpty(str1)){
|
||||
@ -810,7 +811,7 @@ public class ValueDecoder {
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return valueType+": "+String.format("0x%08x", value);
|
||||
return valueType+": "+HexUtil.toHex8(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.header;
|
||||
|
||||
import com.reandroid.arsc.base.BlockContainer;
|
||||
@ -27,11 +27,12 @@ import com.reandroid.arsc.item.ByteArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.ShortItem;
|
||||
import com.reandroid.arsc.util.HexBytesWriter;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
public class HeaderBlock extends ExpandableBlockContainer implements BlockLoad {
|
||||
public class HeaderBlock extends ExpandableBlockContainer implements BlockLoad {
|
||||
private final ShortItem mType;
|
||||
private final ShortItem mHeaderSize;
|
||||
private final IntegerItem mChunkSize;
|
||||
@ -57,7 +58,7 @@ import java.util.List;
|
||||
return countBytes();
|
||||
}
|
||||
public ByteArray getExtraBytes() {
|
||||
return extraBytes;
|
||||
return extraBytes;
|
||||
}
|
||||
public void setHeaderLoaded(HeaderLoaded headerLoaded){
|
||||
this.mHeaderLoaded=headerLoaded;
|
||||
@ -111,9 +112,9 @@ import java.util.List;
|
||||
}
|
||||
/**Non buffering reader*/
|
||||
public int readBytes(InputStream inputStream) throws IOException{
|
||||
int result = onReadBytes(inputStream);
|
||||
super.notifyBlockLoad();
|
||||
return result;
|
||||
int result = onReadBytes(inputStream);
|
||||
super.notifyBlockLoad();
|
||||
return result;
|
||||
}
|
||||
private int onReadBytes(InputStream inputStream) throws IOException {
|
||||
int readCount = readBytes(inputStream, this);
|
||||
@ -218,7 +219,7 @@ import java.util.List;
|
||||
builder.append(type.toString());
|
||||
}else {
|
||||
builder.append("Unknown type=");
|
||||
builder.append(String.format("0x%02x", (0xffff & t)));
|
||||
builder.append(HexUtil.toHex4(t));
|
||||
}
|
||||
builder.append("{ValueHeader=");
|
||||
builder.append(getHeaderSize());
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2022 github.com/REAndroid
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -16,7 +16,9 @@
|
||||
package com.reandroid.arsc.item;
|
||||
|
||||
|
||||
public class ByteItem extends BlockItem {
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class ByteItem extends BlockItem {
|
||||
public ByteItem() {
|
||||
super(1);
|
||||
}
|
||||
@ -47,7 +49,7 @@ public class ByteItem extends BlockItem {
|
||||
return 0xff & get();
|
||||
}
|
||||
public String toHex(){
|
||||
return String.format("0x%02x", unsignedInt());
|
||||
return HexUtil.toHex2(get());
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
|
@ -1,27 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class IntegerItem extends BlockItem implements ReferenceItem{
|
||||
public class IntegerItem extends BlockItem implements ReferenceItem{
|
||||
private int mCache;
|
||||
public IntegerItem(){
|
||||
super(4);
|
||||
@ -50,7 +50,7 @@ package com.reandroid.arsc.item;
|
||||
return get() & 0x00000000ffffffffL;
|
||||
}
|
||||
public String toHex(){
|
||||
return String.format("0x%08x", get());
|
||||
return HexUtil.toHex8(get());
|
||||
}
|
||||
@Override
|
||||
protected void onBytesChanged() {
|
||||
|
@ -1,20 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class LongItem extends BlockItem{
|
||||
private long mCache;
|
||||
public LongItem() {
|
||||
@ -31,7 +33,7 @@ public class LongItem extends BlockItem{
|
||||
return mCache;
|
||||
}
|
||||
public String toHex(){
|
||||
return String.format("0x%016x", get());
|
||||
return HexUtil.toHex(get(), 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,22 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||
import com.reandroid.arsc.pool.ResXmlStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -90,7 +91,7 @@ public class ResXmlID extends IntegerItem {
|
||||
builder.append(getIndex());
|
||||
}
|
||||
builder.append(':');
|
||||
builder.append(String.format("0x%08x", get()));
|
||||
builder.append(HexUtil.toHex8(get()));
|
||||
builder.append('}');
|
||||
return builder.toString();
|
||||
}
|
||||
|
@ -1,26 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ShortItem extends BlockItem {
|
||||
public class ShortItem extends BlockItem {
|
||||
private short mCache;
|
||||
|
||||
public ShortItem(){
|
||||
@ -46,7 +47,7 @@ package com.reandroid.arsc.item;
|
||||
return 0xffff & get();
|
||||
}
|
||||
public String toHex(){
|
||||
return String.format("0x%04x", unsignedInt());
|
||||
return HexUtil.toHex4(get());
|
||||
}
|
||||
@Override
|
||||
protected void onBytesChanged() {
|
||||
|
@ -1,21 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.chunk.SpecBlock;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class SpecFlag extends IndirectItem<SpecFlagsArray> {
|
||||
public SpecFlag(SpecFlagsArray specFlagsArray, int offset) {
|
||||
@ -58,7 +59,7 @@ public class SpecFlag extends IndirectItem<SpecFlagsArray> {
|
||||
}
|
||||
int val = getInteger();
|
||||
if(val != 0){
|
||||
return String.format("0x%08x", val);
|
||||
return HexUtil.toHex8(val);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package com.reandroid.arsc.item;
|
||||
|
||||
|
||||
import com.reandroid.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
|
||||
public class TypeString extends StringItem {
|
||||
public TypeString(boolean utf8) {
|
||||
@ -40,6 +41,6 @@ public class TypeString extends StringItem {
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return String.format("0x%02x", getId())+':'+get();
|
||||
return HexUtil.toHex2((byte) getId())+':'+get();
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public class HexBytesWriter {
|
||||
}
|
||||
}
|
||||
private void writeHex(Writer writer, byte b) throws IOException {
|
||||
String hex = String.format("%02x", (0xff & b)).toUpperCase();
|
||||
String hex = HexUtil.toHex(null, (0xff & b), 2).toUpperCase();
|
||||
writer.write(hex);
|
||||
}
|
||||
private void writeString(Writer writer, int width, int position) throws IOException {
|
||||
|
84
src/main/java/com/reandroid/arsc/util/HexUtil.java
Normal file
84
src/main/java/com/reandroid/arsc/util/HexUtil.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.arsc.util;
|
||||
|
||||
public class HexUtil {
|
||||
public static String toHex2(byte num){
|
||||
return toHex((long)(num & 0x00000000000000ffL), 2);
|
||||
}
|
||||
public static String toHex4(short num){
|
||||
return toHex((long)(num & 0x000000000000ffffL), 4);
|
||||
}
|
||||
public static String toHex8(int num){
|
||||
return toHex(num, 8);
|
||||
}
|
||||
public static String toHex8(long num){
|
||||
return toHex(num, 8);
|
||||
}
|
||||
public static String toHex(int num, int minLength){
|
||||
return toHex((0x00000000ffffffffL & num), minLength);
|
||||
}
|
||||
public static String toHex(long num, int minLength){
|
||||
String hex = Long.toHexString(num);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append('0');
|
||||
builder.append('x');
|
||||
int rem = minLength - hex.length();
|
||||
for(int i=0; i < rem; i++){
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(hex);
|
||||
return builder.toString();
|
||||
}
|
||||
public static String toHexNoPrefix8(int num){
|
||||
return toHex(null, (0x00000000ffffffffL & num), 8);
|
||||
}
|
||||
public static String toHexNoPrefix(int num, int minLength){
|
||||
return toHex(null, (0x00000000ffffffffL & num), minLength);
|
||||
}
|
||||
public static String toHex8(String prefix, int num){
|
||||
return toHex(prefix, (0x00000000ffffffffL & num), 8);
|
||||
}
|
||||
public static String toHex(String prefix, int num, int minLength){
|
||||
return toHex(prefix, (0x00000000ffffffffL & num), minLength);
|
||||
}
|
||||
public static String toHex(String prefix, long num, int minLength){
|
||||
String hex = Long.toHexString(num);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if(prefix != null){
|
||||
builder.append(prefix);
|
||||
}
|
||||
int rem = minLength - hex.length();
|
||||
for(int i=0; i < rem; i++){
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(hex);
|
||||
return builder.toString();
|
||||
}
|
||||
public static int parseHex(String hexString){
|
||||
hexString = trim0x(hexString);
|
||||
return (int) Long.parseLong(hexString, 16);
|
||||
}
|
||||
private static String trim0x(String hexString){
|
||||
if(hexString == null || hexString.length() < 3){
|
||||
return hexString;
|
||||
}
|
||||
if(hexString.charAt(0) == '0' && hexString.charAt(1) == 'x'){
|
||||
hexString = hexString.substring(2);
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.*;
|
||||
import com.reandroid.arsc.pool.SpecStringPool;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
@ -429,7 +430,7 @@ public class Entry extends Block implements JSONConvert<JSONObject> {
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(String.format("0x%08x", getResourceId()));
|
||||
builder.append(HexUtil.toHex8(getResourceId()));
|
||||
builder.append(' ');
|
||||
ResConfig resConfig = getResConfig();
|
||||
if(resConfig!=null){
|
||||
|
@ -1,20 +1,21 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
public class EntryHeaderMap extends ValueHeader {
|
||||
@ -92,7 +93,7 @@ public class EntryHeaderMap extends ValueHeader {
|
||||
int parentId = getParentId();
|
||||
if(parentId!=0){
|
||||
builder.append(", parentId=");
|
||||
builder.append(String.format("0x%08x", getParentId()));
|
||||
builder.append(HexUtil.toHex8(getParentId()));
|
||||
}
|
||||
builder.append(", count=").append(getValuesCount());
|
||||
return builder.toString();
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.base.Block;
|
||||
@ -20,6 +20,7 @@ import com.reandroid.arsc.base.BlockCounter;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.FixedLengthString;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
@ -117,7 +118,7 @@ public class LibraryInfo extends Block implements JSONConvert<JSONObject> {
|
||||
public String toString(){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
builder.append("LIBRARY{");
|
||||
builder.append(String.format("0x%02x", getPackageId()));
|
||||
builder.append(HexUtil.toHex2((byte) getPackageId()));
|
||||
builder.append(':');
|
||||
String name=getPackageName();
|
||||
if(name==null){
|
||||
|
@ -1,22 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
public class ResValueMap extends ValueItem implements AttributeValue{
|
||||
@ -110,7 +111,7 @@ public class ResValueMap extends ValueItem implements AttributeValue{
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "name="+String.format("0x%08x", getName())
|
||||
return "name=" + HexUtil.toHex8(getName())
|
||||
+", "+super.toString();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,22 @@
|
||||
/*
|
||||
* 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.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.item.ByteArray;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
@ -22,7 +38,7 @@ public class StagedAliasEntry extends ByteArray implements JSONConvert<JSONObjec
|
||||
return getInteger(0);
|
||||
}
|
||||
public void setStagedResId(int id){
|
||||
putInteger(0, id);
|
||||
putInteger(0, id);
|
||||
}
|
||||
public int getFinalizedResId(){
|
||||
return getInteger(4);
|
||||
@ -32,8 +48,8 @@ public class StagedAliasEntry extends ByteArray implements JSONConvert<JSONObjec
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "stagedResId="+String.format("0x%08x",getStagedResId())
|
||||
+", finalizedResId="+String.format("0x%08x",getFinalizedResId());
|
||||
return "stagedResId=" + HexUtil.toHex8(getStagedResId())
|
||||
+", finalizedResId=" + HexUtil.toHex8(getFinalizedResId());
|
||||
}
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
* 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.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.base.Block;
|
||||
@ -24,308 +24,309 @@ import com.reandroid.arsc.item.ReferenceItem;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class ValueItem extends BlockItem implements Value,
|
||||
JSONConvert<JSONObject>{
|
||||
private ReferenceItem mStringReference;
|
||||
private final int sizeOffset;
|
||||
public ValueItem(int bytesLength, int sizeOffset) {
|
||||
super(bytesLength);
|
||||
this.sizeOffset = sizeOffset;
|
||||
|
||||
writeSize();
|
||||
}
|
||||
public abstract class ValueItem extends BlockItem implements Value,
|
||||
JSONConvert<JSONObject>{
|
||||
private ReferenceItem mStringReference;
|
||||
private final int sizeOffset;
|
||||
public ValueItem(int bytesLength, int sizeOffset) {
|
||||
super(bytesLength);
|
||||
this.sizeOffset = sizeOffset;
|
||||
|
||||
void linkTableStrings(TableStringPool tableStringPool){
|
||||
if(getValueType() == ValueType.STRING){
|
||||
linkStringReference(tableStringPool);
|
||||
}
|
||||
}
|
||||
public void onRemoved(){
|
||||
unLinkStringReference();
|
||||
}
|
||||
protected void onDataChanged(){
|
||||
}
|
||||
public void refresh(){
|
||||
writeSize();
|
||||
}
|
||||
writeSize();
|
||||
}
|
||||
|
||||
byte getRes0(){
|
||||
return getBytesInternal()[this.sizeOffset + OFFSET_RES0];
|
||||
}
|
||||
public byte getType(){
|
||||
return getBytesInternal()[this.sizeOffset + OFFSET_TYPE];
|
||||
}
|
||||
public void setType(byte type){
|
||||
if(type == getType()){
|
||||
return;
|
||||
}
|
||||
byte[] bts = getBytesInternal();
|
||||
int offset = this.sizeOffset + OFFSET_TYPE;
|
||||
byte old = bts[offset];
|
||||
bts[offset] = type;
|
||||
onTypeChanged(old, type);
|
||||
onDataChanged();
|
||||
}
|
||||
public int getSize(){
|
||||
return 0xffff & getShort(getBytesInternal(), this.sizeOffset + OFFSET_SIZE);
|
||||
}
|
||||
public void setSize(int size){
|
||||
size = this.sizeOffset + size;
|
||||
setBytesLength(size, false);
|
||||
writeSize();
|
||||
}
|
||||
private void writeSize(){
|
||||
int offset = this.sizeOffset;
|
||||
int size = countBytes() - offset;
|
||||
putShort(getBytesInternal(), offset + OFFSET_SIZE, (short) size);
|
||||
}
|
||||
protected void onDataLoaded(){
|
||||
if(getValueType() == ValueType.STRING){
|
||||
linkStringReference();
|
||||
}else {
|
||||
unLinkStringReference();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public ValueType getValueType(){
|
||||
return ValueType.valueOf(getType());
|
||||
}
|
||||
@Override
|
||||
public void setValueType(ValueType valueType){
|
||||
byte type = 0;
|
||||
if(valueType!=null){
|
||||
type = valueType.getByte();
|
||||
}
|
||||
setType(type);
|
||||
}
|
||||
@Override
|
||||
public int getData(){
|
||||
return getInteger(getBytesInternal(), this.sizeOffset + OFFSET_DATA);
|
||||
}
|
||||
@Override
|
||||
public void setData(int data){
|
||||
byte[] bts = getBytesInternal();
|
||||
int old = getInteger(bts, this.sizeOffset + OFFSET_DATA);
|
||||
if(old == data){
|
||||
return;
|
||||
}
|
||||
unLinkStringReference();
|
||||
putInteger(bts, this.sizeOffset + OFFSET_DATA, data);
|
||||
if(ValueType.STRING==getValueType()){
|
||||
linkStringReference();
|
||||
}
|
||||
onDataChanged();
|
||||
}
|
||||
void linkTableStrings(TableStringPool tableStringPool){
|
||||
if(getValueType() == ValueType.STRING){
|
||||
linkStringReference(tableStringPool);
|
||||
}
|
||||
}
|
||||
public void onRemoved(){
|
||||
unLinkStringReference();
|
||||
}
|
||||
protected void onDataChanged(){
|
||||
}
|
||||
public void refresh(){
|
||||
writeSize();
|
||||
}
|
||||
|
||||
byte getRes0(){
|
||||
return getBytesInternal()[this.sizeOffset + OFFSET_RES0];
|
||||
}
|
||||
public byte getType(){
|
||||
return getBytesInternal()[this.sizeOffset + OFFSET_TYPE];
|
||||
}
|
||||
public void setType(byte type){
|
||||
if(type == getType()){
|
||||
return;
|
||||
}
|
||||
byte[] bts = getBytesInternal();
|
||||
int offset = this.sizeOffset + OFFSET_TYPE;
|
||||
byte old = bts[offset];
|
||||
bts[offset] = type;
|
||||
onTypeChanged(old, type);
|
||||
onDataChanged();
|
||||
}
|
||||
public int getSize(){
|
||||
return 0xffff & getShort(getBytesInternal(), this.sizeOffset + OFFSET_SIZE);
|
||||
}
|
||||
public void setSize(int size){
|
||||
size = this.sizeOffset + size;
|
||||
setBytesLength(size, false);
|
||||
writeSize();
|
||||
}
|
||||
private void writeSize(){
|
||||
int offset = this.sizeOffset;
|
||||
int size = countBytes() - offset;
|
||||
putShort(getBytesInternal(), offset + OFFSET_SIZE, (short) size);
|
||||
}
|
||||
protected void onDataLoaded(){
|
||||
if(getValueType() == ValueType.STRING){
|
||||
linkStringReference();
|
||||
}else {
|
||||
unLinkStringReference();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public ValueType getValueType(){
|
||||
return ValueType.valueOf(getType());
|
||||
}
|
||||
@Override
|
||||
public void setValueType(ValueType valueType){
|
||||
byte type = 0;
|
||||
if(valueType!=null){
|
||||
type = valueType.getByte();
|
||||
}
|
||||
setType(type);
|
||||
}
|
||||
@Override
|
||||
public int getData(){
|
||||
return getInteger(getBytesInternal(), this.sizeOffset + OFFSET_DATA);
|
||||
}
|
||||
@Override
|
||||
public void setData(int data){
|
||||
byte[] bts = getBytesInternal();
|
||||
int old = getInteger(bts, this.sizeOffset + OFFSET_DATA);
|
||||
if(old == data){
|
||||
return;
|
||||
}
|
||||
unLinkStringReference();
|
||||
putInteger(bts, this.sizeOffset + OFFSET_DATA, data);
|
||||
if(ValueType.STRING==getValueType()){
|
||||
linkStringReference();
|
||||
}
|
||||
onDataChanged();
|
||||
}
|
||||
|
||||
|
||||
public StringItem getDataAsPoolString(){
|
||||
if(getValueType()!=ValueType.STRING){
|
||||
return null;
|
||||
}
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null){
|
||||
return null;
|
||||
}
|
||||
return stringPool.get(getData());
|
||||
}
|
||||
private void onTypeChanged(byte old, byte type){
|
||||
byte typeString = ValueType.STRING.getByte();
|
||||
if(old == typeString){
|
||||
unLinkStringReference();
|
||||
}else if(type == typeString){
|
||||
linkStringReference();
|
||||
}
|
||||
}
|
||||
private void linkStringReference(){
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null || stringPool.isStringLinkLocked()){
|
||||
return;
|
||||
}
|
||||
linkStringReference(stringPool);
|
||||
}
|
||||
private void linkStringReference(StringPool<?> stringPool){
|
||||
StringItem tableString = stringPool.get(getData());
|
||||
if(tableString == null){
|
||||
unLinkStringReference();
|
||||
return;
|
||||
}
|
||||
ReferenceItem stringReference = mStringReference;
|
||||
if(stringReference!=null){
|
||||
unLinkStringReference();
|
||||
}
|
||||
stringReference = new ReferenceBlock<>(this, this.sizeOffset + OFFSET_DATA);
|
||||
mStringReference = stringReference;
|
||||
tableString.addReference(stringReference);
|
||||
}
|
||||
private void unLinkStringReference(){
|
||||
ReferenceItem stringReference = mStringReference;
|
||||
if(stringReference==null){
|
||||
return;
|
||||
}
|
||||
mStringReference = null;
|
||||
onUnlinkDataString(stringReference);
|
||||
}
|
||||
protected void onUnlinkDataString(ReferenceItem referenceItem){
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null){
|
||||
return;
|
||||
}
|
||||
stringPool.removeReference(referenceItem);
|
||||
}
|
||||
public StringPool<?> getStringPool(){
|
||||
Block parent = getParent();
|
||||
while (parent!=null){
|
||||
if(parent instanceof MainChunk){
|
||||
return ((MainChunk) parent).getStringPool();
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException {
|
||||
int readSize = initializeBytes(reader);
|
||||
super.onReadBytes(reader);
|
||||
if(readSize<8){
|
||||
setBytesLength(this.sizeOffset + 8, false);
|
||||
writeSize();
|
||||
}
|
||||
}
|
||||
private int initializeBytes(BlockReader reader) throws IOException {
|
||||
int position = reader.getPosition();
|
||||
int offset = this.sizeOffset;
|
||||
reader.offset(offset);
|
||||
int readSize = reader.readUnsignedShort();
|
||||
int size = readSize;
|
||||
if(size<8){
|
||||
if(reader.available()>=8){
|
||||
size = 8;
|
||||
}
|
||||
}
|
||||
reader.seek(position);
|
||||
setBytesLength(offset + size, false);
|
||||
return readSize;
|
||||
}
|
||||
@Override
|
||||
public String getValueAsString(){
|
||||
StringItem stringItem = getDataAsPoolString();
|
||||
if(stringItem!=null){
|
||||
String value = stringItem.getHtml();
|
||||
if(value == null){
|
||||
value = "";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void setValueAsString(String str){
|
||||
if(getValueType() == ValueType.STRING
|
||||
&& Objects.equals(str, getValueAsString())){
|
||||
return;
|
||||
}
|
||||
if(str == null){
|
||||
str = "";
|
||||
}
|
||||
StringItem stringItem = getStringPool().getOrCreate(str);
|
||||
setData(stringItem.getIndex());
|
||||
setValueType(ValueType.STRING);
|
||||
}
|
||||
public boolean getValueAsBoolean(){
|
||||
return getData()!=0;
|
||||
}
|
||||
public void setValueAsBoolean(boolean val){
|
||||
setValueType(ValueType.INT_BOOLEAN);
|
||||
int data=val?0xffffffff:0;
|
||||
setData(data);
|
||||
}
|
||||
public void setTypeAndData(ValueType valueType, int data){
|
||||
setData(data);
|
||||
setValueType(valueType);
|
||||
}
|
||||
public void merge(ValueItem valueItem){
|
||||
if(valueItem == null || valueItem==this){
|
||||
return;
|
||||
}
|
||||
setSize(valueItem.getSize());
|
||||
ValueType coming = valueItem.getValueType();
|
||||
if(coming == ValueType.STRING){
|
||||
setValueAsString(valueItem.getValueAsString());
|
||||
}else {
|
||||
setTypeAndData(coming, valueItem.getData());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
if(isNull()){
|
||||
return null;
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
ValueType valueType = getValueType();
|
||||
jsonObject.put(NAME_value_type, valueType.name());
|
||||
if(valueType==ValueType.STRING){
|
||||
jsonObject.put(NAME_data, getValueAsString());
|
||||
}else if(valueType==ValueType.INT_BOOLEAN){
|
||||
jsonObject.put(NAME_data, getValueAsBoolean());
|
||||
}else {
|
||||
jsonObject.put(NAME_data, getData());
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
ValueType valueType = ValueType.fromName(json.getString(NAME_value_type));
|
||||
if(valueType==ValueType.STRING){
|
||||
setValueAsString(json.optString(NAME_data, ""));
|
||||
}else if(valueType==ValueType.INT_BOOLEAN){
|
||||
setValueAsBoolean(json.getBoolean(NAME_data));
|
||||
}else {
|
||||
setValueType(valueType);
|
||||
setData(json.getInt(NAME_data));
|
||||
}
|
||||
}
|
||||
public StringItem getDataAsPoolString(){
|
||||
if(getValueType()!=ValueType.STRING){
|
||||
return null;
|
||||
}
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null){
|
||||
return null;
|
||||
}
|
||||
return stringPool.get(getData());
|
||||
}
|
||||
private void onTypeChanged(byte old, byte type){
|
||||
byte typeString = ValueType.STRING.getByte();
|
||||
if(old == typeString){
|
||||
unLinkStringReference();
|
||||
}else if(type == typeString){
|
||||
linkStringReference();
|
||||
}
|
||||
}
|
||||
private void linkStringReference(){
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null || stringPool.isStringLinkLocked()){
|
||||
return;
|
||||
}
|
||||
linkStringReference(stringPool);
|
||||
}
|
||||
private void linkStringReference(StringPool<?> stringPool){
|
||||
StringItem tableString = stringPool.get(getData());
|
||||
if(tableString == null){
|
||||
unLinkStringReference();
|
||||
return;
|
||||
}
|
||||
ReferenceItem stringReference = mStringReference;
|
||||
if(stringReference!=null){
|
||||
unLinkStringReference();
|
||||
}
|
||||
stringReference = new ReferenceBlock<>(this, this.sizeOffset + OFFSET_DATA);
|
||||
mStringReference = stringReference;
|
||||
tableString.addReference(stringReference);
|
||||
}
|
||||
private void unLinkStringReference(){
|
||||
ReferenceItem stringReference = mStringReference;
|
||||
if(stringReference==null){
|
||||
return;
|
||||
}
|
||||
mStringReference = null;
|
||||
onUnlinkDataString(stringReference);
|
||||
}
|
||||
protected void onUnlinkDataString(ReferenceItem referenceItem){
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool == null){
|
||||
return;
|
||||
}
|
||||
stringPool.removeReference(referenceItem);
|
||||
}
|
||||
public StringPool<?> getStringPool(){
|
||||
Block parent = getParent();
|
||||
while (parent!=null){
|
||||
if(parent instanceof MainChunk){
|
||||
return ((MainChunk) parent).getStringPool();
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException {
|
||||
int readSize = initializeBytes(reader);
|
||||
super.onReadBytes(reader);
|
||||
if(readSize<8){
|
||||
setBytesLength(this.sizeOffset + 8, false);
|
||||
writeSize();
|
||||
}
|
||||
}
|
||||
private int initializeBytes(BlockReader reader) throws IOException {
|
||||
int position = reader.getPosition();
|
||||
int offset = this.sizeOffset;
|
||||
reader.offset(offset);
|
||||
int readSize = reader.readUnsignedShort();
|
||||
int size = readSize;
|
||||
if(size<8){
|
||||
if(reader.available()>=8){
|
||||
size = 8;
|
||||
}
|
||||
}
|
||||
reader.seek(position);
|
||||
setBytesLength(offset + size, false);
|
||||
return readSize;
|
||||
}
|
||||
@Override
|
||||
public String getValueAsString(){
|
||||
StringItem stringItem = getDataAsPoolString();
|
||||
if(stringItem!=null){
|
||||
String value = stringItem.getHtml();
|
||||
if(value == null){
|
||||
value = "";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void setValueAsString(String str){
|
||||
if(getValueType() == ValueType.STRING
|
||||
&& Objects.equals(str, getValueAsString())){
|
||||
return;
|
||||
}
|
||||
if(str == null){
|
||||
str = "";
|
||||
}
|
||||
StringItem stringItem = getStringPool().getOrCreate(str);
|
||||
setData(stringItem.getIndex());
|
||||
setValueType(ValueType.STRING);
|
||||
}
|
||||
public boolean getValueAsBoolean(){
|
||||
return getData()!=0;
|
||||
}
|
||||
public void setValueAsBoolean(boolean val){
|
||||
setValueType(ValueType.INT_BOOLEAN);
|
||||
int data=val?0xffffffff:0;
|
||||
setData(data);
|
||||
}
|
||||
public void setTypeAndData(ValueType valueType, int data){
|
||||
setData(data);
|
||||
setValueType(valueType);
|
||||
}
|
||||
public void merge(ValueItem valueItem){
|
||||
if(valueItem == null || valueItem==this){
|
||||
return;
|
||||
}
|
||||
setSize(valueItem.getSize());
|
||||
ValueType coming = valueItem.getValueType();
|
||||
if(coming == ValueType.STRING){
|
||||
setValueAsString(valueItem.getValueAsString());
|
||||
}else {
|
||||
setTypeAndData(coming, valueItem.getData());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
if(isNull()){
|
||||
return null;
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
ValueType valueType = getValueType();
|
||||
jsonObject.put(NAME_value_type, valueType.name());
|
||||
if(valueType==ValueType.STRING){
|
||||
jsonObject.put(NAME_data, getValueAsString());
|
||||
}else if(valueType==ValueType.INT_BOOLEAN){
|
||||
jsonObject.put(NAME_data, getValueAsBoolean());
|
||||
}else {
|
||||
jsonObject.put(NAME_data, getData());
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
ValueType valueType = ValueType.fromName(json.getString(NAME_value_type));
|
||||
if(valueType==ValueType.STRING){
|
||||
setValueAsString(json.optString(NAME_data, ""));
|
||||
}else if(valueType==ValueType.INT_BOOLEAN){
|
||||
setValueAsBoolean(json.getBoolean(NAME_data));
|
||||
}else {
|
||||
setValueType(valueType);
|
||||
setData(json.getInt(NAME_data));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int size = getSize();
|
||||
if(size!=8){
|
||||
builder.append("size=").append(getSize());
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("type=");
|
||||
ValueType valueType=getValueType();
|
||||
if(valueType!=null){
|
||||
builder.append(valueType);
|
||||
}else {
|
||||
builder.append(String.format("0x%02x", (0xff & getType())));
|
||||
}
|
||||
builder.append(", data=");
|
||||
int data = getData();
|
||||
if(valueType==ValueType.STRING){
|
||||
StringItem tableString = getDataAsPoolString();
|
||||
if(tableString!=null){
|
||||
builder.append(tableString.getHtml());
|
||||
}else {
|
||||
builder.append(String.format("0x%08x", data));
|
||||
}
|
||||
}else {
|
||||
builder.append(String.format("0x%08x", data));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int size = getSize();
|
||||
if(size!=8){
|
||||
builder.append("size=").append(getSize());
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("type=");
|
||||
ValueType valueType=getValueType();
|
||||
if(valueType!=null){
|
||||
builder.append(valueType);
|
||||
}else {
|
||||
builder.append(HexUtil.toHex2(getType()));
|
||||
}
|
||||
builder.append(", data=");
|
||||
int data = getData();
|
||||
if(valueType==ValueType.STRING){
|
||||
StringItem tableString = getDataAsPoolString();
|
||||
if(tableString!=null){
|
||||
builder.append(tableString.getHtml());
|
||||
}else {
|
||||
builder.append(HexUtil.toHex8(data));
|
||||
}
|
||||
}else {
|
||||
builder.append(HexUtil.toHex8(data));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static final int OFFSET_SIZE = 0;
|
||||
private static final int OFFSET_RES0 = 2;
|
||||
private static final int OFFSET_TYPE = 3;
|
||||
private static final int OFFSET_DATA = 4;
|
||||
private static final int OFFSET_SIZE = 0;
|
||||
private static final int OFFSET_RES0 = 2;
|
||||
private static final int OFFSET_TYPE = 3;
|
||||
private static final int OFFSET_DATA = 4;
|
||||
|
||||
|
||||
public static final String NAME_data = "data";
|
||||
public static final String NAME_value_type = "value_type";
|
||||
}
|
||||
public static final String NAME_data = "data";
|
||||
public static final String NAME_value_type = "value_type";
|
||||
}
|
||||
|
@ -1,95 +1,96 @@
|
||||
/*
|
||||
* 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.arsc.value.array;
|
||||
/*
|
||||
* 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.arsc.value.array;
|
||||
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
import com.reandroid.arsc.value.bag.BagItem;
|
||||
import com.reandroid.arsc.value.ResValueMap;
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
import com.reandroid.arsc.value.bag.BagItem;
|
||||
import com.reandroid.arsc.value.ResValueMap;
|
||||
|
||||
public class ArrayBagItem extends BagItem {
|
||||
private ArrayBagItem(ResValueMap valueMap) {
|
||||
super(valueMap);
|
||||
}
|
||||
public class ArrayBagItem extends BagItem {
|
||||
private ArrayBagItem(ResValueMap valueMap) {
|
||||
super(valueMap);
|
||||
}
|
||||
|
||||
private ArrayBagItem(StringItem str) {
|
||||
super(str);
|
||||
}
|
||||
private ArrayBagItem(StringItem str) {
|
||||
super(str);
|
||||
}
|
||||
|
||||
private ArrayBagItem(ValueType valueType, int value) {
|
||||
super(valueType, value);
|
||||
}
|
||||
private ArrayBagItem(ValueType valueType, int value) {
|
||||
super(valueType, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<item>");
|
||||
if (hasStringValue()) {
|
||||
builder.append(getStringValue());
|
||||
} else {
|
||||
builder.append(String.format("0x%08x", getValue()));
|
||||
}
|
||||
builder.append("</item>");
|
||||
return builder.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<item>");
|
||||
if (hasStringValue()) {
|
||||
builder.append(getStringValue());
|
||||
} else {
|
||||
builder.append(HexUtil.toHex8(getValue()));
|
||||
}
|
||||
builder.append("</item>");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected static ArrayBagItem create(ResValueMap valueMap) {
|
||||
if (valueMap == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(valueMap);
|
||||
}
|
||||
protected static ArrayBagItem create(ResValueMap valueMap) {
|
||||
if (valueMap == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(valueMap);
|
||||
}
|
||||
|
||||
public static ArrayBagItem create(ValueType valueType, int value) {
|
||||
if (valueType == null || valueType == ValueType.STRING) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(valueType, value);
|
||||
}
|
||||
public static ArrayBagItem create(ValueType valueType, int value) {
|
||||
if (valueType == null || valueType == ValueType.STRING) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(valueType, value);
|
||||
}
|
||||
|
||||
protected static ArrayBagItem copyOf(ResValueMap resValueMap) {
|
||||
ValueType valueType = resValueMap.getValueType();
|
||||
if (valueType == ValueType.STRING) {
|
||||
return new ArrayBagItem(resValueMap.getDataAsPoolString());
|
||||
} else {
|
||||
return new ArrayBagItem(valueType, resValueMap.getData());
|
||||
}
|
||||
}
|
||||
protected static ArrayBagItem copyOf(ResValueMap resValueMap) {
|
||||
ValueType valueType = resValueMap.getValueType();
|
||||
if (valueType == ValueType.STRING) {
|
||||
return new ArrayBagItem(resValueMap.getDataAsPoolString());
|
||||
} else {
|
||||
return new ArrayBagItem(valueType, resValueMap.getData());
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayBagItem encoded(ValueDecoder.EncodeResult encodeResult) {
|
||||
if (encodeResult == null) {
|
||||
return null;
|
||||
}
|
||||
return create(encodeResult.valueType, encodeResult.value);
|
||||
}
|
||||
public static ArrayBagItem encoded(ValueDecoder.EncodeResult encodeResult) {
|
||||
if (encodeResult == null) {
|
||||
return null;
|
||||
}
|
||||
return create(encodeResult.valueType, encodeResult.value);
|
||||
}
|
||||
|
||||
public static ArrayBagItem integer(int n) {
|
||||
return create(ValueType.INT_DEC, n);
|
||||
}
|
||||
public static ArrayBagItem integer(int n) {
|
||||
return create(ValueType.INT_DEC, n);
|
||||
}
|
||||
|
||||
public static ArrayBagItem string(TableString str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(str);
|
||||
}
|
||||
public static ArrayBagItem string(TableString str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayBagItem(str);
|
||||
}
|
||||
|
||||
public static ArrayBagItem reference(int resourceId) {
|
||||
return create(ValueType.REFERENCE, resourceId);
|
||||
}
|
||||
}
|
||||
public static ArrayBagItem reference(int resourceId) {
|
||||
return create(ValueType.REFERENCE, resourceId);
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.arsc.value.attribute;
|
||||
|
||||
import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.group.EntryGroup;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.ResValueMap;
|
||||
import com.reandroid.common.EntryStore;
|
||||
@ -36,7 +37,7 @@ public class AttributeBagItem {
|
||||
public String getNameOrHex(EntryStore entryStore){
|
||||
String name=getName(entryStore);
|
||||
if(name==null){
|
||||
name=String.format("@0x%08x", getBagItem().getName());
|
||||
name=HexUtil.toHex8("@0x", getBagItem().getName());
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@ -162,7 +163,7 @@ public class AttributeBagItem {
|
||||
}
|
||||
ResValueMap item=getBagItem();
|
||||
builder.append(getNameOrHex());
|
||||
builder.append("=").append(String.format("0x%x", item.getData()));
|
||||
builder.append("=").append(HexUtil.toHex8(item.getData()));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@ -214,6 +215,4 @@ public class AttributeBagItem {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
import com.reandroid.arsc.chunk.TableBlock;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.*;
|
||||
import com.reandroid.arsc.value.bag.BagItem;
|
||||
|
||||
@ -83,7 +84,7 @@
|
||||
}
|
||||
|
||||
private String formattedRefValue() {
|
||||
return String.format("@0x%08x", getValue());
|
||||
return HexUtil.toHex8("@0x", getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,189 +1,190 @@
|
||||
/*
|
||||
* 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.arsc.value.style;
|
||||
/*
|
||||
* 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.arsc.value.style;
|
||||
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.value.attribute.AttributeBag;
|
||||
import com.reandroid.arsc.value.attribute.AttributeBagItem;
|
||||
import com.reandroid.arsc.value.bag.BagItem;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.ResValueMap;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
import com.reandroid.common.EntryStore;
|
||||
import com.reandroid.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
import com.reandroid.arsc.util.HexUtil;
|
||||
import com.reandroid.arsc.value.attribute.AttributeBag;
|
||||
import com.reandroid.arsc.value.attribute.AttributeBagItem;
|
||||
import com.reandroid.arsc.value.bag.BagItem;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.arsc.value.ResValueMap;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
import com.reandroid.common.EntryStore;
|
||||
|
||||
public class StyleBagItem extends BagItem {
|
||||
private StyleBagItem(ResValueMap bagItem) {
|
||||
super(bagItem);
|
||||
}
|
||||
public class StyleBagItem extends BagItem {
|
||||
private StyleBagItem(ResValueMap bagItem) {
|
||||
super(bagItem);
|
||||
}
|
||||
|
||||
private StyleBagItem(ValueType valueType, int data) {
|
||||
super(valueType, data);
|
||||
}
|
||||
private StyleBagItem(ValueType valueType, int data) {
|
||||
super(valueType, data);
|
||||
}
|
||||
|
||||
private StyleBagItem(StringItem str) {
|
||||
super(str);
|
||||
}
|
||||
private StyleBagItem(StringItem str) {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (mBagItem == null) {
|
||||
return null;
|
||||
}
|
||||
Entry block = mBagItem.getEntry();
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
char prefix = 0;
|
||||
return block.buildResourceName(mBagItem.getName(), prefix, false);
|
||||
}
|
||||
public Entry getAttributeEntry(EntryStore entryStore) {
|
||||
if (mBagItem == null) {
|
||||
return null;
|
||||
}
|
||||
return entryStore.getEntryGroup(mBagItem.getName()).pickOne();
|
||||
}
|
||||
public String getName() {
|
||||
if (mBagItem == null) {
|
||||
return null;
|
||||
}
|
||||
Entry block = mBagItem.getEntry();
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
char prefix = 0;
|
||||
return block.buildResourceName(mBagItem.getName(), prefix, false);
|
||||
}
|
||||
public Entry getAttributeEntry(EntryStore entryStore) {
|
||||
if (mBagItem == null) {
|
||||
return null;
|
||||
}
|
||||
return entryStore.getEntryGroup(mBagItem.getName()).pickOne();
|
||||
}
|
||||
|
||||
public int getNameId() {
|
||||
if (mBagItem == null) {
|
||||
return 0;
|
||||
}
|
||||
return mBagItem.getName();
|
||||
}
|
||||
public int getNameId() {
|
||||
if (mBagItem == null) {
|
||||
return 0;
|
||||
}
|
||||
return mBagItem.getName();
|
||||
}
|
||||
|
||||
public boolean hasAttributeValue() {
|
||||
return getValueType() == ValueType.ATTRIBUTE;
|
||||
}
|
||||
public boolean hasIntValue() {
|
||||
ValueType valueType = getValueType();
|
||||
return valueType == ValueType.INT_DEC || valueType == ValueType.INT_HEX;
|
||||
}
|
||||
public boolean hasAttributeValue() {
|
||||
return getValueType() == ValueType.ATTRIBUTE;
|
||||
}
|
||||
public boolean hasIntValue() {
|
||||
ValueType valueType = getValueType();
|
||||
return valueType == ValueType.INT_DEC || valueType == ValueType.INT_HEX;
|
||||
}
|
||||
|
||||
public String getValueAsReference() {
|
||||
ValueType valueType = getValueType();
|
||||
if (valueType != ValueType.REFERENCE && valueType != ValueType.ATTRIBUTE) {
|
||||
throw new IllegalArgumentException("Not REF ValueType=" + valueType);
|
||||
}
|
||||
Entry entry = getBagItem().getEntry();
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
char prefix = '@';
|
||||
boolean includeType = true;
|
||||
if (valueType == ValueType.ATTRIBUTE) {
|
||||
prefix = '?';
|
||||
includeType = false;
|
||||
}
|
||||
int id = getValue();
|
||||
return entry.buildResourceName(id, prefix, includeType);
|
||||
}
|
||||
public String decodeAttributeValue(AttributeBag attr, EntryStore entryStore) {
|
||||
if (!hasIntValue()) {
|
||||
return null;
|
||||
}
|
||||
return attr.decodeAttributeValue(entryStore, getValue());
|
||||
}
|
||||
public AttributeBagItem[] getFlagsOrEnum(AttributeBag attr) {
|
||||
if (!hasIntValue()) {
|
||||
return null;
|
||||
}
|
||||
return attr.searchValue(getValue());
|
||||
}
|
||||
public String getValueAsReference() {
|
||||
ValueType valueType = getValueType();
|
||||
if (valueType != ValueType.REFERENCE && valueType != ValueType.ATTRIBUTE) {
|
||||
throw new IllegalArgumentException("Not REF ValueType=" + valueType);
|
||||
}
|
||||
Entry entry = getBagItem().getEntry();
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
char prefix = '@';
|
||||
boolean includeType = true;
|
||||
if (valueType == ValueType.ATTRIBUTE) {
|
||||
prefix = '?';
|
||||
includeType = false;
|
||||
}
|
||||
int id = getValue();
|
||||
return entry.buildResourceName(id, prefix, includeType);
|
||||
}
|
||||
public String decodeAttributeValue(AttributeBag attr, EntryStore entryStore) {
|
||||
if (!hasIntValue()) {
|
||||
return null;
|
||||
}
|
||||
return attr.decodeAttributeValue(entryStore, getValue());
|
||||
}
|
||||
public AttributeBagItem[] getFlagsOrEnum(AttributeBag attr) {
|
||||
if (!hasIntValue()) {
|
||||
return null;
|
||||
}
|
||||
return attr.searchValue(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<item name=\"");
|
||||
String name = getName();
|
||||
if (name == null) {
|
||||
name = String.format("@0x%08x", getNameId());
|
||||
}
|
||||
builder.append(name);
|
||||
builder.append("\">");
|
||||
if (hasStringValue()) {
|
||||
builder.append(getStringValue());
|
||||
}
|
||||
String val = null;
|
||||
if (hasReferenceValue() || hasAttributeValue()) {
|
||||
val = getValueAsReference();
|
||||
}
|
||||
if (val == null) {
|
||||
val = String.format("0x%08x", getValue());
|
||||
}
|
||||
builder.append(val);
|
||||
builder.append("</item>");
|
||||
return builder.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<item name=\"");
|
||||
String name = getName();
|
||||
if (name == null) {
|
||||
name = HexUtil.toHex8("@0x", getNameId());
|
||||
}
|
||||
builder.append(name);
|
||||
builder.append("\">");
|
||||
if (hasStringValue()) {
|
||||
builder.append(getStringValue());
|
||||
}
|
||||
String val = null;
|
||||
if (hasReferenceValue() || hasAttributeValue()) {
|
||||
val = getValueAsReference();
|
||||
}
|
||||
if (val == null) {
|
||||
val = HexUtil.toHex8(getValue());
|
||||
}
|
||||
builder.append(val);
|
||||
builder.append("</item>");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected static StyleBagItem create(ResValueMap resValueMap) {
|
||||
if (resValueMap == null) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(resValueMap);
|
||||
}
|
||||
protected static StyleBagItem create(ResValueMap resValueMap) {
|
||||
if (resValueMap == null) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(resValueMap);
|
||||
}
|
||||
|
||||
public static StyleBagItem create(ValueType valueType, int value) {
|
||||
if (valueType == null || valueType == ValueType.STRING) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(valueType, value);
|
||||
}
|
||||
public static StyleBagItem create(ValueType valueType, int value) {
|
||||
if (valueType == null || valueType == ValueType.STRING) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(valueType, value);
|
||||
}
|
||||
|
||||
protected static StyleBagItem copyOf(ResValueMap resValueMap) {
|
||||
ValueType valueType = resValueMap.getValueType();
|
||||
if (valueType == ValueType.STRING) {
|
||||
return new StyleBagItem(resValueMap.getDataAsPoolString());
|
||||
} else {
|
||||
return new StyleBagItem(valueType, resValueMap.getData());
|
||||
}
|
||||
}
|
||||
protected static StyleBagItem copyOf(ResValueMap resValueMap) {
|
||||
ValueType valueType = resValueMap.getValueType();
|
||||
if (valueType == ValueType.STRING) {
|
||||
return new StyleBagItem(resValueMap.getDataAsPoolString());
|
||||
} else {
|
||||
return new StyleBagItem(valueType, resValueMap.getData());
|
||||
}
|
||||
}
|
||||
|
||||
public static StyleBagItem integer(int n) {
|
||||
return new StyleBagItem(ValueType.INT_DEC, n);
|
||||
}
|
||||
public static StyleBagItem integer(int n) {
|
||||
return new StyleBagItem(ValueType.INT_DEC, n);
|
||||
}
|
||||
|
||||
public static StyleBagItem string(TableString str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(str);
|
||||
}
|
||||
public static StyleBagItem string(TableString str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return new StyleBagItem(str);
|
||||
}
|
||||
|
||||
public static StyleBagItem reference(int resourceId) {
|
||||
return new StyleBagItem(ValueType.REFERENCE, resourceId);
|
||||
}
|
||||
public static StyleBagItem attribute(int resourceId) {
|
||||
return new StyleBagItem(ValueType.ATTRIBUTE, resourceId);
|
||||
}
|
||||
public static StyleBagItem encoded(ValueDecoder.EncodeResult encodeResult) {
|
||||
if (encodeResult == null) {
|
||||
return null;
|
||||
}
|
||||
return create(encodeResult.valueType, encodeResult.value);
|
||||
}
|
||||
public static StyleBagItem color(String color) {
|
||||
return encoded(ValueDecoder.encodeColor(color));
|
||||
}
|
||||
public static StyleBagItem dimensionOrFraction(String str) {
|
||||
return encoded(ValueDecoder.encodeDimensionOrFraction(str));
|
||||
}
|
||||
public static StyleBagItem createFloat(float n) {
|
||||
return new StyleBagItem(ValueType.FLOAT, Float.floatToIntBits(n));
|
||||
}
|
||||
public static StyleBagItem enumOrFlag(AttributeBag attr, String valueString) {
|
||||
return encoded(attr.encodeEnumOrFlagValue(valueString));
|
||||
}
|
||||
}
|
||||
public static StyleBagItem reference(int resourceId) {
|
||||
return new StyleBagItem(ValueType.REFERENCE, resourceId);
|
||||
}
|
||||
public static StyleBagItem attribute(int resourceId) {
|
||||
return new StyleBagItem(ValueType.ATTRIBUTE, resourceId);
|
||||
}
|
||||
public static StyleBagItem encoded(ValueDecoder.EncodeResult encodeResult) {
|
||||
if (encodeResult == null) {
|
||||
return null;
|
||||
}
|
||||
return create(encodeResult.valueType, encodeResult.value);
|
||||
}
|
||||
public static StyleBagItem color(String color) {
|
||||
return encoded(ValueDecoder.encodeColor(color));
|
||||
}
|
||||
public static StyleBagItem dimensionOrFraction(String str) {
|
||||
return encoded(ValueDecoder.encodeDimensionOrFraction(str));
|
||||
}
|
||||
public static StyleBagItem createFloat(float n) {
|
||||
return new StyleBagItem(ValueType.FLOAT, Float.floatToIntBits(n));
|
||||
}
|
||||
public static StyleBagItem enumOrFlag(AttributeBag attr, String valueString) {
|
||||
return encoded(attr.encodeEnumOrFlagValue(valueString));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user