Memory input stream (Simplified version of ReReadableInputStream, which accepts byte array)

This commit is contained in:
Honfika
2013-11-30 16:00:51 +01:00
parent 2af979dbd9
commit ab569f1dd2
18 changed files with 395 additions and 299 deletions
@@ -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<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, String path) throws IOException {
ReReadableInputStream rri = new ReReadableInputStream(this);
return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, 0, -1, path);
}
public List<Action> readActionList(List<DisassemblyListener> 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;
}
}
@@ -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<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endIp, String path) throws IOException {
public static List<Action> readActionList(List<DisassemblyListener> 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<Action> actionMap = new ArrayList<>();
List<Long> 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<Long>());
Map<Action, List<Action>> containerLastActions = new HashMap<>();
@@ -534,8 +533,7 @@ public class ActionListReader {
@SuppressWarnings("unchecked")
private static Action readActionListAtPos(List<DisassemblyListener> listeners, long containerSWFOffset, ConstantPool cpool,
SWFInputStream sis, ReReadableInputStream rri,
List<Action> actions, List<Long> nextOffsets,
SWFInputStream sis, List<Action> actions, List<Long> nextOffsets,
long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List<Long> 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;
}
@@ -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<Action>();
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);
}
@@ -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;
@@ -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<Action>();
int posBef2 = (int) rri.getPos();
//int posBef2 = (int) rri.getPos();
//code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize);
//rri.setPos(posBef2 + codeSize);
}
@@ -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);
@@ -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"));
}
}
@@ -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);
}
@@ -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);
@@ -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<Action> list = ActionListReader.readActionList(listeners, getPos() + hdrSize - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
return list;
@@ -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<Action> list = ActionListReader.readActionList(listeners, getPos() - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
return list;
} catch (Exception ex) {
@@ -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<Action> list = ActionListReader.readActionList(listeners, getPos() + 2 - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
return list;
} catch (Exception ex) {
@@ -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<Action> getActions(int version) {
try {
List<Action> list = ActionListReader.readActionList(listeners, getPos() + 4, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/);
List<Action> list = ActionListReader.readActionList(listeners, getPos() + 4, new MemoryInputStream(actionBytes), version, 0, -1, toString()/*FIXME?*/);
return list;
} catch (Exception ex) {
@@ -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<Action> getActions(int version) {
try {
List<Action> list = ActionListReader.readActionList(listeners, getPos() + hdrPos, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/);
List<Action> 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);
@@ -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() {
@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}
@@ -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);
@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}