From ab569f1dd242ce800e635bee88d0c1810253bb70 Mon Sep 17 00:00:00 2001 From: Honfika Date: Sat, 30 Nov 2013 16:00:51 +0100 Subject: [PATCH] Memory input stream (Simplified version of ReReadableInputStream, which accepts byte array) --- .../decompiler/flash/SWFInputStream.java | 492 +++++++++--------- .../flash/action/ActionListReader.java | 27 +- .../action/swf5/ActionDefineFunction.java | 5 +- .../flash/action/swf5/ActionWith.java | 3 +- .../action/swf7/ActionDefineFunction2.java | 5 +- .../flash/action/swf7/ActionTry.java | 3 +- .../flash/gui/LoadFromMemoryFrame.java | 8 +- .../com/jpexs/decompiler/flash/gui/Main.java | 6 +- .../jpexs/decompiler/flash/gui/MainFrame.java | 3 +- .../flash/tags/DefineButtonTag.java | 6 +- .../decompiler/flash/tags/DoActionTag.java | 7 +- .../flash/tags/DoInitActionTag.java | 6 +- .../flash/types/BUTTONCONDACTION.java | 5 +- .../flash/types/CLIPACTIONRECORD.java | 5 +- .../flash/types/gfx/GFxInputStream.java | 2 +- .../com/jpexs/helpers/MemoryInputStream.java | 76 +++ .../jpexs/helpers/ReReadableInputStream.java | 6 +- .../helpers/streams/SeekableInputStream.java | 29 ++ 18 files changed, 395 insertions(+), 299 deletions(-) create mode 100644 trunk/src/com/jpexs/helpers/MemoryInputStream.java create mode 100644 trunk/src/com/jpexs/helpers/streams/SeekableInputStream.java diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java index ba61a4c10..7851f5308 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.action.model.ConstantPool; import com.jpexs.decompiler.flash.action.special.ActionEnd; import com.jpexs.decompiler.flash.action.special.ActionNop; @@ -55,7 +54,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.helpers.Helper; import com.jpexs.helpers.ProgressListener; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.streams.SeekableInputStream; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -166,6 +165,21 @@ public class SWFInputStream extends InputStream { return pos; } + /** + * Sets position in bytes in the stream + * + * @param pos Number of bytes + */ + public void seek(int pos) throws IOException { + if (is instanceof SeekableInputStream) { + SeekableInputStream sis = (SeekableInputStream) is; + sis.seek(pos); + } + else { + throw new IOException("Underlying stream is not a SeekableInputStream"); + } + } + /** * Reads one byte from the stream * @@ -535,15 +549,6 @@ public class SWFInputStream extends InputStream { return ret; } - public List readActionList(List listeners, long containerSWFOffset, String path) throws IOException { - ReReadableInputStream rri = new ReReadableInputStream(this); - return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, 0, -1, path); - } - - public List readActionList(List listeners, long containerSWFOffset, ReReadableInputStream rri, int maxlen, String path) throws IOException { - return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, (int) rri.getPos(), (int) rri.getPos() + maxlen, path); - } - private static void dumpTag(PrintStream out, int version, Tag tag, int level) { StringBuilder sb = new StringBuilder(); sb.append(Helper.formatHex((int) tag.getPos(), 8)); @@ -1072,251 +1077,244 @@ public class SWFInputStream extends InputStream { return ret; } - public Action readAction(ConstantPool cpool) throws IOException { - return readAction(new ReReadableInputStream(this), cpool); - } - /** * Reads one Action from the stream * - * @param rri * @return Action or null when ActionEndFlag or end of the stream * @throws IOException */ - public Action readAction(ReReadableInputStream rri, ConstantPool cpool) throws IOException { - { - int actionCode = -1; + public Action readAction(ConstantPool cpool) throws IOException { + int actionCode = -1; - try { - actionCode = readUI8(); - if (actionCode == 0) { - return new ActionEnd(); - } - if (actionCode == -1) { - return null; - } - int actionLength = 0; - if (actionCode >= 0x80) { - actionLength = readUI16(); - } - switch (actionCode) { - //SWF3 Actions - case 0x81: - return new ActionGotoFrame(actionLength, this); - case 0x83: - return new ActionGetURL(actionLength, this, version); - case 0x04: - return new ActionNextFrame(); - case 0x05: - return new ActionPrevFrame(); - case 0x06: - return new ActionPlay(); - case 0x07: - return new ActionStop(); - case 0x08: - return new ActionToggleQuality(); - case 0x09: - return new ActionStopSounds(); - case 0x8A: - return new ActionWaitForFrame(actionLength, this, cpool); - case 0x8B: - return new ActionSetTarget(actionLength, this, version); - case 0x8C: - return new ActionGoToLabel(actionLength, this, version); - //SWF4 Actions - case 0x96: - return new ActionPush(actionLength, this, version); - case 0x17: - return new ActionPop(); - case 0x0A: - return new ActionAdd(); - case 0x0B: - return new ActionSubtract(); - case 0x0C: - return new ActionMultiply(); - case 0x0D: - return new ActionDivide(); - case 0x0E: - return new ActionEquals(); - case 0x0F: - return new ActionLess(); - case 0x10: - return new ActionAnd(); - case 0x11: - return new ActionOr(); - case 0x12: - return new ActionNot(); - case 0x13: - return new ActionStringEquals(); - case 0x14: - return new ActionStringLength(); - case 0x21: - return new ActionStringAdd(); - case 0x15: - return new ActionStringExtract(); - case 0x29: - return new ActionStringLess(); - case 0x31: - return new ActionMBStringLength(); - case 0x35: - return new ActionMBStringExtract(); - case 0x18: - return new ActionToInteger(); - case 0x32: - return new ActionCharToAscii(); - case 0x33: - return new ActionAsciiToChar(); - case 0x36: - return new ActionMBCharToAscii(); - case 0x37: - return new ActionMBAsciiToChar(); - case 0x99: - return new ActionJump(actionLength, this); - case 0x9D: - return new ActionIf(actionLength, this); - case 0x9E: - return new ActionCall(actionLength); - case 0x1C: - return new ActionGetVariable(); - case 0x1D: - return new ActionSetVariable(); - case 0x9A: - return new ActionGetURL2(actionLength, this); - case 0x9F: - return new ActionGotoFrame2(actionLength, this); - case 0x20: - return new ActionSetTarget2(); - case 0x22: - return new ActionGetProperty(); - case 0x23: - return new ActionSetProperty(); - case 0x24: - return new ActionCloneSprite(); - case 0x25: - return new ActionRemoveSprite(); - case 0x27: - return new ActionStartDrag(); - case 0x28: - return new ActionEndDrag(); - case 0x8D: - return new ActionWaitForFrame2(actionLength, this, cpool); - case 0x26: - return new ActionTrace(); - case 0x34: - return new ActionGetTime(); - case 0x30: - return new ActionRandomNumber(); - //SWF5 Actions - case 0x3D: - return new ActionCallFunction(); - case 0x52: - return new ActionCallMethod(); - case 0x88: - return new ActionConstantPool(actionLength, this, version); - case 0x9B: - return new ActionDefineFunction(actionLength, this, rri, version); - case 0x3C: - return new ActionDefineLocal(); - case 0x41: - return new ActionDefineLocal2(); - case 0x3A: - return new ActionDelete(); - case 0x3B: - return new ActionDelete2(); - case 0x46: - return new ActionEnumerate(); - case 0x49: - return new ActionEquals2(); - case 0x4E: - return new ActionGetMember(); - case 0x42: - return new ActionInitArray(); - case 0x43: - return new ActionInitObject(); - case 0x53: - return new ActionNewMethod(); - case 0x40: - return new ActionNewObject(); - case 0x4F: - return new ActionSetMember(); - case 0x45: - return new ActionTargetPath(); - case 0x94: - return new ActionWith(actionLength, this, rri, version); - case 0x4A: - return new ActionToNumber(); - case 0x4B: - return new ActionToString(); - case 0x44: - return new ActionTypeOf(); - case 0x47: - return new ActionAdd2(); - case 0x48: - return new ActionLess2(); - case 0x3F: - return new ActionModulo(); - case 0x60: - return new ActionBitAnd(); - case 0x63: - return new ActionBitLShift(); - case 0x61: - return new ActionBitOr(); - case 0x64: - return new ActionBitRShift(); - case 0x65: - return new ActionBitURShift(); - case 0x62: - return new ActionBitXor(); - case 0x51: - return new ActionDecrement(); - case 0x50: - return new ActionIncrement(); - case 0x4C: - return new ActionPushDuplicate(); - case 0x3E: - return new ActionReturn(); - case 0x4D: - return new ActionStackSwap(); - case 0x87: - return new ActionStoreRegister(actionLength, this); - //SWF6 Actions - case 0x54: - return new ActionInstanceOf(); - case 0x55: - return new ActionEnumerate2(); - case 0x66: - return new ActionStrictEquals(); - case 0x67: - return new ActionGreater(); - case 0x68: - return new ActionStringGreater(); - //SWF7 Actions - case 0x8E: - return new ActionDefineFunction2(actionLength, this, rri, version); - case 0x69: - return new ActionExtends(); - case 0x2B: - return new ActionCastOp(); - case 0x2C: - return new ActionImplementsOp(); - case 0x8F: - return new ActionTry(actionLength, this, rri, version); - case 0x2A: - return new ActionThrow(); - default: - /*if (actionLength > 0) { - //skip(actionLength); - }*/ - //throw new UnknownActionException(actionCode); - Action r = new ActionNop(); - r.actionCode = actionCode; - r.actionLength = actionLength; - return r; - //return new Action(actionCode, actionLength); - } - } catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) { + try { + actionCode = readUI8(); + if (actionCode == 0) { + return new ActionEnd(); + } + if (actionCode == -1) { return null; } + int actionLength = 0; + if (actionCode >= 0x80) { + actionLength = readUI16(); + } + switch (actionCode) { + //SWF3 Actions + case 0x81: + return new ActionGotoFrame(actionLength, this); + case 0x83: + return new ActionGetURL(actionLength, this, version); + case 0x04: + return new ActionNextFrame(); + case 0x05: + return new ActionPrevFrame(); + case 0x06: + return new ActionPlay(); + case 0x07: + return new ActionStop(); + case 0x08: + return new ActionToggleQuality(); + case 0x09: + return new ActionStopSounds(); + case 0x8A: + return new ActionWaitForFrame(actionLength, this, cpool); + case 0x8B: + return new ActionSetTarget(actionLength, this, version); + case 0x8C: + return new ActionGoToLabel(actionLength, this, version); + //SWF4 Actions + case 0x96: + return new ActionPush(actionLength, this, version); + case 0x17: + return new ActionPop(); + case 0x0A: + return new ActionAdd(); + case 0x0B: + return new ActionSubtract(); + case 0x0C: + return new ActionMultiply(); + case 0x0D: + return new ActionDivide(); + case 0x0E: + return new ActionEquals(); + case 0x0F: + return new ActionLess(); + case 0x10: + return new ActionAnd(); + case 0x11: + return new ActionOr(); + case 0x12: + return new ActionNot(); + case 0x13: + return new ActionStringEquals(); + case 0x14: + return new ActionStringLength(); + case 0x21: + return new ActionStringAdd(); + case 0x15: + return new ActionStringExtract(); + case 0x29: + return new ActionStringLess(); + case 0x31: + return new ActionMBStringLength(); + case 0x35: + return new ActionMBStringExtract(); + case 0x18: + return new ActionToInteger(); + case 0x32: + return new ActionCharToAscii(); + case 0x33: + return new ActionAsciiToChar(); + case 0x36: + return new ActionMBCharToAscii(); + case 0x37: + return new ActionMBAsciiToChar(); + case 0x99: + return new ActionJump(actionLength, this); + case 0x9D: + return new ActionIf(actionLength, this); + case 0x9E: + return new ActionCall(actionLength); + case 0x1C: + return new ActionGetVariable(); + case 0x1D: + return new ActionSetVariable(); + case 0x9A: + return new ActionGetURL2(actionLength, this); + case 0x9F: + return new ActionGotoFrame2(actionLength, this); + case 0x20: + return new ActionSetTarget2(); + case 0x22: + return new ActionGetProperty(); + case 0x23: + return new ActionSetProperty(); + case 0x24: + return new ActionCloneSprite(); + case 0x25: + return new ActionRemoveSprite(); + case 0x27: + return new ActionStartDrag(); + case 0x28: + return new ActionEndDrag(); + case 0x8D: + return new ActionWaitForFrame2(actionLength, this, cpool); + case 0x26: + return new ActionTrace(); + case 0x34: + return new ActionGetTime(); + case 0x30: + return new ActionRandomNumber(); + //SWF5 Actions + case 0x3D: + return new ActionCallFunction(); + case 0x52: + return new ActionCallMethod(); + case 0x88: + return new ActionConstantPool(actionLength, this, version); + case 0x9B: + return new ActionDefineFunction(actionLength, this, version); + case 0x3C: + return new ActionDefineLocal(); + case 0x41: + return new ActionDefineLocal2(); + case 0x3A: + return new ActionDelete(); + case 0x3B: + return new ActionDelete2(); + case 0x46: + return new ActionEnumerate(); + case 0x49: + return new ActionEquals2(); + case 0x4E: + return new ActionGetMember(); + case 0x42: + return new ActionInitArray(); + case 0x43: + return new ActionInitObject(); + case 0x53: + return new ActionNewMethod(); + case 0x40: + return new ActionNewObject(); + case 0x4F: + return new ActionSetMember(); + case 0x45: + return new ActionTargetPath(); + case 0x94: + return new ActionWith(actionLength, this, version); + case 0x4A: + return new ActionToNumber(); + case 0x4B: + return new ActionToString(); + case 0x44: + return new ActionTypeOf(); + case 0x47: + return new ActionAdd2(); + case 0x48: + return new ActionLess2(); + case 0x3F: + return new ActionModulo(); + case 0x60: + return new ActionBitAnd(); + case 0x63: + return new ActionBitLShift(); + case 0x61: + return new ActionBitOr(); + case 0x64: + return new ActionBitRShift(); + case 0x65: + return new ActionBitURShift(); + case 0x62: + return new ActionBitXor(); + case 0x51: + return new ActionDecrement(); + case 0x50: + return new ActionIncrement(); + case 0x4C: + return new ActionPushDuplicate(); + case 0x3E: + return new ActionReturn(); + case 0x4D: + return new ActionStackSwap(); + case 0x87: + return new ActionStoreRegister(actionLength, this); + //SWF6 Actions + case 0x54: + return new ActionInstanceOf(); + case 0x55: + return new ActionEnumerate2(); + case 0x66: + return new ActionStrictEquals(); + case 0x67: + return new ActionGreater(); + case 0x68: + return new ActionStringGreater(); + //SWF7 Actions + case 0x8E: + return new ActionDefineFunction2(actionLength, this, version); + case 0x69: + return new ActionExtends(); + case 0x2B: + return new ActionCastOp(); + case 0x2C: + return new ActionImplementsOp(); + case 0x8F: + return new ActionTry(actionLength, this, version); + case 0x2A: + return new ActionThrow(); + default: + /*if (actionLength > 0) { + //skip(actionLength); + }*/ + //throw new UnknownActionException(actionCode); + Action r = new ActionNop(); + r.actionCode = actionCode; + r.actionLength = actionLength; + return r; + //return new Action(actionCode, actionLength); + } + } catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) { + return null; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java index e16882813..c6a17f618 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -43,7 +43,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.NotCompileTimeItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -71,7 +71,7 @@ public class ActionListReader { * ActionEndFlag(=0) or end of the stream. * @param listeners * @param containerSWFOffset - * @param rri + * @param mis * @param version * @param ip * @param endIp @@ -79,19 +79,18 @@ public class ActionListReader { * @return List of actions * @throws IOException */ - public static List readActionList(List listeners, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endIp, String path) throws IOException { + public static List readActionList(List listeners, long containerSWFOffset, MemoryInputStream mis, int version, int ip, int endIp, String path) throws IOException { boolean deobfuscate = Configuration.autoDeobfuscate.get(); ConstantPool cpool = new ConstantPool(); - SWFInputStream sis = new SWFInputStream(rri, version); + SWFInputStream sis = new SWFInputStream(mis, version); // List of the actions. N. item contains the action which starts in offset N. List actionMap = new ArrayList<>(); List nextOffsets = new ArrayList<>(); - Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool, - sis, rri, - actionMap, nextOffsets, + Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool, + sis, actionMap, nextOffsets, ip, ip, endIp, version, path, false, new ArrayList()); Map> containerLastActions = new HashMap<>(); @@ -534,8 +533,7 @@ public class ActionListReader { @SuppressWarnings("unchecked") private static Action readActionListAtPos(List listeners, long containerSWFOffset, ConstantPool cpool, - SWFInputStream sis, ReReadableInputStream rri, - List actions, List nextOffsets, + SWFInputStream sis, List actions, List nextOffsets, long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List visitedContainers) throws IOException { Action entryAction = null; @@ -550,10 +548,10 @@ public class ActionListReader { while (!jumpQueue.isEmpty()) { ip = jumpQueue.remove(); while ((endIp == -1) || (endIp > ip)) { - rri.setPos((int) ip); + sis.seek((int) ip); Action a; - if ((a = sis.readAction(rri, cpool)) == null) { + if ((a = sis.readAction(cpool)) == null) { break; } @@ -583,8 +581,10 @@ public class ActionListReader { actions.set((int) ip, a); nextOffsets.set((int) ip, ip + actionLengthWithHeader); + long pos = sis.getPos(); + long length = pos + sis.available(); for (int i = 0; i < listeners.size(); i++) { - listeners.get(i).progress("Reading", rri.getCount(), rri.length()); + listeners.get(i).progress("Reading", pos, length); } a.containerSWFOffset = containerSWFOffset; @@ -619,8 +619,7 @@ public class ActionListReader { long ip2 = ip + actionLengthWithHeader; //long endIp2 = ip + actionLengthWithHeader + size; readActionListAtPos(listeners, containerSWFOffset, cpool, - sis, rri, - actions, nextOffsets, + sis, actions, nextOffsets, ip2, startIp, endIp, version, newPath, indeterminate, visitedContainers); actionLengthWithHeader += size; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java index 42b214cb8..7fd8f1922 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java @@ -28,7 +28,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -56,7 +55,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta this.paramNames = paramNames; } - public ActionDefineFunction(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException { + public ActionDefineFunction(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x9B, actionLength); this.version = version; //byte[] data=sis.readBytes(actionLength); @@ -71,7 +70,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta long endPos = sis.getPos(); //code = new ArrayList(); hdrSize = endPos - startPos; - int posBef2 = (int) rri.getPos(); + //int posBef2 = (int) rri.getPos(); //code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize); //rri.setPos(posBef2 + codeSize); } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java index 74e48fa72..adb8ce642 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java @@ -26,7 +26,6 @@ import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.helpers.ReReadableInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -50,7 +49,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer { return false; } - public ActionWith(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException { + public ActionWith(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x94, actionLength); codeSize = sis.readUI16(); this.version = version; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java b/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java index 7a739896a..592b78cfd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java @@ -28,7 +28,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -78,7 +77,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont this.paramRegisters = paramRegisters; } - public ActionDefineFunction2(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException { + public ActionDefineFunction2(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x8E, actionLength); long posBef = sis.getPos(); this.version = version; @@ -103,7 +102,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont long posAfter = sis.getPos(); hdrSize = posAfter - posBef; //code = new ArrayList(); - int posBef2 = (int) rri.getPos(); + //int posBef2 = (int) rri.getPos(); //code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize); //rri.setPos(posBef2 + codeSize); } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java b/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java index df70b7ed2..e1bcae5db 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java @@ -31,7 +31,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -64,7 +63,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer { this.version = version; } - public ActionTry(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException { + public ActionTry(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x8F, actionLength); long startPos = sis.getPos(); sis.readUB(5); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java index 475fbf138..942244cb9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/LoadFromMemoryFrame.java @@ -104,7 +104,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener { ReReadableInputStream is = new ReReadableInputStream(pmi); SWF swf = new SWF(is, null, false, true); long limit = pmi.getPos(); - is.setPos(0); + is.seek(0); is = new ReReadableInputStream(new LimitedInputStream(is, limit)); if (swf.fileSize > 0 && swf.version > 0 && !swf.tags.isEmpty() && swf.version < 25/*Needs to be fixed when SWF versions reaches this value*/) { String p = translate("swfitem").replace("%version%", "" + swf.version).replace("%size%", "" + swf.fileSize); @@ -143,7 +143,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener { if (index > -1) { ReReadableInputStream str = foundIs.get(index); try { - str.setPos(0); + str.seek(0); } catch (IOException ex) { Logger.getLogger(LoadFromMemoryFrame.class.getName()).log(Level.SEVERE, null, ex); return; @@ -362,12 +362,12 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener { try { if (selected.length == 1) { ReReadableInputStream bis = foundIs.get(selected[0]); - bis.setPos(0); + bis.seek(0); Helper.saveStream(bis, file); } else { for (int sel : selected) { ReReadableInputStream bis = foundIs.get(sel); - bis.setPos(0); + bis.seek(0); Helper.saveStream(bis, new File(file, "movie" + sel + ".swf")); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 2ef64414f..909d611cb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame; import com.jpexs.helpers.Cache; import com.jpexs.helpers.Helper; import com.jpexs.helpers.ProgressListener; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.streams.SeekableInputStream; import com.jpexs.helpers.utf8.Utf8PrintWriter; import com.sun.jna.Platform; import java.awt.*; @@ -313,9 +313,9 @@ public class Main { } else { if (inputStream instanceof FileInputStream) { openFile(file); - } else if (inputStream instanceof ReReadableInputStream) { + } else if (inputStream instanceof SeekableInputStream) { try { - ((ReReadableInputStream) inputStream).setPos(0); + ((SeekableInputStream) inputStream).seek(0); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index c74d456f2..aaec53589 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -105,7 +105,6 @@ import com.jpexs.helpers.AsyncResult; import com.jpexs.helpers.Cache; import com.jpexs.helpers.Callback; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.Stopwatch; import com.jpexs.process.ProcessTools; import java.awt.BorderLayout; import java.awt.CardLayout; @@ -3154,7 +3153,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T try { tempFile = File.createTempFile("temp", ".swf"); tempFile.deleteOnExit(); - swf.saveTo(new FileOutputStream(tempFile)); + swf.saveTo(new BufferedOutputStream(new FileOutputStream(tempFile))); flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, swf.frameRate); } catch (IOException iex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index a3b70675d..4c1e0cb12 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -36,7 +36,7 @@ import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Cache; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.awt.Color; import java.awt.Point; import java.awt.image.BufferedImage; @@ -173,8 +173,8 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT prevLength = prevData.length; } baos.write(actionBytes); - ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray())); - rri.setPos(prevLength); + MemoryInputStream rri = new MemoryInputStream(baos.toByteArray()); + rri.seek(prevLength); List list = ActionListReader.readActionList(listeners, getPos() + hdrSize - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/); return list; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index e6c346ce1..e246cf432 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -25,8 +25,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; -import java.io.ByteArrayInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; @@ -118,8 +117,8 @@ public class DoActionTag extends Tag implements ASMSource { prevLength += header.length; } baos.write(actionBytes); - ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray())); - rri.setPos(prevLength); + MemoryInputStream rri = new MemoryInputStream(baos.toByteArray()); + rri.seek(prevLength); List list = ActionListReader.readActionList(listeners, getPos() - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/); return list; } catch (Exception ex) { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index c938f1a5d..a637cfdf5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -127,8 +127,8 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { prevLength += header.length; } baos.write(actionBytes); - ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray())); - rri.setPos(prevLength); + MemoryInputStream rri = new MemoryInputStream(baos.toByteArray()); + rri.seek(prevLength); List list = ActionListReader.readActionList(listeners, getPos() + 2 - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/); return list; } catch (Exception ex) { diff --git a/trunk/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java b/trunk/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java index 7e8ba3859..21abcd30f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java @@ -27,8 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.tags.base.Exportable; import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; -import java.io.ByteArrayInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -175,7 +174,7 @@ public class BUTTONCONDACTION implements ASMSource, Exportable, ContainerItem { @Override public List getActions(int version) { try { - List list = ActionListReader.readActionList(listeners, getPos() + 4, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionList(listeners, getPos() + 4, new MemoryInputStream(actionBytes), version, 0, -1, toString()/*FIXME?*/); return list; } catch (Exception ex) { diff --git a/trunk/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java b/trunk/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java index 954d93c2e..5de93fe96 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java @@ -27,8 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.tags.base.Exportable; import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.ReReadableInputStream; -import java.io.ByteArrayInputStream; +import com.jpexs.helpers.MemoryInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -174,7 +173,7 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem { @Override public List getActions(int version) { try { - List list = ActionListReader.readActionList(listeners, getPos() + hdrPos, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/); + List list = ActionListReader.readActionList(listeners, getPos() + hdrPos, new MemoryInputStream(actionBytes), version, 0, -1, toString()/*FIXME?*/); return list; } catch (Exception ex) { Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex); diff --git a/trunk/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java b/trunk/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java index 4540bdef5..94d7363a6 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/gfx/GFxInputStream.java @@ -39,7 +39,7 @@ public class GFxInputStream extends InputStream { } public void setPos(long pos) throws IOException { - is.setPos(pos); + is.seek(pos); } public long getPos() { diff --git a/trunk/src/com/jpexs/helpers/MemoryInputStream.java b/trunk/src/com/jpexs/helpers/MemoryInputStream.java new file mode 100644 index 000000000..b5fa101ca --- /dev/null +++ b/trunk/src/com/jpexs/helpers/MemoryInputStream.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.helpers; + +import com.jpexs.helpers.streams.SeekableInputStream; +import java.io.IOException; + +/** + * + * @author JPEXS + */ +public class MemoryInputStream extends SeekableInputStream { + + byte[] buffer; + long pos = 0; + int count = 0; + + public MemoryInputStream(byte[] buffer) { + this.buffer = buffer; + } + + public int getCount() { + return count; + } + + public byte[] getAllRead() { + return buffer; + } + + public long getPos() { + return pos; + } + + @Override + public void seek(long pos) throws IOException { + this.pos = pos; + } + + @Override + public int read() throws IOException { + if (pos > count) { + count = (int) pos; + } + + if (pos < buffer.length) { + int ret = buffer[(int) pos] & 0xff; + pos++; + return ret; + } + + return -1; + } + + @Override + public int available() throws IOException { + return buffer.length - (int) pos; + } + + public long length() throws IOException { + return buffer.length; + } +} diff --git a/trunk/src/com/jpexs/helpers/ReReadableInputStream.java b/trunk/src/com/jpexs/helpers/ReReadableInputStream.java index 43186dca6..dc582a3c0 100644 --- a/trunk/src/com/jpexs/helpers/ReReadableInputStream.java +++ b/trunk/src/com/jpexs/helpers/ReReadableInputStream.java @@ -16,6 +16,7 @@ */ package com.jpexs.helpers; +import com.jpexs.helpers.streams.SeekableInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -24,7 +25,7 @@ import java.io.InputStream; * * @author JPEXS */ -public class ReReadableInputStream extends InputStream { +public class ReReadableInputStream extends SeekableInputStream { InputStream is; ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -48,7 +49,8 @@ public class ReReadableInputStream extends InputStream { this.is = is; } - public void setPos(long pos) throws IOException { + @Override + public void seek(long pos) throws IOException { if (pos > count) { this.pos = count; skip(pos - count); diff --git a/trunk/src/com/jpexs/helpers/streams/SeekableInputStream.java b/trunk/src/com/jpexs/helpers/streams/SeekableInputStream.java new file mode 100644 index 000000000..04bf86267 --- /dev/null +++ b/trunk/src/com/jpexs/helpers/streams/SeekableInputStream.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.helpers.streams; + +import java.io.IOException; +import java.io.InputStream; + +/** + * + * @author JPEXS + */ +public abstract class SeekableInputStream extends InputStream { + + public abstract void seek(long pos) throws IOException; +}