diff --git a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java index 0180f7f..840101d 100755 --- a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java @@ -85,7 +85,8 @@ public abstract class AbstractFormattedDisk implements FormattedDisk name = "tmp.dsk"; DefaultAppleFileSource afs = - new DefaultAppleFileSource (name, disk.toString (), this); + // new DefaultAppleFileSource (name, disk.toString (), this); + new DefaultAppleFileSource (name, new DefaultDataSource (disk), this); DefaultMutableTreeNode root = new DefaultMutableTreeNode (afs); DefaultTreeModel treeModel = new DefaultTreeModel (root); catalogTree = new JTree (treeModel); diff --git a/src/com/bytezone/diskbrowser/disk/AppleDisk.java b/src/com/bytezone/diskbrowser/disk/AppleDisk.java index 63f67aa..bb2e55d 100755 --- a/src/com/bytezone/diskbrowser/disk/AppleDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AppleDisk.java @@ -13,10 +13,10 @@ import java.util.List; import java.util.zip.CRC32; import java.util.zip.Checksum; -import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.nib.NibFile; import com.bytezone.diskbrowser.nib.V2dFile; import com.bytezone.diskbrowser.nib.WozFile; +import com.bytezone.diskbrowser.utilities.Binary2; import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.NuFX; @@ -38,7 +38,10 @@ public class AppleDisk implements Disk private final int trackSize; // 4096 public int sectorSize; // 256 or 512 + private NuFX nuFX; + private Binary2 bin2; + private WozFile wozFile; private int interleave = 0; private static int[][] interleaveSector = // @@ -85,8 +88,6 @@ public class AppleDisk implements Disk private ActionListener actionListenerList; private List blockList; - private WozFile wozFile; - private final boolean debug = false; // ---------------------------------------------------------------------------------// @@ -235,20 +236,26 @@ public class AppleDisk implements Disk } // ---------------------------------------------------------------------------------// - public AppleDisk (File file, int tracks, int sectors, NuFX nufx) - throws FileFormatException + void setNuFX (NuFX nufx) // ---------------------------------------------------------------------------------// { - this (file, tracks, sectors); this.nuFX = nufx; } + // ---------------------------------------------------------------------------------// + void setBinary2 (Binary2 bin2) + // ---------------------------------------------------------------------------------// + { + this.bin2 = bin2; + } + // ---------------------------------------------------------------------------------// public AppleDisk (V2dFile disk, int tracks, int sectors) // ---------------------------------------------------------------------------------// { this.tracks = tracks; this.sectors = sectors; + file = disk.file; diskBuffer = disk.getDiskBuffer (); @@ -708,11 +715,11 @@ public class AppleDisk implements Disk } // ---------------------------------------------------------------------------------// - public AppleFileSource getDetails () - // ---------------------------------------------------------------------------------// - { - return new DefaultAppleFileSource (toString (), file.getName (), null); - } + // private AppleFileSource getDetails () + // // ---------------------------------------------------------------------------------// + // { + // return new DefaultAppleFileSource (toString (), file.getName (), null); + // } // ---------------------------------------------------------------------------------// @Override @@ -741,12 +748,16 @@ public class AppleDisk implements Disk text.append ("\n\n"); text.append (wozFile); } - - if (nuFX != null) + else if (nuFX != null) { text.append ("\n\n"); text.append (nuFX); } + else if (bin2 != null) + { + text.append ("\n\n"); + text.append (bin2); + } return text.toString (); } diff --git a/src/com/bytezone/diskbrowser/disk/DefaultDataSource.java b/src/com/bytezone/diskbrowser/disk/DefaultDataSource.java index f9af439..4e09df8 100755 --- a/src/com/bytezone/diskbrowser/disk/DefaultDataSource.java +++ b/src/com/bytezone/diskbrowser/disk/DefaultDataSource.java @@ -14,6 +14,7 @@ public class DefaultDataSource implements DataSource { public String text; byte[] buffer; + Object textSource; // ---------------------------------------------------------------------------------// public DefaultDataSource (String text) @@ -22,6 +23,13 @@ public class DefaultDataSource implements DataSource this.text = text; } + // ---------------------------------------------------------------------------------// + public DefaultDataSource (Object textSource) + // ---------------------------------------------------------------------------------// + { + this.textSource = textSource; + } + // ---------------------------------------------------------------------------------// @Override public String getAssembler () @@ -53,7 +61,7 @@ public class DefaultDataSource implements DataSource public String getText () // ---------------------------------------------------------------------------------// { - return text; + return textSource == null ? text : textSource.toString (); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index 7419f54..365d6e3 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -20,6 +20,7 @@ import com.bytezone.diskbrowser.nib.V2dFile; import com.bytezone.diskbrowser.nib.WozFile; import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.prodos.ProdosDisk; +import com.bytezone.diskbrowser.utilities.Binary2; import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.NuFX; import com.bytezone.diskbrowser.utilities.Utility; @@ -36,6 +37,7 @@ public class DiskFactory private static final int DISK_116K = 116480; private static NuFX nuFX; + private static Binary2 binary2; // ---------------------------------------------------------------------------------// private DiskFactory () @@ -139,7 +141,7 @@ public class DiskFactory } if ("sdk".equals (suffix) || "shk".equals (suffix) // shrinkit disk/file archive - || "bxy".equals (suffix) || "bny".equals (suffix)) + || "bxy".equals (suffix)) { if (debug) System.out.println (" ** sdk/shk/bxy **"); @@ -170,6 +172,33 @@ public class DiskFactory return null; } } + else if ("bny".equals (suffix)) + { + if (debug) + System.out.println (" ** bny **"); + try + { + binary2 = new Binary2 (file.toPath ()); + byte[] diskBuffer = binary2.getDiskBuffer (); + + File tmp = File.createTempFile (suffix, null); + FileOutputStream fos = new FileOutputStream (tmp); + fos.write (diskBuffer); + fos.close (); + + tmp.deleteOnExit (); + file = tmp; + suffix = "dsk"; + compressed = true; + } + catch (Exception e) + { + // e.printStackTrace (); + System.out.println (e.getMessage ()); + System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ()); + return null; + } + } FormattedDisk disk = null; FormattedDisk disk2 = null; @@ -226,7 +255,7 @@ public class DiskFactory System.out.println ("File length is wrong: " + file.length ()); disk = checkDos (new AppleDisk (file, 35, 16)); if (disk != null) - return disk; + return check (disk); } if (debug) @@ -237,7 +266,7 @@ public class DiskFactory { if (compressed) disk.setOriginalPath (originalPath); - return disk; + return check (disk); } if (file.length () == DISK_800K) // 800K 3.5" @@ -368,10 +397,12 @@ public class DiskFactory AppleDisk appleDisk256 = new AppleDisk (file, 35, 16); AppleDisk appleDisk512; - if (nuFX == null) - appleDisk512 = new AppleDisk (file, 35, 8); - else - appleDisk512 = new AppleDisk (file, 35, 8, nuFX); + // if (nuFX != null) + // appleDisk512 = new AppleDisk (file, 35, 8, nuFX); + // else if (binary2 != null) + // appleDisk512 = new AppleDisk (file, 35, 8, binary2); + // else + appleDisk512 = new AppleDisk (file, 35, 8); if (true) { @@ -456,7 +487,7 @@ public class DiskFactory { if (compressed) disk.setOriginalPath (originalPath); - return disk; + return check (disk); } // empty boot sector @@ -532,6 +563,21 @@ public class DiskFactory if (disk != null && compressed) disk.setOriginalPath (originalPath); + return check (disk); + } + + // ---------------------------------------------------------------------------------// + private static FormattedDisk check (FormattedDisk disk) + // ---------------------------------------------------------------------------------// + { + if (disk.getDisk ()instanceof AppleDisk appleDisk) + { + if (nuFX != null) + appleDisk.setNuFX (nuFX); + else if (binary2 != null) + appleDisk.setBinary2 (binary2); + } + return disk; } @@ -642,10 +688,10 @@ public class DiskFactory System.out.println ("*** extended ***"); // System Addons.hdv } AppleDisk disk; - if (nuFX == null) - disk = new AppleDisk (file, tracks, 8); - else - disk = new AppleDisk (file, tracks, 8, nuFX); + // if (nuFX == null) + disk = new AppleDisk (file, tracks, 8); + // else + // disk = new AppleDisk (file, tracks, 8, nuFX); if (ProdosDisk.isCorrectFormat (disk)) { diff --git a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java index 9a03bb5..67af2fe 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java +++ b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java @@ -30,7 +30,7 @@ public class ProdosDisk private static final int CATALOG_SIZE = 4; private static final int BITS_PER_BLOCK = 8 * BLOCK_SIZE; - static final String[] storageTypes = + public static final String[] storageTypes = { "Deleted", "Seedling", "Sapling", "Tree", "", "", "", "", "", "", "", "", "", "Subdirectory", "Subdirectory Header", "Volume Directory Header" }; @@ -74,7 +74,7 @@ public class ProdosDisk } // ---------------------------------------------------------------------------------// - void createCatalog (String volumeName) throws DiskFullException + private void createCatalog (String volumeName) throws DiskFullException // ---------------------------------------------------------------------------------// { // reserve two boot blocks diff --git a/src/com/bytezone/diskbrowser/utilities/Binary2.java b/src/com/bytezone/diskbrowser/utilities/Binary2.java new file mode 100644 index 0000000..da9d7fe --- /dev/null +++ b/src/com/bytezone/diskbrowser/utilities/Binary2.java @@ -0,0 +1,104 @@ +package com.bytezone.diskbrowser.utilities; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import com.bytezone.diskbrowser.prodos.write.DiskFullException; +import com.bytezone.diskbrowser.prodos.write.FileAlreadyExistsException; +import com.bytezone.diskbrowser.prodos.write.ProdosDisk; +import com.bytezone.diskbrowser.prodos.write.VolumeCatalogFullException; + +// -----------------------------------------------------------------------------------// +public class Binary2 +// -----------------------------------------------------------------------------------// +{ + private static final String UNDERLINE = + "------------------------------------------------------" + + "-----------------------"; + + Binary2Header binary2Header; + byte[] buffer; + List headers = new ArrayList<> (); + int totalBlocks; + String fileName; + + // ---------------------------------------------------------------------------------// + public Binary2 (Path path) throws IOException + // ---------------------------------------------------------------------------------// + { + fileName = path.toFile ().getName (); + buffer = Files.readAllBytes (path); + int ptr = 0; + + do + { + binary2Header = new Binary2Header (buffer, ptr); + System.out.println (binary2Header); + headers.add (binary2Header); + + totalBlocks += binary2Header.totalBlocks; + ptr += ((binary2Header.eof - 1) / 128 + 1) * 128 + 128; + } while (binary2Header.filesToFollow > 0); + + } + + // ---------------------------------------------------------------------------------// + public byte[] getDiskBuffer () throws DiskFullException, VolumeCatalogFullException, + FileAlreadyExistsException, IOException + // ---------------------------------------------------------------------------------// + { + ProdosDisk disk = new ProdosDisk (800, "DiskBrowser"); + + for (Binary2Header header : headers) + { + byte[] dataBuffer = new byte[header.eof]; // this sux + System.arraycopy (buffer, header.ptr + 128, dataBuffer, 0, dataBuffer.length); + + disk.addFile (header.fileName, header.fileType, header.auxType, header.created, + header.modified, dataBuffer, header.eof); + + } + disk.close (); + + return disk.getBuffer (); + } + + // ---------------------------------------------------------------------------------// + @Override + public String toString () + // ---------------------------------------------------------------------------------// + { + StringBuilder text = new StringBuilder (); + + text.append (String.format (" %-15.15s Recs:%5d%n%n", + fileName, headers.size ())); + + text.append (" Name Type Auxtyp Modified" + + " Fmat Length\n"); + + text.append (String.format ("%s%n", UNDERLINE)); + + // int totalUncompressedSize = 0; + // int totalCompressedSize = 0; + + for (Binary2Header header : headers) + { + text.append (String.format ("%s%n", header.getLine ())); + // totalUncompressedSize += record.getUncompressedSize (); + // totalCompressedSize += record.getCompressedSize (); + } + + text.append (String.format ("%s%n", UNDERLINE)); + + // float pct = 0; + // if (totalUncompressedSize > 0) + // pct = totalCompressedSize * 100 / totalUncompressedSize; + // text.append (String.format (" Uncomp:%7d Comp:%7d %%of orig:%3.0f%%%n%n", + // totalUncompressedSize, totalCompressedSize, pct)); + + return text.toString (); + } +} diff --git a/src/com/bytezone/diskbrowser/utilities/Binary2Header.java b/src/com/bytezone/diskbrowser/utilities/Binary2Header.java index ddd5cc1..93a4de5 100644 --- a/src/com/bytezone/diskbrowser/utilities/Binary2Header.java +++ b/src/com/bytezone/diskbrowser/utilities/Binary2Header.java @@ -2,6 +2,8 @@ package com.bytezone.diskbrowser.utilities; import java.time.LocalDateTime; +import com.bytezone.diskbrowser.prodos.write.ProdosDisk; + // -----------------------------------------------------------------------------------// public class Binary2Header // -----------------------------------------------------------------------------------// @@ -11,8 +13,11 @@ public class Binary2Header "Macintosh HFS", "Lisa", "CPM", "Reserved", "MS-DOS", "High Sierra (CD-ROM)", "ISO 9660 (CD-ROM)", "AppleShare" }; + int ptr; + byte[] buffer; + int accessCode; - int fileType; + byte fileType; int auxType; int storageType; int totalBlocks; @@ -40,37 +45,47 @@ public class Binary2Header boolean sparsePacked; // ---------------------------------------------------------------------------------// - public Binary2Header (byte[] buffer) + public Binary2Header (byte[] buffer, int ptr) // ---------------------------------------------------------------------------------// { - 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; + this.ptr = ptr; + this.buffer = buffer; + + accessCode = buffer[ptr + 3] & 0xFF; + fileType = buffer[ptr + 4]; + auxType = Utility.readShort (buffer, ptr + 5); + storageType = buffer[ptr + 7] & 0xFF; + totalBlocks = Utility.readShort (buffer, ptr + 8); + modified = Utility.getAppleDate (buffer, ptr + 10); + created = Utility.getAppleDate (buffer, ptr + 14); + id = buffer[ptr + 18] & 0xFF; + eof = Utility.readTriple (buffer, ptr + 20); + fileName = HexFormatter.getPascalString (buffer, ptr + 23); + prodos16accessCode = buffer[ptr + 111] & 0xFF; + prodos16fileType = buffer[ptr + 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; + prodos16totalBlocks = Utility.readShort (buffer, ptr + 114); + prodos16eof = buffer[ptr + 116] & 0xFF; + diskSpaceRequired = Utility.getLong (buffer, ptr + 117); + osType = buffer[ptr + 121] & 0xFF; + nativeFileType = Utility.readShort (buffer, ptr + 122); + phantomFileFlag = buffer[ptr + 124] & 0xFF; + dataFlags = buffer[ptr + 125] & 0xFF; + version = buffer[ptr + 126] & 0xFF; + filesToFollow = buffer[ptr + 127] & 0xFF; compressed = (dataFlags & 0x80) != 0; encrypted = (dataFlags & 0x40) != 0; sparsePacked = (dataFlags & 0x01) != 0; } + // ---------------------------------------------------------------------------------// + public String getLine () + // ---------------------------------------------------------------------------------// + { + return String.format ("%s ", fileName); + } + // ---------------------------------------------------------------------------------// @Override public String toString () @@ -81,7 +96,8 @@ public class Binary2Header 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 ("Storage type .......... %02X %s%n", storageType, + ProdosDisk.storageTypes[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)); diff --git a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java index 2fdf0f1..2225a6e 100644 --- a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java +++ b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java @@ -41,7 +41,7 @@ class MasterHeader if (isBin2 (buffer, ptr)) { - binary2Header = new Binary2Header (buffer); + binary2Header = new Binary2Header (buffer, 0); ptr += 128; bin2 = true; continue; diff --git a/src/com/bytezone/diskbrowser/utilities/NuFX.java b/src/com/bytezone/diskbrowser/utilities/NuFX.java index 99208c7..e65dc7c 100644 --- a/src/com/bytezone/diskbrowser/utilities/NuFX.java +++ b/src/com/bytezone/diskbrowser/utilities/NuFX.java @@ -24,7 +24,7 @@ public class NuFX + "-----------------------"; private MasterHeader masterHeader; private final byte[] buffer; - private final boolean debug = true; + private final boolean debug = false; private final List records = new ArrayList<> (); private int totalFiles; @@ -80,7 +80,8 @@ public class NuFX if (record.hasDisk ()) ++totalDisks; } - listFiles (); + + // listFiles (); } // ---------------------------------------------------------------------------------// @@ -262,17 +263,11 @@ public class NuFX for (Record record : records) { - // if (record.hasDisk ()) - // { - // - // } - // else - { - text.append (String.format ("%s%n", record.getLine ())); - totalUncompressedSize += record.getUncompressedSize (); - totalCompressedSize += record.getCompressedSize (); - } + text.append (String.format ("%s%n", record.getLine ())); + totalUncompressedSize += record.getUncompressedSize (); + totalCompressedSize += record.getCompressedSize (); } + text.append (String.format ("%s%n", UNDERLINE)); float pct = 0; diff --git a/src/com/bytezone/diskbrowser/utilities/Record.java b/src/com/bytezone/diskbrowser/utilities/Record.java index a279184..729b104 100644 --- a/src/com/bytezone/diskbrowser/utilities/Record.java +++ b/src/com/bytezone/diskbrowser/utilities/Record.java @@ -196,27 +196,21 @@ class Record LocalDateTime getCreated () // ---------------------------------------------------------------------------------// { - if (created == null) - return null; - return created.getLocalDateTime (); + return created == null ? null : created.getLocalDateTime (); } // ---------------------------------------------------------------------------------// LocalDateTime getModified () // ---------------------------------------------------------------------------------// { - if (modified == null) - return null; - return modified.getLocalDateTime (); + return modified == null ? null : modified.getLocalDateTime (); } // ---------------------------------------------------------------------------------// LocalDateTime getArchived () // ---------------------------------------------------------------------------------// { - if (archived == null) - return null; - return archived.getLocalDateTime (); + return archived == null ? null : archived.getLocalDateTime (); } // ---------------------------------------------------------------------------------// @@ -347,8 +341,8 @@ class Record text.append (String.format ("Attributes ..... %d%n", attributes)); text.append (String.format ("Version ........ %d%n", version)); text.append (String.format ("Threads ........ %d%n", totThreads)); - text.append (String.format ("File sys id .... %d (%s)%n", fileSystemID, - fileSystems[fileSystemID])); + text.append ( + String.format ("File sys id .... %d (%s)%n", fileSystemID, getFileSystemName ())); text.append (String.format ("Separator ...... %s%n", separator)); text.append (String.format ("Access ......... %s %s%n", bits, decode));