diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 70b8bbd15..47c59e692 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -19,10 +19,12 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph; import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser; import com.jpexs.decompiler.flash.abc.avm2.parser.MissingSymbolHandler; import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException; +import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.gui.GraphFrame; import com.jpexs.decompiler.flash.gui.View; @@ -86,9 +88,11 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi setText(textWithHex); } else { if (textHexOnly == null) { - textHexOnly = new HilightedText(Helper.byteArrToString(abc.bodies[bodyIndex].code.getBytes())); + HilightedTextWriter writer = new HilightedTextWriter(true); + Helper.byteArrayToHex(writer, abc.bodies[bodyIndex].code.getBytes()); + textHexOnly = new HilightedText(writer); } - setText(textWithHex); + setText(textHexOnly); } hilighOffset(oldOffset); } @@ -176,30 +180,44 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi public boolean save(ConstantPool constants) { try { - AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes("UTF-8")), constants, trait, new MissingSymbolHandler() { - //no longer ask for adding new constants - @Override - public boolean missingString(String value) { - return true; + String text = getText(); + if (text.trim().startsWith("#hexdata")) { + byte[] data = Helper.getBytesFromHexaText(text); + MethodBody mb = abc.bodies[bodyIndex]; + mb.codeBytes = data; + try { + mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes)); + } catch (UnknownInstructionCode re) { + mb.code = new AVM2Code(); + Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re); } + mb.code.compact(); + } else { + AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(text.getBytes("UTF-8")), constants, trait, new MissingSymbolHandler() { + //no longer ask for adding new constants + @Override + public boolean missingString(String value) { + return true; + } - @Override - public boolean missingInt(long value) { - return true; - } + @Override + public boolean missingInt(long value) { + return true; + } - @Override - public boolean missingUInt(long value) { - return true; - } + @Override + public boolean missingUInt(long value) { + return true; + } - @Override - public boolean missingDouble(double value) { - return true; - } - }, abc.bodies[bodyIndex], abc.method_info[abc.bodies[bodyIndex].method_info]); - acode.getBytes(abc.bodies[bodyIndex].codeBytes); - abc.bodies[bodyIndex].code = acode; + @Override + public boolean missingDouble(double value) { + return true; + } + }, abc.bodies[bodyIndex], abc.method_info[abc.bodies[bodyIndex].method_info]); + acode.getBytes(abc.bodies[bodyIndex].codeBytes); + abc.bodies[bodyIndex].code = acode; + } } catch (IOException ex) { } catch (ParseException ex) { View.showMessageDialog(this, (ex.text + " on line " + ex.line)); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java index 55baa8ce4..024d08117 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java @@ -108,14 +108,12 @@ public class MethodCodePanel extends JPanel implements ActionListener { hexButton.setToolTipText(AppStrings.translate("button.viewhex")); hexButton.setMargin(new Insets(3, 3, 3, 3)); - // todo: find icon, and set visible + // todo: find icon hexOnlyButton = new JToggleButton(View.getIcon("hex16")); hexOnlyButton.setActionCommand("HEXONLY"); hexOnlyButton.addActionListener(this); hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex")); hexOnlyButton.setMargin(new Insets(3, 3, 3, 3)); - hexOnlyButton.setVisible(false); - buttonsPanel.add(graphButton); buttonsPanel.add(hexButton); @@ -137,6 +135,11 @@ public class MethodCodePanel extends JPanel implements ActionListener { } if (e.getActionCommand().equals("HEX") || e.getActionCommand().equals("HEXONLY")) { + if (e.getActionCommand().equals("HEX")) { + hexOnlyButton.setSelected(false); + } else { + hexButton.setSelected(false); + } sourceTextArea.setHex(getExportMode(), false); } } @@ -148,10 +151,10 @@ public class MethodCodePanel extends JPanel implements ActionListener { } public void setEditMode(boolean val) { + ExportMode exportMode = getExportMode(); if (val) { - sourceTextArea.setHex(ExportMode.PCODE, false); + sourceTextArea.setHex(exportMode == ExportMode.HEX ? ExportMode.HEX : ExportMode.PCODE, false); } else { - ExportMode exportMode = getExportMode(); if (exportMode != ExportMode.PCODE) { sourceTextArea.setHex(exportMode, false); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 954687cf6..e02018c7a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -306,7 +306,9 @@ public class ActionPanel extends JPanel implements ActionListener { } } else { if (srcHexOnly == null) { - srcHexOnly = new HilightedText(Helper.byteArrToString(src.getActionBytes())); + HilightedTextWriter writer = new HilightedTextWriter(true); + Helper.byteArrayToHex(writer, src.getActionBytes()); + srcHexOnly = new HilightedText(writer); } setText(srcHexOnly); } @@ -443,13 +445,12 @@ public class ActionPanel extends JPanel implements ActionListener { hexButton.setToolTipText(AppStrings.translate("button.viewhex")); hexButton.setMargin(new Insets(3, 3, 3, 3)); - // todo: find icon, and set visible + // todo: find icon hexOnlyButton = new JToggleButton(View.getIcon("hex16")); hexOnlyButton.setActionCommand("HEXONLY"); hexOnlyButton.addActionListener(this); hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex")); hexOnlyButton.setMargin(new Insets(3, 3, 3, 3)); - //hexOnlyButton.setVisible(false); topButtonsPan = new JPanel(); topButtonsPan.setLayout(new BoxLayout(topButtonsPan, BoxLayout.X_AXIS)); @@ -618,8 +619,7 @@ public class ActionPanel extends JPanel implements ActionListener { } public void setEditMode(boolean val) { - // todo: create UI for editing raw data - final boolean rawEdit = false; + boolean rawEdit = hexOnlyButton.isSelected(); if (val) { setText(rawEdit ? srcHexOnly : srcNoHex); @@ -630,7 +630,7 @@ public class ActionPanel extends JPanel implements ActionListener { editor.getCaret().setVisible(true); asmLabel.setIcon(View.getIcon("editing16")); } else { - setText(hexButton.isSelected() ? srcWithHex : srcNoHex); + setHex(getExportMode()); editor.setEditable(false); saveButton.setVisible(false); editButton.setVisible(true); @@ -714,6 +714,11 @@ public class ActionPanel extends JPanel implements ActionListener { } else if (e.getActionCommand().equals("EDITACTION")) { setEditMode(true); } else if (e.getActionCommand().equals("HEX") || e.getActionCommand().equals("HEXONLY")) { + if (e.getActionCommand().equals("HEX")) { + hexOnlyButton.setSelected(false); + } else { + hexButton.setSelected(false); + } setHex(getExportMode()); } else if (e.getActionCommand().equals("CANCELACTION")) { setEditMode(false); @@ -722,7 +727,7 @@ public class ActionPanel extends JPanel implements ActionListener { try { String text = editor.getText(); if (text.trim().startsWith("#hexdata")) { - src.setActionBytes(getBytesFromHexaText(text)); + src.setActionBytes(Helper.getBytesFromHexaText(text)); } else { src.setActions(ASMParser.parse(0, src.getPos(), true, text, SWF.DEFAULT_VERSION, false), SWF.DEFAULT_VERSION); } @@ -763,26 +768,6 @@ public class ActionPanel extends JPanel implements ActionListener { return exportMode; } - public byte[] getBytesFromHexaText(String text) { - Scanner scanner = new Scanner(text); - scanner.nextLine(); // ignore first line - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - while (scanner.hasNextLine()) { - String line = scanner.nextLine().trim(); - if (line.startsWith(";")) { - continue; - } - line = line.replace(" ", ""); - for (int i = 0; i < line.length() / 2; i++) { - String hexStr = line.substring(i * 2, (i + 1) * 2); - byte b = (byte) Integer.parseInt(hexStr, 16); - baos.write(b); - } - } - byte[] data = baos.toByteArray(); - return data; - } - public void updateSearchPos() { searchPos.setText((foundPos + 1) + "/" + found.size()); setSource(found.get(foundPos), true); diff --git a/trunk/src/com/jpexs/decompiler/flash/helpers/HilightedText.java b/trunk/src/com/jpexs/decompiler/flash/helpers/HilightedText.java index 8136ade7a..91b7fa28d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/helpers/HilightedText.java +++ b/trunk/src/com/jpexs/decompiler/flash/helpers/HilightedText.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.helpers; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; /** @@ -61,5 +62,10 @@ public class HilightedText implements Serializable { public HilightedText(String text) { this.text = text; + this.traitHilights = new ArrayList<>(); + this.classHilights = new ArrayList<>(); + this.methodHilights = new ArrayList<>(); + this.instructionHilights = new ArrayList<>(); + this.specialHilights = new ArrayList<>(); } } diff --git a/trunk/src/com/jpexs/helpers/Helper.java b/trunk/src/com/jpexs/helpers/Helper.java index 5db7df549..5d1c84edf 100644 --- a/trunk/src/com/jpexs/helpers/Helper.java +++ b/trunk/src/com/jpexs/helpers/Helper.java @@ -604,6 +604,26 @@ public class Helper { return writer.toString(); } + public static byte[] getBytesFromHexaText(String text) { + Scanner scanner = new Scanner(text); + scanner.nextLine(); // ignore first line + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (scanner.hasNextLine()) { + String line = scanner.nextLine().trim(); + if (line.startsWith(";")) { + continue; + } + line = line.replace(" ", ""); + for (int i = 0; i < line.length() / 2; i++) { + String hexStr = line.substring(i * 2, (i + 1) * 2); + byte b = (byte) Integer.parseInt(hexStr, 16); + baos.write(b); + } + } + byte[] data = baos.toByteArray(); + return data; + } + public static T timedCall(Callable c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException { FutureTask task = new FutureTask<>(c); THREAD_POOL.execute(task);