removed dependency on Common

This commit is contained in:
Denis Molony 2017-04-22 16:31:25 +10:00
parent 9c9cf87ca8
commit 0fe2a21f96
14 changed files with 132 additions and 75 deletions

View File

@ -133,6 +133,7 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
// restore the menuHandler items before they are referenced // restore the menuHandler items before they are referenced
quitAction.restore (); quitAction.restore ();
diskLayoutPanel.setFree (menuHandler.showFreeSectorsItem.isSelected ());
// Remove the two optional panels if they were previously hidden // Remove the two optional panels if they were previously hidden
if (!menuHandler.showLayoutItem.isSelected ()) if (!menuHandler.showLayoutItem.isSelected ())

View File

@ -16,14 +16,14 @@ class ShowFreeSectorsAction extends AbstractAction
{ {
super ("Show free sectors"); super ("Show free sectors");
putValue (Action.SHORT_DESCRIPTION, putValue (Action.SHORT_DESCRIPTION,
"Display which sectors are marked free in the disk layout panel"); "Display which sectors are marked free in the disk layout panel");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt F")); putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt F"));
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_F); putValue (Action.MNEMONIC_KEY, KeyEvent.VK_F);
this.panel = panel; this.panel = panel;
this.mh = mh; this.mh = mh;
panel.setFree (mh.showFreeSectorsItem.isSelected ()); // set initial state
} }
@Override
public void actionPerformed (ActionEvent e) public void actionPerformed (ActionEvent e)
{ {
panel.setFree (mh.showFreeSectorsItem.isSelected ()); panel.setFree (mh.showFreeSectorsItem.isSelected ());

View File

@ -41,13 +41,19 @@ class FileEntry extends CatalogEntry implements ProdosConstants
this.catalogBlock = this.disk.getDiskAddress (parentBlock); this.catalogBlock = this.disk.getDiskAddress (parentBlock);
fileType = entryBuffer[16] & 0xFF; fileType = entryBuffer[16] & 0xFF;
keyPtr = HexFormatter.intValue (entryBuffer[17], entryBuffer[18]); // keyPtr = HexFormatter.intValue (entryBuffer[17], entryBuffer[18]);
blocksUsed = HexFormatter.intValue (entryBuffer[19], entryBuffer[20]); keyPtr = HexFormatter.unsignedShort (entryBuffer, 17);
// System.out.printf ("%5d %5d%n",
// HexFormatter.intValue (entryBuffer[17], entryBuffer[18]), keyPtr);
// blocksUsed = HexFormatter.intValue (entryBuffer[19], entryBuffer[20]);
blocksUsed = HexFormatter.unsignedShort (entryBuffer, 19);
endOfFile = HexFormatter.intValue (entryBuffer[21], entryBuffer[22], entryBuffer[23]); endOfFile = HexFormatter.intValue (entryBuffer[21], entryBuffer[22], entryBuffer[23]);
auxType = HexFormatter.intValue (entryBuffer[31], entryBuffer[32]); // auxType = HexFormatter.intValue (entryBuffer[31], entryBuffer[32]);
auxType = HexFormatter.unsignedShort (entryBuffer, 31);
modified = HexFormatter.getAppleDate (entryBuffer, 33); modified = HexFormatter.getAppleDate (entryBuffer, 33);
headerPointer = HexFormatter.intValue (entryBuffer[37], entryBuffer[38]); // headerPointer = HexFormatter.intValue (entryBuffer[37], entryBuffer[38]);
headerPointer = HexFormatter.unsignedShort (entryBuffer, 37);
switch (storageType) switch (storageType)
{ {
@ -70,6 +76,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
case TYPE_TREE: case TYPE_TREE:
parentDisk.setSectorType (keyPtr, fDisk.masterIndexSector); parentDisk.setSectorType (keyPtr, fDisk.masterIndexSector);
masterIndexBlock = disk.getDiskAddress (keyPtr); masterIndexBlock = disk.getDiskAddress (keyPtr);
indexBlocks.add (masterIndexBlock);
if (isGEOSFile ()) if (isGEOSFile ())
traverseGEOSMasterIndex (keyPtr); traverseGEOSMasterIndex (keyPtr);
else else
@ -113,6 +120,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants
} while (block > 0); } while (block > 0);
break; break;
case TYPE_PASCAL_ON_PROFILE:
indexBlocks.add (disk.getDiskAddress (keyPtr));
break;
default: default:
System.out.println ("Unknown storage type: " + storageType); System.out.println ("Unknown storage type: " + storageType);
} }
@ -365,8 +376,11 @@ class FileEntry extends CatalogEntry implements ProdosConstants
case FILE_TYPE_GSOS_FILE_SYSTEM_TRANSLATOR: case FILE_TYPE_GSOS_FILE_SYSTEM_TRANSLATOR:
file = new FileSystemTranslator (name, exactBuffer); file = new FileSystemTranslator (name, exactBuffer);
break; break;
case FILE_TYPE_PASCAL_VOLUME:
file = new DefaultAppleFile (name, exactBuffer);
break;
default: default:
System.out.format ("%s - Unknown file type : %02X%n", name, fileType); System.out.format ("%s - Unknown Prodos file type : %02X%n", name, fileType);
file = new DefaultAppleFile (name, exactBuffer); file = new DefaultAppleFile (name, exactBuffer);
} }
} }
@ -502,6 +516,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants
case TYPE_GSOS_EXTENDED_FILE: case TYPE_GSOS_EXTENDED_FILE:
return disk.readSectors (dataBlocks); // data and resource forks concatenated return disk.readSectors (dataBlocks); // data and resource forks concatenated
case TYPE_PASCAL_ON_PROFILE:
return disk.readSectors (dataBlocks);
default: default:
System.out.println ("Unknown storage type in getBuffer : " + storageType); System.out.println ("Unknown storage type in getBuffer : " + storageType);
return new byte[512]; return new byte[512];

