calculating the action length without writing it to a stream

This commit is contained in:
honfika@gmail.com
2015-07-17 09:19:51 +02:00
parent 3e7d891280
commit a6dc717225
35 changed files with 454 additions and 326 deletions

View File

@@ -302,7 +302,7 @@ public class SWFInputStream implements AutoCloseable {
private static final Logger logger = Logger.getLogger(SWFInputStream.class.getName());
private static final byte[] BYTE_ARRAY_EMPTY = new byte[0];
public static final byte[] BYTE_ARRAY_EMPTY = new byte[0];
private final List<ProgressListener> listeners = new ArrayList<>();

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc;
import com.jpexs.decompiler.flash.EndOfStreamException;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.abc.types.Decimal;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
@@ -63,7 +64,7 @@ public class ABCInputStream implements AutoCloseable {
public byte[] stopBuffer() {
if (bufferOs == null) {
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
byte[] ret = bufferOs.toByteArray();
bufferOs.reset();

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
@@ -218,7 +219,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
} catch (IOException ex) {
Logger.getLogger(AVM2SourceGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
@@ -38,7 +39,7 @@ public class ExceptionMarkAVM2Instruction extends AVM2Instruction {
@Override
public byte[] getBytes() {
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ABCInputStream;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
@@ -92,7 +93,7 @@ public final class MethodBody implements Cloneable {
public MethodBody(ABC abc) {
this.traits = new Traits();
this.codeBytes = new byte[0];
this.codeBytes = SWFInputStream.BYTE_ARRAY_EMPTY;
this.exceptions = new ABCException[0];
this.abc = abc;
}

View File

@@ -195,7 +195,7 @@ public abstract class Action implements GraphSourceItem {
}
public int getTotalActionLength() {
return actionLength + 1 + ((actionCode >= 0x80) ? 2 : 0);
return actionLength + 1 + (actionCode >= 0x80 ? 2 : 0);
}
/**
@@ -301,8 +301,19 @@ public abstract class Action implements GraphSourceItem {
* @param version SWF version
* @return Array of bytes
*/
public byte[] getBytes(int version) {
return surroundWithAction(new byte[0], version);
public final byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
getContentBytes(sos);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
}
protected void getContentBytes(SWFOutputStream sos) throws IOException {
}
/**
@@ -311,18 +322,27 @@ public abstract class Action implements GraphSourceItem {
* @param version SWF version
* @return Length
*/
public int getBytesLength(int version) {
return getBytes(version).length;
public final int getBytesLength(int version) {
int contentLength = getContentBytesLength();
if (contentLength == -1) {
return getBytes(version).length;
}
return contentLength + 1 + (actionCode >= 0x80 ? 2 : 0);
}
protected int getContentBytesLength() {
return 0;
}
/**
* Uptates the action length to the length calculated from action bytes
* Updates the action length to the length calculated from action bytes
*
* @param version SWF version
*/
public void updateLength(int version) {
int length = getBytes(version).length;
actionLength = length - 1 - ((actionCode >= 0x80) ? 2 : 0);
int length = getBytesLength(version);
actionLength = length - 1 - (actionCode >= 0x80 ? 2 : 0);
}
/**
@@ -332,7 +352,7 @@ public abstract class Action implements GraphSourceItem {
* @param version SWF version
* @return Byte array
*/
protected byte[] surroundWithAction(byte[] data, int version) {
private byte[] surroundWithAction(byte[] data, int version) {
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos2, version);
try {
@@ -942,7 +962,17 @@ public abstract class Action implements GraphSourceItem {
}
List<GraphTargetItem> out;
try {
out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
try {
out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName));
} catch (InterruptedException ex) {
throw ex;
} catch (Exception ex) {
boolean inter = Thread.currentThread().isInterrupted();
ActionList a = new ActionList(actions);
String b = a.toString();
String c = b;
throw ex;
}
} catch (OutOfMemoryError | TranslateException | StackOverflowError ex2) {
logger.log(Level.SEVERE, "Decompilation error in: " + path, ex2);
if (ex2 instanceof OutOfMemoryError) {

View File

@@ -78,7 +78,7 @@ public class ActionGraphSource extends GraphSource {
@Override
public List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
return (Action.actionsPartToTree(registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path));
return Action.actionsPartToTree(registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);
}
private List<Long> posCache = null;

View File

@@ -1,18 +1,19 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library 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
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.flashlite;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -23,7 +24,6 @@ import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -43,16 +43,18 @@ public class ActionStrictMode extends Action {
}
@Override
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI8(mode);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI8(mode);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 1;
}
@Override

View File

@@ -30,7 +30,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -63,17 +63,19 @@ public class ActionGetURL extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeString(urlString);
sos.writeString(targetString);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeString(urlString);
sos.writeString(targetString);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(urlString) + Utf8Helper.getBytesLength(targetString) + 2;
}
@Override

View File

@@ -25,7 +25,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -52,16 +52,18 @@ public class ActionGoToLabel extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeString(label);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeString(label);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(label) + 1;
}
public ActionGoToLabel(FlasmLexer lexer) throws IOException, ActionParseException {

View File

@@ -1,18 +1,19 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library 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
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.swf3;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -23,7 +24,6 @@ import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -48,16 +48,18 @@ public class ActionGotoFrame extends Action {
}
@Override
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI16(frame);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI16(frame);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 2;
}
public ActionGotoFrame(FlasmLexer lexer) throws IOException, ActionParseException {

View File

@@ -25,7 +25,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -52,16 +52,18 @@ public class ActionSetTarget extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeString(targetName);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeString(targetName);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(targetName) + 1;
}
public ActionSetTarget(FlasmLexer lexer) throws IOException, ActionParseException {

View File

@@ -30,7 +30,6 @@ import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -64,17 +63,19 @@ public class ActionWaitForFrame extends Action implements ActionStore {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI16(frame);
sos.writeUI8(skipCount);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI16(frame);
sos.writeUI8(skipCount);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 3;
}
public ActionWaitForFrame(FlasmLexer lexer) throws IOException, ActionParseException {

View File

@@ -36,7 +36,6 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -78,19 +77,21 @@ public class ActionGetURL2 extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUB(1, loadVariablesFlag ? 1 : 0);
sos.writeUB(1, loadTargetFlag ? 1 : 0);
sos.writeUB(4, reserved);
sos.writeUB(2, sendVarsMethod);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUB(1, loadVariablesFlag ? 1 : 0);
sos.writeUB(1, loadTargetFlag ? 1 : 0);
sos.writeUB(4, reserved);
sos.writeUB(2, sendVarsMethod);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 1;
}
public ActionGetURL2(FlasmLexer lexer) throws IOException, ActionParseException {

View File

@@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -59,21 +58,28 @@ public class ActionGotoFrame2 extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUB(6, reserved);
sos.writeUB(1, sceneBiasFlag ? 1 : 0);
sos.writeUB(1, playFlag ? 1 : 0);
if (sceneBiasFlag) {
sos.writeUI16(sceneBias);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUB(6, reserved);
sos.writeUB(1, sceneBiasFlag ? 1 : 0);
sos.writeUB(1, playFlag ? 1 : 0);
if (sceneBiasFlag) {
sos.writeUI16(sceneBias);
}
return surroundWithAction(baos.toByteArray(), version);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = 1;
if (sceneBiasFlag) {
res += 2;
}
return res;
}
@Override

View File

@@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -66,16 +65,18 @@ public class ActionIf extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeSI16(offset);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeSI16(offset);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 2;
}
@Override

View File

@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphSource;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -67,16 +66,18 @@ public class ActionJump extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeSI16(offset);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeSI16(offset);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 2;
}
@Override

View File

@@ -40,7 +40,7 @@ import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.FalseItem;
import com.jpexs.decompiler.graph.model.TrueItem;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -135,57 +135,95 @@ public class ActionPush extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
for (Object o : values) {
if (o instanceof String) {
sos.writeUI8(0);
sos.writeString((String) o);
} else if (o instanceof Float) {
sos.writeUI8(1);
sos.writeFLOAT((Float) o);
} else if (o instanceof Null) {
sos.writeUI8(2);
} else if (o instanceof Undefined) {
sos.writeUI8(3);
} else if (o instanceof RegisterNumber) {
sos.writeUI8(4);
sos.writeUI8(((RegisterNumber) o).number);
} else if (o instanceof Boolean) {
sos.writeUI8(5);
sos.writeUI8((Boolean) o ? 1 : 0);
} else if (o instanceof Double || o instanceof Long) {
if (o instanceof Long) {
long l = (Long) o;
if (l < -0x80000000 || l > 0x7fffffff) {
o = (double) l;
}
}
if (o instanceof Double) {
sos.writeUI8(6);
sos.writeDOUBLE((Double) o);
} else if (o instanceof Long) {
sos.writeUI8(7);
sos.writeSI32((Long) o);
}
} else if (o instanceof ConstantIndex) {
int cIndex = ((ConstantIndex) o).index;
if (cIndex < 256) {
sos.writeUI8(8);
sos.writeUI8(cIndex);
} else {
sos.writeUI8(9);
sos.writeUI16(cIndex);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
for (Object o : values) {
if (o instanceof String) {
sos.writeUI8(0);
sos.writeString((String) o);
} else if (o instanceof Float) {
sos.writeUI8(1);
sos.writeFLOAT((Float) o);
} else if (o instanceof Null) {
sos.writeUI8(2);
} else if (o instanceof Undefined) {
sos.writeUI8(3);
} else if (o instanceof RegisterNumber) {
sos.writeUI8(4);
sos.writeUI8(((RegisterNumber) o).number);
} else if (o instanceof Boolean) {
sos.writeUI8(5);
sos.writeUI8((Boolean) o ? 1 : 0);
} else if (o instanceof Double || o instanceof Long) {
if (o instanceof Long) {
long l = (Long) o;
if (l < -0x80000000 || l > 0x7fffffff) {
o = (double) l;
}
}
if (o instanceof Double) {
sos.writeUI8(6);
sos.writeDOUBLE((Double) o);
} else if (o instanceof Long) {
sos.writeUI8(7);
sos.writeSI32((Long) o);
}
} else if (o instanceof ConstantIndex) {
int cIndex = ((ConstantIndex) o).index;
if (cIndex < 256) {
sos.writeUI8(8);
sos.writeUI8(cIndex);
} else {
sos.writeUI8(9);
sos.writeUI16(cIndex);
}
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = 0;
for (Object o : values) {
if (o instanceof String) {
res += Utf8Helper.getBytesLength((String) o) + 2;
} else if (o instanceof Float) {
res += 5;
} else if (o instanceof Null) {
res++;
} else if (o instanceof Undefined) {
res++;
} else if (o instanceof RegisterNumber) {
res += 2;
} else if (o instanceof Boolean) {
res += 2;
} else if (o instanceof Double || o instanceof Long) {
if (o instanceof Long) {
long l = (Long) o;
if (l < -0x80000000 || l > 0x7fffffff) {
o = (double) l;
}
}
if (o instanceof Double) {
res += 9;
} else if (o instanceof Long) {
res += 5;
}
} else if (o instanceof ConstantIndex) {
int cIndex = ((ConstantIndex) o).index;
if (cIndex < 256) {
res += 2;
} else {
res += 3;
}
}
}
return res;
}
public static boolean isValidValue(Object value) {

View File

@@ -29,7 +29,6 @@ import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -100,16 +99,18 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI8(skipCount);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI8(skipCount);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 1;
}
@Override

View File

@@ -25,7 +25,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -63,19 +63,26 @@ public class ActionConstantPool extends Action {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI16(constantPool.size());
for (String s : constantPool) {
sos.writeString(s);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI16(constantPool.size());
for (String s : constantPool) {
sos.writeString(s);
}
return surroundWithAction(baos.toByteArray(), version);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = 2;
for (String s : constantPool) {
res += Utf8Helper.getBytesLength(s) + 1;
}
return res;
}
@Override

View File

@@ -29,7 +29,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -84,28 +84,32 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta
@Override
public long getHeaderSize() {
return getBytes(version).length;
return getBytesLength(version);
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
try {
sos.writeString(functionName);
sos.writeUI16(paramNames.size());
for (String s : paramNames) {
sos.writeString(s);
}
sos.writeUI16(codeSize);
sos.close();
baos2.write(surroundWithAction(baos.toByteArray(), version));
} catch (IOException e) {
throw new Error("This should never happen.", e);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeString(functionName);
sos.writeUI16(paramNames.size());
for (String s : paramNames) {
sos.writeString(s);
}
return baos2.toByteArray();
sos.writeUI16(codeSize);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = Utf8Helper.getBytesLength(functionName) + 5;
for (String s : paramNames) {
res += Utf8Helper.getBytesLength(s) + 1;
}
return res;
}
@Override

View File

@@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.graph.GraphSourceItemPos;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -59,16 +58,18 @@ public class ActionStoreRegister extends Action implements StoreTypeAction {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI8(registerNumber);
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return surroundWithAction(baos.toByteArray(), version);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI8(registerNumber);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 1;
}
@Override

View File

@@ -27,7 +27,6 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -63,18 +62,18 @@ public class ActionWith extends Action implements GraphSourceItemContainer {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUI16(codeSize);
sos.close();
baos2.write(surroundWithAction(baos.toByteArray(), version));
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos2.toByteArray();
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUI16(codeSize);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
return 2;
}
@Override
@@ -110,7 +109,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer {
@Override
public long getHeaderSize() {
return surroundWithAction(new byte[]{0, 0}, version).length;
return super.getBytesLength(version) + 2;
}
@Override

View File

@@ -30,7 +30,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -143,40 +143,44 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
@Override
public long getHeaderSize() {
return getBytes(version).length;
return getBytesLength(version);
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
try {
sos.writeString(functionName);
sos.writeUI16(paramNames.size());
sos.writeUI8(registerCount);
sos.writeUB(1, preloadParentFlag ? 1 : 0);
sos.writeUB(1, preloadRootFlag ? 1 : 0);
sos.writeUB(1, suppressSuperFlag ? 1 : 0);
sos.writeUB(1, preloadSuperFlag ? 1 : 0);
sos.writeUB(1, suppressArgumentsFlag ? 1 : 0);
sos.writeUB(1, preloadArgumentsFlag ? 1 : 0);
sos.writeUB(1, suppressThisFlag ? 1 : 0);
sos.writeUB(1, preloadThisFlag ? 1 : 0);
sos.writeUB(7, reserved);
sos.writeUB(1, preloadGlobalFlag ? 1 : 0);
for (int i = 0; i < paramNames.size(); i++) {
sos.writeUI8(paramRegisters.get(i));
sos.writeString(paramNames.get(i));
}
sos.writeUI16(codeSize);
sos.close();
baos2.write(surroundWithAction(baos.toByteArray(), version));
} catch (IOException e) {
throw new Error("This should never happen.", e);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeString(functionName);
sos.writeUI16(paramNames.size());
sos.writeUI8(registerCount);
sos.writeUB(1, preloadParentFlag ? 1 : 0);
sos.writeUB(1, preloadRootFlag ? 1 : 0);
sos.writeUB(1, suppressSuperFlag ? 1 : 0);
sos.writeUB(1, preloadSuperFlag ? 1 : 0);
sos.writeUB(1, suppressArgumentsFlag ? 1 : 0);
sos.writeUB(1, preloadArgumentsFlag ? 1 : 0);
sos.writeUB(1, suppressThisFlag ? 1 : 0);
sos.writeUB(1, preloadThisFlag ? 1 : 0);
sos.writeUB(7, reserved);
sos.writeUB(1, preloadGlobalFlag ? 1 : 0);
for (int i = 0; i < paramNames.size(); i++) {
sos.writeUI8(paramRegisters.get(i));
sos.writeString(paramNames.get(i));
}
return baos2.toByteArray();
sos.writeUI16(codeSize);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = Utf8Helper.getBytesLength(functionName) + 8;
for (int i = 0; i < paramNames.size(); i++) {
res += Utf8Helper.getBytesLength(paramNames.get(i)) + 2;
}
return res;
}
@Override

View File

@@ -33,7 +33,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.helpers.Helper;
import java.io.ByteArrayOutputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -95,27 +95,34 @@ public class ActionTry extends Action implements GraphSourceItemContainer {
}
@Override
public byte[] getBytes(int version) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, version);
try {
sos.writeUB(5, reserved);
sos.writeUB(1, catchInRegisterFlag ? 1 : 0);
sos.writeUB(1, finallyBlockFlag ? 1 : 0);
sos.writeUB(1, catchBlockFlag ? 1 : 0);
sos.writeUI16((int) trySize);
sos.writeUI16((int) catchSize);
sos.writeUI16((int) finallySize);
if (catchInRegisterFlag) {
sos.writeUI8(catchRegister);
} else {
sos.writeString(catchName == null ? "" : catchName);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
protected void getContentBytes(SWFOutputStream sos) throws IOException {
sos.writeUB(5, reserved);
sos.writeUB(1, catchInRegisterFlag ? 1 : 0);
sos.writeUB(1, finallyBlockFlag ? 1 : 0);
sos.writeUB(1, catchBlockFlag ? 1 : 0);
sos.writeUI16((int) trySize);
sos.writeUI16((int) catchSize);
sos.writeUI16((int) finallySize);
if (catchInRegisterFlag) {
sos.writeUI8(catchRegister);
} else {
sos.writeString(catchName == null ? "" : catchName);
}
return surroundWithAction(baos.toByteArray(), version);
}
/**
* Gets the length of action converted to bytes
*
* @return Length
*/
@Override
protected int getContentBytesLength() {
int res = 8;
if (!catchInRegisterFlag) {
res += Utf8Helper.getBytesLength(catchName == null ? "" : catchName);
}
return res;
}
public ActionTry(FlasmLexer lexer, int version) throws IOException, ActionParseException {
@@ -173,7 +180,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer {
@Override
public long getHeaderSize() {
return getBytes(version).length;
return getBytesLength(version);
}
public long getTrySize() {

View File

@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.ApplicationInfo;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings;
@@ -122,7 +123,7 @@ public class FontExporter {
} catch (IOException ex) {
Logger.getLogger(FontExporter.class.getName()).log(Level.SEVERE, null, ex);
}
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
public void exportFont(FontTag ft, FontExportMode mode, File file) throws IOException {

View File

@@ -98,7 +98,7 @@ public class MovieExporter {
HashMap<Integer, VideoFrameTag> frames = new HashMap<>();
SWF.populateVideoFrames(videoStream.characterID, swf.tags, frames);
if (frames.isEmpty()) {
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
//double ms = 1000.0f / ((float) frameRate);

View File

@@ -62,7 +62,7 @@ public class DefineFont4Tag extends CharacterTag {
super(swf, ID, NAME, null);
fontID = swf.getNextCharacterId();
fontName = "New font";
fontData = new byte[0];
fontData = SWFInputStream.BYTE_ARRAY_EMPTY;
}
public DefineFont4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {

View File

@@ -39,7 +39,7 @@ public class JPEGTablesTag extends Tag {
*/
public JPEGTablesTag(SWF swf) {
super(swf, ID, NAME, null);
jpegData = new byte[0];
jpegData = SWFInputStream.BYTE_ARRAY_EMPTY;
}
public JPEGTablesTag(SWFInputStream sis, ByteArrayRange data) throws IOException {

View File

@@ -58,7 +58,7 @@ public class BUTTONCONDACTION implements ASMSource, Serializable {
public BUTTONCONDACTION() {
swf = null;
tag = null;
actionBytes = new ByteArrayRange(new byte[0]);
actionBytes = new ByteArrayRange(SWFInputStream.BYTE_ARRAY_EMPTY);
}
@Override

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types.gfx;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
import com.jpexs.helpers.MemoryInputStream;
import com.jpexs.helpers.utf8.Utf8Helper;
@@ -215,7 +216,7 @@ public class GFxInputStream {
*/
public byte[] readBytes(long count, String name) throws IOException {
if (count <= 0) {
return new byte[0];
return SWFInputStream.BYTE_ARRAY_EMPTY;
}
newDumpLevel(name, "bytes");
byte[] ret = new byte[(int) count];

View File

@@ -1366,7 +1366,7 @@ public class XFLConverter {
boolean soundType = false;
boolean soundSize = false;
long soundSampleCount = 0;
byte[] soundData = new byte[0];
byte[] soundData = SWFInputStream.BYTE_ARRAY_EMPTY;
int[] rateMap = {5, 11, 22, 44};
String exportFormat = "flv";
if (symbol instanceof SoundStreamHeadTypeTag) {
@@ -1491,7 +1491,7 @@ public class XFLConverter {
}
SoundTag st = (SoundTag) symbol;
SoundFormat fmt = st.getSoundFormat();
byte[] data = new byte[0];
byte[] data = SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data = new SoundExporter().exportSound(st, SoundExportMode.MP3_WAV);
} catch (IOException ex) {
@@ -1544,7 +1544,7 @@ public class XFLConverter {
break;
}
byte[] data = new byte[0];
byte[] data = SWFInputStream.BYTE_ARRAY_EMPTY;
try {
data = new MovieExporter().exportMovie(video, MovieExportMode.FLV);
} catch (IOException ex) {

View File

@@ -16,13 +16,15 @@
*/
package com.jpexs.helpers;
import com.jpexs.decompiler.flash.SWFInputStream;
/**
*
* @author JPEXS
*/
public class ByteArrayRange {
public static final ByteArrayRange EMPTY = new ByteArrayRange(new byte[0]);
public static final ByteArrayRange EMPTY = new ByteArrayRange(SWFInputStream.BYTE_ARRAY_EMPTY);
private final byte[] array;

View File

@@ -1,18 +1,19 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library 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
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.helpers.utf8;
import java.io.UnsupportedEncodingException;
@@ -38,4 +39,9 @@ public class Utf8Helper {
public static byte[] getBytes(String string) {
return string.getBytes(charset);
}
public static int getBytesLength(String string) {
// todo: make it faster without actually writing it to an array
return string.getBytes(charset).length;
}
}