diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java index 1f18644f8..f22625d83 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.action; -import com.jpexs.decompiler.flash.AppResources; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator; diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 2ee307356..5d33fac38 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -1262,13 +1262,13 @@ public class CommandLineArgumentParser { } catch (NumberFormatException nfe) { System.err.println("CharacterId should be integer"); - badArguments(); + System.exit(1); } int characterId = Integer.parseInt(args.remove()); SWF swf = new SWF(is, Configuration.parallelSpeedUp.get()); if (!swf.characters.containsKey(characterId)) { System.err.println("CharacterId not exits"); - badArguments(); + System.exit(1); } CharacterTag characterTag = swf.characters.get(characterId); @@ -1281,7 +1281,7 @@ public class CommandLineArgumentParser { new ImageImporter().importImage(imageTag, data); } else { System.err.println("The specified tag type it not supported for import"); - badArguments(); + System.exit(1); } try { diff --git a/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java b/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java index 2ea8ee805..df11b0cfb 100644 --- a/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/BinaryPanel.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.decompiler.flash.gui.hexview.HexView; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ComponentEvent; diff --git a/src/com/jpexs/decompiler/flash/gui/HexView.java b/src/com/jpexs/decompiler/flash/gui/HexView.java deleted file mode 100644 index 3a322c428..000000000 --- a/src/com/jpexs/decompiler/flash/gui/HexView.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2010-2014 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.decompiler.flash.gui; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Rectangle; -import javax.swing.JLabel; -import javax.swing.JTable; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableColumn; - -/** - * - * @author JPEXS - */ -public class HexView extends JTable { - - private final int bytesInRow = 16; - private long[] highlightStarts; - private long[] highlightEnds; - private byte[] data; - private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"}; - private final Color[] highlightColors; - private Color bgColor = Color.decode("#F7F7F7"); - private Color bgColorAlternate = Color.decode("#EDEDED"); - - public class HighlightCellRenderer extends DefaultTableCellRenderer { - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { - - JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); - int level = -1; - if (col > 0 && highlightStarts != null) { - if (col != bytesInRow + 1) { - int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1)); - for (int i = 0; i < highlightStarts.length; i++) { - if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) { - level++; - } else { - break; - } - } - } - } - - if (level > -1) { - l.setForeground(Color.white); - l.setBackground(highlightColors[level % highlightColors.length]); - } else { - l.setForeground(Color.black); - l.setBackground(row % 2 == 0 ? bgColor : bgColorAlternate); - } - - return l; - } - } - - public HexView() { - highlightColors = new Color[highlightColorsStr.length]; - for (int i = 0; i < highlightColors.length; i++) { - highlightColors[i] = Color.decode("#" + highlightColorsStr[i]); - } - - setModel(new AbstractTableModel() { - - @Override - public int getRowCount() { - if (data == null) { - return 0; - } - int byteCount = data.length; - int rowCount = byteCount / bytesInRow; - if (byteCount % bytesInRow != 0) { - rowCount++; - } - return rowCount; - } - - @Override - public int getColumnCount() { - return 2 * bytesInRow + 1 + 1; - } - - @Override - public String getColumnName(int column) { - if (column == 0) { - return "Address"; - } else if (column <= bytesInRow) { - return String.format("%01X", column - 1); - } - return ""; - } - - @Override - public Object getValueAt(int row, int column) { - if (column == 0) { - return String.format("%08X", (long) row * bytesInRow); - } else if (column <= bytesInRow) { - int pos = row * bytesInRow + column - 1; - if (pos < data.length) { - return String.format("%02X", data[pos]); - } - return null; - } else if (column == 1 + bytesInRow) { - return null; - } else { - int pos = row * bytesInRow + column - bytesInRow - 1 - 1; - if (pos < data.length) { - return (char) data[pos]; - } - return null; - } - } - }); - - setBackground(Color.white); - setFont(new Font("Monospaced", Font.PLAIN, 12)); - setTableHeader(new JTableHeader()); - setMaximumSize(new Dimension(200, 200)); - - setShowHorizontalLines(false); - setShowVerticalLines(false); - setRowSelectionAllowed(false); - setColumnSelectionAllowed(false); - - HighlightCellRenderer cellRenderer = new HighlightCellRenderer(); - TableColumn column = columnModel.getColumn(0); - column.setMaxWidth(80); - //column.setCellRenderer(cellRenderer); - for (int i = 0; i < bytesInRow; i++) { - column = columnModel.getColumn(i + 1); - column.setMaxWidth(25); - column.setCellRenderer(cellRenderer); - } - - column = columnModel.getColumn(bytesInRow + 1); - column.setMaxWidth(10); - - for (int i = 0; i < bytesInRow; i++) { - column = columnModel.getColumn(i + bytesInRow + 1 + 1); - column.setMaxWidth(10); - column.setCellRenderer(cellRenderer); - } - } - - public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) { - - if ((highlightStarts == null) ^ (highlightEnds == null)) { - throw new Error("highlightStarts and highlightEnds should be both null or not null."); - } - - if (highlightStarts != null && highlightStarts.length != highlightEnds.length) { - throw new Error("highlightStarts and highlightEnds should have the same number of elements."); - } - - this.data = data; - this.highlightStarts = highlightStarts; - this.highlightEnds = highlightEnds; - } - - public void scrollToByte(long byteNum) { - int row = (int) (byteNum / bytesInRow); - - //final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight()); - getSelectionModel().setSelectionInterval(row, row); - scrollRectToVisible(new Rectangle(getCellRect(row, 0, true))); - } - - public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) { - for (int i = 0; i < byteNumStarts.length; i++) { - scrollToByte(byteNumStarts[i]); - scrollToByte(byteNumEnds[i]); - scrollToByte(byteNumStarts[i]); - } - } -} diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 5131e7783..2db9db6e6 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -358,7 +358,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private JPanel createDumpPreviewCard() { JPanel dumpViewCard = new JPanel(new BorderLayout()); - dumpViewPanel = new DumpViewPanel(); + dumpViewPanel = new DumpViewPanel(dumpTree); dumpViewCard.add(new JScrollPane(dumpViewPanel), BorderLayout.CENTER); return dumpViewCard; @@ -2172,8 +2172,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return; } - dumpViewPanel.setData(DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData, dumpInfo); dumpViewPanel.revalidate(); + dumpViewPanel.setSelectedNode(dumpInfo); showCard(CARDDUMPVIEW); } diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java index 76f4b57aa..c07b27847 100644 --- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java @@ -17,7 +17,10 @@ package com.jpexs.decompiler.flash.gui.dumpview; import com.jpexs.decompiler.flash.dumpview.DumpInfo; -import com.jpexs.decompiler.flash.gui.HexView; +import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode; +import com.jpexs.decompiler.flash.gui.hexview.HexView; +import com.jpexs.decompiler.flash.gui.hexview.HexViewListener; +import com.jpexs.helpers.Helper; import java.awt.BorderLayout; import java.awt.Dimension; import java.util.ArrayList; @@ -25,6 +28,8 @@ import java.util.List; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; /** * @@ -32,21 +37,89 @@ import javax.swing.JScrollPane; */ public class DumpViewPanel extends JPanel { + private final JLabel selectedByteInfo; private final JLabel dumpViewLabel; private final HexView dumpViewHexTable; + private final DumpTree dumpTree; + private DumpInfo selectedDumpInfo; + private boolean skipNextScroll; + private boolean skipValueChange; - public DumpViewPanel() { + public DumpViewPanel(final DumpTree dumpTree) { super(new BorderLayout()); + this.dumpTree = dumpTree; + + selectedByteInfo = new JLabel(); + selectedByteInfo.setMinimumSize(new Dimension(100, 20)); + selectedByteInfo.setText("-"); + add(selectedByteInfo, BorderLayout.NORTH); + dumpViewLabel = new JLabel(); dumpViewLabel.setMinimumSize(new Dimension(100, 20)); + dumpViewLabel.setText("-"); add(dumpViewLabel, BorderLayout.SOUTH); dumpViewHexTable = new HexView(); + dumpViewHexTable.addListener(new HexViewListener() { + + @Override + public void byteValueChanged(int address, byte b) { + if (skipValueChange) { + return; + } + + TreeModel model = dumpTree.getModel(); + DumpInfo di = DumpInfoSwfNode.getSwfNode(selectedDumpInfo); + while (model.getChildCount(di) > 0) { + boolean found = false; + for (DumpInfo child : di.getChildInfos()) { + if (child.startByte > address) { + break; + } + if (child.getEndByte() >= address) { + di = child; + found = true; + } + } + if (!found) { + break; + } + } + List path = new ArrayList<>(); + while (di != null) { + path.add(0, di); + di = di.parent; + } + path.add(0, model.getRoot()); + TreePath tp = new TreePath(path.toArray()); + skipNextScroll = true; + dumpTree.setSelectionPath(tp); + dumpTree.scrollPathToVisible(tp); + } + + @Override + public void byteMouseMoved(int address, byte b) { + int b2 = b & 0xff; + selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8) + + " Hex: " + Helper.padZeros(Integer.toHexString(b2), 2) + + " Dec: " + b2 + + " Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8) + + " Ascii: " + (char) b2); + } + }); + add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER); } - public void setData(byte[] data, DumpInfo dumpInfo) { + public void setSelectedNode(DumpInfo dumpInfo) { + if (this.selectedDumpInfo == dumpInfo) { + skipNextScroll = false; + return; + } + + this.selectedDumpInfo = dumpInfo; + byte[] data = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData; List dumpInfos = new ArrayList<>(); DumpInfo di = dumpInfo; while (di.parent != null) { @@ -61,12 +134,17 @@ public class DumpViewPanel extends JPanel { highlightEnds[i] = di2.getEndByte(); } dumpViewHexTable.setData(data, highlightStarts, highlightEnds); + dumpViewHexTable.revalidate(); if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) { int selectionStart = (int) dumpInfo.startByte; int selectionEnd = (int) dumpInfo.getEndByte(); - dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds); + if (!skipNextScroll) { + skipValueChange = true; + dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds); + skipValueChange = false; + } setLabelText("startByte: " + dumpInfo.startByte + " startBit: " + dumpInfo.startBit @@ -76,6 +154,7 @@ public class DumpViewPanel extends JPanel { + " selectionEnd: " + selectionEnd); } + skipNextScroll = false; repaint(); } diff --git a/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java b/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java new file mode 100644 index 000000000..161baec7f --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/hexview/HexView.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010-2014 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.decompiler.flash.gui.hexview; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; + +/** + * + * @author JPEXS + */ +public class HexView extends JTable { + + private static final int bytesInRow = 16; + private long[] highlightStarts; + private long[] highlightEnds; + private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"}; + private final Color[] highlightColors; + private final Color bgColor = Color.decode("#F7F7F7"); + private final Color bgColorAlternate = Color.decode("#EDEDED"); + private int itsRow = 0; + private int itsColumn = 0; + private HexViewListener listener; + + private class HighlightCellRenderer extends DefaultTableCellRenderer { + + public int byteIndex; + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { + + JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + int level = -1; + if (col > 0 && highlightStarts != null && col != bytesInRow + 1) { + int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1)); + byteIndex = idx; + for (int i = 0; i < highlightStarts.length; i++) { + if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) { + level++; + } else { + break; + } + } + } + + Color foreground; + Color background; + if (level > -1) { + foreground = Color.white; + background = highlightColors[level % highlightColors.length]; + } else { + foreground = Color.black; + background = row % 2 == 0 ? bgColor : bgColorAlternate; + } + + if (col == itsColumn && row == itsRow) { + foreground = new Color(255 - foreground.getRed(), 255 - foreground.getGreen(), 255 - foreground.getBlue()); + background = new Color(255 - background.getRed(), 255 - background.getGreen(), 255 - background.getBlue()); + } + l.setForeground(foreground); + l.setBackground(background); + + + return l; + } + } + + private class HexViewSelectionListener implements ListSelectionListener { + + private final HexView table; + + public HexViewSelectionListener(HexView table) { + this.table = table; + } + + @Override + public void valueChanged(ListSelectionEvent e) { + + int col = table.getSelectedColumn(); + int row = table.getSelectedRow(); + + if (col > 0 && highlightStarts != null && col != bytesInRow + 1) { + int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1)); + byte[] data = getModel().getData(); + if (idx < data.length) { + if (listener != null) { + listener.byteValueChanged(idx, data[idx]); + } + } + } + } + } + + private class HexViewMouseAdapter extends MouseAdapter { + + @Override + public void mouseClicked(MouseEvent e) { + } + } + + private class HexViewMouseMotionAdapter extends MouseMotionAdapter { + + @Override + public void mouseMoved(MouseEvent e) { + HexView table = (HexView) e.getSource(); + Point point = e.getPoint(); + int col = table.columnAtPoint(point); + int row = table.rowAtPoint(point); + itsColumn = col; + itsRow = row; + getModel().fireTableCellUpdated(row, col); + + if (listener != null) { + int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1)); + listener.byteMouseMoved(idx, getModel().getData()[idx]); + } + } + } + + public HexView() { + super(new HexViewTableModel(bytesInRow)); + highlightColors = new Color[highlightColorsStr.length]; + for (int i = 0; i < highlightColors.length; i++) { + highlightColors[i] = Color.decode("#" + highlightColorsStr[i]); + } + + setBackground(Color.white); + setFont(new Font("Monospaced", Font.PLAIN, 12)); + setTableHeader(new JTableHeader()); + setMaximumSize(new Dimension(200, 200)); + + setShowHorizontalLines(false); + setShowVerticalLines(false); + setRowSelectionAllowed(false); + setColumnSelectionAllowed(false); + + HighlightCellRenderer cellRenderer = new HighlightCellRenderer(); + TableColumn column = columnModel.getColumn(0); + column.setMaxWidth(80); + for (int i = 0; i < bytesInRow; i++) { + column = columnModel.getColumn(i + 1); + column.setMaxWidth(25); + column.setCellRenderer(cellRenderer); + } + + column = columnModel.getColumn(bytesInRow + 1); + column.setMaxWidth(10); + + for (int i = 0; i < bytesInRow; i++) { + column = columnModel.getColumn(i + bytesInRow + 1 + 1); + column.setMaxWidth(10); + column.setCellRenderer(cellRenderer); + } + + addMouseListener(new HexViewMouseAdapter()); + addMouseMotionListener(new HexViewMouseMotionAdapter()); + ListSelectionModel rowSelModel = getSelectionModel(); + ListSelectionModel colSelModel = getColumnModel().getSelectionModel(); + ListSelectionListener selectionListener = new HexViewSelectionListener(this); + rowSelModel.addListSelectionListener(selectionListener); + colSelModel.addListSelectionListener(selectionListener); + } + + @Override + public HexViewTableModel getModel() { + TableModel model = super.getModel(); + return (HexViewTableModel) model; + } + + public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) { + + if ((highlightStarts == null) ^ (highlightEnds == null)) { + throw new Error("highlightStarts and highlightEnds should be both null or not null."); + } + + if (highlightStarts != null && highlightStarts.length != highlightEnds.length) { + throw new Error("highlightStarts and highlightEnds should have the same number of elements."); + } + + getModel().setData(data); + this.highlightStarts = highlightStarts; + this.highlightEnds = highlightEnds; + } + + public void scrollToByte(long byteNum) { + + int row = (int) (byteNum / bytesInRow); + + //final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight()); + getSelectionModel().setSelectionInterval(row, row); + scrollRectToVisible(new Rectangle(getCellRect(row, 0, true))); + } + + public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) { + for (int i = 0; i < byteNumStarts.length; i++) { + scrollToByte(byteNumStarts[i]); + scrollToByte(byteNumEnds[i]); + scrollToByte(byteNumStarts[i]); + } + } + + public void addListener(HexViewListener listener) { + this.listener = listener; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/hexview/HexViewListener.java b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewListener.java new file mode 100644 index 000000000..a5344a2a1 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewListener.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010-2014 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.decompiler.flash.gui.hexview; + +/** + * + * @author JPEXS + */ +public interface HexViewListener { + + public void byteValueChanged(int address, byte b); + + public void byteMouseMoved(int address, byte b); +} diff --git a/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java new file mode 100644 index 000000000..d5588b777 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/hexview/HexViewTableModel.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010-2014 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.decompiler.flash.gui.hexview; + +import javax.swing.table.AbstractTableModel; + +/** + * + * @author JPEXS + */ +public class HexViewTableModel extends AbstractTableModel { + + private byte[] data; + private final int bytesInRow; + + public HexViewTableModel(int bytesInRow) { + this.bytesInRow = bytesInRow; + } + + @Override + public int getRowCount() { + if (data == null) { + return 0; + } + int byteCount = data.length; + int rowCount = byteCount / bytesInRow; + if (byteCount % bytesInRow != 0) { + rowCount++; + } + return rowCount; + } + + @Override + public int getColumnCount() { + return 2 * bytesInRow + 1 + 1; + } + + @Override + public String getColumnName(int column) { + if (column == 0) { + return "Address"; + } else if (column <= bytesInRow) { + return String.format("%01X", column - 1); + } + return ""; + } + + @Override + public Object getValueAt(int row, int column) { + if (column == 0) { + return String.format("%08X", (long) row * bytesInRow); + } else if (column <= bytesInRow) { + int pos = row * bytesInRow + column - 1; + if (pos < data.length) { + return String.format("%02X", data[pos]); + } + return null; + } else if (column == 1 + bytesInRow) { + return null; + } else { + int pos = row * bytesInRow + column - bytesInRow - 1 - 1; + if (pos < data.length) { + return (char) (data[pos] & 0xff); + } + return null; + } + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + @Override + public void fireTableCellUpdated(int row, int columnd) { + super.fireTableCellUpdated(bytesInRow, bytesInRow); + } +}