From 4353d0e0ca1350ff372c3ae12b835fe974ff8864 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sun, 2 May 2021 09:38:24 +1000 Subject: [PATCH] tidying --- .../applefile/ProdosDirectory.java | 3 +- .../diskbrowser/prodos/CatalogEntry.java | 5 +- .../diskbrowser/prodos/DirectoryHeader.java | 8 +- .../diskbrowser/utilities/Binary2Header.java | 104 ++++++++++++++++++ .../bytezone/diskbrowser/utilities/LZW.java | 72 ++++++------ .../bytezone/diskbrowser/utilities/LZW1.java | 15 ++- .../bytezone/diskbrowser/utilities/LZW2.java | 10 +- .../diskbrowser/utilities/MasterHeader.java | 3 + .../bytezone/diskbrowser/utilities/NuFX.java | 2 +- .../diskbrowser/utilities/Thread.java | 11 +- .../diskbrowser/utilities/compression.txt | 27 +++++ 11 files changed, 198 insertions(+), 62 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/utilities/Binary2Header.java create mode 100644 src/com/bytezone/diskbrowser/utilities/compression.txt diff --git a/src/com/bytezone/diskbrowser/applefile/ProdosDirectory.java b/src/com/bytezone/diskbrowser/applefile/ProdosDirectory.java index 9b07202..3eee24b 100755 --- a/src/com/bytezone/diskbrowser/applefile/ProdosDirectory.java +++ b/src/com/bytezone/diskbrowser/applefile/ProdosDirectory.java @@ -17,7 +17,8 @@ public class ProdosDirectory extends AbstractFile implements ProdosConstants { static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy"); static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm"); - static final String UNDERLINE = "--------------------------------------------------\n"; + static final String UNDERLINE = + "----------------------------------------------------\n"; private static final String NO_DATE = ""; diff --git a/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java b/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java index 8ac21ab..fc69b8a 100755 --- a/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java @@ -15,6 +15,8 @@ import com.bytezone.diskbrowser.utilities.Utility; abstract class CatalogEntry implements AppleFileSource // -----------------------------------------------------------------------------------// { + static String[] storageTypes = { "Del", "Sdl", "Sap", "Tre", "", "", "", "", "", "", "", + "", "", "DIR", "SDH", "VDH" }; Disk disk; ProdosDisk parentDisk; @@ -61,7 +63,8 @@ abstract class CatalogEntry implements AppleFileSource public String getText () // ---------------------------------------------------------------------------------// { - return String.format ("%04X:%02X %-15s %02X", blockNo, entryNo, name, storageType); + return String.format ("%04X:%02X %-15s %s", blockNo, entryNo, name, + storageTypes[storageType]); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/prodos/DirectoryHeader.java b/src/com/bytezone/diskbrowser/prodos/DirectoryHeader.java index a20a872..7fe2201 100755 --- a/src/com/bytezone/diskbrowser/prodos/DirectoryHeader.java +++ b/src/com/bytezone/diskbrowser/prodos/DirectoryHeader.java @@ -3,7 +3,7 @@ package com.bytezone.diskbrowser.prodos; import com.bytezone.diskbrowser.utilities.Utility; // -----------------------------------------------------------------------------------// -public abstract class DirectoryHeader extends CatalogEntry +public abstract class DirectoryHeader extends CatalogEntry implements ProdosConstants // -----------------------------------------------------------------------------------// { final int entryLength; @@ -51,9 +51,9 @@ public abstract class DirectoryHeader extends CatalogEntry int fileType = buffer[ptr + 0x10] & 0xFF; int keyPointer = Utility.intValue (buffer[ptr + 0x11], buffer[ptr + 0x12]); int headerPointer = Utility.intValue (buffer[ptr + 0x25], buffer[ptr + 0x26]); - text.append (String.format ("%04X:%02X %-15s %02X %04X %02X %04X %04X%n", - blockNo, entryNo, name, storageType, blocksUsed, fileType, keyPointer, - headerPointer)); + text.append (String.format ("%04X:%02X %-15s %s %04X %s %04X %04X%n", + blockNo, entryNo, name, storageTypes[storageType], blocksUsed, + fileTypes[fileType], keyPointer, headerPointer)); } ptr += 0x27; ++entryNo; diff --git a/src/com/bytezone/diskbrowser/utilities/Binary2Header.java b/src/com/bytezone/diskbrowser/utilities/Binary2Header.java new file mode 100644 index 0000000..0770253 --- /dev/null +++ b/src/com/bytezone/diskbrowser/utilities/Binary2Header.java @@ -0,0 +1,104 @@ +package com.bytezone.diskbrowser.utilities; + +import java.time.LocalDateTime; + +// -----------------------------------------------------------------------------------// +public class Binary2Header +// -----------------------------------------------------------------------------------// +{ + static String[] osTypes = { "Prodos", "DOS 3.3", "Pascal", "CPM", "MS-DOS" }; + + int accessCode; + int fileType; + int auxType; + int storageType; + int totalBlocks; + LocalDateTime modified; + LocalDateTime created; + int id; // always 0x02 + int eof; + String fileName; + String nativeFileName; + int prodos16accessCode; + int prodos16fileType; + int prodos16storageType; + int prodos16totalBlocks; + int prodos16eof; + long diskSpaceRequired; + int osType; + int nativeFileType; + int phantomFileFlag; + int dataFlags; + int version; + int filesToFollow; + + boolean compressed; + boolean encrypted; + boolean sparsePacked; + + // ---------------------------------------------------------------------------------// + public Binary2Header (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + accessCode = buffer[3] & 0xFF; + fileType = buffer[4] & 0xFF; + auxType = Utility.readShort (buffer, 5); + storageType = buffer[7] & 0xFF; + totalBlocks = Utility.readShort (buffer, 8); + modified = Utility.getAppleDate (buffer, 10); + created = Utility.getAppleDate (buffer, 14); + id = buffer[18] & 0xFF; + eof = Utility.readTriple (buffer, 20); + fileName = HexFormatter.getPascalString (buffer, 23); + prodos16accessCode = buffer[111] & 0xFF; + prodos16fileType = buffer[112] & 0xFF; + prodos16storageType = buffer[113] & 0xFF; + prodos16totalBlocks = Utility.readShort (buffer, 114); + prodos16eof = buffer[116] & 0xFF; + diskSpaceRequired = Utility.getLong (buffer, 117); + osType = buffer[121] & 0xFF; + nativeFileType = Utility.readShort (buffer, 122); + phantomFileFlag = buffer[124] & 0xFF; + dataFlags = buffer[125] & 0xFF; + version = buffer[126] & 0xFF; + filesToFollow = buffer[127] & 0xFF; + + compressed = (dataFlags & 0x80) != 0; + encrypted = (dataFlags & 0x40) != 0; + sparsePacked = (dataFlags & 0x01) != 0; + } + + // ---------------------------------------------------------------------------------// + @Override + public String toString () + // ---------------------------------------------------------------------------------// + { + StringBuilder text = new StringBuilder (); + + text.append (String.format ("Access ................ %02X%n", accessCode)); + text.append (String.format ("File type ............. %02X%n", fileType)); + text.append (String.format ("Aux type .............. %04X%n", auxType)); + text.append (String.format ("Storage type .......... %02X%n", storageType)); + text.append (String.format ("Total blocks .......... %04X %<,d%n", totalBlocks)); + text.append (String.format ("Modified .............. %s%n", modified)); + text.append (String.format ("Created ............... %s%n", created)); + text.append (String.format ("ID (0x02) ............. %02X%n", id)); + text.append (String.format ("End of file ........... %06X %<,d%n", eof)); + text.append (String.format ("File name ............. %s%n", fileName)); + text.append (String.format ("Prodos access ......... %02X%n", prodos16accessCode)); + text.append (String.format ("Prodos file type ...... %02X%n", prodos16fileType)); + text.append (String.format ("Prodos storage type ... %02X%n", prodos16storageType)); + text.append (String.format ("Prodos total blocks ... %02X%n", prodos16totalBlocks)); + text.append (String.format ("Prodos eof ............ %06X %<,d%n", prodos16eof)); + text.append ( + String.format ("Disk space needed ..... %08X %<,d%n", diskSpaceRequired)); + text.append ( + String.format ("OS type ............... %02X %s%n", osType, osTypes[osType])); + text.append (String.format ("Native file type ...... %02X%n", nativeFileType)); + text.append (String.format ("Data flags ............ %02X%n", dataFlags)); + text.append (String.format ("Version ............... %02X%n", version)); + text.append (String.format ("Following files ....... %02X%n", filesToFollow)); + + return text.toString (); + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/utilities/LZW.java b/src/com/bytezone/diskbrowser/utilities/LZW.java index 1d47edd..0064004 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW.java @@ -2,27 +2,29 @@ package com.bytezone.diskbrowser.utilities; import java.util.ArrayList; import java.util.List; +import java.util.Objects; // -----------------------------------------------------------------------------------// class LZW // -----------------------------------------------------------------------------------// { - static protected final String[] st = new String[0x1000]; - static protected final int TRACK_LENGTH = 0x1000; + static final String[] st = new String[0x1000]; + static final int TRACK_LENGTH = 0x1000; - protected final List chunks = new ArrayList<> (); - protected int volume; - protected byte runLengthChar; - protected int crc; - protected int crcBase; + final List chunks = new ArrayList<> (); + int volume; + byte runLengthChar; + + int crc; + int crcBase; int v3eof; // LZW/2 calculates the crc sans padding - private int buffer; // one character buffer + private int byteBuffer; // one character buffer private int bitsLeft; // unused bits left in buffer private int ptr; private int startPtr; - protected byte[] bytes; + byte[] bytes; // ---------------------------------------------------------------------------------// static @@ -33,41 +35,27 @@ class LZW } // ---------------------------------------------------------------------------------// - public void setBuffer (byte[] buffer, int ptr) + LZW (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + bytes = Objects.requireNonNull (buffer); + } + + // ---------------------------------------------------------------------------------// + void setBuffer (int ptr) // ---------------------------------------------------------------------------------// { - bytes = buffer; startPtr = this.ptr = ptr; bitsLeft = 0; } // ---------------------------------------------------------------------------------// - public int bytesRead () + int bytesRead () // ---------------------------------------------------------------------------------// { return ptr - startPtr; } - // ---------------------------------------------------------------------------------// - private void fillBuffer () - // ---------------------------------------------------------------------------------// - { - buffer = bytes[ptr++] & 0xFF; - bitsLeft = 8; - } - - // ---------------------------------------------------------------------------------// - private boolean readBoolean () - // ---------------------------------------------------------------------------------// - { - if (bitsLeft == 0) - fillBuffer (); - - bitsLeft--; - boolean bit = ((buffer << bitsLeft) & 0x80) == 0x80; - return bit; - } - // ---------------------------------------------------------------------------------// int readInt (int width) // ---------------------------------------------------------------------------------// @@ -83,6 +71,22 @@ class LZW return x; } + // ---------------------------------------------------------------------------------// + private boolean readBoolean () + // ---------------------------------------------------------------------------------// + { + if (bitsLeft == 0) + { + byteBuffer = bytes[ptr++] & 0xFF; + bitsLeft = 8; + } + + bitsLeft--; + boolean bit = ((byteBuffer << bitsLeft) & 0x80) == 0x80; + + return bit; + } + // ---------------------------------------------------------------------------------// byte[] undoRLE (byte[] inBuffer, int inPtr, int length) // ---------------------------------------------------------------------------------// @@ -110,14 +114,14 @@ class LZW } // ---------------------------------------------------------------------------------// - public int getSize () + int getSize () // ---------------------------------------------------------------------------------// { return chunks.size () * TRACK_LENGTH; } // ---------------------------------------------------------------------------------// - public byte[] getData () + byte[] getData () // ---------------------------------------------------------------------------------// { byte[] buffer = new byte[getSize ()]; diff --git a/src/com/bytezone/diskbrowser/utilities/LZW1.java b/src/com/bytezone/diskbrowser/utilities/LZW1.java index 6e1b068..1e710b7 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW1.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW1.java @@ -1,7 +1,5 @@ package com.bytezone.diskbrowser.utilities; -import java.util.Objects; - // -----------------------------------------------------------------------------------// class LZW1 extends LZW // -----------------------------------------------------------------------------------// @@ -10,7 +8,7 @@ class LZW1 extends LZW public LZW1 (byte[] buffer) // ---------------------------------------------------------------------------------// { - bytes = Objects.requireNonNull (buffer); + super (buffer); crc = Utility.getWord (buffer, 0); crcBase = 0; @@ -19,15 +17,15 @@ class LZW1 extends LZW runLengthChar = (byte) (buffer[3] & 0xFF); int ptr = 4; - while (ptr < buffer.length - 1) // what is in the last byte? + while (ptr < buffer.length - 2) { int rleLength = Utility.getWord (buffer, ptr); - int lzwPerformed = buffer[ptr + 2] & 0xFF; + boolean lzwPerformed = (buffer[ptr + 2] & 0xFF) != 0; ptr += 3; - if (lzwPerformed != 0) + if (lzwPerformed) { - setBuffer (buffer, ptr); // prepare to read n-bit integers + setBuffer (ptr); // prepare to read n-bit integers byte[] lzwBuffer = undoLZW (rleLength); if (rleLength == TRACK_LENGTH) // no run length encoding @@ -54,11 +52,12 @@ class LZW1 extends LZW } // ---------------------------------------------------------------------------------// - protected byte[] undoLZW (int rleLength) + byte[] undoLZW (int rleLength) // ---------------------------------------------------------------------------------// { byte[] lzwBuffer = new byte[rleLength]; // must fill this array from input int ptr = 0; + int nextEntry = 0x100; // always start with a fresh table String prev = ""; diff --git a/src/com/bytezone/diskbrowser/utilities/LZW2.java b/src/com/bytezone/diskbrowser/utilities/LZW2.java index 59ff129..c203a72 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW2.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW2.java @@ -1,7 +1,5 @@ package com.bytezone.diskbrowser.utilities; -import java.util.Objects; - // -----------------------------------------------------------------------------------// class LZW2 extends LZW // -----------------------------------------------------------------------------------// @@ -14,7 +12,7 @@ class LZW2 extends LZW public LZW2 (byte[] buffer, int crc, int eof) // ---------------------------------------------------------------------------------// { - bytes = Objects.requireNonNull (buffer); + super (buffer); this.crc = crc; this.v3eof = eof; @@ -26,7 +24,7 @@ class LZW2 extends LZW runLengthChar = (byte) (buffer[1] & 0xFF); int ptr = 2; - while (ptr < buffer.length - 1) // what is in the last byte? + while (ptr < buffer.length - 1) { int rleLength = Utility.getWord (buffer, ptr); boolean lzwPerformed = (rleLength & 0x8000) != 0; @@ -41,7 +39,7 @@ class LZW2 extends LZW int chunkLength = Utility.getWord (buffer, ptr); ptr += 2; - setBuffer (buffer, ptr); // prepare to read n-bit integers + setBuffer (ptr); // prepare to read n-bit integers byte[] lzwBuffer = undoLZW (rleLength); if ((chunkLength - 4) != bytesRead ()) @@ -75,7 +73,7 @@ class LZW2 extends LZW } // ---------------------------------------------------------------------------------// - protected byte[] undoLZW (int rleLength) + byte[] undoLZW (int rleLength) // ---------------------------------------------------------------------------------// { byte[] lzwBuffer = new byte[rleLength]; // must fill this array from buffer diff --git a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java index bcacc27..366bc38 100644 --- a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java +++ b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java @@ -17,6 +17,7 @@ class MasterHeader private final int eof; boolean bin2; + Binary2Header binary2Header; // ---------------------------------------------------------------------------------// public MasterHeader (byte[] buffer) throws FileFormatException @@ -31,6 +32,8 @@ class MasterHeader if (isBin2 (buffer, ptr)) { + binary2Header = new Binary2Header (buffer); + System.out.println (binary2Header); ptr += 128; bin2 = true; continue; diff --git a/src/com/bytezone/diskbrowser/utilities/NuFX.java b/src/com/bytezone/diskbrowser/utilities/NuFX.java index 1e93568..d096f8b 100644 --- a/src/com/bytezone/diskbrowser/utilities/NuFX.java +++ b/src/com/bytezone/diskbrowser/utilities/NuFX.java @@ -18,7 +18,7 @@ public class NuFX { private MasterHeader masterHeader; private final byte[] buffer; - private final boolean debug = false; + private final boolean debug = true; private final List records = new ArrayList<> (); private int totalFiles; diff --git a/src/com/bytezone/diskbrowser/utilities/Thread.java b/src/com/bytezone/diskbrowser/utilities/Thread.java index 8760931..949b9c8 100644 --- a/src/com/bytezone/diskbrowser/utilities/Thread.java +++ b/src/com/bytezone/diskbrowser/utilities/Thread.java @@ -31,8 +31,6 @@ class Thread private boolean hasFile; private boolean hasFileName; - private int fileSize; - // ---------------------------------------------------------------------------------// public Thread (byte[] buffer, int offset, int dataOffset) // ---------------------------------------------------------------------------------// @@ -99,7 +97,6 @@ class Thread { case 0: // data fork of file hasFile = true; - fileSize = lzw != null ? lzw.getSize () : uncompressedEOF; break; case 1: // disk image hasDisk = true; @@ -113,14 +110,14 @@ class Thread case 3: switch (threadKind) { - case 0: // filename + case 0: // filename hasFileName = true; fileName = new String (data, 0, uncompressedEOF); break; - case 1: // undefined + case 1: // undefined break; - case 2: // undefined + case 2: // undefined break; } break; @@ -193,7 +190,7 @@ class Thread int getFileSize () // ---------------------------------------------------------------------------------// { - return fileSize; + return lzw != null ? lzw.getSize () : uncompressedEOF; } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/compression.txt b/src/com/bytezone/diskbrowser/utilities/compression.txt new file mode 100644 index 0000000..949756a --- /dev/null +++ b/src/com/bytezone/diskbrowser/utilities/compression.txt @@ -0,0 +1,27 @@ +Format |Filename + |Suffix + | |[C]reates and + | |Unpacks, or + | |[U]npacks Only + | | | + | | |Computer(s) Which + | | |Use This Format +--------------------------------|------|---|-------------------------- +NuFX . . . . . . . . . . . . . .| .SHK | C | Apple II +NuFX in Binary II . . . . . . . | .BXY | C | Apple II +Binary II . . . . . . . . . . . | .BNY | U | Apple II +Binary II in Binary II. . . . . | .BNY | U | Apple II +ACU (Used on America Online) . .| .ACU | U | Apple II +ACU in Binary II . . . . . . . .| -- | U | Apple II +ALU in TEXT .(filetypes) . . . .| -- | U | Apple II +SQ (BLU) . . . . . . . . . . . | .QQ | U | Apple II +SQ in Binary II (BLU) . . . . . | .BQY | U | Apple II +AppleSingle . . . . . . . . . . | -- | C | Apple II +AppleSingle in Binary II . . . | -- | U | Apple II +StuffIt . . . . . . . . . . . . | .SIT | U | Macintosh +StuffIt in MacBinary I or II. . | .SIT | U | Macintosh +StuffIt from America Online . . | .SIT | U | Macintosh +Zoo . . . . . . . . . . . . . . | .ZOO | U | IBM PC, Amiga, Atari ST, + | | | Unix systems +ARC . . . . . . . . . . . . . . | .ARC | U | IBM PC, Amiga, Atari ST +Compress . . . . . . . . . . . | .Z | U | Unix Systems \ No newline at end of file