This commit is contained in:
Denis Molony 2021-04-25 18:14:14 +10:00
parent 8db6489649
commit 113917e278
5 changed files with 107 additions and 54 deletions

View File

@ -79,8 +79,8 @@ public class DirectoryHeader
int blockNo = ptr / BLOCK_SIZE;
text.append (String.format ("Block ............ %04X%n", blockNo));
text.append (String.format ("Entry ............ %02X%n",
(ptr - blockNo * BLOCK_SIZE - 4) / 39));
text.append (
String.format ("Entry ............ %02X%n", ((ptr % BLOCK_SIZE) - 4) / 39 + 1));
text.append (String.format ("Storage type ..... %02X %s%n", storageType,
ProdosDisk.storageTypes[storageType]));

View File

@ -1,6 +1,10 @@
package com.bytezone.diskbrowser.prodos.write;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.BLOCK_SIZE;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.ENTRY_SIZE;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.SAPLING;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.SEEDLING;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.TREE;
import static com.bytezone.diskbrowser.prodos.write.ProdosDisk.UNDERLINE;
import static com.bytezone.diskbrowser.utilities.Utility.getAppleDate;
import static com.bytezone.diskbrowser.utilities.Utility.putAppleDate;
@ -15,13 +19,9 @@ import java.time.LocalDateTime;
public class FileEntry
// -----------------------------------------------------------------------------------//
{
private static final int SEEDLING = 0x01;
private static final int SAPLING = 0x02;
private static final int TREE = 0x03;
ProdosDisk disk;
byte[] buffer;
int ptr;
private final ProdosDisk disk;
private final byte[] buffer;
private final int ptr;
String fileName;
byte storageType;
@ -49,6 +49,20 @@ public class FileEntry
this.ptr = ptr;
}
// ---------------------------------------------------------------------------------//
int getBlockNo ()
// ---------------------------------------------------------------------------------//
{
return ptr / BLOCK_SIZE;
}
// ---------------------------------------------------------------------------------//
int getEntryNo ()
// ---------------------------------------------------------------------------------//
{
return (((ptr % BLOCK_SIZE) - 4) / ENTRY_SIZE + 1);
}
// ---------------------------------------------------------------------------------//
void read ()
// ---------------------------------------------------------------------------------//
@ -307,8 +321,8 @@ public class FileEntry
text.append (UNDERLINE);
int blockNo = ptr / BLOCK_SIZE;
text.append (String.format ("Block ............ %04X%n", blockNo));
text.append (String.format ("Entry ............ %02X%n",
(ptr - blockNo * BLOCK_SIZE - 4) / 39));
text.append (
String.format ("Entry ............ %02X%n", ((ptr % BLOCK_SIZE) - 4) / 39 + 1));
text.append (String.format ("Storage type ..... %02X %s%n", storageType,
ProdosDisk.storageTypes[storageType]));
text.append (String.format ("Name length ...... %02X%n", fileName.length ()));

View File

