package com.bytezone.diskbrowser.applefile; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; import com.bytezone.diskbrowser.disk.FormattedDisk; import com.bytezone.diskbrowser.prodos.DirectoryHeader; import com.bytezone.diskbrowser.prodos.ProdosConstants; import com.bytezone.diskbrowser.prodos.ProdosDisk; import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.Utility; // -----------------------------------------------------------------------------------// public class ProdosDirectory extends AbstractFile implements ProdosConstants // -----------------------------------------------------------------------------------// { private static Locale US = Locale.US; // to force 3 character months static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy", US); static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm"); static final String UNDERLINE = "----------------------------------------------------\n"; private static final String NO_DATE = ""; private final ProdosDisk parentFD; private final int totalBlocks; private final int freeBlocks; private final int usedBlocks; // ---------------------------------------------------------------------------------// public ProdosDirectory (FormattedDisk parent, String name, byte[] buffer, int totalBlocks, int freeBlocks, int usedBlocks) // ---------------------------------------------------------------------------------// { super (name, buffer); this.parentFD = (ProdosDisk) parent; this.totalBlocks = totalBlocks; this.freeBlocks = freeBlocks; this.usedBlocks = usedBlocks; } // ---------------------------------------------------------------------------------// @Override public String getText () // ---------------------------------------------------------------------------------// { if (showDebugText) return getDebugText (); else return getDirectoryText (); } // ---------------------------------------------------------------------------------// private String getDebugText () // ---------------------------------------------------------------------------------// { List directoryHeaders = parentFD.getDirectoryHeaders (); StringBuilder text = new StringBuilder (); for (DirectoryHeader directoryHeader : directoryHeaders) { text.append (UNDERLINE); text.append (directoryHeader.getText ()); text.append ("\n"); text.append (UNDERLINE); directoryHeader.listFileEntries (text); } return text.toString (); } // ---------------------------------------------------------------------------------// private String getDirectoryText () // ---------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); text.append ("File : " + parentFD.getDisplayPath () + "\n\n"); for (int i = 0; i < buffer.length; i += ENTRY_SIZE) { int storageType = (buffer[i] & 0xF0) >> 4; if (storageType == 0) continue; // break?? int nameLength = buffer[i] & 0x0F; String filename = HexFormatter.getString (buffer, i + 1, nameLength); String subType = ""; switch (storageType) { case VOLUME_HEADER: case SUBDIRECTORY_HEADER: String root = storageType == VOLUME_HEADER ? "/" : ""; text.append (root + filename + "\n\n"); text.append (" NAME TYPE BLOCKS " + "MODIFIED CREATED ENDFILE SUBTYPE" + "\n\n"); break; case FREE: case SEEDLING: case SAPLING: case TREE: case PASCAL_ON_PROFILE: case GSOS_EXTENDED_FILE: case SUBDIRECTORY: int type = buffer[i + 16] & 0xFF; int blocks = Utility.getShort (buffer, i + 19); LocalDateTime createdDate = Utility.getAppleDate (buffer, i + 24); LocalDateTime modifiedDate = Utility.getAppleDate (buffer, i + 33); String dateC = createdDate == null ? NO_DATE : createdDate.format (df).toUpperCase (); String dateM = modifiedDate == null ? NO_DATE : modifiedDate.format (df).toUpperCase (); String timeC = createdDate == null ? "" : createdDate.format (tf); String timeM = modifiedDate == null ? "" : modifiedDate.format (tf); int eof = Utility.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]); int fileType = buffer[i + 16] & 0xFF; String locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*"; int aux = Utility.getShort (buffer, i + 31); switch (fileType) { case FILE_TYPE_TEXT: subType = String.format ("R=%5d", aux); break; case FILE_TYPE_BINARY: case FILE_TYPE_PNT: case FILE_TYPE_PIC: case FILE_TYPE_FOT: subType = String.format ("A=$%4X", aux); break; case FILE_TYPE_AWP: int flags = Utility.intValue (buffer[i + 32], buffer[i + 31]); // aux backwards! if (flags != 0) filename = convert (filename, flags); break; default: subType = ""; } String forkFlag = storageType == 5 ? "+" : " "; text.append ( String.format ("%s%-15s %3s%s %5d %9s %5s %9s %5s %8d %7s %04X%n", locked, filename, ProdosConstants.fileTypes[type], forkFlag, blocks, dateM, timeM, dateC, timeC, eof, subType, aux)); break; default: text.append (" >>= 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); } }