Adding '-pt' switch to import text with appropriate assumptions #27

This commit is contained in:
Rob Greene 2018-11-23 22:38:06 -06:00
parent a0a0c1ce74
commit c5ff4fb97d
4 changed files with 150 additions and 2 deletions

View File

@ -53,6 +53,7 @@ import com.webcodepro.applecommander.storage.physical.ProdosOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.StreamUtil;
import com.webcodepro.applecommander.util.TextBundle;
import com.webcodepro.applecommander.util.TranslatorStream;
import io.github.applecommander.applesingle.AppleSingle;
import io.github.applecommander.applesingle.ProdosFileInfo;
@ -134,6 +135,8 @@ public class ac {
} 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])) {
putTxtFile(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$
@ -260,7 +263,15 @@ public class ac {
putFile(imageName, name, fileType, address, System.in);
}
/**
* Put <stdin&gt. as an Apple text file into the file named
* fileName on the disk named imageName.
*/
static void putTxtFile(String imageName, Name name) throws IOException, DiskException {
putFile(imageName, name, "TXT", "0", TranslatorStream.builder(System.in).lfToCr().setHighBit().get());
}
/**
* Put InputStream into the file named fileName on the disk named imageName;
* Note: only volume level supported; input size unlimited.

View File

@ -0,0 +1,69 @@
package com.webcodepro.applecommander.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.UncheckedIOException;
import java.util.function.Function;
public class TranslatorStream extends InputStream {
private PushbackInputStream sourceStream;
// Defaults to a no-op transformation
private Function<Integer,Integer> fn = i -> i;
private TranslatorStream(InputStream sourceStream) {
this.sourceStream = new PushbackInputStream(sourceStream);
}
@Override
public int read() throws IOException {
return fn.apply(sourceStream.read());
}
private int setHighBit(int value) {
return value | 0x80;
}
private int lfToCr(int value) {
if (value == '\r') {
try {
int nextValue = sourceStream.read();
if (nextValue == '\n') {
return '\r';
} else {
if (nextValue != -1) sourceStream.unread(nextValue);
return value;
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
return (value == '\n') ? '\r' : value;
}
public static Builder builder(InputStream sourceStream) {
return new Builder(sourceStream);
}
public static class Builder {
private TranslatorStream stream;
private Builder(InputStream sourceStream) {
stream = new TranslatorStream(sourceStream);
}
private Builder fn(Function<Integer,Integer> andThen) {
stream.fn = stream.fn.andThen(andThen);
return this;
}
public Builder setHighBit() {
return fn(stream::setHighBit);
}
public Builder lfToCr() {
return fn(stream::lfToCr);
}
public TranslatorStream get() {
return stream;
}
}
}

View File

@ -102,7 +102,30 @@ CreateDirectoryMenuItem=Create Directory...
CommandLineErrorMessage = Error: {0}
CommandLineNoMatchMessage = {0}: No match.
CommandLineStatus = {0} format; {1} bytes free; {2} bytes used.
CommandLineHelp = CommandLineHelp = AppleCommander command line options [{0}]:\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-ll <imagename> [<imagename>] list detailed directory of image(s).\n-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-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-dos140 <imagename> create a 140K DOS 3.3 image.\n-pro140 <imagename> <volname> create a 140K ProDOS image.\n-pro800 <imagename> <volname> create an 800K ProDOS image.\n-pas140 <imagename> <volname> create a 140K Pascal image.\n-pas800 <imagename> <volname> create an 800K Pascal image.\n-convert <filename> <imagename> [<sizeblocks>] uncompress a ShrinkIt or Binary\n II file; or convert a DiskCopy 4.2 image into a ProDOS disk image.\n-bas <imagename> <filename> import an AppleSoft basic file from text\n back to it's tokenized format.
CommandLineHelp = \
CommandLineHelp = AppleCommander command line options [{0}]:\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\
-ll <imagename> [<imagename>] list detailed directory of image(s).\n\
-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\
-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\
-dos140 <imagename> create a 140K DOS 3.3 image.\n-pro140 <imagename> <volname> create a 140K ProDOS image.\n\
-pro800 <imagename> <volname> create an 800K ProDOS image.\n\
-pas140 <imagename> <volname> create a 140K Pascal image.\n\
-pas800 <imagename> <volname> create an 800K Pascal image.\n\
-convert <filename> <imagename> [<sizeblocks>] uncompress a ShrinkIt or Binary\n II file; or convert a DiskCopy 4.2 image into a ProDOS disk image.\n\
-bas <imagename> <filename> import an AppleSoft basic file from text\n back to it's tokenized format.
CommandLineSDKReadOnly = SDK, SHK, and DC42 files are read-only. Use the convert option on them first.
CommandLineDC42Bad = Unable to interpret this DiskCopy 42 image.

View File

@ -0,0 +1,45 @@
package com.webcodepro.applecommander.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Assert;
import org.junit.Test;
public class TranslatorStreamTest {
@Test
public void testUnixLineEndings() throws IOException {
byte[] source = "Hello\nWorld!\n".getBytes();
testAgainstExpected(source);
}
@Test
public void testDosLineEndings() throws IOException {
byte[] source = "Hello\r\nWorld!\r\n".getBytes();
testAgainstExpected(source);
}
@Test
public void testAppleLineEndings() throws IOException {
byte[] source = "Hello\rWorld!\r".getBytes();
testAgainstExpected(source);
}
private void testAgainstExpected(final byte[] source) throws IOException {
final byte[] expected = { (byte)0xc8, (byte)0xe5, (byte)0xec, (byte)0xec,
(byte)0xef, (byte)0x8d, (byte)0xd7, (byte)0xef, (byte)0xf2,
(byte)0xec, (byte)0xe4, (byte)0xa1, (byte)0x8d };
InputStream is = TranslatorStream.builder(new ByteArrayInputStream(source)).lfToCr().setHighBit().get();
byte[] actual = null;
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
StreamUtil.copy(is, os);
actual = os.toByteArray();
}
Assert.assertArrayEquals(expected, actual);
}
}