View File

@ -33,7 +33,7 @@ class ProdosBitMapSector extends AbstractSector
int width = (grid.width - 1) / 8 + 1; // must be 1-4 int width = (grid.width - 1) / 8 + 1; // must be 1-4
StringBuilder text = getHeader ("Prodos Bit Map Sector"); StringBuilder text = getHeader ("Volume Bit Map Block");
if (false) if (false)
{ {

View File

@ -23,7 +23,7 @@ class ProdosCatalogSector extends AbstractSector
@Override @Override
public String createText () public String createText ()
{ {
StringBuilder text = getHeader ("Prodos Catalog Sector"); StringBuilder text = getHeader ("Volume Directory Block");
addTextAndDecimal (text, buffer, 0, 2, "Previous block"); addTextAndDecimal (text, buffer, 0, 2, "Previous block");
addTextAndDecimal (text, buffer, 2, 2, "Next block"); addTextAndDecimal (text, buffer, 2, 2, "Next block");

View File

@ -22,6 +22,7 @@ public interface ProdosConstants
int FILE_TYPE_FONT = 0xC8; int FILE_TYPE_FONT = 0xC8;
int FILE_TYPE_ICN = 0xCA; int FILE_TYPE_ICN = 0xCA;
int FILE_TYPE_APPLETALK = 0xE2; int FILE_TYPE_APPLETALK = 0xE2;
int FILE_TYPE_PASCAL_VOLUME = 0xEF;
int FILE_TYPE_USER_DEFINED_1 = 0xF1; int FILE_TYPE_USER_DEFINED_1 = 0xF1;
int FILE_TYPE_INTEGER_BASIC = 0xFA; int FILE_TYPE_INTEGER_BASIC = 0xFA;
int FILE_TYPE_INTEGER_BASIC_VARS = 0xFB; int FILE_TYPE_INTEGER_BASIC_VARS = 0xFB;
@ -70,7 +71,7 @@ public interface ProdosConstants
"$D0", "$D1", "$D2", "$D3", "$D4", "MUS", "INS", "MDI", // "$D0", "$D1", "$D2", "$D3", "$D4", "MUS", "INS", "MDI", //
"SND", "$D9", "$DA", "DBM", "$DC", "DDD", "$DE", "$DF", // "SND", "$D9", "$DA", "DBM", "$DC", "DDD", "$DE", "$DF", //
"LBR", "$E1", "ATK", "$E3", "$E4", "$E5", "$E6", "$E7", // "LBR", "$E1", "ATK", "$E3", "$E4", "$E5", "$E6", "$E7", //
"$E8", "$E9", "$EA", "$EB", "$EC", "$ED", "R16", "PAS", // "$E8", "$E9", "$EA", "$EB", "$EC", "$ED", "R16", "PAR", //
"CMD", "OVL", "UD2", "UD3", "UD4", "BAT", "UD6", "UD7", // "CMD", "OVL", "UD2", "UD3", "UD4", "BAT", "UD6", "UD7", //
"PRG", "P16", "INT", "IVR", "BAS", "VAR", "REL", "SYS" }; "PRG", "P16", "INT", "IVR", "BAS", "VAR", "REL", "SYS" };
@ -206,4 +207,37 @@ public interface ProdosConstants
* $FF SYS ProDOS System File * $FF SYS ProDOS System File
*/ */
// See also http://www.kreativekorp.com/miscpages/a2info/filetypes.shtml // See also http://www.kreativekorp.com/miscpages/a2info/filetypes.shtml
/*
* https://groups.google.com/forum/#!topic/comp.sys.apple2/waoYCIbkJKs
*
* There are a number of disk utilities available that store images of disks that
* utilize file systems that are not ProDOS, at the end of a ProDOS volume.
* There's DOS Master, by Glen Bredon, that stores images of DOS 3.3 disks at the
* end of a ProDOS volume. Similarly, Pro/Part, by Steven Hirsch, stores images
* of CP/M volumes. Also, there's Pascal Partition Manager (PPM) that stores
* images of UCSD Pascal volumes. I've decided to refer to the area used to store
* volume images, by all three of these systems, as a Foreign Volume Area or FVA.
* All three of these systems modify the Block Allocation Map of a ProDOS volume
* to keep ProDOS from assigning blocks used by FVAs for use by files being
* written by ProDOS. Pascal Partition Manager is different from the other two
* in that it has a file type ($EF) and file kind (4) assigned to it by Apple.
* A directory listing of a ProODS volume containing an FVA managed by PPM will
* show a file name of "PASCAL.AREA". A directory listing of a ProDOS volume
* containing an FVA managed by DOS Master or Pro/Part will show absolutely nothing.
* Running a popular utility named "MR.FIXIT", also by Glen Bredon, against a
* ProDOS volume containing an FVA will report an error. Specifically, "MR.FIXIT"
* will complain that all the blocks used by an FVA as allocated but not in use.
* To solve this problem for Pro/Part I wrote a Foreign Volume Area utility
* program that generates a directory entry for the Pro/Part area. That entry has
* file kind 4, file type $EF, file name "PROPART.AREA" and an auxiliary file
* type $4853 (Steven Hirsch's initials). Today I realized that it's likely that
* the same thing could be done for DOS Master. Study of the source code for
* DOS Master will reveal it that's true. If it is, I propose that "DOS33.AREA"
* be used as the file name and $4247 as the auxiliary type (Glen Bredon's initials).
* As I compose the text of this message I realize that another solution is to
* modify "MR.FIXIT" to be aware of FVAs. But doing that would not allow someone
* doing a directory listing of a ProDOS volume containing an FVA to be aware
* that the FVA exists.
*/

View File

@ -18,21 +18,22 @@ class ProdosIndexSector extends AbstractSector
@Override @Override
public String createText () public String createText ()
{ {
StringBuilder text = getHeader ("Prodos Index Sector : " + name); StringBuilder text = getHeader ("Prodos Index Block : " + name);
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
text.append (String.format ("%02X %02X %02X", i, buffer[i], text.append (
buffer[i + 256])); String.format ("%02X %02X %02X", i, buffer[i], buffer[i + 256]));
if (buffer[i] != 0 || buffer[i + 256] != 0) if (buffer[i] != 0 || buffer[i + 256] != 0)
text.append (String text.append (String.format (" %s%n",
.format (" %s%n", "block " + HexFormatter.intValue (buffer[i], buffer[i + 256])));
"block " + HexFormatter.intValue (buffer[i], buffer[i + 256])));
else else
text.append ("\n"); text.append ("\n");
} }
if (text.length () > 0) if (text.length () > 0)
text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1);
return text.toString (); return text.toString ();
} }
} }

