From 43ff3c203e9b99a9ebde725821ba1dca42713539 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Mon, 19 Apr 2021 12:33:14 +1000 Subject: [PATCH] bug fixes --- .../diskbrowser/prodos/write/FileEntry.java | 1 + .../diskbrowser/prodos/write/ProdosDisk.java | 8 +- .../prodos/write/SubdirectoryHeader.java | 4 + .../bytezone/diskbrowser/utilities/NuFX.java | 166 ++++++++++++------ 4 files changed, 122 insertions(+), 57 deletions(-) diff --git a/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java index 4e12d18..7c1a922 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java @@ -54,6 +54,7 @@ public class FileEntry // ---------------------------------------------------------------------------------// { storageType = (byte) ((buffer[ptr] & 0xF0) >>> 4); + int nameLength = buffer[ptr] & 0x0F; if (nameLength > 0) fileName = new String (buffer, ptr + 1, nameLength); diff --git a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java index 1680e0d..b7f2253 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java +++ b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java @@ -146,6 +146,7 @@ public class ProdosDisk if (fileEntry != null) { System.out.println ("File already exists: " + path); + System.out.println (fileEntry); return null; // throw something? } @@ -206,9 +207,10 @@ public class ProdosDisk else { int nameLength = buffer[ptr] & 0x0F; + int storageType = (buffer[ptr] & 0xF0) >>> 4; - String entryName = new String (buffer, ptr + 1, nameLength); - if (entryName.equals (fileName)) + if (storageType < 0x0E + && fileName.equals (new String (buffer, ptr + 1, nameLength))) { FileEntry fileEntry = new FileEntry (this, buffer, ptr); fileEntry.read (); @@ -251,7 +253,7 @@ public class ProdosDisk subdirectoryHeader.fileName = name; subdirectoryHeader.creationDate = LocalDateTime.now (); subdirectoryHeader.fileCount = 0; - subdirectoryHeader.parentPointer = (byte) blockNo; + subdirectoryHeader.parentPointer = blockNo; subdirectoryHeader.parentEntry = (byte) (((fileEntry.ptr % BLOCK_SIZE) - 4) / ENTRY_SIZE + 1); diff --git a/src/com/bytezone/diskbrowser/prodos/write/SubdirectoryHeader.java b/src/com/bytezone/diskbrowser/prodos/write/SubdirectoryHeader.java index fcfebb0..70b550f 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/SubdirectoryHeader.java +++ b/src/com/bytezone/diskbrowser/prodos/write/SubdirectoryHeader.java @@ -33,6 +33,8 @@ public class SubdirectoryHeader extends DirectoryHeader parentPointer = readShort (buffer, ptr + 0x23); parentEntry = buffer[ptr + 0x25]; parentEntryLength = buffer[ptr + 0x26]; + + assert parentPointer > 0; } // ---------------------------------------------------------------------------------// @@ -54,6 +56,8 @@ public class SubdirectoryHeader extends DirectoryHeader writeShort (buffer, ptr + 0x23, parentPointer); buffer[ptr + 0x25] = parentEntry; buffer[ptr + 0x26] = parentEntryLength; + + assert parentPointer > 0; } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/NuFX.java b/src/com/bytezone/diskbrowser/utilities/NuFX.java index 0dd86bd..6d3b6b2 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 int totalDisks; private int totalBlocks; - private List paths = new ArrayList<> (); + private VolumeName volumeName = new VolumeName (); // ---------------------------------------------------------------------------------// public NuFX (Path path) throws FileFormatException, IOException @@ -76,44 +76,14 @@ public class NuFX else // tree totalBlocks += blocks + (blocks / 256) + 2; - storePath (record.getFileName ()); + volumeName.storePath (record.getFileName ()); } if (record.hasDisk ()) ++totalDisks; } - if (false) - { - System.out.println ("Unique paths:"); - if (paths.size () == 0) - System.out.println (""); - for (String pathName : paths) - System.out.println (pathName); - } - } - - // ---------------------------------------------------------------------------------// - private void storePath (String fileName) - // ---------------------------------------------------------------------------------// - { - int pos = fileName.lastIndexOf ('/'); - if (pos > 0) - { - String path = fileName.substring (0, pos); - for (int i = 0; i < paths.size (); i++) - { - String cmp = paths.get (i); - if (cmp.startsWith (path)) // longer path already there - return; - if (path.startsWith (cmp)) - { - paths.set (i, path); // replace shorter path with longer path - return; - } - } - paths.add (path); - } + // volumeName.info (); } // ---------------------------------------------------------------------------------// @@ -127,25 +97,11 @@ public class NuFX if (thread.hasDisk ()) return thread.getData (); } - else if (totalFiles > 0) + + if (totalFiles > 0) { - // choose Volume Name - String volumeName = "DiskBrowser"; - int nameOffset = 0; - // should check that files are all in prodos format - if (paths.size () == 1) // exactly one directory path - { - String onlyPath = paths.get (0); - int pos = onlyPath.indexOf ('/'); - if (pos == -1) // no separators - volumeName = onlyPath; - else // use first component - volumeName = onlyPath.substring (0, pos); - nameOffset = volumeName.length () + 1; // skip volume name in all paths - } - int[] diskSizes = { 280, 800, 1600, 3200, 6400, 65536 }; for (int diskSize : diskSizes) // in case we choose a size that is too small { @@ -154,13 +110,14 @@ public class NuFX try { - ProdosDisk disk = new ProdosDisk (diskSize, volumeName); + ProdosDisk disk = new ProdosDisk (diskSize, volumeName.getVolumeName ()); int count = 0; + for (Record record : records) { if (record.hasFile ()) { - String fileName = record.getFileName (); + String fileName = volumeName.convert (record.getFileName ()); // int fileSize = record.getFileSize (); byte fileType = (byte) record.getFileType (); int eof = record.getUncompressedSize (); @@ -169,9 +126,6 @@ public class NuFX LocalDateTime modified = record.getModified (); byte[] buffer = record.getData (); - if (nameOffset > 0) // remove volume name from path - fileName = fileName.substring (nameOffset); - if (false) System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count, fileName, fileType, auxType, eof, buffer.length, created, modified); @@ -247,6 +201,110 @@ public class NuFX return "no disk"; } + // ---------------------------------------------------------------------------------// + class VolumeName + // ---------------------------------------------------------------------------------// + { + private List paths = new ArrayList<> (); + private boolean rootContainsFiles; + + private String volumeName = "DiskBrowser"; + private int nameOffset = 0; + + // -------------------------------------------------------------------------------// + private void storePath (String fileName) + // -------------------------------------------------------------------------------// + { + int pos = fileName.lastIndexOf ('/'); + if (pos < 0) + rootContainsFiles = true; + else + { + String path = fileName.substring (0, pos); + for (int i = 0; i < paths.size (); i++) + { + String cmp = paths.get (i); + if (cmp.startsWith (path)) // longer path already there + return; + if (path.startsWith (cmp)) + { + paths.set (i, path); // replace shorter path with longer path + return; + } + } + paths.add (path); + } + } + + // -------------------------------------------------------------------------------// + private String getVolumeName () + // -------------------------------------------------------------------------------// + { + if (rootContainsFiles) + return volumeName; + + if (paths.size () > 0) + { + int pos = paths.get (0).indexOf ('/'); + if (pos > 0) + { + String firstPath = paths.get (0).substring (0, pos + 1); + System.out.println (firstPath); + + boolean allSame = true; + for (String pathName : paths) + if (!pathName.startsWith (firstPath)) + { + allSame = false; + break; + } + + if (allSame) + { + volumeName = firstPath.substring (0, pos); + nameOffset = volumeName.length () + 1; // skip volume name in all paths + } + } + } + + if (paths.size () == 1) // exactly one directory path + { + String onlyPath = paths.get (0); + int pos = onlyPath.indexOf ('/'); + if (pos == -1) // no separators + volumeName = onlyPath; + else // use first component + volumeName = onlyPath.substring (0, pos); + nameOffset = volumeName.length () + 1; // skip volume name in all paths + } + + return volumeName; + } + + // -------------------------------------------------------------------------------// + String convert (String fileName) + // -------------------------------------------------------------------------------// + { + if (nameOffset > 0) // remove volume name from path + return fileName.substring (nameOffset); + + return fileName; + } + + // -------------------------------------------------------------------------------// + void info () + // -------------------------------------------------------------------------------// + { + if (rootContainsFiles) + System.out.println ("Root contains files"); + System.out.println ("Unique paths:"); + if (paths.size () == 0) + System.out.println (""); + for (String pathName : paths) + System.out.println (pathName); + } + } + // ---------------------------------------------------------------------------------// public static void main (String[] args) throws FileFormatException, IOException // ---------------------------------------------------------------------------------//