2015-06-01 09:35:51 +00:00
|
|
|
package com.bytezone.diskbrowser.disk;
|
|
|
|
|
2016-02-20 09:48:47 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2015-06-01 09:35:51 +00:00
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.nio.file.Paths;
|
|
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
|
|
|
|
import com.bytezone.diskbrowser.cpm.CPMDisk;
|
|
|
|
import com.bytezone.diskbrowser.dos.DosDisk;
|
|
|
|
import com.bytezone.diskbrowser.infocom.InfocomDisk;
|
|
|
|
import com.bytezone.diskbrowser.pascal.PascalDisk;
|
|
|
|
import com.bytezone.diskbrowser.prodos.ProdosDisk;
|
2016-02-24 21:11:14 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
|
|
|
import com.bytezone.diskbrowser.utilities.NuFX;
|
2015-06-01 09:35:51 +00:00
|
|
|
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
|
|
|
|
|
|
|
|
public class DiskFactory
|
|
|
|
{
|
2016-02-25 07:45:24 +00:00
|
|
|
private static boolean debug = false;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
private DiskFactory ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public static FormattedDisk createDisk (File file)
|
|
|
|
{
|
|
|
|
return createDisk (file.getAbsolutePath ());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static FormattedDisk createDisk (String path)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Factory : " + path);
|
|
|
|
|
|
|
|
File file = new File (path);
|
|
|
|
if (!file.exists ())
|
|
|
|
return null;
|
|
|
|
|
|
|
|
String suffix = path.substring (path.lastIndexOf (".") + 1).toLowerCase ();
|
|
|
|
Boolean compressed = false;
|
|
|
|
Path p = Paths.get (path);
|
|
|
|
|
2016-02-28 05:41:10 +00:00
|
|
|
if (suffix.equals ("sdk"))
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
NuFX nuFX = new NuFX (p);
|
|
|
|
File tmp = File.createTempFile ("sdk", null);
|
|
|
|
FileOutputStream fos = new FileOutputStream (tmp);
|
|
|
|
fos.write (nuFX.getBuffer ());
|
|
|
|
fos.close ();
|
|
|
|
tmp.deleteOnExit ();
|
|
|
|
file = tmp;
|
|
|
|
suffix = "dsk";
|
|
|
|
compressed = true;
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
catch (FileFormatException e)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2016-02-28 05:41:10 +00:00
|
|
|
else if (suffix.equals ("gz")) // will be .dsk.gz
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
InputStream in = new GZIPInputStream (new FileInputStream (path));
|
|
|
|
File tmp = File.createTempFile ("gzip", null);
|
|
|
|
FileOutputStream fos = new FileOutputStream (tmp);
|
|
|
|
|
|
|
|
int bytesRead;
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
while ((bytesRead = in.read (buffer)) > 0)
|
|
|
|
fos.write (buffer, 0, bytesRead);
|
|
|
|
|
|
|
|
fos.close ();
|
|
|
|
in.close ();
|
|
|
|
tmp.deleteOnExit ();
|
|
|
|
file = tmp;
|
|
|
|
suffix = "dsk";
|
|
|
|
compressed = true;
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FormattedDisk disk = null;
|
|
|
|
FormattedDisk disk2 = null;
|
|
|
|
|
|
|
|
if (suffix.equals ("hdv"))
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
|
|
|
ProdosDisk prodosDisk = checkHardDisk (file);
|
|
|
|
if (prodosDisk != null)
|
|
|
|
return prodosDisk;
|
|
|
|
|
|
|
|
disk2 = check2mgDisk (file);
|
|
|
|
if (disk2 != null)
|
|
|
|
return disk2;
|
|
|
|
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (suffix.equals ("2mg"))
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
|
|
|
disk2 = check2mgDisk (file);
|
|
|
|
if (disk2 != null)
|
|
|
|
return disk2;
|
|
|
|
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (((suffix.equals ("po") || suffix.equals ("dsk")) && file.length () > 143360))
|
|
|
|
{
|
2016-03-01 00:16:31 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking po or dsk hard drive: " + file.length ());
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
disk = checkHardDisk (file);
|
|
|
|
if (disk != null)
|
|
|
|
{
|
|
|
|
if (compressed)
|
|
|
|
disk.setOriginalPath (p);
|
|
|
|
return disk;
|
|
|
|
}
|
2016-03-01 00:16:31 +00:00
|
|
|
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Creating a data disk from bad length");
|
|
|
|
try
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
2016-03-01 00:16:31 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println ("created");
|
2016-02-24 02:13:52 +00:00
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2016-03-01 00:16:31 +00:00
|
|
|
catch (FileFormatException e)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Creating AppleDisk failed");
|
|
|
|
return null;
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long length = file.length ();
|
|
|
|
if (length != 143360 && length != 116480)
|
|
|
|
{
|
2016-02-20 09:48:47 +00:00
|
|
|
System.out.printf ("%s: invalid file length : %,d%n", file.getName (),
|
|
|
|
file.length ());
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sectors = file.length () == 143360 ? 16 : 13;
|
|
|
|
if (true)
|
|
|
|
{
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, 35, sectors);
|
|
|
|
long checksum = appleDisk.getBootChecksum ();
|
|
|
|
|
|
|
|
if (checksum == 3176296590L || checksum == 108825457L || checksum == 1439356606L
|
2016-02-20 09:48:47 +00:00
|
|
|
|| checksum == 1550012074L || checksum == 1614602459L || checksum == 940889336L
|
|
|
|
|| checksum == 990032697 || checksum == 2936955085L || checksum == 1348415927L
|
|
|
|
|| checksum == 3340889101L || checksum == 18315788L || checksum == 993895235L)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
disk = checkDos (file);
|
|
|
|
disk2 = checkProdos (file);
|
|
|
|
if (disk2 != null && disk != null)
|
|
|
|
disk = new DualDosDisk (disk, disk2);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (checksum == 1737448647L || checksum == 170399908L)
|
|
|
|
{
|
|
|
|
disk = checkProdos (file);
|
|
|
|
disk2 = checkDos (file);
|
|
|
|
if (disk2 != null && disk != null)
|
|
|
|
disk = new DualDosDisk (disk, disk2);
|
|
|
|
}
|
|
|
|
|
2016-02-20 09:48:47 +00:00
|
|
|
else if (checksum == 2803644711L || checksum == 3317783349L
|
|
|
|
|| checksum == 1728863694L || checksum == 198094178L)
|
2015-06-01 09:35:51 +00:00
|
|
|
disk = checkPascalDisk (file);
|
|
|
|
|
|
|
|
else if (checksum == 3028642627L || checksum == 2070151659L)
|
|
|
|
disk = checkInfocomDisk (file);
|
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
// else if (checksum == 1212926910L || checksum == 1365043894L
|
|
|
|
// || checksum == 2128073918L)
|
|
|
|
// disk = checkCPMDisk (file);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 09:48:09 +00:00
|
|
|
// System.out.println (checksum);
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk != null)
|
|
|
|
{
|
|
|
|
if (compressed)
|
|
|
|
disk.setOriginalPath (p);
|
|
|
|
return disk;
|
|
|
|
}
|
|
|
|
|
|
|
|
// empty boot sector
|
|
|
|
if (checksum != 227968344L && false)
|
|
|
|
System.out.println ("Unknown checksum : " + checksum + " : " + path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (suffix.equals ("dsk") || suffix.equals ("do") || suffix.equals ("d13"))
|
|
|
|
{
|
|
|
|
disk = checkDos (file);
|
|
|
|
if (disk == null)
|
|
|
|
disk = checkProdos (file);
|
|
|
|
else if (sectors == 16)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking DualDos disk");
|
|
|
|
disk2 = checkProdos (file);
|
|
|
|
if (disk2 != null)
|
|
|
|
disk = new DualDosDisk (disk, disk2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (suffix.equals ("po"))
|
|
|
|
{
|
|
|
|
disk = checkProdos (file);
|
|
|
|
if (disk == null)
|
|
|
|
disk = checkDos (file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (disk == null)
|
|
|
|
disk = checkPascalDisk (file);
|
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
if (disk == null)
|
|
|
|
disk = checkCPMDisk (file);
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk == null)
|
|
|
|
{
|
|
|
|
disk2 = checkInfocomDisk (file);
|
|
|
|
if (disk2 != null)
|
|
|
|
disk = disk2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (disk == null)
|
|
|
|
disk = new DataDisk (new AppleDisk (file, 35, 16));
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" Factory creating disk : "
|
2016-02-20 09:48:47 +00:00
|
|
|
+ disk.getDisk ().getFile ().getAbsolutePath ());
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (disk != null && compressed)
|
|
|
|
disk.setOriginalPath (p);
|
|
|
|
|
|
|
|
return disk;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static DosDisk checkDos (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking DOS disk");
|
|
|
|
try
|
|
|
|
{
|
|
|
|
int sectors = file.length () == 143360 ? 16 : 13;
|
|
|
|
AppleDisk disk = new AppleDisk (file, 35, sectors);
|
|
|
|
if (DosDisk.isCorrectFormat (disk))
|
|
|
|
return new DosDisk (disk);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a DOS disk");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ProdosDisk checkProdos (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Prodos disk");
|
2016-02-28 05:41:10 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
AppleDisk disk = new AppleDisk (file, 35, 8);
|
|
|
|
if (ProdosDisk.isCorrectFormat (disk))
|
|
|
|
return new ProdosDisk (disk);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a Prodos disk");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ProdosDisk checkHardDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
System.out.println ("\nChecking Prodos hard disk");
|
|
|
|
System.out.printf ("Total blocks : %f%n", (float) file.length () / 512);
|
|
|
|
System.out.printf ("Total tracks : %f%n", (float) file.length () / 4096);
|
|
|
|
System.out.printf ("File length : %d%n", file.length ());
|
|
|
|
System.out.println ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// assumes a sector is 512 bytes
|
|
|
|
if ((file.length () % 512) != 0)
|
|
|
|
{
|
|
|
|
if (debug)
|
2016-03-01 00:16:31 +00:00
|
|
|
System.out.printf ("file length not divisible by 512 : %,d%n%n", file.length ());
|
|
|
|
return null;
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// assumes a track is 4096 bytes
|
2016-03-01 07:38:20 +00:00
|
|
|
// if ((file.length () % 4096) != 0)
|
|
|
|
// {
|
|
|
|
// if (debug)
|
|
|
|
// System.out.printf ("file length not divisible by 4096 : %d%n%n", file.length ());
|
|
|
|
// return null;
|
|
|
|
// }
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2016-03-01 07:38:20 +00:00
|
|
|
// truncate the file if necessary
|
2015-06-01 09:35:51 +00:00
|
|
|
AppleDisk disk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
if (ProdosDisk.isCorrectFormat (disk))
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
System.out.println ("Yay, it's a prodos hard disk");
|
|
|
|
System.out.println (disk);
|
|
|
|
}
|
|
|
|
return new ProdosDisk (disk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debug)
|
2016-02-24 02:13:52 +00:00
|
|
|
System.out.println ("Not a Prodos hard disk\n");
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static FormattedDisk check2mgDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Prodos 2mg disk");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
AppleDisk disk = new AppleDisk (file, 0, 0);
|
|
|
|
if (ProdosDisk.isCorrectFormat (disk))
|
|
|
|
return new ProdosDisk (disk);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a Prodos 2mg disk");
|
2016-02-24 02:13:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static FormattedDisk checkPascalDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Pascal disk");
|
|
|
|
AppleDisk disk = new AppleDisk (file, 35, 8);
|
|
|
|
if (!PascalDisk.isCorrectFormat (disk, debug))
|
|
|
|
return null;
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Pascal disk OK - Checking Wizardry disk");
|
|
|
|
if (WizardryScenarioDisk.isWizardryFormat (disk, debug))
|
|
|
|
return new WizardryScenarioDisk (disk);
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a Wizardry disk");
|
|
|
|
return new PascalDisk (disk);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static InfocomDisk checkInfocomDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Infocom disk");
|
|
|
|
AppleDisk disk = new AppleDisk (file, 35, 16);
|
|
|
|
if (InfocomDisk.isCorrectFormat (disk))
|
|
|
|
return new InfocomDisk (disk);
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not an InfocomDisk disk");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static CPMDisk checkCPMDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking CPM disk");
|
|
|
|
AppleDisk disk = new AppleDisk (file, 35, 16);
|
|
|
|
if (CPMDisk.isCorrectFormat (disk))
|
|
|
|
return new CPMDisk (disk);
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a CPM disk");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|