View File

@ -23,9 +23,9 @@ class VolumeDirectoryHeader extends DirectoryHeader
{ {
super (parentDisk, entryBuffer); super (parentDisk, entryBuffer);
bitMapBlock = HexFormatter.intValue (entryBuffer[35], entryBuffer[36]); bitMapBlock = HexFormatter.unsignedShort (entryBuffer, 35);
totalBlocks = HexFormatter.intValue (entryBuffer[37], entryBuffer[38]); totalBlocks = HexFormatter.unsignedShort (entryBuffer, 37);
if (totalBlocks == 0xFFFF | totalBlocks == 0x7FFF) if (totalBlocks == 0xFFFF || totalBlocks == 0x7FFF)
totalBlocks = (int) disk.getFile ().length () / 4096 * 8; // ignore extra bytes totalBlocks = (int) disk.getFile ().length () / 4096 * 8; // ignore extra bytes
// totalBitMapBlocks = (totalBlocks * 8 - 1) / 4096 + 1; // totalBitMapBlocks = (totalBlocks * 8 - 1) / 4096 + 1;
totalBitMapBlocks = (totalBlocks - 1) / 512 + 1; totalBitMapBlocks = (totalBlocks - 1) / 512 + 1;
@ -35,7 +35,7 @@ class VolumeDirectoryHeader extends DirectoryHeader
{ {
dataBlocks.add (disk.getDiskAddress (block)); dataBlocks.add (disk.getDiskAddress (block));
byte[] buffer = disk.readSector (block); byte[] buffer = disk.readSector (block);
block = HexFormatter.intValue (buffer[2], buffer[3]); block = HexFormatter.unsignedShort (buffer, 2);
} while (block > 0); } while (block > 0);
// convert the Free Sector Table // convert the Free Sector Table

View File

@ -329,13 +329,14 @@ public class HexFormatter
public static int unsignedShort (byte[] buffer, int ptr) public static int unsignedShort (byte[] buffer, int ptr)
{ {
int val = 0; // int val = 0;
for (int i = 1; i >= 0; i--) // for (int i = 1; i >= 0; i--)
{ // {
val <<= 8; // val <<= 8;
val += buffer[ptr + i] & 0xFF; // val += buffer[ptr + i] & 0xFF;
} // }
return val; // return val;
return (buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8);
} }
// public static int signedShort (byte[] buffer, int ptr) // public static int signedShort (byte[] buffer, int ptr)

View File

@ -110,4 +110,16 @@ class LZW
{ {
return 32 - Integer.numberOfLeadingZeros (maximumValue); return 32 - Integer.numberOfLeadingZeros (maximumValue);
} }
static int getLong (byte[] buffer, int ptr)
{
return getWord (buffer, ptr) + getWord (buffer, ptr + 2) * 0x10000;
}
static int getWord (byte[] buffer, int ptr)
{
int a = (buffer[ptr + 1] & 0xFF) << 8;
int b = buffer[ptr] & 0xFF;
return a + b;
}
} }