@ -22,10 +22,9 @@ public class ProdosDisk
{
static final String UNDERLINE = "------------------------------------------------\n";
// static final int BLOCK_SIZE = 512;
private static final int CATALOG_SIZE = 4;
// static final int ENTRY_SIZE = 0x27;
private static final int BITS_PER_BLOCK = 8 * BLOCK_SIZE;
static final String[] storageTypes =
{ "Deleted", "Seedling", "Sapling", "Tree", "", "", "", "", "", "", "", "", "",
"Subdirectory", "Subdirectory Header", "Volume Directory Header" };
@ -125,7 +124,7 @@ public class ProdosDisk
{
// split the full path into an array of subdirectories and a file name
String[] subdirectories;
String fileName = "";
String fileName;
int pos = path.lastIndexOf ('/');
if (pos > 0)
@ -160,7 +159,7 @@ public class ProdosDisk
return null; // throw something?
}
// create the file in the current catalog block
// create a file entry in the current catalog block
fileEntry = findFreeSlot (catalogBlockNo);
if (fileEntry != null)
@ -168,7 +167,7 @@ public class ProdosDisk
fileEntry.fileName = fileName;
fileEntry.version = 0x00;
fileEntry.minVersion = 0x00;
fileEntry.headerPointer = catalogBlockNo;
fileEntry.headerPointer = catalogBlockNo; // block containing catalog header
fileEntry.fileType = type;
fileEntry.auxType = auxType;
fileEntry.creationDate = created;
@ -182,7 +181,7 @@ public class ProdosDisk
return fileEntry;
}
return null;
return null; // should be impossible
}
// ---------------------------------------------------------------------------------//
@ -193,6 +192,8 @@ public class ProdosDisk
volumeDirectoryHeader.write ();
for (SubdirectoryHeader subdirectoryHeader : subdirectoryHeaders.values ())
subdirectoryHeader.write ();
System.out.println (this);
}
// ---------------------------------------------------------------------------------//
@ -240,43 +241,42 @@ public class ProdosDisk
throws DiskFullException, VolumeCatalogFullException
// ---------------------------------------------------------------------------------//
{
// this will return a new, empty file entry, or throw an exception
FileEntry fileEntry = findFreeSlot (blockNo);
if (fileEntry != null)
if (fileEntry == null) // should be impossible
{
fileEntry.storageType = SUBDIRECTORY;
fileEntry.fileName = name;
fileEntry.keyPointer = allocateNextBlock ();
fileEntry.blocksUsed = 1;
fileEntry.eof = BLOCK_SIZE;
fileEntry.fileType = FILE_TYPE_DIRECTORY;
fileEntry.headerPointer = blockNo;
fileEntry.creationDate = LocalDateTime.now ();
fileEntry.modifiedDate = LocalDateTime.now ();
fileEntry.write ();
updateFileCount (fileEntry.headerPointer);
SubdirectoryHeader subdirectoryHeader =
new SubdirectoryHeader (this, buffer, fileEntry.keyPointer * BLOCK_SIZE + 4);
subdirectoryHeader.fileName = name;
subdirectoryHeader.creationDate = LocalDateTime.now ();
subdirectoryHeader.fileCount = 0;
subdirectoryHeader.parentPointer = fileEntry.ptr / BLOCK_SIZE;
subdirectoryHeader.parentEntry =
(byte) (((fileEntry.ptr % BLOCK_SIZE) - 4) / ENTRY_SIZE + 1);
subdirectoryHeader.write ();
subdirectoryHeaders.put (fileEntry.keyPointer, subdirectoryHeader);
return fileEntry;
System.out.println ("failed");
return null;
}
System.out.println ("failed");
fileEntry.storageType = SUBDIRECTORY;
fileEntry.fileName = name;
fileEntry.keyPointer = allocateNextBlock (); // allocate block for the subdirectory header
fileEntry.blocksUsed = 1;
fileEntry.eof = BLOCK_SIZE;
fileEntry.fileType = FILE_TYPE_DIRECTORY;
fileEntry.headerPointer = blockNo;
fileEntry.creationDate = LocalDateTime.now ();
fileEntry.modifiedDate = LocalDateTime.now ();
return null; // no empty slots found
fileEntry.write ();
updateFileCount (fileEntry.headerPointer);
SubdirectoryHeader subdirectoryHeader =
new SubdirectoryHeader (this, buffer, fileEntry.keyPointer * BLOCK_SIZE + 4);
subdirectoryHeader.fileName = name;
subdirectoryHeader.creationDate = LocalDateTime.now ();
subdirectoryHeader.fileCount = 0;
subdirectoryHeader.setParentDetails (fileEntry);
subdirectoryHeader.write ();
subdirectoryHeaders.put (fileEntry.keyPointer, subdirectoryHeader);
return fileEntry;
}
// ---------------------------------------------------------------------------------//
@ -385,4 +385,25 @@ public class ProdosDisk
{
return buffer;
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
text.append (volumeDirectoryHeader);
text.append ("\n");
for (SubdirectoryHeader subdirectoryHeader : subdirectoryHeaders.values ())
{
text.append (subdirectoryHeader);
text.append ("\n");
text.append (subdirectoryHeader.getParentFileEntry ());
text.append ("\n");
}
return text.toString ();
}
}

View File

@ -12,9 +12,9 @@ import java.time.LocalDateTime;
public class SubdirectoryHeader extends DirectoryHeader
// -----------------------------------------------------------------------------------//
{
int parentPointer;
byte parentEntry;
byte parentEntryLength = ENTRY_SIZE;
private int parentPointer;
private byte parentEntry;
private byte parentEntryLength;
// ---------------------------------------------------------------------------------//
public SubdirectoryHeader (ProdosDisk disk, byte[] buffer, int ptr)
@ -27,12 +27,30 @@ public class SubdirectoryHeader extends DirectoryHeader
}
// ---------------------------------------------------------------------------------//
void updateParentFileEntry ()
void setParentDetails (FileEntry fileEntry)
// ---------------------------------------------------------------------------------//
{
parentPointer = fileEntry.getBlockNo ();
parentEntry = (byte) fileEntry.getEntryNo ();
parentEntryLength = ENTRY_SIZE;
}
// ---------------------------------------------------------------------------------//
FileEntry getParentFileEntry ()
// ---------------------------------------------------------------------------------//
{
FileEntry fileEntry = new FileEntry (disk, buffer,
parentPointer * BLOCK_SIZE + (parentEntry - 1) * ENTRY_SIZE + 4);
fileEntry.read ();
return fileEntry;
}
// ---------------------------------------------------------------------------------//
void updateParentFileEntry ()
// ---------------------------------------------------------------------------------//
{
FileEntry fileEntry = getParentFileEntry ();
fileEntry.blocksUsed++;
fileEntry.eof += BLOCK_SIZE;
fileEntry.modifiedDate = LocalDateTime.now ();
@ -85,7 +103,7 @@ public class SubdirectoryHeader extends DirectoryHeader
text.append ("Subdirectory Header\n");
text.append (UNDERLINE);
text.append (super.toString ());
text.append (String.format ("Parent pointer ... %d%n", parentPointer));
text.append (String.format ("Parent pointer ... %04X%n", parentPointer));
text.append (String.format ("Parent entry ..... %02X%n", parentEntry));
text.append (String.format ("PE length ........ %02X%n", parentEntryLength));
text.append (UNDERLINE);

View File

@ -53,7 +53,7 @@ public class VolumeDirectoryHeader extends DirectoryHeader
text.append ("Volume Directory Header\n");
text.append (UNDERLINE);
text.append (super.toString ());
text.append (String.format ("Bitmap pointer ... %d%n", bitMapPointer));
text.append (String.format ("Bitmap pointer ... %02X%n", bitMapPointer));
text.append (String.format ("Total blocks ..... %d%n", totalBlocks));
text.append (UNDERLINE);