dmolony-DiskBrowser/src/com/bytezone/diskbrowser/utilities/Record.java

278 lines
9.8 KiB
Java
Raw Normal View History

2021-03-29 01:04:01 +00:00
package com.bytezone.diskbrowser.utilities;
2021-04-17 02:14:06 +00:00
import java.time.LocalDateTime;
2021-04-15 07:27:20 +00:00
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.prodos.ProdosConstants;
2021-03-29 01:04:01 +00:00
// -----------------------------------------------------------------------------------//
class Record
// -----------------------------------------------------------------------------------//
{
2021-04-15 07:27:20 +00:00
private static final byte[] NuFX = { 0x4E, (byte) 0xF5, 0x46, (byte) 0xD8 };
2021-03-29 01:04:01 +00:00
private static String[] fileSystems =
{ "", "ProDOS/SOS", "DOS 3.3", "DOS 3.2", "Apple II Pascal", "Macintosh HFS",
"Macintosh MFS", "Lisa File System", "Apple CP/M", "", "MS-DOS", "High Sierra",
"ISO 9660", "AppleShare" };
2021-04-15 07:27:20 +00:00
private static String[] storage = { "", "Seedling", "Sapling", "Tree", "", "Extended",
"", "", "", "", "", "", "", "Subdirectory" };
private static String[] accessChars = { "D", "R", "B", "", "", "I", "W", "R" };
2021-03-29 01:04:01 +00:00
private final int totThreads;
private final int crc;
private final char separator;
private final int fileSystemID;
private final int attributes;
private final int version;
private final int access;
private final int fileType;
private final int auxType;
private final int storType;
private final DateTime created;
private final DateTime modified;
private final DateTime archived;
private final int optionSize;
private final int fileNameLength;
private final String fileName;
2021-04-15 07:27:20 +00:00
final List<Thread> threads = new ArrayList<> ();
2021-03-29 01:04:01 +00:00
// ---------------------------------------------------------------------------------//
public Record (byte[] buffer, int dataPtr) throws FileFormatException
// ---------------------------------------------------------------------------------//
{
// check for NuFX
2021-04-15 07:27:20 +00:00
if (!Utility.isMagic (buffer, dataPtr, NuFX))
2021-03-29 01:04:01 +00:00
throw new FileFormatException ("NuFX not found");
crc = Utility.getWord (buffer, dataPtr + 4);
attributes = Utility.getWord (buffer, dataPtr + 6);
version = Utility.getWord (buffer, dataPtr + 8);
totThreads = Utility.getLong (buffer, dataPtr + 10);
fileSystemID = Utility.getWord (buffer, dataPtr + 14);
separator = (char) (buffer[dataPtr + 16] & 0x00FF);
access = Utility.getLong (buffer, dataPtr + 18);
fileType = Utility.getLong (buffer, dataPtr + 22);
auxType = Utility.getLong (buffer, dataPtr + 26);
storType = Utility.getWord (buffer, dataPtr + 30);
created = new DateTime (buffer, dataPtr + 32);
modified = new DateTime (buffer, dataPtr + 40);
archived = new DateTime (buffer, dataPtr + 48);
optionSize = Utility.getWord (buffer, dataPtr + 56);
fileNameLength = Utility.getWord (buffer, dataPtr + attributes - 2);
int len = attributes + fileNameLength - 6;
byte[] crcBuffer = new byte[len + totThreads * 16];
System.arraycopy (buffer, dataPtr + 6, crcBuffer, 0, crcBuffer.length);
2021-04-17 04:41:36 +00:00
if (crc != Utility.getCRC (crcBuffer, crcBuffer.length, 0))
2021-03-29 01:04:01 +00:00
{
2021-04-18 10:11:26 +00:00
System.out.println ("***** Record CRC mismatch *****");
throw new FileFormatException ("Record CRC failed");
2021-03-29 01:04:01 +00:00
}
if (fileNameLength > 0)
{
int start = dataPtr + attributes;
int end = start + fileNameLength;
for (int i = start; i < end; i++)
buffer[i] &= 0x7F;
fileName = new String (buffer, start, fileNameLength);
}
else
fileName = "";
}
// ---------------------------------------------------------------------------------//
int getAttributes ()
// ---------------------------------------------------------------------------------//
{
return attributes;
}
// ---------------------------------------------------------------------------------//
int getFileNameLength ()
// ---------------------------------------------------------------------------------//
{
return fileNameLength;
}
// ---------------------------------------------------------------------------------//
int getTotalThreads ()
// ---------------------------------------------------------------------------------//
{
return totThreads;
}
2021-04-15 07:27:20 +00:00
// ---------------------------------------------------------------------------------//
boolean hasDisk ()
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasDisk ())
return true;
return false;
}
// ---------------------------------------------------------------------------------//
boolean hasFile ()
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasFile ())
return true;
return false;
}
// ---------------------------------------------------------------------------------//
boolean hasFile (String fileName)
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasFile (fileName))
return true;
return false;
}
// ---------------------------------------------------------------------------------//
String getFileName ()
// ---------------------------------------------------------------------------------//
{
2021-04-26 00:03:43 +00:00
if (fileNameLength > 0) // probably version 0
return fileName;
2021-04-15 07:27:20 +00:00
for (Thread thread : threads)
if (thread.hasFileName ())
2021-04-17 02:14:06 +00:00
{
String fileName = thread.getFileName ();
if (separator != '/')
return fileName.replace (separator, '/');
2021-04-15 07:27:20 +00:00
return thread.getFileName ();
2021-04-17 02:14:06 +00:00
}
2021-04-15 07:27:20 +00:00
return "";
}
// ---------------------------------------------------------------------------------//
int getFileType ()
// ---------------------------------------------------------------------------------//
{
return fileType;
}
2021-04-17 02:14:06 +00:00
// ---------------------------------------------------------------------------------//
int getAuxType ()
// ---------------------------------------------------------------------------------//
{
return auxType;
}
// ---------------------------------------------------------------------------------//
LocalDateTime getCreated ()
// ---------------------------------------------------------------------------------//
{
if (created == null)
return null;
return created.getLocalDateTime ();
}
// ---------------------------------------------------------------------------------//
LocalDateTime getModified ()
// ---------------------------------------------------------------------------------//
{
if (modified == null)
return null;
return modified.getLocalDateTime ();
}
2021-04-17 21:32:03 +00:00
// ---------------------------------------------------------------------------------//
int getFileSystemID ()
// ---------------------------------------------------------------------------------//
{
return fileSystemID;
}
2021-04-15 07:27:20 +00:00
// ---------------------------------------------------------------------------------//
int getFileSize ()
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasFile ())
return thread.getFileSize ();
return 0;
}
// ---------------------------------------------------------------------------------//
int getUncompressedSize ()
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasFile ())
return thread.getUncompressedEOF ();
return 0;
}
2021-03-29 01:04:01 +00:00
// ---------------------------------------------------------------------------------//
2021-04-16 11:08:59 +00:00
byte[] getData ()
// ---------------------------------------------------------------------------------//
{
for (Thread thread : threads)
if (thread.hasFile ())
return thread.getData ();
return null;
}
// ---------------------------------------------------------------------------------//
2021-03-29 01:04:01 +00:00
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
2021-04-15 07:27:20 +00:00
String bits = "00000000" + Integer.toBinaryString (access & 0xFF);
bits = bits.substring (bits.length () - 8);
String decode = Utility.matchFlags (access, accessChars);
2021-04-17 02:14:06 +00:00
text.append (String.format ("Header CRC ..... %,d (%<04X)%n", crc));
2021-03-29 01:04:01 +00:00
text.append (String.format ("Attributes ..... %d%n", attributes));
text.append (String.format ("Version ........ %d%n", version));
text.append (String.format ("Threads ........ %d%n", totThreads));
text.append (String.format ("File sys id .... %d (%s)%n", fileSystemID,
fileSystems[fileSystemID]));
text.append (String.format ("Separator ...... %s%n", separator));
2021-04-15 07:27:20 +00:00
text.append (String.format ("Access ......... %s %s%n", bits, decode));
2021-04-18 10:11:26 +00:00
2021-04-15 07:27:20 +00:00
if (storType < 16)
{
2021-04-17 04:41:36 +00:00
text.append (String.format ("File type ...... %02X %s%n", fileType,
2021-04-15 07:27:20 +00:00
ProdosConstants.fileTypes[fileType]));
2021-04-17 04:41:36 +00:00
text.append (String.format ("Aux type ....... %,d $%<04X%n", auxType));
2021-04-15 07:27:20 +00:00
text.append (
String.format ("Stor type ...... %,d %s%n", storType, storage[storType]));
}
else
{
text.append (String.format ("Zero ........... %,d%n", fileType));
text.append (String.format ("Total blocks ... %,d%n", auxType));
text.append (String.format ("Block size ..... %,d%n", storType));
}
2021-04-18 10:11:26 +00:00
2021-03-29 01:04:01 +00:00
text.append (String.format ("Created ........ %s%n", created.format ()));
text.append (String.format ("Modified ....... %s%n", modified.format ()));
text.append (String.format ("Archived ....... %s%n", archived.format ()));
text.append (String.format ("Option size .... %,d%n", optionSize));
text.append (String.format ("Filename len ... %,d%n", fileNameLength));
text.append (String.format ("Filename ....... %s", fileName));
return text.toString ();
}
}