package com.bytezone.diskbrowser.dos; import com.bytezone.diskbrowser.disk.AppleDiskAddress; import com.bytezone.diskbrowser.disk.DiskAddress; import com.bytezone.diskbrowser.dos.DosDisk.FileType; import com.bytezone.diskbrowser.utilities.Utility; // -----------------------------------------------------------------------------------// class CatalogEntry extends AbstractCatalogEntry // -----------------------------------------------------------------------------------// { private int textFileGaps; private int length; private int address; // ---------------------------------------------------------------------------------// CatalogEntry (DosDisk dosDisk, DiskAddress catalogSector, byte[] entryBuffer) // ---------------------------------------------------------------------------------// { super (dosDisk, catalogSector, entryBuffer); // if (reportedSize > 0 && disk.isValidAddress (entryBuffer[0], entryBuffer[1])) if (disk.isValidAddress (entryBuffer[0], entryBuffer[1])) { // Get address of first TS-list sector DiskAddress da = disk.getDiskAddress (entryBuffer[0], entryBuffer[1]); // Loop through all TS-list sectors loop: while (!da.isZero () || ((AppleDiskAddress) da).zeroFlag ()) { if (dosDisk.stillAvailable (da)) { if (isValidCatalogSector (da)) dosDisk.sectorTypes[da.getBlockNo ()] = dosDisk.tsListSector; else { System.out.printf ("Attempt to assign invalid TS sector " + ": %s from %s%n", da, name); break; } } else { System.out.printf ( "Attempt to assign TS sector to occupied sector " + ": %s from %s%n", da, name); break; } tsSectors.add (da); byte[] sectorBuffer = disk.readBlock (da); int startPtr = 12; // the tsList *should* start at 0xC0, but some disks start in the unused bytes if (false) for (int i = 7; i < startPtr; i++) if (sectorBuffer[i] != 0) { startPtr = i; break; } DiskAddress thisDA = da; for (int i = startPtr, max = disk.getBlockSize (); i < max; i += 2) { da = getValidAddress (sectorBuffer, i); if (da == null) { System.out.printf ( "T/S list at offset %02X contains an invalid address : %02X, %02X (file %s)%n", i, sectorBuffer[i], sectorBuffer[i + 1], name.trim ()); break loop; } if (da.isZero () && !((AppleDiskAddress) da).zeroFlag ()) { if (fileType != FileType.Text) break; ++textFileGaps; dataSectors.add (null); } else { dataSectors.add (da); if (dosDisk.stillAvailable (da)) dosDisk.sectorTypes[da.getBlockNo ()] = dosDisk.dataSector; else { System.out .print ("Attempt to assign Data sector to occupied sector : " + da); System.out.println (" from " + name); } } } da = getValidAddress (sectorBuffer, 1); if (da == null) { System.out.print ("Next T/S list in sector " + thisDA); System.out.printf (" is invalid : %02X, %02X%n", sectorBuffer[1], sectorBuffer[2]); break; } if (thisDA.matches (da) && ((AppleDiskAddress) thisDA) .zeroFlag () == ((AppleDiskAddress) da).zeroFlag ()) { System.out.printf ("Next T/S list in sector %s points to itself%n", thisDA); break; } } } // remove trailing empty sectors if (fileType == FileType.Text) { while (dataSectors.size () > 0) { DiskAddress da = dataSectors.get (dataSectors.size () - 1); if (da == null) { dataSectors.remove (dataSectors.size () - 1); --textFileGaps; } else break; } } else if (dataSectors.size () > 0) // get the file length { byte[] buffer = disk.readBlock (dataSectors.get (0)); switch (fileType) { case IntegerBasic: case ApplesoftBasic: length = Utility.getShort (buffer, 0); break; default: address = Utility.getShort (buffer, 0); length = Utility.getShort (buffer, 2); } } } // ---------------------------------------------------------------------------------// private boolean isValidCatalogSector (DiskAddress da) // ---------------------------------------------------------------------------------// { byte[] buffer = da.readBlock (); if (!da.getDisk ().isValidAddress (buffer[1], buffer[2])) return false; if (buffer[3] != 0 || buffer[4] != 0) // not supposed to be used // Diags2E.dsk stores its own sector address here if (da.getTrackNo () != (buffer[3] & 0xFF) && da.getSectorNo () != (buffer[4] & 0xFF)) return false; return true; } // ---------------------------------------------------------------------------------// String getDetails () // ---------------------------------------------------------------------------------// { int actualSize = dataSectors.size () + tsSectors.size () - textFileGaps; String addressText = address == 0 ? "" : String.format ("$%4X", address); String lengthText = length == 0 ? "" : String.format ("$%4X %,6d", length, length); String message = ""; String lockedFlag = (locked) ? "*" : " "; if (dosDisk.dosVTOCSector.dosVersion >= 0x41) message = lastModified.toString ().replace ('T', ' '); if (reportedSize != actualSize) message += "Actual size (" + actualSize + ") "; // if (dataSectors.size () == 0) // message += "No data "; if (reportedSize > 999) message += "Reported " + reportedSize; String text = String.format ("%1s %1s %03d %-30.30s %-5s %-13s %3d %3d %s", lockedFlag, getFileType (), reportedSize % 1000, displayName, addressText, lengthText, tsSectors.size (), (dataSectors.size () - textFileGaps), message.trim ()); // if (actualSize == 0) // text = text.substring (0, 50); return text; } }