diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index 3b4670c..4f074f4 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -175,6 +175,7 @@ public class DiskFactory } catch (Exception e) { + System.out.println (e.getMessage ()); System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ()); return null; } diff --git a/src/com/bytezone/diskbrowser/prodos/write/ExtendedKeyBlock.java b/src/com/bytezone/diskbrowser/prodos/write/ExtendedKeyBlock.java new file mode 100644 index 0000000..952a13d --- /dev/null +++ b/src/com/bytezone/diskbrowser/prodos/write/ExtendedKeyBlock.java @@ -0,0 +1,107 @@ +package com.bytezone.diskbrowser.prodos.write; + +import com.bytezone.diskbrowser.utilities.Utility; + +// -----------------------------------------------------------------------------------// +public class ExtendedKeyBlock +// -----------------------------------------------------------------------------------// +{ + private final ProdosDisk disk; + private final byte[] buffer; + private final int ptr; + + // int blockNo; + + MiniEntry dataFork; + MiniEntry resourceFork; + + // ---------------------------------------------------------------------------------// + public ExtendedKeyBlock (ProdosDisk disk, byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + this.disk = disk; + this.buffer = buffer; + this.ptr = ptr; + } + + // ---------------------------------------------------------------------------------// + void addMiniEntry (int type, byte storageType, int keyBlock, int blocksUsed, int eof) + // ---------------------------------------------------------------------------------// + { + MiniEntry miniEntry = new MiniEntry (storageType, keyBlock, blocksUsed, eof); + + if (type == 1) // enum?? + dataFork = miniEntry; + else + resourceFork = miniEntry; + } + + // ---------------------------------------------------------------------------------// + void read (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + if (buffer[ptr] != 0) + dataFork = new MiniEntry (buffer, 0); + + if (buffer[ptr + 0x100] != 0) + resourceFork = new MiniEntry (buffer, 0x100); + } + + // ---------------------------------------------------------------------------------// + void write () + // ---------------------------------------------------------------------------------// + { + if (dataFork != null) // else zero buffer?? + dataFork.write (buffer, ptr); + + if (resourceFork != null) + resourceFork.write (buffer, ptr + 0x100); + } + + // ---------------------------------------------------------------------------------// + class MiniEntry + // ---------------------------------------------------------------------------------// + { + byte storageType; // uses low nibble + int keyBlock; + int blocksUsed; + int eof; + + // -------------------------------------------------------------------------------// + MiniEntry (byte[] buffer, int ptr) + // -------------------------------------------------------------------------------// + { + read (buffer, ptr); + } + + // -------------------------------------------------------------------------------// + MiniEntry (byte storageType, int keyBlock, int blocksUsed, int eof) + // -------------------------------------------------------------------------------// + { + this.storageType = storageType; + this.keyBlock = keyBlock; + this.blocksUsed = blocksUsed; + this.eof = eof; + } + + // -------------------------------------------------------------------------------// + void read (byte[] buffer, int ptr) + // -------------------------------------------------------------------------------// + { + storageType = buffer[ptr]; + keyBlock = Utility.readShort (buffer, ptr + 1); + blocksUsed = Utility.readShort (buffer, ptr + 3); + eof = Utility.readTriple (buffer, ptr + 5); + } + + // -------------------------------------------------------------------------------// + void write (byte[] buffer, int ptr) + // -------------------------------------------------------------------------------// + { + buffer[ptr] = storageType; + Utility.writeShort (buffer, ptr + 1, keyBlock); + Utility.writeShort (buffer, ptr + 3, blocksUsed); + Utility.writeTriple (buffer, ptr + 5, eof); + } + } +} diff --git a/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java index cbc28fe..d58d227 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/write/FileEntry.java @@ -2,9 +2,6 @@ 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; @@ -37,9 +34,6 @@ public class FileEntry int auxType; int headerPointer; - private IndexBlock indexBlock = null; - private MasterIndexBlock masterIndexBlock = null; - // ---------------------------------------------------------------------------------// public FileEntry (ProdosDisk disk, byte[] buffer, int ptr) // ---------------------------------------------------------------------------------// @@ -112,203 +106,6 @@ public class FileEntry writeShort (buffer, ptr + 0x25, headerPointer); } - // ---------------------------------------------------------------------------------// - void writeFile (byte[] dataBuffer) throws DiskFullException - // ---------------------------------------------------------------------------------// - { - this.eof = dataBuffer.length; - - int dataPtr = 0; - int remaining = eof; - - while (dataPtr < eof) - { - int actualBlockNo = allocateNextBlock (); - map (dataPtr / BLOCK_SIZE, actualBlockNo); - - int bufferPtr = actualBlockNo * BLOCK_SIZE; - int tfr = Math.min (remaining, BLOCK_SIZE); - - System.arraycopy (dataBuffer, dataPtr, buffer, bufferPtr, tfr); - - dataPtr += BLOCK_SIZE; - remaining -= BLOCK_SIZE; - } - - writeIndices (); - } - - // ---------------------------------------------------------------------------------// - void writeRecord (int recordNo, byte[] dataBuffer) throws DiskFullException - // ---------------------------------------------------------------------------------// - { - assert auxType > 0; // record length - - int destPtr = auxType * recordNo; - int remaining = Math.min (auxType, dataBuffer.length); - int max = destPtr + remaining; - int dataPtr = 0; - - if (eof < max) - eof = max; - - while (destPtr < max) - { - int logicalBlockNo = destPtr / BLOCK_SIZE; - int blockOffset = destPtr % BLOCK_SIZE; - int tfr = Math.min (BLOCK_SIZE - blockOffset, remaining); - - int actualBlockNo = getActualBlockNo (logicalBlockNo); - int bufferPtr = actualBlockNo * BLOCK_SIZE + blockOffset; - - System.arraycopy (dataBuffer, dataPtr, buffer, bufferPtr, tfr); - - // System.out.printf ("%7d %5d %5d %5d%n", destPtr, tfr, logicalBlockNo, - // blockOffset); - - destPtr += tfr; - dataPtr += tfr; - remaining -= tfr; - } - - writeIndices (); - } - - // ---------------------------------------------------------------------------------// - int allocateNextBlock () throws DiskFullException - // ---------------------------------------------------------------------------------// - { - blocksUsed++; - return disk.allocateNextBlock (); - } - - // ---------------------------------------------------------------------------------// - int getActualBlockNo (int logicalBlockNo) throws DiskFullException - // ---------------------------------------------------------------------------------// - { - int actualBlockNo = 0; - - switch (storageType) - { - case TREE: - actualBlockNo = - masterIndexBlock.get (logicalBlockNo / 256).get (logicalBlockNo % 256); - break; - - case SAPLING: - if (logicalBlockNo < 256) - actualBlockNo = indexBlock.get (logicalBlockNo); - break; - - case SEEDLING: - if (logicalBlockNo == 0) - actualBlockNo = keyPointer; - break; - } - - if (actualBlockNo == 0) - { - actualBlockNo = allocateNextBlock (); - map (logicalBlockNo, actualBlockNo); - } - - return actualBlockNo; - } - - // ---------------------------------------------------------------------------------// - private void writeIndices () - // ---------------------------------------------------------------------------------// - { - if (storageType == TREE) - masterIndexBlock.write (buffer); - else if (storageType == SAPLING) - indexBlock.write (buffer); - } - - // ---------------------------------------------------------------------------------// - void map (int logicalBlockNo, int actualBlockNo) throws DiskFullException - // ---------------------------------------------------------------------------------// - { - if (logicalBlockNo > 255) // potential TREE - { - if (storageType != TREE) - { - masterIndexBlock = new MasterIndexBlock (allocateNextBlock ()); - - if (storageType == SAPLING) // sapling -> tree - { - masterIndexBlock.set (0, indexBlock); - } - else if (storageType == SEEDLING) // seedling -> sapling -> tree - { - indexBlock = new IndexBlock (allocateNextBlock ()); - indexBlock.set (0, keyPointer); - masterIndexBlock.set (0, indexBlock); - } - - keyPointer = masterIndexBlock.blockNo; - storageType = TREE; - indexBlock = null; - } - - getIndexBlock (logicalBlockNo / 256).set (logicalBlockNo % 256, actualBlockNo); - } - else if (logicalBlockNo > 0) // potential SAPLING - { - if (storageType == TREE) // already a tree - { - getIndexBlock (0).set (logicalBlockNo, actualBlockNo); - } - else if (storageType == SAPLING) // already a sapling - { - indexBlock.set (logicalBlockNo, actualBlockNo); - } - else // new file or already a seedling - { - indexBlock = new IndexBlock (allocateNextBlock ()); - if (storageType == SEEDLING) // seedling -> sapling - indexBlock.set (0, keyPointer); - - keyPointer = indexBlock.blockNo; - storageType = SAPLING; - indexBlock.set (logicalBlockNo, actualBlockNo); - } - } - else if (logicalBlockNo == 0) // potential SEEDLING - { - if (storageType == TREE) // already a tree - { - getIndexBlock (0).set (0, actualBlockNo); - } - else if (storageType == SAPLING) // already a sapling - { - indexBlock.set (0, actualBlockNo); - } - else - { - keyPointer = actualBlockNo; - storageType = SEEDLING; - } - } - else - System.out.println ("Error"); - } - - // ---------------------------------------------------------------------------------// - IndexBlock getIndexBlock (int position) throws DiskFullException - // ---------------------------------------------------------------------------------// - { - IndexBlock indexBlock = masterIndexBlock.get (position); - - if (indexBlock == null) - { - indexBlock = new IndexBlock (allocateNextBlock ()); - masterIndexBlock.set (position, indexBlock); - } - - return indexBlock; - } - // ---------------------------------------------------------------------------------// String toText () // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/prodos/write/FileWriter.java b/src/com/bytezone/diskbrowser/prodos/write/FileWriter.java new file mode 100644 index 0000000..3a4f43a --- /dev/null +++ b/src/com/bytezone/diskbrowser/prodos/write/FileWriter.java @@ -0,0 +1,225 @@ +package com.bytezone.diskbrowser.prodos.write; + +import static com.bytezone.diskbrowser.prodos.ProdosConstants.BLOCK_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; + +// -----------------------------------------------------------------------------------// +public class FileWriter +// -----------------------------------------------------------------------------------// +{ + private final ProdosDisk disk; + private final byte[] buffer; + + private IndexBlock indexBlock = null; + private MasterIndexBlock masterIndexBlock = null; + + byte storageType; + int keyPointer; + int blocksUsed; + int eof; + + // ---------------------------------------------------------------------------------// + FileWriter (ProdosDisk disk, byte[] buffer) + // ---------------------------------------------------------------------------------// + { + this.disk = disk; + this.buffer = buffer; + } + + // ---------------------------------------------------------------------------------// + void writeFile (byte[] dataBuffer, int eof) throws DiskFullException + // ---------------------------------------------------------------------------------// + { + this.eof = eof; + + int dataPtr = 0; + int remaining = eof; + + while (dataPtr < eof) + { + int actualBlockNo = allocateNextBlock (); + map (dataPtr / BLOCK_SIZE, actualBlockNo); + + int bufferPtr = actualBlockNo * BLOCK_SIZE; + int tfr = Math.min (remaining, BLOCK_SIZE); + + System.arraycopy (dataBuffer, dataPtr, buffer, bufferPtr, tfr); + + dataPtr += BLOCK_SIZE; + remaining -= BLOCK_SIZE; + } + + writeIndices (); + } + + // ---------------------------------------------------------------------------------// + void writeRecord (int recordNo, byte[] dataBuffer, int recordLength) + throws DiskFullException + // ---------------------------------------------------------------------------------// + { + assert recordLength > 0; + + int destPtr = recordLength * recordNo; + int remaining = Math.min (recordLength, dataBuffer.length); + int max = destPtr + remaining; + int dataPtr = 0; + + if (eof < max) + eof = max; + + while (destPtr < max) + { + int logicalBlockNo = destPtr / BLOCK_SIZE; + int blockOffset = destPtr % BLOCK_SIZE; + int tfr = Math.min (BLOCK_SIZE - blockOffset, remaining); + + int actualBlockNo = getActualBlockNo (logicalBlockNo); + int bufferPtr = actualBlockNo * BLOCK_SIZE + blockOffset; + + System.arraycopy (dataBuffer, dataPtr, buffer, bufferPtr, tfr); + + destPtr += tfr; + dataPtr += tfr; + remaining -= tfr; + } + + writeIndices (); + } + + // ---------------------------------------------------------------------------------// + private int allocateNextBlock () throws DiskFullException + // ---------------------------------------------------------------------------------// + { + blocksUsed++; + return disk.allocateNextBlock (); + } + + // ---------------------------------------------------------------------------------// + private int getActualBlockNo (int logicalBlockNo) throws DiskFullException + // ---------------------------------------------------------------------------------// + { + int actualBlockNo = 0; + + switch (storageType) + { + case TREE: + actualBlockNo = + masterIndexBlock.get (logicalBlockNo / 256).get (logicalBlockNo % 256); + break; + + case SAPLING: + if (logicalBlockNo < 256) + actualBlockNo = indexBlock.get (logicalBlockNo); + break; + + case SEEDLING: + if (logicalBlockNo == 0) + actualBlockNo = keyPointer; + break; + } + + if (actualBlockNo == 0) + { + actualBlockNo = allocateNextBlock (); + map (logicalBlockNo, actualBlockNo); + } + + return actualBlockNo; + } + + // ---------------------------------------------------------------------------------// + private void writeIndices () + // ---------------------------------------------------------------------------------// + { + if (storageType == TREE) + masterIndexBlock.write (buffer); + else if (storageType == SAPLING) + indexBlock.write (buffer); + } + + // ---------------------------------------------------------------------------------// + private void map (int logicalBlockNo, int actualBlockNo) throws DiskFullException + // ---------------------------------------------------------------------------------// + { + if (logicalBlockNo > 255) // potential TREE + { + if (storageType != TREE) + { + masterIndexBlock = new MasterIndexBlock (allocateNextBlock ()); + + if (storageType == SAPLING) // sapling -> tree + { + masterIndexBlock.set (0, indexBlock); + } + else if (storageType == SEEDLING) // seedling -> sapling -> tree + { + indexBlock = new IndexBlock (allocateNextBlock ()); + indexBlock.set (0, keyPointer); + masterIndexBlock.set (0, indexBlock); + } + + keyPointer = masterIndexBlock.blockNo; + storageType = TREE; + indexBlock = null; + } + + getIndexBlock (logicalBlockNo / 256).set (logicalBlockNo % 256, actualBlockNo); + } + else if (logicalBlockNo > 0) // potential SAPLING + { + if (storageType == TREE) // already a tree + { + getIndexBlock (0).set (logicalBlockNo, actualBlockNo); + } + else if (storageType == SAPLING) // already a sapling + { + indexBlock.set (logicalBlockNo, actualBlockNo); + } + else // new file or already a seedling + { + indexBlock = new IndexBlock (allocateNextBlock ()); + if (storageType == SEEDLING) // seedling -> sapling + indexBlock.set (0, keyPointer); + + keyPointer = indexBlock.blockNo; + storageType = SAPLING; + indexBlock.set (logicalBlockNo, actualBlockNo); + } + } + else if (logicalBlockNo == 0) // potential SEEDLING + { + if (storageType == TREE) // already a tree + { + getIndexBlock (0).set (0, actualBlockNo); + } + else if (storageType == SAPLING) // already a sapling + { + indexBlock.set (0, actualBlockNo); + } + else + { + keyPointer = actualBlockNo; + storageType = SEEDLING; + } + } + else + System.out.println ("Error"); + } + + // ---------------------------------------------------------------------------------// + private IndexBlock getIndexBlock (int position) throws DiskFullException + // ---------------------------------------------------------------------------------// + { + IndexBlock indexBlock = masterIndexBlock.get (position); + + if (indexBlock == null) + { + indexBlock = new IndexBlock (allocateNextBlock ()); + masterIndexBlock.set (position, indexBlock); + } + + return indexBlock; + } +} diff --git a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java index fc9cc39..bbde3c7 100644 --- a/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java +++ b/src/com/bytezone/diskbrowser/prodos/write/ProdosDisk.java @@ -187,7 +187,13 @@ public class ProdosDisk fileEntry.creationDate = created; fileEntry.modifiedDate = modified; - fileEntry.writeFile (dataBuffer); + FileWriter fileWriter = new FileWriter (this, buffer); + fileWriter.writeFile (dataBuffer, dataBuffer.length); + + fileEntry.storageType = fileWriter.storageType; + fileEntry.keyPointer = fileWriter.keyPointer; + fileEntry.blocksUsed = fileWriter.blocksUsed; + fileEntry.eof = fileWriter.eof; fileEntry.write (); updateFileCount (fileEntry.headerPointer); @@ -198,6 +204,31 @@ public class ProdosDisk return null; // should be impossible } + // ---------------------------------------------------------------------------------// + public void addResourceFork (FileEntry fileEntry, byte[] dataBuffer, int eof) + throws DiskFullException + // ---------------------------------------------------------------------------------// + { + FileWriter fileWriter = new FileWriter (this, buffer); // create dummy FileEntry + fileWriter.writeFile (dataBuffer, eof); + + int blockNo = allocateNextBlock (); + + ExtendedKeyBlock extendedKeyBlock = + new ExtendedKeyBlock (this, buffer, blockNo * BLOCK_SIZE); + + extendedKeyBlock.addMiniEntry (1, fileEntry.storageType, fileEntry.keyPointer, + fileEntry.blocksUsed, fileEntry.eof); + extendedKeyBlock.addMiniEntry (2, fileWriter.storageType, fileWriter.keyPointer, + fileWriter.blocksUsed, fileWriter.eof); + + fileEntry.keyPointer = blockNo; // extended key block + fileEntry.storageType = 0x05; // extended + + fileEntry.write (); + extendedKeyBlock.write (); + } + // ---------------------------------------------------------------------------------// private boolean verify (String path) // ---------------------------------------------------------------------------------// @@ -393,6 +424,16 @@ public class ProdosDisk } } + // ---------------------------------------------------------------------------------// + // private int createExtendedKeyBlock (FileEntry fileEntry) throws DiskFullException + // // ---------------------------------------------------------------------------------// + // { + // int blockNo = allocateNextBlock (); + // ExtendedKeyBlock extendedKeyBlock = new ExtendedKeyBlock (blockNo); + // + // return blockNo; + // } + // ---------------------------------------------------------------------------------// int allocateNextBlock () throws DiskFullException // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/DateTime.java b/src/com/bytezone/diskbrowser/utilities/DateTime.java index 027803c..658ec92 100644 --- a/src/com/bytezone/diskbrowser/utilities/DateTime.java +++ b/src/com/bytezone/diskbrowser/utilities/DateTime.java @@ -57,9 +57,9 @@ class DateTime // ---------------------------------------------------------------------------------// { int adjustedYear = year + (year > 70 ? 1900 : 2000); - if (day < 1 || day > 31) + if (day < 0 || day > 30) return null; - return LocalDateTime.of (adjustedYear, month + 1, day, hour, minute); + return LocalDateTime.of (adjustedYear, month + 1, day + 1, hour, minute); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/LZW2.java b/src/com/bytezone/diskbrowser/utilities/LZW2.java index 77f8bc7..d36a7d2 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW2.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW2.java @@ -16,8 +16,6 @@ class LZW2 extends LZW this.crc = crc; this.v3eof = eof; - - // unpack (); } // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java index 8c852e5..df6dc27 100644 --- a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java +++ b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java @@ -33,7 +33,6 @@ 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 de9a75f..2e07ca4 100644 --- a/src/com/bytezone/diskbrowser/utilities/NuFX.java +++ b/src/com/bytezone/diskbrowser/utilities/NuFX.java @@ -77,6 +77,7 @@ public class NuFX if (record.hasDisk ()) ++totalDisks; } + printSummary (); } @@ -96,14 +97,17 @@ public class NuFX for (Record record : records) { - System.out.printf (" %s%n", record.getLine ()); + System.out.println (record.getLine ()); totalUncompressedSize += record.getUncompressedSize (); totalCompressedSize += record.getCompressedSize (); } System.out.println (UNDERLINE); - System.out.printf (" Uncomp:%7d Comp:%7d %%of orig:%3.0f%%%n", - totalUncompressedSize, totalCompressedSize, - (float) (totalCompressedSize * 100 / totalUncompressedSize)); + + float pct = 0; + if (totalUncompressedSize > 0) + pct = totalCompressedSize * 100 / totalUncompressedSize; + System.out.printf (" Uncomp:%7d Comp:%7d %%of orig:%3.0f%%%n%n", + totalUncompressedSize, totalCompressedSize, pct); } // ---------------------------------------------------------------------------------// @@ -116,7 +120,7 @@ public class NuFX if (record.hasFile ()) { // note: total blocks does not include subdirectory blocks - int blocks = (record.getFileSize () - 1) / 512 + 1; + int blocks = (record.getUncompressedSize () - 1) / 512 + 1; if (blocks == 1) // seedling totalBlocks += blocks; else if (blocks <= 256) // sapling @@ -132,6 +136,8 @@ public class NuFX { if (totalDisks > 0) { + if (debug) + System.out.println ("Reading disk"); for (Record record : records) for (Thread thread : record.threads) if (thread.hasDisk ()) @@ -140,8 +146,8 @@ public class NuFX if (totalFiles > 0) { - // should check that files are all in prodos format - + if (debug) + System.out.println ("Reading files"); calculateTotalBlocks (); int[] diskSizes = { 280, 800, 1600, 3200, 6400, 65536 }; for (int diskSize : diskSizes) // in case we choose a size that is too small @@ -184,6 +190,12 @@ public class NuFX System.out.printf ("File %s not added%n", fileName); break; } + + if (record.hasResource ()) + { + buffer = record.getResourceData (); + System.out.println (HexFormatter.format (buffer)); + } } } @@ -191,11 +203,6 @@ public class NuFX return disk.getBuffer (); } - catch (IOException e) - { - e.printStackTrace (); - return null; - } catch (DiskFullException e) { System.out.println ("disk full: " + diskSize); // go round again @@ -205,6 +212,11 @@ public class NuFX e.printStackTrace (); return null; } + catch (IOException e) + { + e.printStackTrace (); + return null; + } } } diff --git a/src/com/bytezone/diskbrowser/utilities/Record.java b/src/com/bytezone/diskbrowser/utilities/Record.java index 6b81985..b2ed787 100644 --- a/src/com/bytezone/diskbrowser/utilities/Record.java +++ b/src/com/bytezone/diskbrowser/utilities/Record.java @@ -148,6 +148,17 @@ class Record return false; } + // ---------------------------------------------------------------------------------// + boolean hasResource () + // ---------------------------------------------------------------------------------// + { + for (Thread thread : threads) + if (thread.hasResource ()) + return true; + + return false; + } + // ---------------------------------------------------------------------------------// String getFileName () // ---------------------------------------------------------------------------------// @@ -199,6 +210,15 @@ class Record return modified.getLocalDateTime (); } + // ---------------------------------------------------------------------------------// + LocalDateTime getArchived () + // ---------------------------------------------------------------------------------// + { + if (archived == null) + return null; + return archived.getLocalDateTime (); + } + // ---------------------------------------------------------------------------------// int getFileSystemID () // ---------------------------------------------------------------------------------// @@ -239,22 +259,26 @@ class Record int getUncompressedSize () // ---------------------------------------------------------------------------------// { - for (Thread thread : threads) - if (thread.hasFile ()) - return thread.getUncompressedEOF (); + int size = 0; - return 0; + for (Thread thread : threads) + if (thread.hasFile () || thread.hasResource ()) + size += thread.getUncompressedEOF (); + + return size; } // ---------------------------------------------------------------------------------// int getCompressedSize () // ---------------------------------------------------------------------------------// { - for (Thread thread : threads) - if (thread.hasFile ()) - return thread.getCompressedEOF (); + int size = 0; - return 0; + for (Thread thread : threads) + if (thread.hasFile () || thread.hasResource ()) + size += thread.getCompressedEOF (); + + return size; } // ---------------------------------------------------------------------------------// @@ -264,6 +288,18 @@ class Record for (Thread thread : threads) if (thread.hasFile ()) return thread.getData (); + + return null; + } + + // ---------------------------------------------------------------------------------// + byte[] getResourceData () + // ---------------------------------------------------------------------------------// + { + for (Thread thread : threads) + if (thread.hasResource ()) + return thread.getData (); + return null; } @@ -271,9 +307,17 @@ class Record String getLine () // ---------------------------------------------------------------------------------// { - float pct = getCompressedSize () * 100 / getUncompressedSize (); - return String.format ("%-27.27s %s $%04X %-15s %s %3.0f%% %7d", getFileName (), - fileTypes[fileType], auxType, created.format2 (), + float pct = 0; + if (getUncompressedSize () > 0) + pct = getCompressedSize () * 100 / getUncompressedSize (); + String lockedFlag = (access | 0xC3) == 1 ? "+" : " "; + String forkedFlag = hasResource () ? "+" : " "; + String name = getFileName (); + if (name.length () > 27) + name = ".." + name.substring (name.length () - 25); + + return String.format ("%s%-27.27s %s%s $%04X %-15s %s %3.0f%% %7d", lockedFlag, + name, fileTypes[fileType], forkedFlag, auxType, archived.format2 (), threadFormats[getThreadFormat ()], pct, getUncompressedSize ()); } diff --git a/src/com/bytezone/diskbrowser/utilities/Thread.java b/src/com/bytezone/diskbrowser/utilities/Thread.java index 949b9c8..50f51dc 100644 --- a/src/com/bytezone/diskbrowser/utilities/Thread.java +++ b/src/com/bytezone/diskbrowser/utilities/Thread.java @@ -29,6 +29,7 @@ class Thread private boolean hasDisk; private boolean hasFile; + private boolean hasResource; private boolean hasFileName; // ---------------------------------------------------------------------------------// @@ -102,6 +103,7 @@ class Thread hasDisk = true; break; case 2: // resource fork of file + hasResource = true; break; } @@ -172,6 +174,13 @@ class Thread return hasFile; } + // ---------------------------------------------------------------------------------// + public boolean hasResource () + // ---------------------------------------------------------------------------------// + { + return hasResource; + } + // ---------------------------------------------------------------------------------// public boolean hasFileName () // ---------------------------------------------------------------------------------// @@ -190,7 +199,11 @@ class Thread int getFileSize () // ---------------------------------------------------------------------------------// { + if (lzw != null) + System.out.printf ("%04X v %04X v %04X%n", compressedEOF, uncompressedEOF, + lzw.getSize ()); return lzw != null ? lzw.getSize () : uncompressedEOF; + // return uncompressedEOF; } // ---------------------------------------------------------------------------------//