Compare commits
7 Commits
8b88fb85f4
...
b583d4a364
Author | SHA1 | Date |
---|---|---|
Brian J. Bernstein | b583d4a364 | |
Rob Greene | 5cd97c6d35 | |
Rob Greene | a375e25c66 | |
Rob Greene | 1c86c39ed2 | |
Brian J. Bernstein | 88e9d48a5a | |
Brian J. Bernstein | 544d146d5b | |
Brian J. Bernstein | 2d811de210 |
|
@ -119,11 +119,11 @@ public class AntTask extends Task
|
|||
else if (_command.equals("cc65"))
|
||||
{
|
||||
System.err.println("Note: 'cc65' is deprecated. Please use 'as' or 'dos' as appropriate.");
|
||||
com.webcodepro.applecommander.ui.ac.putDOS(_input, _imageName, _fileName, _type);
|
||||
com.webcodepro.applecommander.ui.ac.putDOS(_input, _imageName, _fileName, _type, System.in);
|
||||
}
|
||||
else if (_command.equals("dos"))
|
||||
{
|
||||
com.webcodepro.applecommander.ui.ac.putDOS(_input, _imageName, _fileName, _type);
|
||||
com.webcodepro.applecommander.ui.ac.putDOS(_input, _imageName, _fileName, _type, System.in);
|
||||
}
|
||||
else {
|
||||
com.webcodepro.applecommander.ui.ac.putAppleSingle(_imageName, _fileName,
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -112,82 +113,169 @@ import io.github.applecommander.bastools.api.model.Token;
|
|||
public class ac {
|
||||
private static TextBundle textBundle = UiBundle.getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* Finds the array index of the next operation (e.g. -bas, -ptx, -ll) from the specified
|
||||
* starting point. If there is no further operation found, then a -1 is returned.
|
||||
*
|
||||
* @param args String array of arguments from the command line.
|
||||
* @param startFrom Index to start searching from.
|
||||
* @return Index of the next operation arg, or -1 if the end of the array was hit.
|
||||
*/
|
||||
public static int findNextOperationArg(String[] args, int startFrom) {
|
||||
while (startFrom < args.length) {
|
||||
// we check length>1 to make sure we're differentiating from STDIN '-'
|
||||
if (args[startFrom].startsWith("-") == true && args[startFrom].length() > 1) {
|
||||
return startFrom;
|
||||
}
|
||||
startFrom++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an InputStream handle to either the file specified by arg or STDIN if arg is
|
||||
* null, empty, or simply a '-'.
|
||||
* If a file is specified to arg, then any exceptions that may get raised by attempting to open
|
||||
* the file will simply get passed through since the AC's command line error handling doesn't
|
||||
* really do much other than stacktrace anyway.
|
||||
*
|
||||
* @param arg Either a filename to open or '-' for STDIN.
|
||||
* @return Handle to an InputStream ready to be pulled from.
|
||||
*/
|
||||
public static InputStream stdinOrFile(String arg) {
|
||||
if (arg == null || arg.isEmpty() || arg.equalsIgnoreCase("-")) {
|
||||
return System.in;
|
||||
} else {
|
||||
File f = new File(arg);
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(f);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
help();
|
||||
} else if ("-i".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
getDiskInfo(args);
|
||||
} else if ("-ls".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_STANDARD), args);
|
||||
} else if ("-l".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_NATIVE), args);
|
||||
} else if ("-ll".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_DETAIL), args);
|
||||
} else if ("-lsv".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_STANDARD), args);
|
||||
} else if ("-lv".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_NATIVE), args);
|
||||
} else if ("-llv".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_DETAIL), args);
|
||||
} else if ("-lsj".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_STANDARD), args);
|
||||
} else if ("-lj".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_NATIVE), args);
|
||||
} else if ("-llj".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_DETAIL), args);
|
||||
} else if ("-e".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
getFile(args[1], args[2], true,
|
||||
(args.length > 3 ? new PrintStream(new FileOutputStream(args[3])) : System.out));
|
||||
} else if ("-x".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
getFiles(args[1], (args.length > 2 ? args[2] : ""));
|
||||
} else if ("-g".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
getFile(args[1], args[2], false,
|
||||
(args.length > 3 ? new PrintStream(new FileOutputStream(args[3])) : System.out));
|
||||
} else if ("-p".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
putFile(args[1], new Name(args[2]), args[3],
|
||||
(args.length > 4 ? args[4] : "0x2000"));
|
||||
} else if ("-pt".equalsIgnoreCase(args[0])) {
|
||||
putTxtFileSetHighBit(args[1], new Name(args[2]));
|
||||
} else if ("-ptx".equalsIgnoreCase(args[0])) {
|
||||
putTxtFileClearHighBit(args[1], new Name(args[2]));
|
||||
} else if ("-d".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
deleteFile(args[1], args[2]);
|
||||
} else if ("-k".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
setFileLocked(args[1], args[2], true);
|
||||
} else if ("-u".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
setFileLocked(args[1], args[2], false);
|
||||
} else if ("-n".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
setDiskName(args[1], args[2]);
|
||||
} else if ("-cc65".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
System.err.println("Note: -cc65 is deprecated. Please use -as or -dos as appropriate.");
|
||||
putDOS(args[1], new Name(args[2]), args[3]);
|
||||
} else if ("-dos".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
putDOS(args[1], new Name(args[2]), args[3]);
|
||||
} else if ("-as".equalsIgnoreCase(args[0])) {
|
||||
putAppleSingle(args[1], args.length >= 3 ? args[2] : null);
|
||||
} else if ("-geos".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
putGEOS(args[1]);
|
||||
} else if ("-dos140".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
createDosDisk(args[1], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pas140".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
createPasDisk(args[1], args[2], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pas800".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
createPasDisk(args[1], args[2], Disk.APPLE_800KB_DISK);
|
||||
} else if ("-pro140".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
createProDisk(args[1], args[2], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pro800".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
createProDisk(args[1], args[2], Disk.APPLE_800KB_DISK);
|
||||
} else if ("-convert".equalsIgnoreCase(args[0])) { //$NON-NLS-1$
|
||||
if (args.length > 3)
|
||||
convert(args[1], args[2], Integer.parseInt(args[3]));
|
||||
else
|
||||
convert(args[1], args[2]);
|
||||
} else if ("-bas".equalsIgnoreCase(args[0])) {
|
||||
putAppleSoft(args[1], args[2]);
|
||||
} else {
|
||||
help();
|
||||
}
|
||||
|
||||
int argPtr = 0;
|
||||
while (argPtr < args.length && argPtr > -1) {
|
||||
InputStream inputStream = null;
|
||||
|
||||
int nextArg = findNextOperationArg(args, argPtr + 1);
|
||||
if (nextArg == -1) {
|
||||
nextArg = args.length;
|
||||
}
|
||||
|
||||
String[] trimmedArgs = Arrays.copyOfRange(args, argPtr, nextArg);
|
||||
|
||||
if ("-i".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
getDiskInfo(trimmedArgs);
|
||||
} else if ("-ls".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_STANDARD), trimmedArgs);
|
||||
} else if ("-l".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_NATIVE), trimmedArgs);
|
||||
} else if ("-ll".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.text(FormattedDisk.FILE_DISPLAY_DETAIL), trimmedArgs);
|
||||
} else if ("-lsv".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_STANDARD), trimmedArgs);
|
||||
} else if ("-lv".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_NATIVE), trimmedArgs);
|
||||
} else if ("-llv".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.csv(FormattedDisk.FILE_DISPLAY_DETAIL), trimmedArgs);
|
||||
} else if ("-lsj".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_STANDARD), trimmedArgs);
|
||||
} else if ("-lj".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_NATIVE), trimmedArgs);
|
||||
} else if ("-llj".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
showDirectory(DirectoryLister.json(FormattedDisk.FILE_DISPLAY_DETAIL), trimmedArgs);
|
||||
} else if ("-e".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
getFile(trimmedArgs[1], trimmedArgs[2], true,
|
||||
(trimmedArgs.length > 3 ? new PrintStream(new FileOutputStream(trimmedArgs[3])) : System.out));
|
||||
} else if ("-x".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
getFiles(trimmedArgs[1], (args.length > 2 ? trimmedArgs[2] : ""));
|
||||
} else if ("-g".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
getFile(trimmedArgs[1], trimmedArgs[2], false,
|
||||
(trimmedArgs.length > 3 ? new PrintStream(new FileOutputStream(trimmedArgs[3])) : System.out));
|
||||
} else if ("-p".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
String addr = "0x2000";
|
||||
if (trimmedArgs.length > 5) {
|
||||
addr = trimmedArgs[4];
|
||||
inputStream = stdinOrFile(trimmedArgs[5]);
|
||||
} else {
|
||||
inputStream = stdinOrFile(trimmedArgs[4]);
|
||||
}
|
||||
putFile(trimmedArgs[1], new Name(trimmedArgs[2]), trimmedArgs[3], addr, inputStream);
|
||||
} else if ("-pt".equalsIgnoreCase(trimmedArgs[0])) {
|
||||
inputStream = stdinOrFile(trimmedArgs[3]);
|
||||
putTxtFileSetHighBit(trimmedArgs[1], new Name(trimmedArgs[2]), inputStream);
|
||||
} else if ("-ptx".equalsIgnoreCase(trimmedArgs[0])) {
|
||||
inputStream = stdinOrFile(trimmedArgs[3]);
|
||||
putTxtFileClearHighBit(trimmedArgs[1], new Name(trimmedArgs[2]), inputStream);
|
||||
} else if ("-d".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
deleteFile(trimmedArgs[1], trimmedArgs[2]);
|
||||
} else if ("-k".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
setFileLocked(trimmedArgs[1], trimmedArgs[2], true);
|
||||
} else if ("-u".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
setFileLocked(trimmedArgs[1], trimmedArgs[2], false);
|
||||
} else if ("-n".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
setDiskName(trimmedArgs[1], trimmedArgs[2]);
|
||||
} else if ("-cc65".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
System.err.println("Note: -cc65 is deprecated. Please use -as or -dos as appropriate.");
|
||||
inputStream = stdinOrFile(trimmedArgs[4]);
|
||||
putDOS(trimmedArgs[1], new Name(trimmedArgs[2]), trimmedArgs[3], inputStream);
|
||||
} else if ("-dos".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
inputStream = stdinOrFile(trimmedArgs[4]);
|
||||
putDOS(trimmedArgs[1], new Name(trimmedArgs[2]), trimmedArgs[3], inputStream);
|
||||
} else if ("-as".equalsIgnoreCase(trimmedArgs[0])) {
|
||||
String fname = null;
|
||||
if (trimmedArgs.length > 4) {
|
||||
fname = trimmedArgs[2];
|
||||
inputStream = stdinOrFile(trimmedArgs[3]);
|
||||
} else {
|
||||
inputStream = stdinOrFile(trimmedArgs[2]);
|
||||
}
|
||||
putAppleSingle(trimmedArgs[1], trimmedArgs.length >= 3 ? fname : null, inputStream);
|
||||
} else if ("-geos".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
inputStream = stdinOrFile(trimmedArgs[2]);
|
||||
putGEOS(trimmedArgs[1], inputStream);
|
||||
} else if ("-dos140".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
createDosDisk(trimmedArgs[1], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pas140".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
createPasDisk(trimmedArgs[1], trimmedArgs[2], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pas800".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
createPasDisk(trimmedArgs[1], trimmedArgs[2], Disk.APPLE_800KB_DISK);
|
||||
} else if ("-pro140".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
createProDisk(trimmedArgs[1], trimmedArgs[2], Disk.APPLE_140KB_DISK);
|
||||
} else if ("-pro800".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
createProDisk(trimmedArgs[1], trimmedArgs[2], Disk.APPLE_800KB_DISK);
|
||||
} else if ("-convert".equalsIgnoreCase(trimmedArgs[0])) { //$NON-NLS-1$
|
||||
if (trimmedArgs.length > 3)
|
||||
convert(trimmedArgs[1], trimmedArgs[2], Integer.parseInt(trimmedArgs[3]));
|
||||
else
|
||||
convert(trimmedArgs[1], trimmedArgs[2]);
|
||||
} else if ("-bas".equalsIgnoreCase(trimmedArgs[0])) {
|
||||
inputStream = stdinOrFile(trimmedArgs[3]);
|
||||
putAppleSoft(trimmedArgs[1], trimmedArgs[2], inputStream);
|
||||
} else {
|
||||
help();
|
||||
}
|
||||
|
||||
// close out InputStream if we used one
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
argPtr = findNextOperationArg(args, argPtr + 1);
|
||||
|
||||
} // while
|
||||
} catch (Exception ex) {
|
||||
System.err.println(textBundle.format("CommandLineErrorMessage", //$NON-NLS-1$
|
||||
ex.getLocalizedMessage()));
|
||||
|
@ -201,11 +289,11 @@ public class ac {
|
|||
* Note that we try to infer the BASIC type dynamically and hard-code the start address
|
||||
* to 0x801.
|
||||
*/
|
||||
public static void putAppleSoft(String imageName, String fileName) throws IOException, DiskException {
|
||||
File fakeTempSource = File.createTempFile("ac-", "bas");
|
||||
fakeTempSource.deleteOnExit();
|
||||
public static void putAppleSoft(String imageName, String fileName, InputStream inputStream) throws IOException, DiskException {
|
||||
File fakeTempSource = File.createTempFile("ac-", "bas");
|
||||
fakeTempSource.deleteOnExit();
|
||||
Configuration config = Configuration.builder().sourceFile(fakeTempSource).build();
|
||||
Queue<Token> tokens = TokenReader.tokenize(System.in);
|
||||
Queue<Token> tokens = TokenReader.tokenize(inputStream);
|
||||
Parser parser = new Parser(tokens);
|
||||
Program program = parser.parse();
|
||||
byte[] data = Visitors.byteVisitor(config).dump(program);
|
||||
|
@ -271,32 +359,22 @@ public class ac {
|
|||
}
|
||||
|
||||
/**
|
||||
* Put <stdin>. into the file named fileName on the disk named imageName;
|
||||
* Note: only volume level supported; input size unlimited.
|
||||
* Put <stdin>. as an Apple text file into the file named
|
||||
* fileName on the disk named imageName.
|
||||
*/
|
||||
static void putFile(String imageName, Name name, String fileType,
|
||||
String address) throws IOException, DiskException {
|
||||
|
||||
putFile(imageName, name, fileType, address, System.in);
|
||||
static void putTxtFileSetHighBit(String imageName, Name name, InputStream inputStream) throws IOException, DiskException {
|
||||
// Order on the stream is important to ensure the translated newlines have the high bit done appropriately
|
||||
putFile(imageName, name, "TXT", "0", TranslatorStream.builder(inputStream).lfToCr().setHighBit().get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Put <stdin>. as an Apple text file into the file named
|
||||
* fileName on the disk named imageName.
|
||||
*/
|
||||
static void putTxtFileSetHighBit(String imageName, Name name) throws IOException, DiskException {
|
||||
// Order on the stream is important to ensure the translated newlines have the high bit done appropriately
|
||||
putFile(imageName, name, "TXT", "0", TranslatorStream.builder(System.in).lfToCr().setHighBit().get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Put <stdin>. as an Apple text file into the file named
|
||||
* fileName on the disk named imageName.
|
||||
*/
|
||||
static void putTxtFileClearHighBit(String imageName, Name name) throws IOException, DiskException {
|
||||
// Order on the stream is important to ensure the translated newlines have the high bit done appropriately
|
||||
putFile(imageName, name, "TXT", "0", TranslatorStream.builder(System.in).lfToCr().clearHighBit().get());
|
||||
}
|
||||
/**
|
||||
* Put <stdin>. as an Apple text file into the file named
|
||||
* fileName on the disk named imageName.
|
||||
*/
|
||||
static void putTxtFileClearHighBit(String imageName, Name name, InputStream inputStream) throws IOException, DiskException {
|
||||
// Order on the stream is important to ensure the translated newlines have the high bit done appropriately
|
||||
putFile(imageName, name, "TXT", "0", TranslatorStream.builder(inputStream).lfToCr().clearHighBit().get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Put InputStream into the file named fileName on the disk named imageName;
|
||||
|
@ -335,11 +413,11 @@ public class ac {
|
|||
* Put file fileName into the file named fileOnImageName on the disk named imageName;
|
||||
* Assume a cc65 style four-byte header with start address in bytes 0-1.
|
||||
*/
|
||||
public static void putDOS(String fileName, String imageName, String fileOnImageName, String fileType)
|
||||
public static void putDOS(String fileName, String imageName, String fileOnImageName, String fileType, InputStream inputStream)
|
||||
throws IOException, DiskException {
|
||||
|
||||
byte[] header = new byte[4];
|
||||
if (System.in.read(header, 0, 4) == 4) {
|
||||
if (inputStream.read(header, 0, 4) == 4) {
|
||||
int address = AppleUtil.getWordValue(header, 0);
|
||||
putFile(fileName, imageName, fileOnImageName, fileType, Integer.toString(address));
|
||||
}
|
||||
|
@ -349,22 +427,16 @@ public class ac {
|
|||
* Put <stdin> into the file named fileName on the disk named imageName;
|
||||
* Assume an DOS 3.x style four-byte header with start address in bytes 0-1.
|
||||
*/
|
||||
static void putDOS(String imageName, Name name, String fileType)
|
||||
static void putDOS(String imageName, Name name, String fileType, InputStream inputStream)
|
||||
throws IOException, DiskException {
|
||||
|
||||
byte[] header = new byte[4];
|
||||
if (System.in.read(header, 0, 4) == 4) {
|
||||
if (inputStream.read(header, 0, 4) == 4) {
|
||||
int address = AppleUtil.getWordValue(header, 0);
|
||||
putFile(imageName, name, fileType, Integer.toString(address));
|
||||
putFile(imageName, name, fileType, Integer.toString(address), inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put file from AppleSingle format into ProDOS image.
|
||||
*/
|
||||
public static void putAppleSingle(String imageName, String fileName) throws IOException, DiskException {
|
||||
putAppleSingle(imageName, fileName, System.in);
|
||||
}
|
||||
/**
|
||||
* AppleSingle shim to allow for unit testing.
|
||||
*/
|
||||
|
@ -395,9 +467,9 @@ public class ac {
|
|||
* Interpret <stdin> as a GEOS file and place it on the disk named imageName.
|
||||
* This would only make sense for a ProDOS-formatted disk.
|
||||
*/
|
||||
static void putGEOS(String imageName)
|
||||
static void putGEOS(String imageName, InputStream inputStream)
|
||||
throws IOException, DiskException {
|
||||
putFile(imageName, new Name("GEOS-Should Be ProDOS"), "GEO", "0"); //$NON-NLS-2$ $NON-NLS-3$
|
||||
putFile(imageName, new Name("GEOS-Should Be ProDOS"), "GEO", "0", inputStream); //$NON-NLS-2$ $NON-NLS-3$
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,16 +19,14 @@
|
|||
*/
|
||||
package io.github.applecommander.acx.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.util.Name;
|
||||
import com.webcodepro.applecommander.util.filestreamer.FileStreamer;
|
||||
import com.webcodepro.applecommander.util.filestreamer.FileTuple;
|
||||
import com.webcodepro.applecommander.util.filestreamer.TypeOfFile;
|
||||
|
||||
import io.github.applecommander.acx.base.ReadWriteDiskCommandOptions;
|
||||
import io.github.applecommander.acx.converter.DiskConverter;
|
||||
import io.github.applecommander.acx.fileutil.FileUtils;
|
||||
|
@ -36,6 +34,10 @@ import picocli.CommandLine.Command;
|
|||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Parameters;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Command(name = "copy", description = "Copy files between disks.",
|
||||
aliases = { "cp" })
|
||||
public class CopyFileCommand extends ReadWriteDiskCommandOptions {
|
||||
|
@ -63,7 +65,7 @@ public class CopyFileCommand extends ReadWriteDiskCommandOptions {
|
|||
List<FileTuple> files = FileStreamer.forDisk(sourceDisk)
|
||||
.ignoreErrors(true)
|
||||
.includeTypeOfFile(TypeOfFile.BOTH)
|
||||
.recursive(recursiveFlag)
|
||||
.recursive(false) // we handle recursion in the FileUtils
|
||||
.matchGlobs(globs)
|
||||
.stream()
|
||||
.collect(Collectors.toList());
|
||||
|
|
|
@ -19,17 +19,16 @@
|
|||
*/
|
||||
package io.github.applecommander.acx.fileutil;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.util.readerwriter.FileEntryReader;
|
||||
import com.webcodepro.applecommander.util.readerwriter.FileEntryWriter;
|
||||
|
||||
import io.github.applecommander.acx.command.CopyFileCommand;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class FileUtils {
|
||||
private static Logger LOG = Logger.getLogger(CopyFileCommand.class.getName());
|
||||
|
||||
|
@ -40,7 +39,7 @@ public class FileUtils {
|
|||
}
|
||||
|
||||
public void copy(DirectoryEntry directory, FileEntry file) throws DiskException {
|
||||
LOG.fine(() -> String.format("Copying '%s'", file.getFilename()));
|
||||
LOG.fine(() -> String.format("Copying '%s' into directory '%s'", file.getFilename(), directory.getDirname()));
|
||||
if (file.isDeleted()) {
|
||||
// Skip deleted files
|
||||
}
|
||||
|
@ -112,13 +111,15 @@ public class FileUtils {
|
|||
source.getBinaryAddress().ifPresent(target::setBinaryAddress);
|
||||
source.getBinaryLength().ifPresent(target::setBinaryLength);
|
||||
source.getAuxiliaryType().ifPresent(target::setAuxiliaryType);
|
||||
source.getCreationDate().ifPresent(target::setCreationDate);
|
||||
source.getLastModificationDate().ifPresent(target::setLastModificationDate);
|
||||
source.getCreationDate().ifPresent(target::setCreationDate);
|
||||
|
||||
if (source.getFileData().isPresent() && source.getResourceData().isPresent()) {
|
||||
target.setFileData(source.getFileData().get(), source.getResourceData().get());
|
||||
} else {
|
||||
source.getFileData().ifPresent(target::setFileData);
|
||||
}
|
||||
|
||||
// Modification date needs to be done last since writing file data/attributes are likely to change it
|
||||
source.getLastModificationDate().ifPresent(target::setLastModificationDate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,11 @@ asVersion=1.2.1
|
|||
btVersion=0.3.1
|
||||
swtVersion=3.123.0
|
||||
piSwtVersion=3.8.2
|
||||
junitVersion=4.12
|
||||
antVersion=1.8.2
|
||||
junitVersion=4.13.1
|
||||
antVersion=1.9.16
|
||||
commonsLang3Version=3.7
|
||||
commonsCsvVersion=1.8
|
||||
gsonVersion=2.8.6
|
||||
gsonVersion=2.8.9
|
||||
picocliVersion=4.6.2
|
||||
springBoot=2.6.1
|
||||
acdasmVersion=0.4.0
|
||||
|
|
|
@ -33,6 +33,11 @@ import java.util.List;
|
|||
* @author Lisias Toledo
|
||||
*/
|
||||
public interface DirectoryEntry {
|
||||
/**
|
||||
* Return a name for this directory.
|
||||
*/
|
||||
public String getDirname();
|
||||
|
||||
/**
|
||||
* Retrieve the list of files in this directory.
|
||||
* Note that if this is not a directory, the return
|
||||
|
|
|
@ -19,14 +19,15 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage;
|
||||
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
/**
|
||||
* Abstract representation of a formatted Apple2 disk (floppy, 800k, hard disk).
|
||||
|
@ -139,7 +140,14 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
|
|||
* but "DISK VOLUME #xxx" (DOS 3.3) or "/MY.DISK" (ProDOS).
|
||||
*/
|
||||
public abstract String getDiskName();
|
||||
|
||||
|
||||
/**
|
||||
* Return a name for this directory.
|
||||
*/
|
||||
public String getDirname(){
|
||||
return getDiskName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the disk to volumeName.
|
||||
*/
|
||||
|
@ -404,4 +412,15 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
|
|||
* Gives an indication on how this disk's geometry should be handled.
|
||||
*/
|
||||
public abstract DiskGeometry getDiskGeometry();
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
public abstract String fromProdosFiletype(String prodosFiletype);
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
public abstract String toProdosFiletype(String nativeFiletype);
|
||||
}
|
||||
|
|
|
@ -19,22 +19,13 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.cpm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in the Apple CP/M format.
|
||||
* <p>
|
||||
|
@ -565,4 +556,29 @@ public class CpmFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.TRACK_SECTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
if ("TXT".equalsIgnoreCase(prodosFiletype)) {
|
||||
return "TXT";
|
||||
}
|
||||
return "BIN";
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
for (String textFiletype : CpmFileEntry.TEXT_FILETYPES) {
|
||||
if (textFiletype.equalsIgnoreCase(nativeFiletype)) {
|
||||
return "TXT";
|
||||
}
|
||||
}
|
||||
return "BIN";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,23 +19,13 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.dos33;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in Apple DOS 3.3 format.
|
||||
* <p>
|
||||
|
@ -70,11 +60,20 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
/**
|
||||
* The list of filetypes available.
|
||||
*/
|
||||
private static final String[] filetypes = {
|
||||
"T", "A", "I", "B", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
"S", "R", "a", "b" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
private static final String[] FILE_TYPES = {
|
||||
"T", "A", "I", "B",
|
||||
"S", "R", "a", "b"
|
||||
};
|
||||
|
||||
private static final Map<String,String> FILE_TYPE_MAPPING = Map.of(
|
||||
"T", "TXT",
|
||||
"I", "INT",
|
||||
"A", "BAS",
|
||||
"B", "BIN",
|
||||
"S", "$F1",
|
||||
"R", "REL",
|
||||
"a", "$F2",
|
||||
"b", "$F3"
|
||||
);
|
||||
/**
|
||||
* Use this inner interface for managing the disk usage data.
|
||||
* This off-loads format-specific implementation to the implementing class.
|
||||
|
@ -739,7 +738,7 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
* specific to each operating system, a simple String is used.
|
||||
*/
|
||||
public String[] getFiletypes() {
|
||||
return filetypes;
|
||||
return FILE_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -781,4 +780,26 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.TRACK_SECTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return FILE_TYPE_MAPPING.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().equals(prodosFiletype))
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.orElse("B");
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return FILE_TYPE_MAPPING.getOrDefault(nativeFiletype, "BIN");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,19 +19,14 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.gutenberg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in Gutenberg Word Processor format.
|
||||
* <p>
|
||||
|
@ -707,4 +702,21 @@ public class GutenbergFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.TRACK_SECTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return "T";
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return "TXT";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,19 +19,14 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.nakedos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in NakedOS format.
|
||||
* <p>
|
||||
|
@ -545,4 +540,21 @@ public class NakedosFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.TRACK_SECTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return "B";
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return "BIN";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,13 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.pascal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in the Pascal format.
|
||||
* <p>
|
||||
|
@ -58,15 +50,31 @@ public class PascalFormatDisk extends FormattedDisk {
|
|||
/**
|
||||
* The known filetypes for a Pascal disk.
|
||||
*/
|
||||
private static final String[] filetypes = {
|
||||
"xdskfile", //$NON-NLS-1$
|
||||
private static final String[] FILE_TYPES = {
|
||||
"xdskfile",
|
||||
CODEFILE,
|
||||
TEXTFILE,
|
||||
"INFO", //$NON-NLS-1$
|
||||
"INFO",
|
||||
DATAFILE,
|
||||
"GRAF", //$NON-NLS-1$
|
||||
"FOTO", //$NON-NLS-1$
|
||||
"securedir" }; //$NON-NLS-1$
|
||||
"GRAF",
|
||||
"FOTO",
|
||||
"securedir"
|
||||
};
|
||||
private static final Map<String,String> FILE_TYPE_MAP = Map.of(
|
||||
// Pascal => Prodos
|
||||
"xdskfile", "BAD",
|
||||
CODEFILE, "BIN",
|
||||
TEXTFILE, "TXT",
|
||||
"INFO", "TXT",
|
||||
DATAFILE, "BIN",
|
||||
"GRAF", "BIN",
|
||||
"FOTO", "BIN",
|
||||
"securedir", "BIN",
|
||||
|
||||
// Prodos => Pascal
|
||||
"BIN", DATAFILE,
|
||||
"TXT", TEXTFILE
|
||||
);
|
||||
|
||||
/**
|
||||
* Use this inner interface for managing the disk usage data.
|
||||
|
@ -624,7 +632,7 @@ public class PascalFormatDisk extends FormattedDisk {
|
|||
* specific to each operating system, a simple String is used.
|
||||
*/
|
||||
public String[] getFiletypes() {
|
||||
return filetypes;
|
||||
return FILE_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -675,4 +683,21 @@ public class PascalFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.BLOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return FILE_TYPE_MAP.getOrDefault(prodosFiletype, DATAFILE);
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return FILE_TYPE_MAP.getOrDefault(nativeFiletype, "BIN");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.prodos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implement directory functionality.
|
||||
* <p>
|
||||
|
@ -55,6 +55,13 @@ public class ProdosDirectoryEntry extends ProdosFileEntry implements DirectoryEn
|
|||
return this.subdirectoryHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name for this directory.
|
||||
*/
|
||||
public String getDirname(){
|
||||
return getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the list of files in this directory.
|
||||
* Note that if this is not a directory, the return
|
||||
|
|
|
@ -19,27 +19,15 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.prodos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in the ProDOS format.
|
||||
* <p>
|
||||
|
@ -1469,4 +1457,21 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.BLOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return prodosFiletype;
|
||||
};
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return nativeFiletype;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,21 +19,17 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.storage.os.rdos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ProdosOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manages a disk that is in the RDOS format.
|
||||
* <p>
|
||||
|
@ -79,7 +75,12 @@ public class RdosFormatDisk extends FormattedDisk {
|
|||
/**
|
||||
* The known filetypes for a RDOS disk.
|
||||
*/
|
||||
public static final String[] filetypes = { "B", "A", "T" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
public static final String[] FILE_TYPES = { "B", "A", "T" };
|
||||
private static final Map<String,String> FILE_TYPE_MAPPING = Map.of(
|
||||
"T", "TXT",
|
||||
"A", "BAS",
|
||||
"B", "BIN"
|
||||
);
|
||||
|
||||
/**
|
||||
* 13 sectors for RDOS 2.1/3.2, native sectoring (16) for RDOS 3.3
|
||||
|
@ -517,7 +518,7 @@ public class RdosFormatDisk extends FormattedDisk {
|
|||
* specific to each operating system, a simple String is used.
|
||||
*/
|
||||
public String[] getFiletypes() {
|
||||
return filetypes;
|
||||
return FILE_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -570,4 +571,26 @@ public class RdosFormatDisk extends FormattedDisk {
|
|||
public DiskGeometry getDiskGeometry() {
|
||||
return DiskGeometry.TRACK_SECTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides conversation from a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String fromProdosFiletype(String prodosFiletype) {
|
||||
return FILE_TYPE_MAPPING.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().equals(prodosFiletype))
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.orElse("B");
|
||||
}
|
||||
/**
|
||||
* Provides conversation to a given ProDOS file type since as it is common across
|
||||
* many archiving tools.
|
||||
*/
|
||||
@Override
|
||||
public String toProdosFiletype(String nativeFiletype) {
|
||||
return FILE_TYPE_MAPPING.getOrDefault(nativeFiletype, "BIN");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,29 +19,14 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.util.readerwriter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.os.dos33.DosFileEntry;
|
||||
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class DosFileEntryReaderWriter implements FileEntryReader, FileEntryWriter {
|
||||
private static final Map<String,String> FILE_TYPES;
|
||||
static {
|
||||
FILE_TYPES = Map.of(
|
||||
"T", "TXT",
|
||||
"I", "INT",
|
||||
"A", "BAS",
|
||||
"B", "BIN",
|
||||
"S", "$F1",
|
||||
"R", "REL",
|
||||
"a", "$F2",
|
||||
"b", "$F3"
|
||||
);
|
||||
}
|
||||
|
||||
private DosFileEntry fileEntry;
|
||||
|
||||
public DosFileEntryReaderWriter(DosFileEntry fileEntry) {
|
||||
|
@ -62,17 +47,13 @@ public class DosFileEntryReaderWriter implements FileEntryReader, FileEntryWrite
|
|||
|
||||
@Override
|
||||
public Optional<String> getProdosFiletype() {
|
||||
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
|
||||
String prodosFiletype = fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype());
|
||||
return Optional.ofNullable(prodosFiletype);
|
||||
}
|
||||
@Override
|
||||
public void setProdosFiletype(String filetype) {
|
||||
String dosFileType = FILE_TYPES.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().equals(filetype))
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.orElse("B");
|
||||
fileEntry.setFiletype(dosFileType);
|
||||
String dosFiletype = fileEntry.getFormattedDisk().fromProdosFiletype(filetype);
|
||||
fileEntry.setFiletype(dosFiletype);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,35 +19,16 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.util.readerwriter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
||||
import com.webcodepro.applecommander.storage.os.pascal.PascalFileEntry;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
public class PascalFileEntryReaderWriter implements FileEntryReader, FileEntryWriter {
|
||||
private static final PascalTextFileFilter TEXT_FILTER = new PascalTextFileFilter();
|
||||
private static final Map<String,String> FILE_TYPES;
|
||||
static {
|
||||
FILE_TYPES = Map.of(
|
||||
// Pascal => Prodos
|
||||
"xdskfile", "BAD", // TODO we should skip bad block files
|
||||
"CODE", "BIN", // TODO is there an address?
|
||||
"TEXT", "TXT",
|
||||
"INFO", "TXT", // TODO We should skip debugger info
|
||||
"DATA", "BIN",
|
||||
"GRAF", "BIN", // TODO compressed graphics image
|
||||
"FOTO", "BIN", // TODO screen image
|
||||
"securedir", "BIN", // TODO is this even implemented
|
||||
|
||||
// Prodos => Pascal
|
||||
"BIN", "DATA",
|
||||
"TXT", "TEXT"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private PascalFileEntry fileEntry;
|
||||
|
||||
public PascalFileEntryReaderWriter(PascalFileEntry fileEntry) {
|
||||
|
@ -65,11 +46,11 @@ public class PascalFileEntryReaderWriter implements FileEntryReader, FileEntryWr
|
|||
|
||||
@Override
|
||||
public Optional<String> getProdosFiletype() {
|
||||
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
|
||||
return Optional.ofNullable(fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype()));
|
||||
}
|
||||
@Override
|
||||
public void setProdosFiletype(String filetype) {
|
||||
fileEntry.setFiletype(FILE_TYPES.getOrDefault(filetype, "DATA"));
|
||||
fileEntry.setFiletype(fileEntry.getFormattedDisk().fromProdosFiletype(filetype));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,21 +19,11 @@
|
|||
*/
|
||||
package com.webcodepro.applecommander.util.readerwriter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.webcodepro.applecommander.storage.os.rdos.RdosFileEntry;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class RdosFileEntryReader implements FileEntryReader {
|
||||
private static final Map<String,String> FILE_TYPES;
|
||||
static {
|
||||
FILE_TYPES = Map.of(
|
||||
"T", "TXT",
|
||||
"A", "BAS",
|
||||
"B", "BIN"
|
||||
);
|
||||
}
|
||||
|
||||
private RdosFileEntry fileEntry;
|
||||
|
||||
public RdosFileEntryReader(RdosFileEntry fileEntry) {
|
||||
|
@ -52,7 +42,7 @@ public class RdosFileEntryReader implements FileEntryReader {
|
|||
|
||||
@Override
|
||||
public Optional<String> getProdosFiletype() {
|
||||
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
|
||||
return Optional.ofNullable(fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -104,6 +104,7 @@ CommandLineNoMatchMessage = {0}: No match.
|
|||
CommandLineStatus = {0} format; {1} bytes free; {2} bytes used.
|
||||
CommandLineHelp = \
|
||||
AppleCommander command line options [{0}]:\n\
|
||||
NOTE: <infile> can either be a local file or '-' for STDIN.\n\
|
||||
-i <imagename> [<imagename>] display information about image(s).\n\
|
||||
-ls <imagename> [<imagename>] list brief directory of image(s).\n\
|
||||
-l <imagename> [<imagename>] list directory of image(s).\n\
|
||||
|
@ -117,16 +118,16 @@ CommandLineHelp = \
|
|||
-e <imagename> <filename> [<output>] export file from image to stdout\n or to an output file.\n\
|
||||
-x <imagename> [<directory>] extract all files from image to directory.\n\
|
||||
-g <imagename> <filename> [<output>] get raw file from image to stdout\n or to an output file.\n\
|
||||
-p <imagename> <filename> <type> [[$|0x]<addr>] put stdin\n in filename on image, using file type and address [0x2000].\n\
|
||||
-pt <imagename> <filename> put stdin in filename on image\n defaulting to TXT file type, setting high bit on and replacing\n newline characters with $8D.\n\
|
||||
-ptx <imagename> <filename> put stdin in filename on image\n defaulting to TXT file type, clearing high bit and replacing\n newline characters with $0D.\n\
|
||||
-p <imagename> <filename> <type> [[$|0x]<addr>] <infile> put infile\n as filename on image, using file type and address [0x2000].\n\
|
||||
-pt <imagename> <filename> <infile> put infile as filename on image\n defaulting to TXT file type, setting high bit on and replacing\n newline characters with $8D.\n\
|
||||
-ptx <imagename> <filename> <infile> put infile as filename on image\n defaulting to TXT file type, clearing high bit and replacing\n newline characters with $0D.\n\
|
||||
-d <imagename> <filename> delete file from image.\n\
|
||||
-k <imagename> <filename> lock file on image.\n\
|
||||
-u <imagename> <filename> unlock file on image.\n\
|
||||
-n <imagename> <volname> change volume name (ProDOS or Pascal).\n\
|
||||
-dos <imagename> <filename> <type> put stdin with DOS header\n in filename on image, using file type and address from header.\n\
|
||||
-as <imagename> [<filename>] put stdin with AppleSingle format\n in filename on image, using file type, address, and (optionally) name\n from the AppleSingle file.\n\
|
||||
-geos <imagename> interpret stdin as a GEOS conversion file and\n place it on image (ProDOS only).\n\
|
||||
-dos <imagename> <filename> <type> <infile> put infile with DOS header\n as filename on image, using file type and address from header.\n\
|
||||
-as <imagename> [<filename>] <infile> put infile with AppleSingle format\n as filename on image, using file type, address, and (optionally) name\n from the AppleSingle file.\n\
|
||||
-geos <imagename> interpret infile as a GEOS conversion file and\n place it on image (ProDOS only).\n\
|
||||
-dos140 <imagename> create a 140K DOS 3.3 image.\n\
|
||||
-pro140 <imagename> <volname>\n create a 140K ProDOS image.\n\
|
||||
-pro800 <imagename> <volname> create an 800K ProDOS image.\n\
|
||||
|
|
|
@ -211,7 +211,8 @@ public class ImportSelectFilesWizardPane extends WizardPane {
|
|||
AppleSingle as = AppleSingle.read(data);
|
||||
suggestedFilename = Optional.ofNullable(as.getRealName())
|
||||
.orElse(suggestedFilename);
|
||||
suggestedFiletype = ProdosFormatDisk.getFiletype(as.getProdosFileInfo().getFileType());
|
||||
suggestedFiletype = wizard.getDisk().fromProdosFiletype(
|
||||
ProdosFormatDisk.getFiletype(as.getProdosFileInfo().getFileType()));
|
||||
suggestedAddress = Optional.ofNullable(as.getProdosFileInfo())
|
||||
.map(ProdosFileInfo::getAuxType)
|
||||
.orElse(suggestedAddress);
|
||||
|
@ -285,7 +286,7 @@ public class ImportSelectFilesWizardPane extends WizardPane {
|
|||
label.setText(textBundle.get("FiletypeLabel")); //$NON-NLS-1$
|
||||
final Combo filetypes = new Combo(dialog, SWT.BORDER | SWT.READ_ONLY);
|
||||
filetypes.setItems(wizard.getDisk().getFiletypes());
|
||||
if (spec.hasFiletype()) {
|
||||
if (spec.hasFiletype() && filetypes.indexOf(spec.getFiletype()) != -1) {
|
||||
filetypes.select(filetypes.indexOf(spec.getFiletype()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue