bug fixes

This commit is contained in:
Denis Molony 2021-04-19 12:33:14 +10:00
parent 373e8d29a3
commit 43ff3c203e
4 changed files with 122 additions and 57 deletions

View File

@ -54,6 +54,7 @@ public class FileEntry
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
storageType = (byte) ((buffer[ptr] & 0xF0) >>> 4); storageType = (byte) ((buffer[ptr] & 0xF0) >>> 4);
int nameLength = buffer[ptr] & 0x0F; int nameLength = buffer[ptr] & 0x0F;
if (nameLength > 0) if (nameLength > 0)
fileName = new String (buffer, ptr + 1, nameLength); fileName = new String (buffer, ptr + 1, nameLength);

View File

@ -146,6 +146,7 @@ public class ProdosDisk
if (fileEntry != null) if (fileEntry != null)
{ {
System.out.println ("File already exists: " + path); System.out.println ("File already exists: " + path);
System.out.println (fileEntry);
return null; // throw something? return null; // throw something?
} }
@ -206,9 +207,10 @@ public class ProdosDisk
else else
{ {
int nameLength = buffer[ptr] & 0x0F; int nameLength = buffer[ptr] & 0x0F;
int storageType = (buffer[ptr] & 0xF0) >>> 4;
String entryName = new String (buffer, ptr + 1, nameLength); if (storageType < 0x0E
if (entryName.equals (fileName)) && fileName.equals (new String (buffer, ptr + 1, nameLength)))
{ {
FileEntry fileEntry = new FileEntry (this, buffer, ptr); FileEntry fileEntry = new FileEntry (this, buffer, ptr);
fileEntry.read (); fileEntry.read ();
@ -251,7 +253,7 @@ public class ProdosDisk
subdirectoryHeader.fileName = name; subdirectoryHeader.fileName = name;
subdirectoryHeader.creationDate = LocalDateTime.now (); subdirectoryHeader.creationDate = LocalDateTime.now ();
subdirectoryHeader.fileCount = 0; subdirectoryHeader.fileCount = 0;
subdirectoryHeader.parentPointer = (byte) blockNo; subdirectoryHeader.parentPointer = blockNo;
subdirectoryHeader.parentEntry = subdirectoryHeader.parentEntry =
(byte) (((fileEntry.ptr % BLOCK_SIZE) - 4) / ENTRY_SIZE + 1); (byte) (((fileEntry.ptr % BLOCK_SIZE) - 4) / ENTRY_SIZE + 1);

View File

@ -33,6 +33,8 @@ public class SubdirectoryHeader extends DirectoryHeader
parentPointer = readShort (buffer, ptr + 0x23); parentPointer = readShort (buffer, ptr + 0x23);
parentEntry = buffer[ptr + 0x25]; parentEntry = buffer[ptr + 0x25];
parentEntryLength = buffer[ptr + 0x26]; parentEntryLength = buffer[ptr + 0x26];
assert parentPointer > 0;
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -54,6 +56,8 @@ public class SubdirectoryHeader extends DirectoryHeader
writeShort (buffer, ptr + 0x23, parentPointer); writeShort (buffer, ptr + 0x23, parentPointer);
buffer[ptr + 0x25] = parentEntry; buffer[ptr + 0x25] = parentEntry;
buffer[ptr + 0x26] = parentEntryLength; buffer[ptr + 0x26] = parentEntryLength;
assert parentPointer > 0;
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -24,7 +24,7 @@ public class NuFX
private int totalDisks; private int totalDisks;
private int totalBlocks; private int totalBlocks;
private List<String> paths = new ArrayList<> (); private VolumeName volumeName = new VolumeName ();
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public NuFX (Path path) throws FileFormatException, IOException public NuFX (Path path) throws FileFormatException, IOException
@ -76,44 +76,14 @@ public class NuFX
else // tree else // tree
totalBlocks += blocks + (blocks / 256) + 2; totalBlocks += blocks + (blocks / 256) + 2;
storePath (record.getFileName ()); volumeName.storePath (record.getFileName ());
} }
if (record.hasDisk ()) if (record.hasDisk ())
++totalDisks; ++totalDisks;
} }
if (false) // volumeName.info ();
{
System.out.println ("Unique paths:");
if (paths.size () == 0)
System.out.println ("<none>");
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);
}
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -127,25 +97,11 @@ public class NuFX
if (thread.hasDisk ()) if (thread.hasDisk ())
return thread.getData (); 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 // 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 }; int[] diskSizes = { 280, 800, 1600, 3200, 6400, 65536 };
for (int diskSize : diskSizes) // in case we choose a size that is too small for (int diskSize : diskSizes) // in case we choose a size that is too small
{ {
@ -154,13 +110,14 @@ public class NuFX
try try
{ {
ProdosDisk disk = new ProdosDisk (diskSize, volumeName); ProdosDisk disk = new ProdosDisk (diskSize, volumeName.getVolumeName ());
int count = 0; int count = 0;
for (Record record : records) for (Record record : records)
{ {
if (record.hasFile ()) if (record.hasFile ())
{ {
String fileName = record.getFileName (); String fileName = volumeName.convert (record.getFileName ());
// int fileSize = record.getFileSize (); // int fileSize = record.getFileSize ();
byte fileType = (byte) record.getFileType (); byte fileType = (byte) record.getFileType ();
int eof = record.getUncompressedSize (); int eof = record.getUncompressedSize ();
@ -169,9 +126,6 @@ public class NuFX
LocalDateTime modified = record.getModified (); LocalDateTime modified = record.getModified ();
byte[] buffer = record.getData (); byte[] buffer = record.getData ();
if (nameOffset > 0) // remove volume name from path
fileName = fileName.substring (nameOffset);
if (false) if (false)
System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count, System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count,
fileName, fileType, auxType, eof, buffer.length, created, modified); fileName, fileType, auxType, eof, buffer.length, created, modified);
@ -247,6 +201,110 @@ public class NuFX
return "no disk"; return "no disk";
} }
// ---------------------------------------------------------------------------------//
class VolumeName
// ---------------------------------------------------------------------------------//
{
private List<String> 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 ("<none>");
for (String pathName : paths)
System.out.println (pathName);
}
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public static void main (String[] args) throws FileFormatException, IOException public static void main (String[] args) throws FileFormatException, IOException
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//