diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/BaseChunk.java b/src/main/java/com/reandroid/lib/arsc/chunk/BaseChunk.java index 1b2f139..344ab36 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/BaseChunk.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/BaseChunk.java @@ -35,6 +35,9 @@ public abstract class BaseChunk extends ExpandableBlockContainer { protected void addToHeader(Block block){ mHeaderBlock.addChild(block); } + void setHeaderLoaded(HeaderBlock.HeaderLoaded headerLoaded){ + mHeaderBlock.setHeaderLoaded(headerLoaded); + } public HeaderBlock getHeaderBlock(){ return mHeaderBlock; } @@ -50,16 +53,21 @@ public abstract class BaseChunk extends ExpandableBlockContainer { @Override public void onReadBytes(BlockReader reader) throws IOException { HeaderBlock headerBlock=reader.readHeaderBlock(); - ChunkType chunkType = headerBlock.getChunkType(); - if(chunkType==null || chunkType==ChunkType.NULL){ - throw new IOException("Invalid chunk: "+headerBlock); - } - BlockReader chunkReader=reader.create(reader.getPosition(), headerBlock.getChunkSize()); + checkInvalidChunk(headerBlock); + BlockReader chunkReader = reader.create( + reader.getPosition(), + headerBlock.getChunkSize()); super.onReadBytes(chunkReader); reader.offset(headerBlock.getChunkSize()); chunkReader.close(); onChunkLoaded(); } + void checkInvalidChunk(HeaderBlock headerBlock) throws IOException { + ChunkType chunkType = headerBlock.getChunkType(); + if(chunkType==null || chunkType==ChunkType.NULL){ + throw new IOException("Invalid chunk: "+headerBlock); + } + } @Override public String toString(){ StringBuilder builder=new StringBuilder(); diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java index 80e9062..d1380ad 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java @@ -115,6 +115,9 @@ package com.reandroid.lib.arsc.chunk; addChild(mPackageLastBlocks); } + public BlockList getUnknownChunkList(){ + return mPackageLastBlocks.getUnknownChunkList(); + } public StagedAliasEntry searchByStagedResId(int stagedResId){ for(StagedAlias stagedAlias:getStagedAliasList().getChildes()){ diff --git a/src/main/java/com/reandroid/lib/arsc/container/PackageLastBlocks.java b/src/main/java/com/reandroid/lib/arsc/container/PackageLastBlocks.java index d644ea0..53acf24 100755 --- a/src/main/java/com/reandroid/lib/arsc/container/PackageLastBlocks.java +++ b/src/main/java/com/reandroid/lib/arsc/container/PackageLastBlocks.java @@ -29,22 +29,30 @@ public class PackageLastBlocks extends FixedBlockContainer { private final BlockList mStagedAliasList; private final BlockList mOverlayableList; private final BlockList mOverlayablePolicyList; + private final BlockList mUnknownChunkList; public PackageLastBlocks(SpecTypePairArray specTypePairArray, LibraryBlock libraryBlock, BlockList stagedAliasList, BlockList overlayableList, BlockList overlayablePolicyList){ - super(5); + super(6); this.mSpecTypePairArray=specTypePairArray; this.mLibraryBlock=libraryBlock; this.mStagedAliasList=stagedAliasList; this.mOverlayableList=overlayableList; this.mOverlayablePolicyList=overlayablePolicyList; + + this.mUnknownChunkList = new BlockList<>(); + addChild(0, mSpecTypePairArray); addChild(1, mLibraryBlock); addChild(2, mStagedAliasList); addChild(3, mOverlayableList); addChild(4, mOverlayablePolicyList); + addChild(5, mUnknownChunkList); + } + public BlockList getUnknownChunkList(){ + return mUnknownChunkList; } @Override @@ -72,7 +80,7 @@ public class PackageLastBlocks extends FixedBlockContainer { }else if(chunkType==ChunkType.STAGED_ALIAS){ readStagedAlias(reader); }else { - readUnexpectedBlock(reader, headerBlock); + readUnknownChunk(reader); } return pos!=reader.getPosition(); } @@ -100,7 +108,9 @@ public class PackageLastBlocks extends FixedBlockContainer { overlayablePolicy.readBytes(reader); mOverlayablePolicyList.add(overlayablePolicy); } - private void readUnexpectedBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{ - throw new IOException(reader.getActualPosition()+", Unexpected block: "+headerBlock.toString()); + private void readUnknownChunk(BlockReader reader) throws IOException{ + UnknownChunk unknownChunk = new UnknownChunk(); + unknownChunk.readBytes(reader); + mUnknownChunkList.add(unknownChunk); } } diff --git a/src/main/java/com/reandroid/lib/arsc/header/HeaderBlock.java b/src/main/java/com/reandroid/lib/arsc/header/HeaderBlock.java index 00b31a4..b410b72 100755 --- a/src/main/java/com/reandroid/lib/arsc/header/HeaderBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/header/HeaderBlock.java @@ -18,13 +18,18 @@ package com.reandroid.lib.arsc.header; import com.reandroid.lib.arsc.chunk.ChunkType; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.container.ExpandableBlockContainer; +import com.reandroid.lib.arsc.io.BlockLoad; +import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.ShortItem; -public class HeaderBlock extends ExpandableBlockContainer { +import java.io.IOException; + + public class HeaderBlock extends ExpandableBlockContainer implements BlockLoad { private final ShortItem mType; private final ShortItem mHeaderSize; private final IntegerItem mChunkSize; + private HeaderLoaded mHeaderLoaded; public HeaderBlock(short type){ super(3); this.mType=new ShortItem(type); @@ -33,6 +38,12 @@ public class HeaderBlock extends ExpandableBlockContainer { addChild(mType); addChild(mHeaderSize); addChild(mChunkSize); + this.mType.setBlockLoad(this); + this.mHeaderSize.setBlockLoad(this); + this.mChunkSize.setBlockLoad(this); + } + public void setHeaderLoaded(HeaderLoaded headerLoaded){ + this.mHeaderLoaded=headerLoaded; } public ChunkType getChunkType(){ return ChunkType.get(mType.get()); @@ -54,7 +65,7 @@ public class HeaderBlock extends ExpandableBlockContainer { } public int getHeaderSize(){ - return (0xffff & mHeaderSize.get()); + return mHeaderSize.unsignedInt(); } public void setHeaderSize(short headerSize){ mHeaderSize.set(headerSize); @@ -82,6 +93,21 @@ public class HeaderBlock extends ExpandableBlockContainer { int count=parent.countBytes(); setChunkSize(count); } + @Override + public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { + HeaderLoaded headerLoaded = mHeaderLoaded; + if(headerLoaded==null){ + return; + } + if(sender==this.mType){ + headerLoaded.onChunkTypeLoaded(mType.get()); + }else if(sender==this.mHeaderSize){ + headerLoaded.onHeaderSizeLoaded(mHeaderSize.unsignedInt()); + }else if(sender==this.mChunkSize){ + headerLoaded.onChunkSizeLoaded(mHeaderSize.unsignedInt(), + mChunkSize.get()); + } + } @Override protected void onRefreshed() { @@ -110,4 +136,10 @@ public class HeaderBlock extends ExpandableBlockContainer { builder.append("}"); return builder.toString(); } + + public interface HeaderLoaded{ + void onChunkTypeLoaded(short type); + void onHeaderSizeLoaded(int headerSize); + void onChunkSizeLoaded(int headerSize, int chunkSize); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/item/ShortItem.java b/src/main/java/com/reandroid/lib/arsc/item/ShortItem.java index faf83aa..a6c8d48 100755 --- a/src/main/java/com/reandroid/lib/arsc/item/ShortItem.java +++ b/src/main/java/com/reandroid/lib/arsc/item/ShortItem.java @@ -37,6 +37,9 @@ public class ShortItem extends BlockItem { public short get(){ return mCache; } + public int unsignedInt(){ + return 0xffff & get(); + } @Override protected void onBytesChanged() { // To save cpu usage, better to calculate once only when bytes changed