Skip to content

Commit

Permalink
feat: Compeleted Hex And Scroll Show
Browse files Browse the repository at this point in the history
  • Loading branch information
yuequan1997 committed Sep 23, 2018
1 parent 7ae2c61 commit 5417db3
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package org.yuequan.bwv.classfile;

import org.yuequan.bwv.classfile.attribute.AttributeInfo;
import org.yuequan.bwv.classfile.constant.ConstantClassInfo;
import org.yuequan.bwv.classfile.constant.ConstantFieldRefInfo;
import org.yuequan.bwv.classfile.constant.ConstantPool;
import org.yuequan.bwv.classfile.datatype.U2;
import org.yuequan.bwv.classfile.datatype.U4;
import org.yuequan.bwv.classfile.field.FieldInfo;
import org.yuequan.bwv.classfile.method.MethodInfo;
import org.yuequan.bwv.classfile.reader.ClassFileReader;

import java.util.ArrayList;
import java.util.List;

public class ClassFile {
private final U4 magic;
private final U2 minorVersion;
Expand All @@ -25,9 +30,10 @@ public class ClassFile {
private final MethodInfo[] methodInfos;
private final U2 attributesCount;
private final AttributeInfo[] attributeInfos;

public ClassFile(ClassFileReader fileReader) {
private String name;
private String hexAndAscii;
public ClassFile(String name, ClassFileReader fileReader) {
this.name = name;
this.magic = new U4("magic", fileReader.readInt());
this.minorVersion = new U2("minor_version", fileReader.readShort());
this.majorVersion = new U2("major_version", fileReader.readShort());
Expand Down Expand Up @@ -126,9 +132,66 @@ public U2 getAttributesCount() {
public AttributeInfo[] getAttributeInfos() {
return attributeInfos;
}

public String getThisClassString(){
ConstantClassInfo classInfo = (ConstantClassInfo) constantPool.getConstantInfo().getInfos().get(thisClass.getValue() - 1);
return new String(constantPool.getConstantInfo().getConstantUtf8InfoMapper().get(Integer.valueOf(classInfo.getNameIndex().getValue())).getBytes());
}

public String getSuperClassString(){
ConstantClassInfo classInfo = (ConstantClassInfo) constantPool.getConstantInfo().getInfos().get(superClass.getValue() - 1);
return new String(constantPool.getConstantInfo().getConstantUtf8InfoMapper().get(Integer.valueOf(classInfo.getNameIndex().getValue())).getBytes());
}

public List<ConstantClassInfo> getInterfaceList(){
List<ConstantClassInfo> constantClassInfos = new ArrayList<>();
for (U2 interfaceU2 : this.getInterfaces()) {
ConstantClassInfo classInfo = (ConstantClassInfo) constantPool.getConstantInfo().getInfos().get(interfaceU2.getValue() - 1);
constantClassInfos.add(classInfo);
}
return constantClassInfos;
}

public List<String> getInterfaceStringList(){
List<String> interfaceStringList = new ArrayList<>();
getInterfaceList().forEach(constantClassInfo -> {
interfaceStringList.add(new String(constantPool.getConstantInfo().getConstantUtf8InfoMapper().get(Integer.valueOf(constantClassInfo.getNameIndex().getValue())).getBytes()));
});
return interfaceStringList;
}

public List<String> getFieldList(){
List<String> constantFieldRefInfos = new ArrayList<>();
for (FieldInfo fieldInfo : this.fieldInfos) {
constantFieldRefInfos.add(constantPool.getConstantInfo().getInfoWrappers().get(fieldInfo.getNameIndex().getValue() - 1).getValue());
}
return constantFieldRefInfos;
}

public List<String> getMethodList(){
List<String> methods = new ArrayList<>();
for (MethodInfo methodInfo : this.methodInfos) {
methods.add(constantPool.getConstantInfo().getInfoWrappers().get(methodInfo.getNameIndex().getValue() - 1).getValue());
}
return methods;
}

public List<String> getAttributeList(){
List<String> attributes = new ArrayList<>();
for (AttributeInfo attributeInfo : this.getAttributeInfos()) {
attributes.add(constantPool.getConstantInfo().getInfoWrappers().get(attributeInfo.getAttributeNameIndex().getValue() - 1).getValue());
}
return attributes;
}

public String getName() {
return name;
}

public String getHexAndAscii() {
return hexAndAscii;
}

public void setHexAndAscii(String hexAndAscii) {
this.hexAndAscii = hexAndAscii;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

public class ClassFileParser {
private File classFile;

private static final int BYTES_PER_ROW = 16;
public ClassFileParser(File classFile) {
this.classFile = classFile;
}
Expand All @@ -19,12 +19,48 @@ public ClassFile parser(){
try {
byte[] classBytes = Files.readAllBytes(Paths.get(classFile.getAbsolutePath()));
ClassFileReader reader = new ClassFileReader(classBytes);
ClassFile classFile = new ClassFile(reader);
ClassFile classFile = new ClassFile(this.classFile.getName() ,reader);

StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < classBytes.length; i+=BYTES_PER_ROW) {
stringBuilder.append(String.format("%08x", i));
stringBuilder.append("| ");
hexRow(classBytes, i, stringBuilder);
stringBuilder.append(" |");
toRowAscii(classBytes, i, stringBuilder);
stringBuilder.append('\n');
}
classFile.setHexAndAscii(stringBuilder.toString());
return classFile;
} catch (IOException e) {
//TODO: Exception Handler
e.printStackTrace();
}
return null;
}


public static void hexRow(byte[] bytes, int offset, StringBuilder sb){
for (int i = 0; i < BYTES_PER_ROW; i++) {
if(i + offset < bytes.length){
byte b = bytes[i + offset];
sb.append(String.format("%02x ", b).toUpperCase());
}else{
sb.append(" ");
}
}
}

public static void toRowAscii(byte[] bytes, int offset, StringBuilder sb){
for (int i = 0; i < BYTES_PER_ROW; i++) {
if(i + offset < bytes.length){
char c = (char) bytes[i + offset];
if(c >= '!' && c <= '~'){
sb.append(c);
}else{
sb.append(".");
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
Expand All @@ -14,7 +14,6 @@
import org.yuequan.bwv.classfile.ClassFile;
import org.yuequan.bwv.classfile.parser.ClassFileParser;
import org.yuequan.bwv.gui.tree.ClassFileNode;
import org.yuequan.bwv.gui.tree.ClassFileTreeItem;
import org.yuequan.bwv.gui.tree.ClassFileTreePackable;

import java.io.File;
Expand All @@ -33,6 +32,8 @@ public class AppController {
private BorderPane rootPane;
@FXML
private TreeView<ClassFileNode> treeView;
@FXML
private TextArea hexTextArea;

private double xOffset;
private double yOffset;
Expand All @@ -42,31 +43,6 @@ public class AppController {
*/
@FXML
public void initialize(){
// ClassFileTreeItem rootItem = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("Test.class")));
// rootItem.setExpanded(true);
// for (int i = 0; i < 6; i++) {
// ClassFileTreeItem item;
// if(i == 0){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("macgic: 0XCAFEBABE")));
// }else if(i == 1){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("minor_version: 0")));
// }else if(i == 2){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("major_version: 52")));
// }else if(i == 3){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("constant_pool_count: 13")));
// }else if(i == 4){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("constant_pool")));
// item.getChildren().add(new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("no message"))));
// item.getChildren().add(new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("no message"))));
// } else if(i == 5){
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("interfaces_count: 0")));
// }else{
// item = new ClassFileTreeItem(new ClassFileNode(new ClassFileComponent("no message")));
// }
// rootItem.getChildren().add(item);
// }
// treeView.setRoot(rootItem);

}

/**
Expand Down Expand Up @@ -108,7 +84,9 @@ public void handleOpenFileOnAction(ActionEvent event){
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Choose Class File", "*.class"));
File file = fileChooser.showOpenDialog(getWindow());
if(file != null){
ClassFileTreePackable.pack(new ClassFileParser(file).parser(), treeView);
ClassFile classFile = new ClassFileParser(file).parser();
ClassFileTreePackable.pack(classFile, treeView);
hexTextArea.setText(classFile.getHexAndAscii());
}
}

Expand Down
9 changes: 7 additions & 2 deletions bwv-gui/src/main/java/org/yuequan/bwv/gui/view/AppView.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" stylesheets="@../../../../../../resources/style.css, @/style.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.yuequan.bwv.gui.controller.AppController">
<BorderPane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1000.0" stylesheets="@../../../../../../resources/style.css, @/style.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.yuequan.bwv.gui.controller.AppController">
<left>
<AnchorPane fx:id="leftPane" prefHeight="200.0" prefWidth="200.0" styleClass="left-pane" BorderPane.alignment="CENTER">
<children>
Expand All @@ -21,7 +21,7 @@
</Label>
</children>
</AnchorPane>
<ScrollPane layoutY="50.0" prefHeight="515.0" prefWidth="196.0" styleClass="left-pane__scroll-pannel" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="55.0">
<ScrollPane fitToHeight="true" fitToWidth="true" layoutY="50.0" prefHeight="515.0" prefWidth="196.0" styleClass="left-pane__scroll-pannel" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="55.0">
<content>
<AnchorPane styleClass="scroll-panel__tree-panel">
<children>
Expand Down Expand Up @@ -50,6 +50,11 @@
<Button layoutX="563.0" layoutY="16.0" mnemonicParsing="false" onAction="#handleCloseButtonAction" styleClass="close" text="X" AnchorPane.rightAnchor="19.0" AnchorPane.topAnchor="16.0" />
</children>
</AnchorPane>
<TextArea fx:id="hexTextArea" editable="false" layoutX="14.0" layoutY="56.0" prefHeight="535.0" prefWidth="600.0" styleClass="hex-textarea" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
<font>
<Font name="Courier New" size="16.0" />
</font>
</TextArea>
</children></AnchorPane>
</center>
</BorderPane>
41 changes: 40 additions & 1 deletion bwv-gui/src/main/resources/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,46 @@
-fx-text-fill: #cbc9c9;
}


.tree-cell > .tree-disclosure-node > .arrow {
-fx-background-color: #cbc9c9;
}
.hex-textarea{
-fx-text-box-border: transparent;
-fx-focus-color: transparent; -fx-text-box-border: transparent;
-fx-background-color: transparent, #252525, transparent, #252525;
-fx-text-fill: #6b6a6a;
-fx-font-size: 16;
-fx-font-family: "Courier New";
}
.hex-textarea .content{
-fx-padding: 10px;
-fx-background-color: #252525;
-fx-text-fill: #6b6a6a;
-fx-font-family: "Courier New";
}

.scroll-pane {
-fx-background-color: #252525;
}

.scroll-bar:horizontal, .scroll-bar:vertical{
-fx-background-color:transparent;
}

.increment-button, .decrement-button {
-fx-background-color: transparent;
-fx-border-color: transparent;
}

.scroll-bar:horizontal .track,
.scroll-bar:vertical .track{
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-background-radius: 0em;
}

.scroll-bar:horizontal .thumb,
.scroll-bar:vertical .thumb {
-fx-background-color: #73fbef;
-fx-background-radius: 6em;
}

0 comments on commit 5417db3

Please sign in to comment.