From a17ba317b9fb147ae75a905c0e6147cf7f199d0a Mon Sep 17 00:00:00 2001 From: REAndroid Date: Sun, 20 Nov 2022 16:10:21 -0500 Subject: [PATCH] V1.0.1 --- build.gradle | 4 + libs/ArchiveUtil.jar | Bin 0 -> 24935 bytes .../reandroid/lib/arsc/chunk/TableBlock.java | 56 ++++++- .../arsc/chunk/xml/AndroidManifestBlock.java | 1 + .../lib/arsc/decoder/ValueDecoder.java | 1 - .../reandroid/lib/arsc/io/BlockReader.java | 1 - .../reandroid/lib/arsc/value/EntryBlock.java | 118 +++++++++++--- .../reandroid/lib/arsc/value/ResConfig.java | 3 + .../lib/arsc/value/ResConfigHelper.java | 126 ++++++++------- .../lib/arsc/value/ResValueBagItem.java | 16 +- .../lib/arsc/value/array/ArrayBag.java | 90 +++++++++++ .../lib/arsc/value/array/ArrayBagItem.java | 107 +++++++++++++ .../lib/arsc/value/plurals/PluralsBag.java | 90 +++++++++++ .../arsc/value/plurals/PluralsBagItem.java | 115 ++++++++++++++ .../lib/arsc/value/style/StyleBag.java | 126 +++++++++++++++ .../lib/arsc/value/style/StyleBagItem.java | 149 ++++++++++++++++++ 16 files changed, 914 insertions(+), 89 deletions(-) create mode 100644 libs/ArchiveUtil.jar create mode 100644 src/main/java/com/reandroid/lib/arsc/value/array/ArrayBag.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/array/ArrayBagItem.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/plurals/PluralsBag.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/plurals/PluralsBagItem.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/style/StyleBag.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/style/StyleBagItem.java diff --git a/build.gradle b/build.gradle index 0e23ca1..db1c9d5 100755 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,10 @@ repositories { mavenLocal() } +dependencies { + compile(files("$rootProject.projectDir/libs/ArchiveUtil.jar")) +} + processResources { filesMatching('lib.properties') { expand('version': version) diff --git a/libs/ArchiveUtil.jar b/libs/ArchiveUtil.jar new file mode 100644 index 0000000000000000000000000000000000000000..222aafb8f9f7cf152dc2853dc7eabef6d484aa4e GIT binary patch literal 24935 zcma&NV~}OtvW8o>ZJS-T(Pf)mwpZD5P9szCqa0RsX9GP1K_{2B)WQuxOzguf^LRpn@6U~BAXXJO3v z&$Sr;pIQS)BXbKElm9q_1_T8K1vDr0zkdbUKc3ODuotqnFtcSavNmvX%GQMS%3N|5 zI7vK|PY`&eCm(-@Zbmt{4}+J>7<56~A9M-0>IDAT+%rg$Vob)xNL7S}Rm+wntldv# zR9V5XY%@hPJw;4c&?lOrJeD-`6!_GrthI&irA?l^qneSdfJ#eJ*&wW z{R1u6AcV+@n@7h!HYbx&5^ z(4Apo9y<(d2F-@0IC6NZp>uJpAvl9{QODvqKmS=OtX1a(=Ild>{lEkpRV3ic^Q;*#A2rzTnHDwdwkgB@D6T}!GL+OpjVDj}EbJwH&>mwi?Rjw= zqq^6QzPB7xVh@YT!TgGYa;L(LB5xP=_>_4YX!--)?1&>sdjn^sc~lU4A?dPrJ(+f+ z{|bLk_NvOcK#r`0X=+re(i)DVY7_?0$Yu-8qw+zOmaMgdVSAyWxT3dGN3yv*O9NtC za;E8jsd3Q$)Krz;6!Ggg;�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 literal 0 HcmV?d00001 diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java index 0495055..dc4f7d1 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java @@ -2,18 +2,23 @@ package com.reandroid.lib.arsc.chunk; import com.reandroid.lib.arsc.array.PackageArray; import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock; +import com.reandroid.lib.arsc.group.EntryGroup; import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.common.Frameworks; import java.io.*; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class TableBlock extends BaseChunk { private final IntegerItem mPackageCount; private final TableStringPool mTableStringPool; private final PackageArray mPackageArray; + private final Set mFrameWorks=new HashSet<>(); public TableBlock() { super(ChunkType.TABLE, 2); this.mPackageCount=new IntegerItem(); @@ -81,18 +86,60 @@ public class TableBlock extends BaseChunk { builder.append(pkgCount); return builder.toString(); } - + public EntryGroup search(int resourceId){ + if(resourceId==0){ + return null; + } + int pkgId=resourceId>>24; + pkgId=pkgId&0xff; + PackageBlock packageBlock=getPackageBlockById((byte) pkgId); + if(packageBlock!=null){ + EntryGroup entryGroup=packageBlock.getEntryGroup(resourceId); + if(entryGroup!=null){ + return entryGroup; + } + } + for(TableBlock tableBlock:getFrameWorks()){ + EntryGroup entryGroup= tableBlock.search(resourceId); + if(entryGroup!=null){ + return entryGroup; + } + } + return null; + } + public Set getFrameWorks(){ + return mFrameWorks; + } + public void addFramework(TableBlock tableBlock){ + if(tableBlock==null||tableBlock==this){ + return; + } + for(TableBlock frm:tableBlock.getFrameWorks()){ + if(frm==this){ + return; + } + } + mFrameWorks.add(tableBlock); + } + public static TableBlock loadWithAndroidFramework(InputStream inputStream) throws IOException{ + TableBlock tableBlock=new TableBlock(); + tableBlock.readBytes(inputStream); + tableBlock.addFramework(Frameworks.getAndroid()); + return tableBlock; + } public static boolean isResTableBlock(File file){ if(file==null){ return false; } + boolean result=false; try { InputStream inputStream=new FileInputStream(file); - return isResTableBlock(inputStream); - } catch (FileNotFoundException ignored) { - return false; + result=isResTableBlock(inputStream); + inputStream.close(); + } catch (IOException ignored) { } + return result; } public static boolean isResTableBlock(InputStream inputStream){ try { @@ -120,5 +167,6 @@ public class TableBlock extends BaseChunk { ChunkType chunkType=headerBlock.getChunkType(); return chunkType==ChunkType.TABLE; } + public static final String FILE_NAME="resources.arsc"; } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java index 67b98c0..04e1c24 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java @@ -163,4 +163,5 @@ public class AndroidManifestBlock extends ResXmlBlock{ private static final String ATTR_versionName="versionName"; private static final String ATTR_android_name="name"; + public static final String FILE_NAME="AndroidManifest.xml"; } diff --git a/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java b/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java index 423dade..5319066 100755 --- a/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java +++ b/src/main/java/com/reandroid/lib/arsc/decoder/ValueDecoder.java @@ -45,7 +45,6 @@ public class ValueDecoder { return attributeBag.decodeAttributeValue(store, rawValue); } - public static String decodeEntryValue(EntryStore store, PackageBlock currentPackage, ValueType valueType, int data){ if(store==null || currentPackage==null){ return null; diff --git a/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java b/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java index ba8d334..11dbbf7 100755 --- a/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java +++ b/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java @@ -315,7 +315,6 @@ public class BlockReader extends InputStream { while((len=in.read(buff))>0){ result=add(result, buff, len); } - in.close(); return result; } private static byte[] add(byte[] arr1, byte[] arr2, int len){ diff --git a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java index e777599..5c52e15 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java @@ -5,6 +5,7 @@ import com.reandroid.lib.arsc.base.BlockCounter; import com.reandroid.lib.arsc.chunk.PackageBlock; import com.reandroid.lib.arsc.chunk.TableBlock; import com.reandroid.lib.arsc.chunk.TypeBlock; +import com.reandroid.lib.arsc.group.EntryGroup; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.pool.SpecStringPool; @@ -202,6 +203,27 @@ public class EntryBlock extends Block { } return null; } + public String getName(){ + SpecString specString=getSpecString(); + if(specString==null){ + return null; + } + return specString.get(); + } + public String getTypeName(){ + TypeString typeString=getTypeString(); + if(typeString==null){ + return null; + } + return typeString.get(); + } + public String getPackageName(){ + PackageBlock packageBlock=getPackageBlock(); + if(packageBlock==null){ + return null; + } + return packageBlock.getPackageName(); + } public SpecString getSpecString(){ PackageBlock packageBlock=getPackageBlock(); if(packageBlock==null){ @@ -217,35 +239,60 @@ public class EntryBlock extends Block { } return null; } + public String buildResourceName(int resourceId, char prefix, boolean includeType){ + if(resourceId==0){ + return null; + } + EntryBlock entryBlock=searchEntry(resourceId); + return buildResourceName(entryBlock, prefix, includeType); + } + private EntryBlock searchEntry(int resourceId){ + if(resourceId==getResourceId()){ + return this; + } + PackageBlock packageBlock=getPackageBlock(); + if(packageBlock==null){ + return null; + } + TableBlock tableBlock= packageBlock.getTableBlock(); + if(tableBlock==null){ + return null; + } + EntryGroup entryGroup = tableBlock.search(resourceId); + if(entryGroup!=null){ + return entryGroup.pickOne(); + } + return null; + } + public String buildResourceName(EntryBlock entryBlock, char prefix, boolean includeType){ + if(entryBlock==null){ + return null; + } + String pkgName=entryBlock.getPackageName(); + if(getResourceId()==entryBlock.getResourceId()){ + pkgName=null; + }else if(pkgName!=null){ + if(pkgName.equals(this.getPackageName())){ + pkgName=null; + } + } + String type=null; + if(includeType){ + type=entryBlock.getTypeName(); + } + String name=entryBlock.getName(); + return buildResourceName(prefix, pkgName, type, name); + } public String getResourceName(){ - return getResourceName("@", null); + return buildResourceName('@',null, getTypeName(), getName()); } - public String getResourceName(String prefix){ - return getResourceName(prefix, null); + public String getResourceName(char prefix){ + return getResourceName(prefix, false, true); } - public String getResourceName(String prefix, String appName){ - if(isNull()){ - return null; - } - TypeString type=getTypeString(); - if(type==null){ - return null; - } - SpecString spec=getSpecString(); - if(spec==null){ - return null; - } - StringBuilder builder=new StringBuilder(); - if(prefix!=null){ - builder.append(prefix); - } - if(appName!=null){ - builder.append(appName); - } - builder.append(type.get()); - builder.append('/'); - builder.append(spec.get()); - return builder.toString(); + public String getResourceName(char prefix, boolean includePackage, boolean includeType){ + String pkg=includePackage?getPackageName():null; + String type=includeType?getTypeName():null; + return buildResourceName(prefix,pkg, type, getName()); } public int getResourceId(){ TypeBlock typeBlock=getTypeBlock(); @@ -497,6 +544,25 @@ public class EntryBlock extends Block { } return builder.toString(); } + public static String buildResourceName(char prefix, String packageName, String type, String name){ + if(name==null){ + return null; + } + StringBuilder builder=new StringBuilder(); + if(prefix!=0){ + builder.append(prefix); + } + if(packageName!=null){ + builder.append(packageName); + builder.append(':'); + } + if(type!=null){ + builder.append(type); + builder.append('/'); + } + builder.append(name); + return builder.toString(); + } private final static short FLAG_COMPLEX_MASK = 0x0001; diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java index f179427..2e37f20 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java @@ -495,6 +495,9 @@ public class ResConfig extends BlockArray implements BlockLoad { qualifiers=ResConfigHelper.sortQualifiers(qualifiers); return getQualifiers().equals(qualifiers); } + public String getLocale(){ + return ResConfigHelper.decodeLocale(this); + } @Override public boolean equals(Object o){ if(o instanceof ResConfig){ diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResConfigHelper.java b/src/main/java/com/reandroid/lib/arsc/value/ResConfigHelper.java index df9537a..50c550c 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResConfigHelper.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResConfigHelper.java @@ -139,6 +139,24 @@ public class ResConfigHelper { char[] chs=country.toCharArray(); resConfig.setRegion(chs); } + public static String decodeLocale(ResConfig resConfig){ + char[] region=resConfig.getRegion(); + char[] language=resConfig.getLanguage(); + StringBuilder builder=new StringBuilder(); + if(language[0]!=0){ + builder.append(language[0]).append(language[1]); + } + if(region[0]!=0){ + if(language[0]!=0){ + builder.append('-'); + } + builder.append(region[0]).append(region[1]); + } + if(builder.length()==0){ + return null; + } + return builder.toString(); + } private static String decodeLanguageAndCountry(ResConfig resConfig) { StringBuilder builder = new StringBuilder(); char[] localeVariant=resConfig.getLocaleVariant(); @@ -993,81 +1011,81 @@ public class ResConfigHelper { private static final Pattern PATTERN_SCREEN_SIZE=Pattern.compile("^-?(?[0-9]+)x(?[0-9]+)$"); - private final static short MASK_LAYOUTDIR = 0xc0; - private final static short SCREENLAYOUT_LAYOUTDIR_ANY = 0x00; - private final static short SCREENLAYOUT_LAYOUTDIR_LTR = 0x40; - private final static short SCREENLAYOUT_LAYOUTDIR_RTL = 0x80; - private final static short SCREENLAYOUT_LAYOUTDIR_SHIFT = 0x06; + public final static short MASK_LAYOUTDIR = 0xc0; + public final static short SCREENLAYOUT_LAYOUTDIR_ANY = 0x00; + public final static short SCREENLAYOUT_LAYOUTDIR_LTR = 0x40; + public final static short SCREENLAYOUT_LAYOUTDIR_RTL = 0x80; + public final static short SCREENLAYOUT_LAYOUTDIR_SHIFT = 0x06; - private final static byte MASK_SCREENSIZE = 0x0f; - private final static byte SCREENSIZE_ANY = 0x00; - private final static byte SCREENSIZE_SMALL = 0x01; - private final static byte SCREENSIZE_NORMAL = 0x02; - private final static byte SCREENSIZE_LARGE = 0x03; - private final static byte SCREENSIZE_XLARGE = 0x04; + public final static byte MASK_SCREENSIZE = 0x0f; + public final static byte SCREENSIZE_ANY = 0x00; + public final static byte SCREENSIZE_SMALL = 0x01; + public final static byte SCREENSIZE_NORMAL = 0x02; + public final static byte SCREENSIZE_LARGE = 0x03; + public final static byte SCREENSIZE_XLARGE = 0x04; - private final static byte MASK_SCREENLONG = 0x30; - private final static byte SCREENLONG_ANY = 0x00; - private final static byte SCREENLONG_NO = 0x10; - private final static byte SCREENLONG_YES = 0x20; + public final static byte MASK_SCREENLONG = 0x30; + public final static byte SCREENLONG_ANY = 0x00; + public final static byte SCREENLONG_NO = 0x10; + public final static byte SCREENLONG_YES = 0x20; - private final static short MASK_SCREENROUND = 0x03; - private final static short SCREENLAYOUT_ROUND_ANY = 0; - private final static short SCREENLAYOUT_ROUND_NO = 0x1; - private final static short SCREENLAYOUT_ROUND_YES = 0x2; + public final static short MASK_SCREENROUND = 0x03; + public final static short SCREENLAYOUT_ROUND_ANY = 0; + public final static short SCREENLAYOUT_ROUND_NO = 0x1; + public final static short SCREENLAYOUT_ROUND_YES = 0x2; - private final static byte ORIENTATION_ANY = 0; - private final static byte ORIENTATION_PORT = 1; - private final static byte ORIENTATION_LAND = 2; - private final static byte ORIENTATION_SQUARE = 3; + public final static byte ORIENTATION_ANY = 0; + public final static byte ORIENTATION_PORT = 1; + public final static byte ORIENTATION_LAND = 2; + public final static byte ORIENTATION_SQUARE = 3; - private final static byte MASK_UI_MODE_TYPE = 0x0f; - private final static byte UI_MODE_TYPE_ANY = 0x00; - private final static byte UI_MODE_TYPE_NORMAL = 0x01; - private final static byte UI_MODE_TYPE_DESK = 0x02; - private final static byte UI_MODE_TYPE_CAR = 0x03; - private final static byte UI_MODE_TYPE_TELEVISION = 0x04; - private final static byte UI_MODE_TYPE_APPLIANCE = 0x05; - private final static byte UI_MODE_TYPE_WATCH = 0x06; - private final static byte UI_MODE_TYPE_VR_HEADSET = 0x07; + public final static byte MASK_UI_MODE_TYPE = 0x0f; + public final static byte UI_MODE_TYPE_ANY = 0x00; + public final static byte UI_MODE_TYPE_NORMAL = 0x01; + public final static byte UI_MODE_TYPE_DESK = 0x02; + public final static byte UI_MODE_TYPE_CAR = 0x03; + public final static byte UI_MODE_TYPE_TELEVISION = 0x04; + public final static byte UI_MODE_TYPE_APPLIANCE = 0x05; + public final static byte UI_MODE_TYPE_WATCH = 0x06; + public final static byte UI_MODE_TYPE_VR_HEADSET = 0x07; - private final static byte MASK_UI_MODE_NIGHT = 0x30; - private final static byte UI_MODE_NIGHT_ANY = 0x00; - private final static byte UI_MODE_NIGHT_NO = 0x10; - private final static byte UI_MODE_NIGHT_YES = 0x20; + public final static byte MASK_UI_MODE_NIGHT = 0x30; + public final static byte UI_MODE_NIGHT_ANY = 0x00; + public final static byte UI_MODE_NIGHT_NO = 0x10; + public final static byte UI_MODE_NIGHT_YES = 0x20; - private final static byte UI_MODE_TYPE_GODZILLAUI = 0x0b; - private final static byte UI_MODE_TYPE_SMALLUI = 0x0c; - private final static byte UI_MODE_TYPE_MEDIUMUI = 0x0d; - private final static byte UI_MODE_TYPE_LARGEUI = 0x0e; - private final static byte UI_MODE_TYPE_HUGEUI = 0x0f; + public final static byte UI_MODE_TYPE_GODZILLAUI = 0x0b; + public final static byte UI_MODE_TYPE_SMALLUI = 0x0c; + public final static byte UI_MODE_TYPE_MEDIUMUI = 0x0d; + public final static byte UI_MODE_TYPE_LARGEUI = 0x0e; + public final static byte UI_MODE_TYPE_HUGEUI = 0x0f; - private final static byte TOUCHSCREEN_ANY = 0; - private final static byte TOUCHSCREEN_NOTOUCH = 1; - private final static byte TOUCHSCREEN_STYLUS = 2; - private final static byte TOUCHSCREEN_FINGER = 3; + public final static byte TOUCHSCREEN_ANY = 0; + public final static byte TOUCHSCREEN_NOTOUCH = 1; + public final static byte TOUCHSCREEN_STYLUS = 2; + public final static byte TOUCHSCREEN_FINGER = 3; - private final static byte MASK_KEYSHIDDEN = 0x3; - private final static byte KEYSHIDDEN_ANY = 0x0; - private final static byte KEYSHIDDEN_NO = 0x1; - private final static byte KEYSHIDDEN_YES = 0x2; - private final static byte KEYSHIDDEN_SOFT = 0x3; + public final static byte MASK_KEYSHIDDEN = 0x3; + public final static byte KEYSHIDDEN_ANY = 0x0; + public final static byte KEYSHIDDEN_NO = 0x1; + public final static byte KEYSHIDDEN_YES = 0x2; + public final static byte KEYSHIDDEN_SOFT = 0x3; private final static byte KEYBOARD_ANY = 0; private final static byte KEYBOARD_NOKEYS = 1; private final static byte KEYBOARD_QWERTY = 2; private final static byte KEYBOARD_12KEY = 3; - private final static byte MASK_NAVHIDDEN = 0xc; - private final static byte NAVHIDDEN_ANY = 0x0; - private final static byte NAVHIDDEN_NO = 0x4; - private final static byte NAVHIDDEN_YES = 0x8; + public final static byte MASK_NAVHIDDEN = 0xc; + public final static byte NAVHIDDEN_ANY = 0x0; + public final static byte NAVHIDDEN_NO = 0x4; + public final static byte NAVHIDDEN_YES = 0x8; private final static byte NAVIGATION_ANY = 0; diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java b/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java index f80bc79..1cdc79f 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResValueBagItem.java @@ -1,8 +1,7 @@ package com.reandroid.lib.arsc.value; -import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.item.ReferenceItem; -import com.reandroid.lib.arsc.pool.SpecStringPool; public class ResValueBagItem extends BaseResValueItem{ @@ -11,6 +10,17 @@ public class ResValueBagItem extends BaseResValueItem{ setHeaderSize(BYTES_SIZE); } + public ResValueBag getParentBag(){ + Block parent=getParent(); + while(parent!=null){ + if(parent instanceof ResValueBag){ + return (ResValueBag) parent; + } + parent=parent.getParent(); + } + return null; + } + @Override public void setHeaderSize(short size) { setShort(OFFSET_SIZE, size); @@ -28,13 +38,13 @@ public class ResValueBagItem extends BaseResValueItem{ return getByte(OFFSET_RESERVED); } - public void setId(int id){ setInt(OFFSET_ID, id); } public int getId(){ return getInt(OFFSET_ID); } + @Override public void setType(ValueType valueType){ byte type=0; diff --git a/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBag.java b/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBag.java new file mode 100644 index 0000000..8fe936e --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBag.java @@ -0,0 +1,90 @@ +package com.reandroid.lib.arsc.value.array; + +import com.reandroid.lib.arsc.item.SpecString; +import com.reandroid.lib.arsc.item.TypeString; +import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.arsc.value.ResValueBag; +import com.reandroid.lib.arsc.value.attribute.AttributeBag; + +public class ArrayBag { + private final ArrayBagItem[] mBagItems; + private ArrayBag(ArrayBagItem[] bagItems){ + this.mBagItems=bagItems; + } + public ArrayBagItem[] getBagItems() { + return mBagItems; + } + public String getName(){ + EntryBlock entryBlock=getBagItems()[0].getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + SpecString spec = entryBlock.getSpecString(); + if(spec==null){ + return null; + } + return spec.get(); + } + public String getTypeName(){ + EntryBlock entryBlock=getBagItems()[0].getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + TypeString typeString = entryBlock.getTypeString(); + if(typeString==null){ + return null; + } + return typeString.get(); + } + @Override + public String toString() { + StringBuilder builder=new StringBuilder(); + builder.append("<"); + String type=getTypeName(); + builder.append(type); + builder.append(" name=\""); + builder.append(getName()); + builder.append("\">"); + ArrayBagItem[] allItems = getBagItems(); + for(int i=0;i"); + return builder.toString(); + } + + /** TODO: find another method to check instead of checking type name (plurals), + * just like {@link AttributeBag} **/ + public static boolean isArray(ResValueBag resValueBag){ + if(resValueBag==null){ + return false; + } + EntryBlock entryBlock= resValueBag.getEntryBlock(); + if(entryBlock==null){ + return false; + } + TypeString typeString = entryBlock.getTypeString(); + if(typeString==null){ + return false; + } + if(!NAME.equals(typeString.get())){ + return false; + } + return ArrayBagItem.create(resValueBag.getBagItems()) != null; + } + + public static ArrayBag create(ResValueBag resValueBag){ + if(resValueBag==null){ + return null; + } + ArrayBagItem[] bagItems=ArrayBagItem.create(resValueBag.getBagItems()); + if(bagItems==null){ + return null; + } + return new ArrayBag(bagItems); + } + public static final String NAME="array"; +} diff --git a/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBagItem.java b/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBagItem.java new file mode 100644 index 0000000..2153486 --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/value/array/ArrayBagItem.java @@ -0,0 +1,107 @@ +package com.reandroid.lib.arsc.value.array; + +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TableBlock; +import com.reandroid.lib.arsc.item.SpecString; +import com.reandroid.lib.arsc.item.TableString; +import com.reandroid.lib.arsc.pool.SpecStringPool; +import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.arsc.value.ResValueBagItem; +import com.reandroid.lib.arsc.value.ValueType; +import com.reandroid.lib.arsc.value.plurals.PluralsBagItem; +import com.reandroid.lib.arsc.value.plurals.PluralsQuantity; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ArrayBagItem { + private final ResValueBagItem mBagItem; + public ArrayBagItem(ResValueBagItem bagItem){ + this.mBagItem=bagItem; + } + public ResValueBagItem getBagItem() { + return mBagItem; + } + + public ValueType getValueType(){ + return getBagItem().getValueType(); + } + private TableStringPool getStringPool(){ + EntryBlock entryBlock=getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + PackageBlock pkg = entryBlock.getPackageBlock(); + if(pkg==null){ + return null; + } + TableBlock tableBlock= pkg.getTableBlock(); + if(tableBlock==null){ + return null; + } + return tableBlock.getTableStringPool(); + } + public int getValue(){ + return getBagItem().getData(); + } + public boolean hasStringValue(){ + return getValueType()==ValueType.STRING; + } + public boolean hasReferenceValue(){ + return getValueType()==ValueType.REFERENCE; + } + public String getStringValue(){ + ValueType valueType=getValueType(); + if(valueType!=ValueType.STRING){ + throw new IllegalArgumentException("Not STRING ValueType="+valueType); + } + TableStringPool stringPool=getStringPool(); + if(stringPool==null){ + return null; + } + int ref=getValue(); + TableString tableString = stringPool.get(ref); + return tableString.getHtml(); + } + + @Override + public String toString() { + StringBuilder builder=new StringBuilder(); + builder.append(""); + if(hasStringValue()){ + builder.append(getStringValue()); + }else { + builder.append(String.format("0x%08x", getValue())); + } + builder.append(""); + return builder.toString(); + } + public static ArrayBagItem[] create(ResValueBagItem[] resValueBagItems){ + if(resValueBagItems==null){ + return null; + } + int len=resValueBagItems.length; + if(len==0){ + return null; + } + List results=new ArrayList<>(); + for(int i=0;i"); + PluralsBagItem[] allItems = getBagItems(); + for(int i=0;i"); + return builder.toString(); + } + + /** TODO: find another method to check instead of checking type name (plurals), + * just like {@link AttributeBag} **/ + public static boolean isPlurals(ResValueBag resValueBag){ + if(resValueBag==null){ + return false; + } + EntryBlock entryBlock= resValueBag.getEntryBlock(); + if(entryBlock==null){ + return false; + } + TypeString typeString = entryBlock.getTypeString(); + if(typeString==null){ + return false; + } + if(!NAME.equals(typeString.get())){ + return false; + } + return PluralsBagItem.create(resValueBag.getBagItems()) != null; + } + + public static PluralsBag create(ResValueBag resValueBag){ + if(resValueBag==null){ + return null; + } + PluralsBagItem[] bagItems=PluralsBagItem.create(resValueBag.getBagItems()); + if(bagItems==null){ + return null; + } + return new PluralsBag(bagItems); + } + public static final String NAME="plurals"; +} diff --git a/src/main/java/com/reandroid/lib/arsc/value/plurals/PluralsBagItem.java b/src/main/java/com/reandroid/lib/arsc/value/plurals/PluralsBagItem.java new file mode 100644 index 0000000..aa3875e --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/value/plurals/PluralsBagItem.java @@ -0,0 +1,115 @@ +package com.reandroid.lib.arsc.value.plurals; + +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TableBlock; +import com.reandroid.lib.arsc.item.TableString; +import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.arsc.value.ResValueBagItem; +import com.reandroid.lib.arsc.value.ValueType; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class PluralsBagItem { + private final ResValueBagItem mBagItem; + private PluralsBagItem(ResValueBagItem bagItem){ + this.mBagItem=bagItem; + } + public ResValueBagItem getBagItem() { + return mBagItem; + } + public PluralsQuantity getQuantity(){ + ResValueBagItem item=getBagItem(); + return PluralsQuantity.valueOf(item.getIdLow()); + } + public ValueType getValueType(){ + return getBagItem().getValueType(); + } + private TableStringPool getStringPool(){ + EntryBlock entryBlock=getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + PackageBlock pkg = entryBlock.getPackageBlock(); + if(pkg==null){ + return null; + } + TableBlock tableBlock= pkg.getTableBlock(); + if(tableBlock==null){ + return null; + } + return tableBlock.getTableStringPool(); + } + public int getValue(){ + return getBagItem().getData(); + } + public boolean hasStringValue(){ + return getValueType()==ValueType.STRING; + } + public boolean hasReferenceValue(){ + return getValueType()==ValueType.REFERENCE; + } + public String getStringValue(){ + ValueType valueType=getValueType(); + if(valueType!=ValueType.STRING){ + throw new IllegalArgumentException("Not STRING ValueType="+valueType); + } + TableStringPool stringPool=getStringPool(); + if(stringPool==null){ + return null; + } + int ref=getValue(); + TableString tableString = stringPool.get(ref); + return tableString.getHtml(); + } + + @Override + public String toString() { + StringBuilder builder=new StringBuilder(); + builder.append(""); + if(hasStringValue()){ + builder.append(getStringValue()); + }else { + builder.append(String.format("@0x%08x", getValue())); + } + builder.append(""); + return builder.toString(); + } + + public static PluralsBagItem[] create(ResValueBagItem[] resValueBagItems){ + if(resValueBagItems==null){ + return null; + } + int len=resValueBagItems.length; + if(len==0){ + return null; + } + Set duplicates=new HashSet<>(); + List results=new ArrayList<>(); + for(int i=0;i"); + StyleBagItem[] allItems = getBagItems(); + for(int i=0;i"); + return builder.toString(); + } + + /** TODO: find another method to check instead of checking type name (plurals), + * just like {@link AttributeBag} **/ + public static boolean isStyle(ResValueBag resValueBag){ + if(resValueBag==null){ + return false; + } + EntryBlock entryBlock = resValueBag.getEntryBlock(); + if(entryBlock==null){ + return false; + } + TypeString typeString = entryBlock.getTypeString(); + if(typeString==null){ + return false; + } + if(!NAME.equals(typeString.get())){ + return false; + } + return ArrayBagItem.create(resValueBag.getBagItems()) != null; + } + + public static StyleBag create(ResValueBag resValueBag){ + if(resValueBag==null){ + return null; + } + StyleBagItem[] bagItems=StyleBagItem.create(resValueBag.getBagItems()); + if(bagItems==null){ + return null; + } + return new StyleBag(bagItems); + } + public static final String NAME="style"; +} diff --git a/src/main/java/com/reandroid/lib/arsc/value/style/StyleBagItem.java b/src/main/java/com/reandroid/lib/arsc/value/style/StyleBagItem.java new file mode 100644 index 0000000..d9f519c --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/value/style/StyleBagItem.java @@ -0,0 +1,149 @@ +package com.reandroid.lib.arsc.value.style; + +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TableBlock; +import com.reandroid.lib.arsc.item.SpecString; +import com.reandroid.lib.arsc.item.TableString; +import com.reandroid.lib.arsc.pool.SpecStringPool; +import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.arsc.value.ResValueBagItem; +import com.reandroid.lib.arsc.value.ValueType; + +import java.util.ArrayList; +import java.util.List; + +public class StyleBagItem { + private final ResValueBagItem mBagItem; + public StyleBagItem(ResValueBagItem bagItem){ + this.mBagItem=bagItem; + } + public ResValueBagItem getBagItem() { + return mBagItem; + } + + public String getName(){ + EntryBlock block=getBagItem().getEntryBlock(); + if(block==null){ + return null; + } + char prefix=0; + return block.buildResourceName(getNameId(), prefix, false); + } + public int getNameId(){ + return getBagItem().getId(); + } + public boolean hasStringValue(){ + return getValueType()== ValueType.STRING; + } + public boolean hasReferenceValue(){ + return getValueType()==ValueType.REFERENCE; + } + public boolean hasAttributeValue(){ + return getValueType()==ValueType.REFERENCE; + } + public String getValueAsReference(){ + ValueType valueType=getValueType(); + if(valueType!=ValueType.REFERENCE && valueType!=ValueType.ATTRIBUTE){ + throw new IllegalArgumentException("Not REF ValueType="+valueType); + } + EntryBlock entryBlock=getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + char prefix='@'; + boolean includeType=true; + if(valueType==ValueType.ATTRIBUTE){ + prefix='?'; + includeType=false; + } + int id=getValue(); + return entryBlock.buildResourceName(id, prefix, includeType); + } + public String getStringValue(){ + ValueType valueType=getValueType(); + if(valueType!=ValueType.STRING){ + throw new IllegalArgumentException("Not STRING ValueType="+valueType); + } + TableStringPool stringPool=getStringPool(); + if(stringPool==null){ + return null; + } + int ref=getValue(); + TableString tableString = stringPool.get(ref); + if(tableString==null){ + return null; + } + return tableString.getHtml(); + } + public ValueType getValueType(){ + return getBagItem().getValueType(); + } + public int getValue(){ + return getBagItem().getData(); + } + private TableStringPool getStringPool(){ + EntryBlock entryBlock=getBagItem().getEntryBlock(); + if(entryBlock==null){ + return null; + } + PackageBlock pkg = entryBlock.getPackageBlock(); + if(pkg==null){ + return null; + } + TableBlock tableBlock= pkg.getTableBlock(); + if(tableBlock==null){ + return null; + } + return tableBlock.getTableStringPool(); + } + @Override + public String toString() { + StringBuilder builder=new StringBuilder(); + 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(""); + return builder.toString(); + } + public static StyleBagItem[] create(ResValueBagItem[] resValueBagItems){ + if(resValueBagItems==null){ + return null; + } + int len=resValueBagItems.length; + if(len==0){ + return null; + } + List results=new ArrayList<>(); + for(int i=0;i