diff --git a/src/yetmorecode/file/BinaryFileInputStream.java b/src/yetmorecode/file/BinaryFileInputStream.java
new file mode 100644
index 0000000..e8508af
--- /dev/null
+++ b/src/yetmorecode/file/BinaryFileInputStream.java
@@ -0,0 +1,101 @@
+package yetmorecode.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class BinaryFileInputStream extends FileInputStream {
+
+ private ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
+
+ public BinaryFileInputStream(String name) throws FileNotFoundException {
+ super(name);
+ }
+
+ public BinaryFileInputStream(String name, ByteOrder order) throws FileNotFoundException {
+ super(name);
+ byteOrder = order;
+ }
+
+ public BinaryFileInputStream(File file) throws FileNotFoundException {
+ super(file);
+ }
+
+ public BinaryFileInputStream(File file, ByteOrder order) throws FileNotFoundException {
+ this(file);
+ byteOrder = order;
+ }
+
+ public int readByte(long offset) throws IOException {
+ var old = position(offset);
+ int ret = readByte();
+ position(old);
+ return ret;
+ }
+
+ public int readByte() throws IOException {
+ return read();
+ }
+
+ public short readShort(long offset) throws IOException {
+ var old = position(offset);
+ var i = readShort();
+ position(old);
+ return i;
+ }
+
+ public short readShort() throws IOException {
+ byte[] bytes = readNBytes(2);
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ bb.order(byteOrder);
+ return bb.getShort();
+ }
+
+ public int readInt(long offset) throws IOException {
+ var old = position(offset);
+ var i = readInt();
+ position(old);
+ return i;
+ }
+
+ public int readInt() throws IOException {
+ byte[] bytes = readNBytes(4);
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ bb.order(byteOrder);
+ return bb.getInt();
+ }
+
+ public float readFloat(long offset) throws IOException {
+ var old = position(offset);
+ var i = readFloat();
+ position(old);
+ return i;
+ }
+
+ public float readFloat() throws IOException {
+ byte[] bytes = readNBytes(4);
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ bb.order(byteOrder);
+ return bb.getFloat();
+ }
+
+ public String readString(long offset, int size) throws IOException {
+ var old = position(offset);
+ var i = readString(size);
+ position(old);
+ return i;
+ }
+
+ public String readString(int size) throws IOException {
+ return new String(readNBytes(size));
+ }
+
+ public long position(long offset) throws IOException {
+ var old = getChannel().position();
+ getChannel().position(offset);
+ return old;
+ }
+}
diff --git a/src/yetmorecode/file/BinaryFileOutputStream.java b/src/yetmorecode/file/BinaryFileOutputStream.java
new file mode 100644
index 0000000..7cfa647
--- /dev/null
+++ b/src/yetmorecode/file/BinaryFileOutputStream.java
@@ -0,0 +1,12 @@
+package yetmorecode.file;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+
+public class BinaryFileOutputStream extends FileOutputStream {
+
+ public BinaryFileOutputStream(String name) throws FileNotFoundException {
+ super(name);
+ }
+
+}
diff --git a/src/yetmorecode/format/exception/InvalidHeaderException.java b/src/yetmorecode/file/exception/InvalidHeaderException.java
similarity index 80%
rename from src/yetmorecode/format/exception/InvalidHeaderException.java
rename to src/yetmorecode/file/exception/InvalidHeaderException.java
index b4e699e..9a6834c 100644
--- a/src/yetmorecode/format/exception/InvalidHeaderException.java
+++ b/src/yetmorecode/file/exception/InvalidHeaderException.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.exception;
+package yetmorecode.file.exception;
/**
* An exception class to handle encountering
diff --git a/src/yetmorecode/format/lx/LeObjectPageTableEntry.java b/src/yetmorecode/file/format/lx/LeObjectPageTableEntry.java
similarity index 96%
rename from src/yetmorecode/format/lx/LeObjectPageTableEntry.java
rename to src/yetmorecode/file/format/lx/LeObjectPageTableEntry.java
index 1cb4a9a..729d169 100644
--- a/src/yetmorecode/format/lx/LeObjectPageTableEntry.java
+++ b/src/yetmorecode/file/format/lx/LeObjectPageTableEntry.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
/**
* The Object page table provides information about a logical page in an object.
diff --git a/src/yetmorecode/format/lx/LxExecutable.java b/src/yetmorecode/file/format/lx/LxExecutable.java
similarity index 85%
rename from src/yetmorecode/format/lx/LxExecutable.java
rename to src/yetmorecode/file/format/lx/LxExecutable.java
index a8320a7..7c45456 100644
--- a/src/yetmorecode/format/lx/LxExecutable.java
+++ b/src/yetmorecode/file/format/lx/LxExecutable.java
@@ -1,8 +1,8 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
import java.util.ArrayList;
-import yetmorecode.format.mz.MzHeader;
+import yetmorecode.file.format.mz.MzHeader;
public class LxExecutable {
/**
diff --git a/src/yetmorecode/format/lx/LxFixupRecord.java b/src/yetmorecode/file/format/lx/LxFixupRecord.java
similarity index 97%
rename from src/yetmorecode/format/lx/LxFixupRecord.java
rename to src/yetmorecode/file/format/lx/LxFixupRecord.java
index b843a64..17b2c58 100644
--- a/src/yetmorecode/format/lx/LxFixupRecord.java
+++ b/src/yetmorecode/file/format/lx/LxFixupRecord.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
import java.util.ArrayList;
diff --git a/src/yetmorecode/format/lx/LxHeader.java b/src/yetmorecode/file/format/lx/LxHeader.java
similarity index 97%
rename from src/yetmorecode/format/lx/LxHeader.java
rename to src/yetmorecode/file/format/lx/LxHeader.java
index 1869e42..8732742 100644
--- a/src/yetmorecode/format/lx/LxHeader.java
+++ b/src/yetmorecode/file/format/lx/LxHeader.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
/**
* LX/LE/LC executable module header
diff --git a/src/yetmorecode/format/lx/LxObjectPageTableEntry.java b/src/yetmorecode/file/format/lx/LxObjectPageTableEntry.java
similarity index 96%
rename from src/yetmorecode/format/lx/LxObjectPageTableEntry.java
rename to src/yetmorecode/file/format/lx/LxObjectPageTableEntry.java
index c6b9532..d258a70 100644
--- a/src/yetmorecode/format/lx/LxObjectPageTableEntry.java
+++ b/src/yetmorecode/file/format/lx/LxObjectPageTableEntry.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
/**
* The Object page table provides information about a logical page in an object.
diff --git a/src/yetmorecode/format/lx/ObjectPageTableEntry.java b/src/yetmorecode/file/format/lx/ObjectPageTableEntry.java
similarity index 73%
rename from src/yetmorecode/format/lx/ObjectPageTableEntry.java
rename to src/yetmorecode/file/format/lx/ObjectPageTableEntry.java
index a47c2a6..4c55a83 100644
--- a/src/yetmorecode/format/lx/ObjectPageTableEntry.java
+++ b/src/yetmorecode/file/format/lx/ObjectPageTableEntry.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
public interface ObjectPageTableEntry {
public int getOffset();
diff --git a/src/yetmorecode/format/lx/ObjectTableEntry.java b/src/yetmorecode/file/format/lx/ObjectTableEntry.java
similarity index 96%
rename from src/yetmorecode/format/lx/ObjectTableEntry.java
rename to src/yetmorecode/file/format/lx/ObjectTableEntry.java
index fbcf98c..2b48755 100644
--- a/src/yetmorecode/format/lx/ObjectTableEntry.java
+++ b/src/yetmorecode/file/format/lx/ObjectTableEntry.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.lx;
+package yetmorecode.file.format.lx;
/**
* LX Executable Object Table Entry
diff --git a/src/yetmorecode/format/mz/MzExecutable.java b/src/yetmorecode/file/format/mz/MzExecutable.java
similarity index 83%
rename from src/yetmorecode/format/mz/MzExecutable.java
rename to src/yetmorecode/file/format/mz/MzExecutable.java
index caf8978..38e333a 100644
--- a/src/yetmorecode/format/mz/MzExecutable.java
+++ b/src/yetmorecode/file/format/mz/MzExecutable.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.mz;
+package yetmorecode.file.format.mz;
import java.util.ArrayList;
diff --git a/src/yetmorecode/format/mz/MzHeader.java b/src/yetmorecode/file/format/mz/MzHeader.java
similarity index 77%
rename from src/yetmorecode/format/mz/MzHeader.java
rename to src/yetmorecode/file/format/mz/MzHeader.java
index 137d86b..c455151 100644
--- a/src/yetmorecode/format/mz/MzHeader.java
+++ b/src/yetmorecode/file/format/mz/MzHeader.java
@@ -1,4 +1,8 @@
-package yetmorecode.format.mz;
+package yetmorecode.file.format.mz;
+
+import java.io.IOException;
+
+import yetmorecode.file.BinaryFileInputStream;
/**
* MS-DOS MZ header
@@ -148,4 +152,30 @@ public class MzHeader {
* DOS-stub bytes
*/
public byte [] stubBytes;
+
+ public static MzHeader fromStream(BinaryFileInputStream input, long offset) throws IOException {
+ var header = new MzHeader();
+ var old = input.position(offset);
+ header.signature = input.readShort();
+ header.bytesOnLastBlock = input.readShort();
+ header.blockCount = input.readShort();
+ header.relocations = input.readShort();
+ header.headerSize = input.readShort();
+ header.minExtraParagraphs = input.readShort();
+ header.maxExtraParagraphs = input.readShort();
+ header.ss = input.readShort();
+ header.sp = input.readShort();
+ header.checksum = input.readShort();
+ header.ip = input.readShort();
+ header.cs = input.readShort();
+ header.relocationTableOffset = input.readShort();
+ header.overlayNumber = input.readShort();
+ input.skip(8);
+ header.oemId = input.readShort();
+ header.oemInfo = input.readShort();
+ input.skip(20);
+ header.fileAddressNewExe = input.readInt();
+ input.position(old);
+ return header;
+ }
}
diff --git a/src/yetmorecode/format/mz/MzRelocationEntry.java b/src/yetmorecode/file/format/mz/MzRelocationEntry.java
similarity index 74%
rename from src/yetmorecode/format/mz/MzRelocationEntry.java
rename to src/yetmorecode/file/format/mz/MzRelocationEntry.java
index bbd1bc1..feead78 100644
--- a/src/yetmorecode/format/mz/MzRelocationEntry.java
+++ b/src/yetmorecode/file/format/mz/MzRelocationEntry.java
@@ -1,4 +1,4 @@
-package yetmorecode.format.mz;
+package yetmorecode.file.format.mz;
/**