dmolony-DiskBrowser/src/com/bytezone/diskbrowser/prodos/ProdosDirectory.java

145 lines
5.7 KiB
Java
Raw Normal View History

2015-06-01 09:35:51 +00:00
package com.bytezone.diskbrowser.prodos;
2019-11-03 05:49:01 +00:00
import java.text.SimpleDateFormat;
2015-06-01 09:35:51 +00:00
import java.util.GregorianCalendar;
import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.disk.FormattedDisk;
2016-02-24 21:11:14 +00:00
import com.bytezone.diskbrowser.utilities.HexFormatter;
2015-06-01 09:35:51 +00:00
2019-11-03 05:49:01 +00:00
// -----------------------------------------------------------------------------------//
2018-07-28 12:00:02 +00:00
class ProdosDirectory extends AbstractFile implements ProdosConstants
2019-11-03 05:49:01 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
private static final String NO_DATE = "<NO DATE>";
private static final String newLine = String.format ("%n");
private static final String newLine2 = newLine + newLine;
2019-11-03 05:49:01 +00:00
private static final SimpleDateFormat sdf = new SimpleDateFormat ("d-MMM-yy");
private static final SimpleDateFormat stf = new SimpleDateFormat ("H:mm");
2015-06-01 09:35:51 +00:00
2016-03-24 00:17:09 +00:00
private final ProdosDisk parentFD;
2015-06-01 09:35:51 +00:00
private final int totalBlocks;
private final int freeBlocks;
private final int usedBlocks;
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2016-02-28 07:17:58 +00:00
public ProdosDirectory (FormattedDisk parent, String name, byte[] buffer,
int totalBlocks, int freeBlocks, int usedBlocks)
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
super (name, buffer);
2016-02-28 07:17:58 +00:00
2016-03-24 00:17:09 +00:00
this.parentFD = (ProdosDisk) parent;
2015-06-01 09:35:51 +00:00
this.totalBlocks = totalBlocks;
this.freeBlocks = freeBlocks;
this.usedBlocks = usedBlocks;
}
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
@Override
public String getText ()
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
StringBuffer text = new StringBuffer ();
2019-01-26 20:06:13 +00:00
text.append ("Disk : " + parentFD.getDisplayPath () + newLine2);
2015-06-01 09:35:51 +00:00
for (int i = 0; i < buffer.length; i += 39)
{
int storageType = (buffer[i] & 0xF0) >> 4;
if (storageType == 0)
2016-02-28 07:17:58 +00:00
continue; // break??
2015-06-01 09:35:51 +00:00
int nameLength = buffer[i] & 0x0F;
String filename = HexFormatter.getString (buffer, i + 1, nameLength);
String subType = "";
String locked;
switch (storageType)
{
2017-05-12 10:42:20 +00:00
case ProdosConstants.VOLUME_HEADER:
case ProdosConstants.SUBDIRECTORY_HEADER:
2015-06-01 09:35:51 +00:00
text.append ("/" + filename + newLine2);
text.append (" NAME TYPE BLOCKS "
2016-02-28 07:17:58 +00:00
+ "MODIFIED CREATED ENDFILE SUBTYPE" + newLine2);
2015-06-01 09:35:51 +00:00
break;
2016-02-28 07:17:58 +00:00
2017-05-12 10:42:20 +00:00
case ProdosConstants.FREE:
case ProdosConstants.SEEDLING:
case ProdosConstants.SAPLING:
case ProdosConstants.TREE:
case ProdosConstants.PASCAL_ON_PROFILE:
case ProdosConstants.GSOS_EXTENDED_FILE:
case ProdosConstants.SUBDIRECTORY:
2016-12-17 22:07:55 +00:00
int type = buffer[i + 16] & 0xFF;
2015-06-01 09:35:51 +00:00
int blocks = HexFormatter.intValue (buffer[i + 19], buffer[i + 20]);
GregorianCalendar created = HexFormatter.getAppleDate (buffer, i + 24);
2016-02-28 07:17:58 +00:00
String dateC = created == null ? NO_DATE
2019-11-03 05:49:01 +00:00
: sdf.format (created.getTime ()).toUpperCase ().replace (".", "");
String timeC = created == null ? "" : stf.format (created.getTime ());
2015-06-01 09:35:51 +00:00
GregorianCalendar modified = HexFormatter.getAppleDate (buffer, i + 33);
2019-11-03 05:49:01 +00:00
String dateM = modified == null ? NO_DATE
: sdf.format (modified.getTime ()).toUpperCase ().replace (".", "");
String timeM = modified == null ? "" : stf.format (modified.getTime ());
2016-02-28 07:17:58 +00:00
int eof =
HexFormatter.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]);
2016-12-17 22:07:55 +00:00
int fileType = buffer[i + 16] & 0xFF;
2015-06-01 09:35:51 +00:00
locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*";
switch (fileType)
{
2018-07-28 12:00:02 +00:00
case FILE_TYPE_TEXT:
2015-06-01 09:35:51 +00:00
int aux = HexFormatter.intValue (buffer[i + 31], buffer[i + 32]);
subType = String.format ("R=%5d", aux);
break;
2017-04-11 21:48:08 +00:00
2018-07-28 12:00:02 +00:00
case FILE_TYPE_BINARY:
case FILE_TYPE_PNT:
case FILE_TYPE_PIC:
2018-08-15 02:32:11 +00:00
case FILE_TYPE_FOT:
2015-06-01 09:35:51 +00:00
aux = HexFormatter.intValue (buffer[i + 31], buffer[i + 32]);
subType = String.format ("A=$%4X", aux);
break;
2017-04-11 21:48:08 +00:00
2018-08-15 02:32:11 +00:00
case FILE_TYPE_AWP:
2015-06-01 09:35:51 +00:00
aux = HexFormatter.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
if (aux != 0)
filename = convert (filename, aux);
break;
2017-04-11 21:48:08 +00:00
2015-06-01 09:35:51 +00:00
default:
subType = "";
}
2016-02-28 07:17:58 +00:00
text.append (String.format ("%s%-15s %3s %5d %9s %5s %9s %5s %8d %7s%n",
2016-12-17 22:07:55 +00:00
locked, filename, ProdosConstants.fileTypes[type], blocks, dateM, timeM,
dateC, timeC, eof, subType));
2015-06-01 09:35:51 +00:00
break;
2016-02-28 07:17:58 +00:00
2015-06-01 09:35:51 +00:00
default:
text.append (" <Unknown strage type : " + storageType + newLine);
}
}
2016-12-17 22:07:55 +00:00
text.append (
String.format ("%nBLOCKS FREE:%5d BLOCKS USED:%5d TOTAL BLOCKS:%5d%n",
freeBlocks, usedBlocks, totalBlocks));
2015-06-01 09:35:51 +00:00
return text.toString ();
}
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
private String convert (String name, int flags)
2019-11-03 05:49:01 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
char[] newName = name.toCharArray ();
for (int i = 0, weight = 0x8000; i < newName.length; i++, weight >>>= 1)
{
if ((flags & weight) != 0)
{
if (newName[i] == '.')
newName[i] = ' ';
else if (newName[i] >= 'A' && newName[i] <= 'Z')
newName[i] += 32;
}
}
return new String (newName);
}
}