more compact swf xml format (do not create xml nodes for each byte in byte arrays)

This commit is contained in:
honfika@gmail.com
2015-03-20 16:14:30 +01:00
parent d5fb45fd54
commit c397e38f61
7 changed files with 45 additions and 20 deletions

View File

@@ -109,7 +109,8 @@ public class ABC {
/* Map from multiname index of namespace value to namespace name**/
private Map<String, String> namespaceMap;
public ABC(SWF swf) {
public ABC(ABCContainerTag tag) {
this.parentTag = tag;
this.deobfuscation = null;
constants.constant_double.add(null);
constants.constant_int.add(null);

View File

@@ -2347,7 +2347,7 @@ public class ActionScriptParser {
System.err.println("WARNING: AS3 compiler is not finished yet. This is only used for debuggging!");
try {
initPlayer();
ABC abc = new ABC(swf);
ABC abc = new ABC(null);
ActionScriptParser parser = new ActionScriptParser(abc, playerABCs);
parser.addScript(new String(Helper.readFile(src), "UTF-8"), true, src, classPos);
try (FileOutputStream fos = new FileOutputStream(new File(dst))) {

View File

@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Helper;
@@ -42,6 +43,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
public int value_kind;
@Internal
public GraphTargetItem assignedValue;
@Override

View File

@@ -95,6 +95,15 @@ public class SwfXmlExporter {
generateXml(doc, node, "swf", swf, false, 0);
}
private static String byteArrayToString(byte[] data) {
StringBuilder sb = new StringBuilder(data.length * 2);
for (int i = 0; i < data.length; i++) {
sb.append(String.format("%02x", data[i]));
}
return sb.toString();
}
private static void generateXml(Document doc, Node node, String name, Object obj, boolean isListItem, int level) {
Class cls = obj != null ? obj.getClass() : null;
@@ -124,12 +133,10 @@ public class SwfXmlExporter {
} else if (obj instanceof ByteArrayRange) {
ByteArrayRange range = (ByteArrayRange) obj;
byte[] data = range.getRangeData();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i++) {
sb.append(String.format("%02x", data[i]));
}
((Element) node).setAttribute(name, sb.toString());
((Element) node).setAttribute(name, byteArrayToString(data));
} else if (obj instanceof byte[]) {
byte[] data = (byte[]) obj;
((Element) node).setAttribute(name, byteArrayToString(data));
} else if (cls != null && List.class.isAssignableFrom(cls)) {
List list = (List) obj;
Element listNode = doc.createElement(name);

View File

@@ -98,6 +98,7 @@ import com.jpexs.helpers.ReflectionTools;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@@ -134,7 +135,7 @@ public class SwfXmlImporter {
try {
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
processElement(doc.getDocumentElement(), swf, swf);
processElement(doc.getDocumentElement(), swf, swf, null);
} catch (ParserConfigurationException | SAXException ex) {
Logger.getLogger(SwfXmlImporter.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -152,7 +153,7 @@ public class SwfXmlImporter {
return field;
}
private void processElement(Element element, Object obj, SWF swf) {
private void processElement(Element element, Object obj, SWF swf, Tag tag) {
Class cls = obj.getClass();
for (int i = 0; i < element.getAttributes().getLength(); i++) {
Attr attr = (Attr) element.getAttributes().item(i);
@@ -182,7 +183,7 @@ public class SwfXmlImporter {
Node childChildNode = child.getChildNodes().item(j);
if (childChildNode instanceof Element) {
Element childChild = (Element) child.getChildNodes().item(j);
Object childObj = processObject(childChild, ReflectionTools.getFieldSubType(obj, field), swf);
Object childObj = processObject(childChild, ReflectionTools.getFieldSubType(obj, field), swf, tag);
list.add(childObj);
}
}
@@ -194,7 +195,7 @@ public class SwfXmlImporter {
Node childChildNode = child.getChildNodes().item(j);
if (childChildNode instanceof Element) {
Element childChild = (Element) child.getChildNodes().item(j);
Object childObj = processObject(childChild, childCls.getComponentType(), swf);
Object childObj = processObject(childChild, childCls.getComponentType(), swf, tag);
list.add(childObj);
}
}
@@ -206,7 +207,7 @@ public class SwfXmlImporter {
field.set(obj, array);
} else {
Object childObj = processObject(child, null, swf);
Object childObj = processObject(child, null, swf, tag);
field.set(obj, childObj);
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InstantiationException | InvocationTargetException ex) {
@@ -216,11 +217,15 @@ public class SwfXmlImporter {
}
}
private Object processObject(Element element, Class requiredType, SWF swf) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
private Object processObject(Element element, Class requiredType, SWF swf, Tag tag) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
String type = element.getAttribute("type");
if (type != null && !type.isEmpty()) {
Object childObj = createObject(type, swf);
processElement(element, childObj, swf);
Object childObj = createObject(type, swf, tag);
if (childObj instanceof Tag) {
tag = (Tag) childObj;
}
processElement(element, childObj, swf, tag);
return childObj;
} else {
String isNullAttr = element.getAttribute("isNull");
@@ -232,7 +237,7 @@ public class SwfXmlImporter {
}
}
private Object createObject(String type, SWF swf) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
private Object createObject(String type, SWF swf, Tag tag) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (swfTags == null) {
Map<String, Class> tags = new HashMap<>();
Map<Integer, Class> knownTags = Tag.getKnownClasses();
@@ -300,7 +305,14 @@ public class SwfXmlImporter {
cls = swfObjectsParam.get(type);
if (cls != null) {
return cls.getConstructor(SWF.class).newInstance(swf);
for (Constructor<?> constructor : cls.getConstructors()) {
if (constructor.getParameterCount() == 1) {
Class<?> parameterType = constructor.getParameterTypes()[0];
if (parameterType.isAssignableFrom(tag.getClass())) {
return constructor.newInstance(tag);
}
}
}
}
System.err.println("Type not found: " + type);
@@ -329,6 +341,9 @@ public class SwfXmlImporter {
} else if (cls == ByteArrayRange.class) {
ByteArrayRange range = new ByteArrayRange(stringValue);
return range;
} else if (cls == byte[].class) {
ByteArrayRange range = new ByteArrayRange(stringValue);
return range.getArray();
} else if (cls.isEnum()) {
return Enum.valueOf(cls, stringValue);
} else {

View File

@@ -79,7 +79,7 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
public DoABCDefineTag(SWF swf) {
super(swf, ID, "DoABCDefine", null);
name = "New DoABC";
abc = new ABC(swf);
abc = new ABC(this);
}
/**

View File

@@ -62,7 +62,7 @@ public class DoABCTag extends Tag implements ABCContainerTag {
*/
public DoABCTag(SWF swf) {
super(swf, ID, "DoABC", null);
abc = new ABC(swf);
abc = new ABC(this);
}
/**