Initial commit from SVN.
This commit is contained in:
170
Class File Services/src/com/de22/javabytecode/code/Test.java
Normal file
170
Class File Services/src/com/de22/javabytecode/code/Test.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package com.de22.javabytecode.code;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.io.ByteArrayInputStream;
|
||||
import com.common.io.ByteArrayOutputStream;
|
||||
import com.common.io.ObjectInputStream;
|
||||
import com.common.io.ObjectOutputStream;
|
||||
import com.de22.javabytecode.Type;
|
||||
|
||||
/**
|
||||
* Copyright Declarative Engineering LLC 2007<p>
|
||||
* A simple test class that reads in a class file and then writes it out without any modifications.
|
||||
* This class tests the ability to read and write a class file without introducing errors.
|
||||
*/
|
||||
public class Test {
|
||||
/**
|
||||
* Reverse engineers a class file and writes it back out to 'output.class'.
|
||||
* @param args The array of initialization parameters.
|
||||
* args[0] = The path and file name of the class to reverse engineer.
|
||||
* args[1] = The path (must exist) where the output.class file will be stored. If the file exists it will be over written.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
String debugText = null;
|
||||
long t = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
File file = new File(args[0]);
|
||||
File path = args.length > 1 ? new File(args[1]) : null;
|
||||
|
||||
if(path != null && (path.isFile() || (!path.exists() && !path.mkdirs()))) {
|
||||
path = null;
|
||||
}//if//
|
||||
|
||||
if(file.getName().endsWith(".class")) {
|
||||
debugText = file.getPath();
|
||||
processClassFile(file, new File(path, "output.class"));
|
||||
compareClassFiles(file, new File(path, "output.class"));
|
||||
}//if//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e, "Caught while processing the class file: " + debugText);
|
||||
}//catch//
|
||||
|
||||
Debug.log("Total time (milliseconds): " + (System.currentTimeMillis() - t));
|
||||
|
||||
System.exit(0);
|
||||
}//main()//
|
||||
/**
|
||||
* Writes a file.
|
||||
* @param file The file to write.
|
||||
* @param bytes The bytes to place in the file.
|
||||
*/
|
||||
public static void writeFile(File file, byte[] bytes) {
|
||||
FileOutputStream fout = null;
|
||||
|
||||
try {
|
||||
fout = new FileOutputStream(file);
|
||||
fout.write(bytes);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}//catch//
|
||||
finally {
|
||||
if(fout != null) {
|
||||
try {
|
||||
fout.close();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
}//catch//
|
||||
}//if//
|
||||
}//finally//
|
||||
}//writeFile()//
|
||||
/**
|
||||
* Reads a file and returns the bytes contained there in.
|
||||
* @param file The file to read.
|
||||
* @return The bytes contained in the file.
|
||||
*/
|
||||
public static byte[] readFile(File file) {
|
||||
FileInputStream fin = null;
|
||||
byte[] bytes = null;
|
||||
int counter = 0;
|
||||
|
||||
try {
|
||||
fin = new FileInputStream(file);
|
||||
bytes = new byte[fin.available()];
|
||||
|
||||
while(counter < bytes.length) {
|
||||
counter += fin.read(bytes, counter, bytes.length - counter);
|
||||
}//while//
|
||||
|
||||
fin.close();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}//catch//
|
||||
finally {
|
||||
if(fin != null) {
|
||||
try {
|
||||
fin.close();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
}//catch//
|
||||
}//if//
|
||||
}//finally//
|
||||
|
||||
return bytes;
|
||||
}//readFile()//
|
||||
/**
|
||||
* Processes a class file and writes out the byte codes in a semi-readable form.
|
||||
* @param bytesIn The input stream containing the bytes codes. This stream will always be closed by this method.
|
||||
* @param outputPath The optional path where the class output should be written to (under its packaging of course). The console will be used otherwise.
|
||||
*/
|
||||
private static void processClassFile(File inputFile, File outputFile) throws Throwable {
|
||||
ByteArrayInputStream bin = null;
|
||||
ObjectInputStream in = null;
|
||||
Type type = null;
|
||||
ByteArrayOutputStream bout = null;
|
||||
ObjectOutputStream out = null;
|
||||
|
||||
try {
|
||||
bin = new ByteArrayInputStream(readFile(inputFile));
|
||||
in = new ObjectInputStream(bin, null, null);
|
||||
|
||||
type = new Type();
|
||||
type.readExternal(in);
|
||||
|
||||
bout = new ByteArrayOutputStream(100000, false);
|
||||
out = new ObjectOutputStream(bout, null);
|
||||
type.writeExternal(out);
|
||||
out.flush();
|
||||
writeFile(outputFile, bout.toByteArray());
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}//catch//
|
||||
}//processClassFile()//
|
||||
/**
|
||||
* Processes a class file and writes out the byte codes in a semi-readable form.
|
||||
* @param bytesIn The input stream containing the bytes codes. This stream will always be closed by this method.
|
||||
* @param outputPath The optional path where the class output should be written to (under its packaging of course). The console will be used otherwise.
|
||||
*/
|
||||
private static void compareClassFiles(File inputFile, File outputFile) throws Throwable {
|
||||
byte[] originalBytes;
|
||||
byte[] modifiedBytes;
|
||||
int byteLength;
|
||||
|
||||
originalBytes = readFile(inputFile);
|
||||
modifiedBytes = readFile(outputFile);
|
||||
byteLength = Math.min(originalBytes.length, modifiedBytes.length);
|
||||
|
||||
for(int index = 0; index < byteLength; index++) {
|
||||
if(originalBytes[index] != modifiedBytes[index]) {
|
||||
Debug.log("Files diverge at index " + index);
|
||||
return;
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
if(originalBytes.length != modifiedBytes.length) {
|
||||
Debug.log("One file has more bytes than the other.");
|
||||
}//if//
|
||||
else {
|
||||
Debug.log("Files are exactly the same.");
|
||||
}//else//
|
||||
}//processClassFile()//
|
||||
}//Test//
|
||||
Reference in New Issue
Block a user