View File

@ -2,15 +2,13 @@ package com.bytezone.diskbrowser.utilities;
import java.util.Objects; import java.util.Objects;
import com.bytezone.common.Utility;
class LZW1 extends LZW class LZW1 extends LZW
{ {
public LZW1 (byte[] buffer) public LZW1 (byte[] buffer)
{ {
bytes = Objects.requireNonNull (buffer); bytes = Objects.requireNonNull (buffer);
crc = Utility.getWord (buffer, 0); crc = LZW.getWord (buffer, 0);
crcBase = 0; crcBase = 0;
volume = buffer[2] & 0xFF; volume = buffer[2] & 0xFF;
@ -19,7 +17,7 @@ class LZW1 extends LZW
while (ptr < buffer.length - 1) // what is in the last byte? while (ptr < buffer.length - 1) // what is in the last byte?
{ {
int rleLength = Utility.getWord (buffer, ptr); int rleLength = LZW.getWord (buffer, ptr);
int lzwPerformed = buffer[ptr + 2] & 0xFF; int lzwPerformed = buffer[ptr + 2] & 0xFF;
ptr += 3; ptr += 3;

View File

@ -2,8 +2,6 @@ package com.bytezone.diskbrowser.utilities;
import java.util.Objects; import java.util.Objects;
import com.bytezone.common.Utility;
class LZW2 extends LZW class LZW2 extends LZW
{ {
private int nextEntry = 0x100; private int nextEntry = 0x100;
@ -24,7 +22,7 @@ class LZW2 extends LZW
while (ptr < buffer.length - 1) // what is in the last byte? while (ptr < buffer.length - 1) // what is in the last byte?
{ {
int rleLength = Utility.getWord (buffer, ptr); int rleLength = LZW.getWord (buffer, ptr);
boolean lzwPerformed = (rleLength & 0x8000) != 0; boolean lzwPerformed = (rleLength & 0x8000) != 0;
ptr += 2; ptr += 2;
@ -34,7 +32,7 @@ class LZW2 extends LZW
if (rleLength == 0) if (rleLength == 0)
rleLength = TRACK_LENGTH; rleLength = TRACK_LENGTH;
int chunkLength = Utility.getWord (buffer, ptr); int chunkLength = LZW.getWord (buffer, ptr);
ptr += 2; ptr += 2;
setBuffer (buffer, ptr); // prepare to read n-bit integers setBuffer (buffer, ptr); // prepare to read n-bit integers

View File

@ -7,8 +7,6 @@ import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.bytezone.common.Utility;
public class NuFX public class NuFX
{ {
private static String[] fileSystems = private static String[] fileSystems =
@ -131,12 +129,12 @@ public class NuFX
throw new FileFormatException ("NuFile not found"); throw new FileFormatException ("NuFile not found");
} }
crc = Utility.getWord (buffer, ptr + 6); crc = LZW.getWord (buffer, ptr + 6);
totalRecords = Utility.getLong (buffer, ptr + 8); totalRecords = LZW.getLong (buffer, ptr + 8);
created = new DateTime (buffer, ptr + 12); created = new DateTime (buffer, ptr + 12);
modified = new DateTime (buffer, ptr + 20); modified = new DateTime (buffer, ptr + 20);
version = Utility.getWord (buffer, ptr + 28); version = LZW.getWord (buffer, ptr + 28);
eof = Utility.getLong (buffer, ptr + 38); eof = LZW.getLong (buffer, ptr + 38);
byte[] crcBuffer = new byte[40]; byte[] crcBuffer = new byte[40];
System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length); System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length);
@ -205,21 +203,21 @@ public class NuFX
if (!isNuFX (buffer, dataPtr)) if (!isNuFX (buffer, dataPtr))
throw new FileFormatException ("NuFX not found"); throw new FileFormatException ("NuFX not found");
crc = Utility.getWord (buffer, dataPtr + 4); crc = LZW.getWord (buffer, dataPtr + 4);
attributes = Utility.getWord (buffer, dataPtr + 6); attributes = LZW.getWord (buffer, dataPtr + 6);
version = Utility.getWord (buffer, dataPtr + 8); version = LZW.getWord (buffer, dataPtr + 8);
totThreads = Utility.getLong (buffer, dataPtr + 10); totThreads = LZW.getLong (buffer, dataPtr + 10);
fileSystemID = Utility.getWord (buffer, dataPtr + 14); fileSystemID = LZW.getWord (buffer, dataPtr + 14);
separator = (char) (buffer[dataPtr + 16] & 0x00FF); separator = (char) (buffer[dataPtr + 16] & 0x00FF);
access = Utility.getLong (buffer, dataPtr + 18); access = LZW.getLong (buffer, dataPtr + 18);
fileType = Utility.getLong (buffer, dataPtr + 22); fileType = LZW.getLong (buffer, dataPtr + 22);
auxType = Utility.getLong (buffer, dataPtr + 26); auxType = LZW.getLong (buffer, dataPtr + 26);
storType = Utility.getWord (buffer, dataPtr + 30); storType = LZW.getWord (buffer, dataPtr + 30);
created = new DateTime (buffer, dataPtr + 32); created = new DateTime (buffer, dataPtr + 32);
modified = new DateTime (buffer, dataPtr + 40); modified = new DateTime (buffer, dataPtr + 40);
archived = new DateTime (buffer, dataPtr + 48); archived = new DateTime (buffer, dataPtr + 48);
optionSize = Utility.getWord (buffer, dataPtr + 56); optionSize = LZW.getWord (buffer, dataPtr + 56);
fileNameLength = Utility.getWord (buffer, dataPtr + attributes - 2); fileNameLength = LZW.getWord (buffer, dataPtr + attributes - 2);
int len = attributes + fileNameLength - 6; int len = attributes + fileNameLength - 6;
byte[] crcBuffer = new byte[len + totThreads * 16]; byte[] crcBuffer = new byte[len + totThreads * 16];

View File

@ -1,18 +1,16 @@
package com.bytezone.diskbrowser.utilities; package com.bytezone.diskbrowser.utilities;
import com.bytezone.common.Utility;
class Thread class Thread
{ {
private static String[] threadClassText = { "Message", "Control", "Data", "Filename" }; private static String[] threadClassText = { "Message", "Control", "Data", "Filename" };
private static String[] formatText = { // private static String[] formatText =
"Uncompressed", "Huffman squeeze", "LZW/1", "LZW/2", "Unix 12-bit Compress", { "Uncompressed", "Huffman squeeze", "LZW/1", "LZW/2", "Unix 12-bit Compress",
"Unix 16-bit Compress" }; "Unix 16-bit Compress" };
private static String[][] threadKindText = {// private static String[][] threadKindText =
{ "ASCII text", "predefined EOF", "IIgs icon" }, { { "ASCII text", "predefined EOF", "IIgs icon" },
{ "create directory", "undefined", "undefined" }, { "create directory", "undefined", "undefined" },
{ "data fork", "disk image", "resource fork" }, { "data fork", "disk image", "resource fork" },
{ "filename", "undefined", "undefined" } }; { "filename", "undefined", "undefined" } };
private final ThreadHeader header; private final ThreadHeader header;
private final byte[] data; private final byte[] data;
@ -106,13 +104,12 @@ class Thread
public ThreadHeader (byte[] buffer, int offset) public ThreadHeader (byte[] buffer, int offset)
{ {
threadClass = Utility.getWord (buffer, offset); threadClass = LZW.getWord (buffer, offset);
format = Utility.getWord (buffer, offset + 2); format = LZW.getWord (buffer, offset + 2);
threadKind = Utility.getWord (buffer, offset + 4); threadKind = LZW.getWord (buffer, offset + 4);
crc = Utility.getWord (buffer, offset + 6); crc = LZW.getWord (buffer, offset + 6);
uncompressedEOF = Utility.getLong (buffer, offset + 8); uncompressedEOF = LZW.getLong (buffer, offset + 8);
compressedEOF = Utility.getLong (buffer, offset + 12); compressedEOF = LZW.getLong (buffer, offset + 12);
// System.out.println (Utility.toHex (buffer, offset, 16));
} }
@Override @Override
@ -121,15 +118,15 @@ class Thread
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append (String.format (" threadClass ....... %d %s%n", threadClass, text.append (String.format (" threadClass ....... %d %s%n", threadClass,
threadClassText[threadClass])); threadClassText[threadClass]));
text.append (String text.append (
.format (" format ............ %d %s%n", format, formatText[format])); String.format (" format ............ %d %s%n", format, formatText[format]));
text.append (String.format (" kind .............. %d %s%n", threadKind, text.append (String.format (" kind .............. %d %s%n", threadKind,
threadKindText[threadClass][threadKind])); threadKindText[threadClass][threadKind]));
text.append (String.format (" crc ............... %,d%n", crc)); text.append (String.format (" crc ............... %,d%n", crc));
text.append (String.format (" uncompressedEOF ... %,d%n", uncompressedEOF)); text.append (String.format (" uncompressedEOF ... %,d%n", uncompressedEOF));
text.append (String.format (" compressedEOF ..... %,d (%08X)", compressedEOF, text.append (String.format (" compressedEOF ..... %,d (%08X)", compressedEOF,
compressedEOF)); compressedEOF));
return text.toString (); return text.toString ();
} }
} }